pierreguillou commited on
Commit
3934f0c
·
verified ·
1 Parent(s): 60e5dfe

Delete helpers/rapport-generator.py

Browse files
Files changed (1) hide show
  1. helpers/rapport-generator.py +0 -380
helpers/rapport-generator.py DELETED
@@ -1,380 +0,0 @@
1
- ## class to generate the DOCX report
2
-
3
- class RapportGenerator:
4
- def __init__(self, json_file: str):
5
- self.doc = Document()
6
- self.logger = logging.getLogger(__name__)
7
- logging.basicConfig(level=logging.INFO)
8
- self.json_data = self.load_json(json_file)
9
- self._setup_document()
10
-
11
- def load_json(self, json_file: str) -> Dict:
12
- """Charge le fichier JSON"""
13
- try:
14
- with open(json_file, 'r', encoding='utf-8') as f:
15
- return json.load(f)
16
- except Exception as e:
17
- self.logger.error(f"Erreur lors de la lecture du JSON: {str(e)}")
18
- raise
19
-
20
- def _setup_document(self):
21
- """Configure le document"""
22
- sections = self.doc.sections
23
- for section in sections:
24
- section.bottom_margin = Inches(1)
25
- self._create_page_number()
26
-
27
- def _create_page_number(self):
28
- """Crée le numéro de page dans le pied de page"""
29
- section = self.doc.sections[0]
30
- footer = section.footer
31
- paragraph = footer.paragraphs[0]
32
- paragraph.alignment = WD_ALIGN_PARAGRAPH.RIGHT
33
-
34
- run = paragraph.add_run()
35
- self._create_element(run, 'PAGE')
36
- run = paragraph.add_run(" / ")
37
- run = paragraph.add_run()
38
- self._create_element(run, 'NUMPAGES')
39
-
40
- def _create_element(self, run, text):
41
- """Crée un élément de champ Word"""
42
- fldChar1 = OxmlElement('w:fldChar')
43
- fldChar1.set(qn('w:fldCharType'), 'begin')
44
- run._r.append(fldChar1)
45
-
46
- instrText = OxmlElement('w:instrText')
47
- instrText.text = text
48
- run._r.append(instrText)
49
-
50
- fldChar2 = OxmlElement('w:fldChar')
51
- fldChar2.set(qn('w:fldCharType'), 'end')
52
- run._r.append(fldChar2)
53
-
54
- def _add_title(self, text: str, level: int = 1):
55
- """Ajoute un titre avec style et taille appropriés"""
56
- heading = self.doc.add_heading(level=level)
57
- heading.alignment = WD_ALIGN_PARAGRAPH.LEFT
58
- run = heading.add_run(text.strip()) # Ajout de strip()
59
- font_sizes = {0: 18, 1: 16, 2: 14, 3: 12}
60
- run.font.size = Pt(font_sizes.get(level, 12))
61
-
62
- def _format_key(self, key: str) -> str:
63
- """Formate la clé en supprimant les suffixes _DEMANDEUR et _DEFENDEUR"""
64
- key = key.replace("_", " ").title()
65
- key = key.replace(" Demandeur", "")
66
- key = key.replace(" Defendeur", "")
67
- return key
68
-
69
- def _get_safe_value(self, data: Dict, key: str, default: str = '') -> str:
70
- """Récupère une valeur en toute sécurité du dictionnaire"""
71
- if isinstance(data, dict):
72
- return str(data.get(key, default))
73
- return default
74
-
75
- def _format_person_info(self, data: Dict, is_lawyer: bool = False) -> Dict[str, str]:
76
- """Formate les informations d'une personne"""
77
- info = {}
78
-
79
- if not isinstance(data, dict):
80
- return info
81
-
82
- if is_lawyer:
83
- # Informations de l'avocat
84
- civilite = self._get_safe_value(data, 'CIVILITE_AVOCAT_DEMANDEUR') or self._get_safe_value(data, 'CIVILITE_AVOCAT_DEFENDEUR')
85
- prenom = self._get_safe_value(data, 'PRENOM_AVOCAT_DEMANDEUR') or self._get_safe_value(data, 'PRENOM_AVOCAT_DEFENDEUR')
86
- nom = self._get_safe_value(data, 'NOM_AVOCAT_DEMANDEUR') or self._get_safe_value(data, 'NOM_AVOCAT_DEFENDEUR')
87
-
88
- info['Nom'] = f"{civilite} {prenom} {nom}".strip()
89
- info['Barreau'] = self._get_safe_value(data, 'BARREAU_AVOCAT_DEMANDEUR') or self._get_safe_value(data, 'BARREAU_AVOCAT_DEFENDEUR')
90
- info['Bureau d\'avocats'] = self._get_safe_value(data, 'BUREAU_AVOCAT_DEMANDEUR') or self._get_safe_value(data, 'BUREAU_AVOCAT_DEFENDEUR')
91
-
92
- adresse = data.get('ADRESSE_AVOCAT_DEMANDEUR', {}) if isinstance(data.get('ADRESSE_AVOCAT_DEMANDEUR'), dict) else {}
93
- if not adresse:
94
- adresse = data.get('ADRESSE_AVOCAT_DEFENDEUR', {}) if isinstance(data.get('ADRESSE_AVOCAT_DEFENDEUR'), dict) else {}
95
-
96
- info['Adresse Complete'] = self._get_safe_value(adresse, 'ADRESSE_COMPLETE_AVOCAT_DEMANDEUR') or self._get_safe_value(adresse, 'ADRESSE_COMPLETE_AVOCAT_DEFENDEUR')
97
- info['Email'] = self._get_safe_value(data, 'EMAIL_AVOCAT_DEMANDEUR') or self._get_safe_value(data, 'EMAIL_AVOCAT_DEFENDEUR')
98
- info['Telephone'] = self._get_safe_value(data, 'TELEPHONE_AVOCAT_DEMANDEUR') or self._get_safe_value(data, 'TELEPHONE_AVOCAT_DEFENDEUR')
99
- else:
100
- # Informations de la partie
101
- civilite = self._get_safe_value(data, 'CIVILITE_DEMANDEUR') or self._get_safe_value(data, 'CIVILITE_DEFENDEUR')
102
- prenom = self._get_safe_value(data, 'PRENOM_DEMANDEUR') or self._get_safe_value(data, 'PRENOM_DEFENDEUR')
103
- nom = self._get_safe_value(data, 'NOM_DEMANDEUR') or self._get_safe_value(data, 'NOM_DEFENDEUR')
104
-
105
- info['Nom'] = f"{civilite} {prenom} {nom}".strip()
106
- info['Organisme'] = self._get_safe_value(data, 'ORGANISME_DEMANDEUR') or self._get_safe_value(data, 'ORGANISME_DEFENDEUR')
107
-
108
- adresse = data.get('ADRESSE_DEMANDEUR', {}) if isinstance(data.get('ADRESSE_DEMANDEUR'), dict) else {}
109
- if not adresse:
110
- adresse = data.get('ADRESSE_DEFENDEUR', {}) if isinstance(data.get('ADRESSE_DEFENDEUR'), dict) else {}
111
-
112
- info['Adresse Complete'] = self._get_safe_value(adresse, 'ADRESSE_COMPLETE_DEMANDEUR') or self._get_safe_value(adresse, 'ADRESSE_COMPLETE_DEFENDEUR')
113
- info['Email'] = self._get_safe_value(data, 'EMAIL_DEMANDEUR') or self._get_safe_value(data, 'EMAIL_DEFENDEUR')
114
- info['Telephone'] = self._get_safe_value(data, 'TELEPHONE_DEMANDEUR') or self._get_safe_value(data, 'TELEPHONE_DEFENDEUR')
115
-
116
- return {k: v for k, v in info.items() if v and v != "Non spécifié"}
117
-
118
- def _process_special_fields(self, key: str, value: Any) -> bool:
119
- """Traite les champs spéciaux (HISTORIQUE et MISSION)"""
120
- if key in ["HISTORIQUE", "MISSION"]:
121
- self._add_title(key.upper().strip(), 1)
122
-
123
- # Vérifier si la valeur est une liste
124
- if isinstance(value, list):
125
- for item in value:
126
- p = self.doc.add_paragraph()
127
- p.add_run(str(item).strip())
128
- else:
129
- # Si c'est une chaîne simple ou autre type
130
- p = self.doc.add_paragraph()
131
- p.add_run(str(value).strip())
132
-
133
- # Ajouter un espace après HISTORIQUE seulement
134
- if key == "HISTORIQUE":
135
- self.doc.add_paragraph()
136
-
137
- return True
138
- return False
139
-
140
- def _process_parties(self, title: str, items: Union[str, List], level: int):
141
- """Traite les parties (demandeurs/défendeurs)"""
142
- self._add_title(title, level)
143
-
144
- # Si aucune partie n'est spécifiée
145
- if isinstance(items, str) and items == "Non spécifié":
146
- p = self.doc.add_paragraph(style='List Bullet')
147
- p.add_run("Non spécifié")
148
- return
149
-
150
- # Traitement de chaque partie
151
- if isinstance(items, list):
152
- for idx, item in enumerate(items, 1):
153
- if not isinstance(item, dict):
154
- continue
155
-
156
- # Sous-titre pour chaque partie
157
- partie_title = f"{title.rstrip('S')} {idx}"
158
- self._add_title(partie_title, level + 1)
159
-
160
- # Formatage du nom complet
161
- civilite = self._get_safe_value(item, f'CIVILITE_{title.rstrip("S")}', '')
162
- prenom = self._get_safe_value(item, f'PRENOM_{title.rstrip("S")}', '')
163
- nom = self._get_safe_value(item, f'NOM_{title.rstrip("S")}', '')
164
- nom_complet = f"{civilite} {prenom} {nom}".strip()
165
-
166
- # Ajout du nom
167
- if nom_complet and nom_complet != "Non spécifié":
168
- p = self.doc.add_paragraph(style='List Bullet')
169
- p.add_run("Nom: ").bold = True
170
- p.add_run(nom_complet)
171
-
172
- # Récupération de l'adresse
173
- adresse = item.get(f'ADRESSE_{title.rstrip("S")}', {})
174
- if isinstance(adresse, dict):
175
- adresse_complete = adresse.get(f'ADRESSE_COMPLETE_{title.rstrip("S")}', '')
176
- if adresse_complete and adresse_complete != "Non spécifié":
177
- p = self.doc.add_paragraph(style='List Bullet')
178
- p.add_run("Adresse Complete: ").bold = True
179
- p.add_run(adresse_complete)
180
-
181
- # Ajout du téléphone
182
- telephone = self._get_safe_value(item, f'TELEPHONE_{title.rstrip("S")}', '')
183
- if telephone and telephone != "Non spécifié":
184
- p = self.doc.add_paragraph(style='List Bullet')
185
- p.add_run("Téléphone: ").bold = True
186
- p.add_run(telephone)
187
-
188
- # Ajout de l'email
189
- email = self._get_safe_value(item, f'EMAIL_{title.rstrip("S")}', '')
190
- if email and email != "Non spécifié":
191
- p = self.doc.add_paragraph(style='List Bullet')
192
- p.add_run("Email: ").bold = True
193
- p.add_run(email)
194
-
195
- # Traitement des avocats
196
- avocat_key = f'AVOCAT_{title.rstrip("S")}'
197
- avocats = item.get(avocat_key, [])
198
-
199
- if isinstance(avocats, list) and avocats and avocats != "Non spécifié":
200
- for avocat_idx, avocat in enumerate(avocats, 1):
201
- if isinstance(avocat, dict):
202
- # Sous-titre pour chaque avocat
203
- self._add_title(f"Avocat {avocat_idx}", level + 2)
204
-
205
- # Nom de l'avocat
206
- civilite_avocat = self._get_safe_value(avocat, f'CIVILITE_AVOCAT_{title.rstrip("S")}', '')
207
- prenom_avocat = self._get_safe_value(avocat, f'PRENOM_AVOCAT_{title.rstrip("S")}', '')
208
- nom_avocat = self._get_safe_value(avocat, f'NOM_AVOCAT_{title.rstrip("S")}', '')
209
- nom_complet_avocat = f"{civilite_avocat} {prenom_avocat} {nom_avocat}".strip()
210
-
211
- if nom_complet_avocat and nom_complet_avocat != "Non spécifié":
212
- p = self.doc.add_paragraph(style='List Bullet')
213
- p.add_run("Nom: ").bold = True
214
- p.add_run(nom_complet_avocat)
215
-
216
- # Barreau
217
- barreau = self._get_safe_value(avocat, f'BARREAU_AVOCAT_{title.rstrip("S")}', '')
218
- if barreau and barreau != "Non spécifié":
219
- p = self.doc.add_paragraph(style='List Bullet')
220
- p.add_run("Barreau: ").bold = True
221
- p.add_run(barreau)
222
-
223
- # Bureau d'avocats
224
- bureau = self._get_safe_value(avocat, f'BUREAU_AVOCAT_{title.rstrip("S")}', '')
225
- if bureau and bureau != "Non spécifié":
226
- p = self.doc.add_paragraph(style='List Bullet')
227
- p.add_run("Bureau d'avocats: ").bold = True
228
- p.add_run(bureau)
229
-
230
- # Adresse de l'avocat
231
- adresse_avocat = avocat.get(f'ADRESSE_AVOCAT_{title.rstrip("S")}', {})
232
- if isinstance(adresse_avocat, dict):
233
- adresse_complete_avocat = adresse_avocat.get(f'ADRESSE_COMPLETE_AVOCAT_{title.rstrip("S")}', '')
234
- if adresse_complete_avocat and adresse_complete_avocat != "Non spécifié":
235
- p = self.doc.add_paragraph(style='List Bullet')
236
- p.add_run("Adresse Complete: ").bold = True
237
- p.add_run(adresse_complete_avocat)
238
-
239
- # Téléphone de l'avocat
240
- tel_avocat = self._get_safe_value(avocat, f'TELEPHONE_AVOCAT_{title.rstrip("S")}', '')
241
- if tel_avocat and tel_avocat != "Non spécifié":
242
- p = self.doc.add_paragraph(style='List Bullet')
243
- p.add_run("Téléphone: ").bold = True
244
- p.add_run(tel_avocat)
245
-
246
- # Email de l'avocat
247
- email_avocat = self._get_safe_value(avocat, f'EMAIL_AVOCAT_{title.rstrip("S")}', '')
248
- if email_avocat and email_avocat != "Non spécifié":
249
- p = self.doc.add_paragraph(style='List Bullet')
250
- p.add_run("Email: ").bold = True
251
- p.add_run(email_avocat)
252
-
253
- # Ajouter un espace entre chaque partie
254
- if idx < len(items):
255
- self.doc.add_paragraph()
256
-
257
- def _add_table_of_contents(self):
258
- """Ajoute une table des matières au document"""
259
- paragraph = self.doc.add_paragraph()
260
- run = paragraph.add_run("TABLE DES MATIÈRES")
261
- run.bold = True
262
- run.font.size = Pt(14)
263
-
264
- self.doc.add_paragraph()
265
- paragraph = self.doc.add_paragraph()
266
-
267
- # Ajouter le champ TOC
268
- run = paragraph.add_run()
269
- fldChar1 = OxmlElement('w:fldChar')
270
- fldChar1.set(qn('w:fldCharType'), 'begin')
271
- run._r.append(fldChar1)
272
-
273
- instrText = OxmlElement('w:instrText')
274
- instrText.set(qn('xml:space'), 'preserve')
275
- instrText.text = 'TOC \\o "1-3" \\h \\z \\u'
276
- run._r.append(instrText)
277
-
278
- fldChar2 = OxmlElement('w:fldChar')
279
- fldChar2.set(qn('w:fldCharType'), 'separate')
280
- run._r.append(fldChar2)
281
-
282
- # Ajouter un espace pour la mise à jour
283
- run = paragraph.add_run()
284
-
285
- fldChar4 = OxmlElement('w:fldChar')
286
- fldChar4.set(qn('w:fldCharType'), 'end')
287
- run._r.append(fldChar4)
288
-
289
- self.doc.add_page_break()
290
-
291
- def _format_person_info_simple(self, data: Dict, prefix: str) -> str:
292
- """Formate les informations d'une personne (magistrat ou greffier)"""
293
- prenom = data.get(f'PRENOM_{prefix}', '').strip()
294
- nom = data.get(f'NOM_{prefix}', '').strip()
295
- titre = data.get(f'TITRE_{prefix}', '').strip()
296
- return f"{prenom} {nom}, {titre}".strip()
297
-
298
- def _format_monetary_value(self, data: Dict, prefix: str) -> str:
299
- """Formate les valeurs monétaires"""
300
- valeur = str(data.get(f'VALEUR_{prefix}', 0)).strip()
301
- monnaie = data.get(f'MONNAIE_{prefix}', '€').strip()
302
- return f"{valeur} {monnaie}".strip()
303
-
304
- def generate_report(self):
305
- """Génère le rapport complet"""
306
- try:
307
- # Titre principal
308
- title = self.doc.add_heading("Données extraites d'une ordonnance de référé", 0)
309
- title.alignment = WD_ALIGN_PARAGRAPH.CENTER
310
-
311
- # Informations générales
312
- self._add_title("INFORMATIONS GÉNÉRALES", 1)
313
- if isinstance(self.json_data.get("INFORMATIONS_GENERALES"), dict):
314
- info_gen = self.json_data["INFORMATIONS_GENERALES"]
315
-
316
- # Liste des champs à traiter
317
- fields_to_process = [
318
- # Champs simples
319
- ("DATE_ORDONNANCE_REFERE", "Date Ordonnance Refere"),
320
- ("VILLE_TRIBUNAL", "Ville Tribunal"),
321
- ("NUMERO_RG", "Numero RG"),
322
-
323
- # Champs complexes avec formatage spécial
324
- ("MAGISTRAT_ORDONNANCE_REFERE", "Magistrat Ordonnance Refere",
325
- lambda x: self._format_person_info_simple(x, "MAGISTRAT_ORDONNANCE_REFERE")),
326
-
327
- ("GREFFIER_ORDONNANCE_REFERE", "Greffier Ordonnance Refere",
328
- lambda x: self._format_person_info_simple(x, "GREFFIER_ORDONNANCE_REFERE")),
329
-
330
- ("CONSIGNATION", "Consignation",
331
- lambda x: self._format_monetary_value(x, "CONSIGNATION")),
332
-
333
- ("SOMME_A_CONSIGER", "Somme A Consiger",
334
- lambda x: self._format_monetary_value(x, "SOMME_A_CONSIGER"))
335
- ]
336
-
337
- # Traitement de chaque champ
338
- for field in fields_to_process:
339
- key = field[0]
340
- display_name = field[1]
341
-
342
- if key in info_gen:
343
- p = self.doc.add_paragraph(style='List Bullet')
344
- p.add_run(f"{display_name}: ").bold = True
345
-
346
- # Si c'est un champ avec formatage spécial (longueur du tuple = 3)
347
- if len(field) == 3:
348
- formatter = field[2]
349
- value = formatter(info_gen[key])
350
- else:
351
- value = str(info_gen[key])
352
-
353
- p.add_run(value)
354
-
355
- # Traitement des demandeurs
356
- if "DEMANDEURS" in self.json_data:
357
- self._process_parties("DEMANDEURS", self.json_data["DEMANDEURS"], 1)
358
-
359
- # Traitement des défendeurs
360
- if "DEFENDEURS" in self.json_data:
361
- self._process_parties("DEFENDEURS", self.json_data["DEFENDEURS"], 1)
362
-
363
- # Historique
364
- if "HISTORIQUE" in self.json_data:
365
- self._process_special_fields("HISTORIQUE", self.json_data["HISTORIQUE"])
366
-
367
- # Mission
368
- if "MISSION" in self.json_data:
369
- self._process_special_fields("MISSION", self.json_data["MISSION"])
370
-
371
- # Sauvegarde du document
372
- output_file = "rapport_extraction.docx"
373
- self.doc.save(output_file)
374
- self.logger.info(f"Rapport généré avec succès: {output_file}")
375
-
376
- return output_file
377
-
378
- except Exception as e:
379
- self.logger.error(f"Erreur lors de la génération du rapport: {str(e)}")
380
- raise