AdrienB134 commited on
Commit
842c593
·
verified ·
1 Parent(s): 425ad66

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +546 -0
app.py ADDED
@@ -0,0 +1,546 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import xml.etree.ElementTree as ET
2
+ import pandas as pd
3
+ import json
4
+ import gradio as gr
5
+
6
+
7
+ def get_clients_from_xml(xml_file):
8
+ """Extract all clients from XML file and return a list of tuples (id, name)"""
9
+ try:
10
+ tree = ET.parse(xml_file.name) # Use .name since gradio provides a temp file
11
+ root = tree.getroot()
12
+
13
+ clients = []
14
+ for client in root.findall(".//client"):
15
+ client_id = client.get("id")
16
+ nom = client.get("nom") if client.get("nom") is not None else ""
17
+ prenom = client.get("prenom") if client.get("prenom") is not None else ""
18
+ clients.append((client_id, f"{prenom} {nom} (ID: {client_id})"))
19
+
20
+ return clients
21
+ except Exception as e:
22
+ print(e)
23
+ return []
24
+
25
+
26
+ def client_to_json(xml_file, client_id):
27
+ tree = ET.parse(xml_file)
28
+ root = tree.getroot()
29
+
30
+ # Find the specific client
31
+ client = root.find(f".//client[@id='{client_id}']")
32
+ if client is None:
33
+ return json.dumps({"error": f"Client ID {client_id} not found"})
34
+
35
+ def element_to_dict(element):
36
+ result = {}
37
+
38
+ # Add attributes
39
+ if element.attrib:
40
+ result.update(element.attrib)
41
+
42
+ # Add text content if it exists and isn't empty
43
+ if element.text and element.text.strip():
44
+ result["_text"] = element.text.strip()
45
+
46
+ # Process child elements
47
+ for child in element:
48
+ child_data = element_to_dict(child)
49
+
50
+ if child.tag in result:
51
+ # If the key already exists, convert it to a list if it isn't already
52
+ if not isinstance(result[child.tag], list):
53
+ result[child.tag] = [result[child.tag]]
54
+ result[child.tag].append(child_data)
55
+ else:
56
+ result[child.tag] = child_data
57
+
58
+ return result
59
+
60
+ # Convert client data to dictionary
61
+ client_data = element_to_dict(client)
62
+
63
+ # Convert to JSON with pretty printing
64
+ return json.dumps(client_data, indent=2, ensure_ascii=False)
65
+
66
+
67
+ def display_nested_json(json_data):
68
+ # If input is a string, parse it to dict
69
+ if isinstance(json_data, str):
70
+ data = json.loads(json_data)
71
+ else:
72
+ data = json_data
73
+
74
+ # 1. Basic Client Information
75
+ basic_info = pd.DataFrame(
76
+ [
77
+ {
78
+ "ID": data.get("id"),
79
+ "Nom": data.get("nom"),
80
+ "Prénom": data.get("prenom"),
81
+ "Civilité": data.get("civilite"),
82
+ "Date Creation": data.get("date_creation"),
83
+ }
84
+ ]
85
+ )
86
+
87
+ # 2. Accounts Table
88
+ accounts_df = extract_accounts(data)
89
+
90
+ # 3. Contact Information
91
+ contacts_df = extract_contacts(data)
92
+
93
+ # 4. Real Estate (Immobilier) Information
94
+ immobilier_df = extract_immobilier(data)
95
+
96
+ # 5. Patrimoine Information
97
+ patrimoine_df = extract_patrimoine(data)
98
+
99
+ # 6. Budget Information
100
+ budget_df = extract_budget(data)
101
+
102
+ return {
103
+ "basic_info": basic_info,
104
+ "accounts": accounts_df,
105
+ "contacts": contacts_df,
106
+ "immobilier": immobilier_df,
107
+ "patrimoine": patrimoine_df,
108
+ "budget": budget_df,
109
+ }
110
+
111
+
112
+ def extract_accounts(data):
113
+ if "comptes" in data and "compte" in data["comptes"]:
114
+ accounts = data["comptes"]["compte"]
115
+ if isinstance(accounts, dict):
116
+ accounts = [accounts]
117
+
118
+ accounts_data = []
119
+ for account in accounts:
120
+ situations = account.get("situations", {})
121
+ situation_data = situations.get("situation", [])
122
+
123
+ if isinstance(situation_data, dict):
124
+ situation_data = [situation_data]
125
+
126
+ for situation in situation_data:
127
+ row = {
128
+ "Account ID": account.get("id"),
129
+ "Account Name": account.get("intitule"),
130
+ "Opening Date": account.get("date_ouverture"),
131
+ "Valuation Date": situations.get("date_valorisation"),
132
+ "Valuation Type": situations.get("type_valorisation"),
133
+ "Support ID": situation.get("support_id"),
134
+ "Quantity": situation.get("quantite"),
135
+ "Price": situation.get("cours"),
136
+ "Value (EUR)": situation.get("valeur_euro"),
137
+ "Weight (%)": situation.get("poids_ligne"),
138
+ "PMV (EUR)": situation.get("pmv_euro"),
139
+ "PMV (%)": situation.get("pmv_pourcentage"),
140
+ }
141
+ accounts_data.append(row)
142
+
143
+ accounts_df = pd.DataFrame(accounts_data)
144
+
145
+ numeric_columns = [
146
+ "Quantity",
147
+ "Price",
148
+ "Value (EUR)",
149
+ "Weight (%)",
150
+ "PMV (EUR)",
151
+ "PMV (%)",
152
+ ]
153
+ for col in numeric_columns:
154
+ if col in accounts_df.columns:
155
+ try:
156
+ accounts_df[col] = pd.to_numeric(accounts_df[col])
157
+ except ValueError:
158
+ print(f"Warning: Could not convert column {col} to numeric.")
159
+
160
+ else:
161
+ accounts_df = pd.DataFrame()
162
+
163
+ return accounts_df
164
+
165
+
166
+ def extract_contacts(data):
167
+ if "modes_contacts" in data:
168
+ contacts = data["modes_contacts"]
169
+ contacts_df = pd.DataFrame(
170
+ [
171
+ {
172
+ "Email": contacts.get("email_personnel"),
173
+ "Mobile": contacts.get("telephone_mobile"),
174
+ }
175
+ ]
176
+ )
177
+ else:
178
+ contacts_df = pd.DataFrame()
179
+
180
+ return contacts_df
181
+
182
+
183
+ def extract_immobilier(data):
184
+ if "immobiliers" in data and "immobilier" in data["immobiliers"]:
185
+ immobilier = data["immobiliers"]["immobilier"]
186
+ if isinstance(immobilier, dict):
187
+ immobilier = [immobilier]
188
+
189
+ immobilier_data = []
190
+ for item in immobilier:
191
+ row = {
192
+ "ID": item.get("id"),
193
+ "Designation": item.get("designation"),
194
+ "Address": item.get("adresse", {}).get("adresse"),
195
+ "City": item.get("adresse", {}).get("ville"),
196
+ "Postal Code": item.get("adresse", {}).get("code_postal"),
197
+ "Country": item.get("adresse", {}).get("pays"),
198
+ "Value": item.get("valeur", {}).get("totale"),
199
+ "Revenues": item.get("revenus", {}).get("montant"),
200
+ "Charges": item.get("charges", {}).get("montant"),
201
+ }
202
+ immobilier_data.append(row)
203
+
204
+ immobilier_df = pd.DataFrame(immobilier_data)
205
+ else:
206
+ immobilier_df = pd.DataFrame()
207
+
208
+ return immobilier_df
209
+
210
+
211
+ def extract_patrimoine(data):
212
+ patrimoine_data = {"actifs": pd.DataFrame(), "passifs": pd.DataFrame()}
213
+
214
+ if "patrimoine" in data:
215
+ # Extract Actifs
216
+ if "actifs" in data["patrimoine"]:
217
+ actifs_items = data["patrimoine"]["actifs"].get("actif", [])
218
+ if isinstance(actifs_items, dict):
219
+ actifs_items = [actifs_items]
220
+
221
+ if actifs_items:
222
+ actifs_data = []
223
+ for item in actifs_items:
224
+ row = {
225
+ "UUID": item.get("uuid"),
226
+ "Libellé": item.get("libelle"),
227
+ "Patrimoine ID": item.get("patrimoine_id"),
228
+ "Montant (EUR)": item.get("montant_euro"),
229
+ "Système": item.get("system_origine"),
230
+ "Détenteur": item.get("detention", {}).get("detenteur"),
231
+ "Mode": item.get("detention", {}).get("mode"),
232
+ }
233
+
234
+ # Extract external references
235
+ ref_externes = item.get("ref_externes", {}).get("ref_externe", [])
236
+ if isinstance(ref_externes, dict):
237
+ ref_externes = [ref_externes]
238
+ if ref_externes:
239
+ systems = [ref.get("system") for ref in ref_externes]
240
+ row["Systèmes Externes"] = ", ".join(filter(None, systems))
241
+
242
+ actifs_data.append(row)
243
+
244
+ actifs_df = pd.DataFrame(actifs_data)
245
+ if "Montant (EUR)" in actifs_df.columns:
246
+ try:
247
+ actifs_df["Montant (EUR)"] = pd.to_numeric(
248
+ actifs_df["Montant (EUR)"]
249
+ )
250
+ except ValueError:
251
+ print(
252
+ "Warning: Could not convert some actifs montants to numeric"
253
+ )
254
+ patrimoine_data["actifs"] = actifs_df
255
+
256
+ # Extract Passifs
257
+ if "passifs" in data["patrimoine"]:
258
+ passifs_items = data["patrimoine"]["passifs"].get("passif", [])
259
+ if isinstance(passifs_items, dict):
260
+ passifs_items = [passifs_items]
261
+
262
+ if passifs_items:
263
+ passifs_data = []
264
+ for item in passifs_items:
265
+ row = {
266
+ "UUID": item.get("uuid"),
267
+ "Libellé": item.get("libelle"),
268
+ "Patrimoine ID": item.get("patrimoine_id"),
269
+ "Système": item.get("system_origine"),
270
+ "Souscripteur": item.get("souscripteur"),
271
+ "Périodicité": item.get("periodicite"),
272
+ "Taux HA": item.get("caracteristiques", {}).get("taux_HA"),
273
+ "Assurance Taux": item.get("assurance", {}).get("taux"),
274
+ "Capital Restant Dû (EUR)": item.get(
275
+ "capital_restant_du", {}
276
+ ).get("montant_euro"),
277
+ "Date Capital Restant Dû": item.get(
278
+ "capital_restant_du", {}
279
+ ).get("date"),
280
+ }
281
+
282
+ # Extract external references
283
+ ref_externes = item.get("ref_externes", {}).get("ref_externe", [])
284
+ if isinstance(ref_externes, dict):
285
+ ref_externes = [ref_externes]
286
+ if ref_externes:
287
+ systems = [ref.get("system") for ref in ref_externes]
288
+ row["Systèmes Externes"] = ", ".join(filter(None, systems))
289
+
290
+ passifs_data.append(row)
291
+
292
+ passifs_df = pd.DataFrame(passifs_data)
293
+ if "Capital Restant Dû (EUR)" in passifs_df.columns:
294
+ try:
295
+ passifs_df["Capital Restant Dû (EUR)"] = pd.to_numeric(
296
+ passifs_df["Capital Restant Dû (EUR)"]
297
+ )
298
+ except ValueError:
299
+ print(
300
+ "Warning: Could not convert some passifs capital restant dû to numeric"
301
+ )
302
+ patrimoine_data["passifs"] = passifs_df
303
+
304
+ return patrimoine_data
305
+
306
+
307
+ def extract_budget(data):
308
+ budget_data = {"revenus": pd.DataFrame(), "charges": pd.DataFrame()}
309
+
310
+ if "budget" in data:
311
+ # Extract Revenus
312
+ if "revenus" in data["budget"]:
313
+ revenus_items = data["budget"]["revenus"].get("revenu", [])
314
+ if isinstance(revenus_items, dict):
315
+ revenus_items = [revenus_items]
316
+
317
+ if revenus_items:
318
+ revenus_data = []
319
+ for item in revenus_items:
320
+ row = {
321
+ "ID": item.get("id"),
322
+ "Budget ID": item.get("budget_id"),
323
+ "Libellé": item.get("libelle"),
324
+ "Montant (EUR)": item.get("montant_euro"),
325
+ "Périodicité": item.get("periodicite"),
326
+ "Bénéficiaire": item.get("beneficiaire"),
327
+ "UUID": item.get("uuid"),
328
+ "Système": item.get("system_origine"),
329
+ "Date Terme": item.get("date_terme", ""),
330
+ }
331
+
332
+ # Extract external references if needed
333
+ ref_externes = item.get("ref_externes", {}).get("ref_externe", [])
334
+ if isinstance(ref_externes, dict):
335
+ ref_externes = [ref_externes]
336
+ if ref_externes:
337
+ systems = [ref.get("system") for ref in ref_externes]
338
+ row["Systèmes Externes"] = ", ".join(filter(None, systems))
339
+
340
+ revenus_data.append(row)
341
+
342
+ revenus_df = pd.DataFrame(revenus_data)
343
+ if "Montant (EUR)" in revenus_df.columns:
344
+ try:
345
+ revenus_df["Montant (EUR)"] = pd.to_numeric(
346
+ revenus_df["Montant (EUR)"]
347
+ )
348
+ except ValueError:
349
+ print(
350
+ "Warning: Could not convert some revenus montants to numeric"
351
+ )
352
+ budget_data["revenus"] = revenus_df
353
+
354
+ # Extract Charges
355
+ if "charges" in data["budget"]:
356
+ charges_items = data["budget"]["charges"].get("charge", [])
357
+ if isinstance(charges_items, dict):
358
+ charges_items = [charges_items]
359
+
360
+ if charges_items:
361
+ charges_data = []
362
+ for item in charges_items:
363
+ row = {
364
+ "ID": item.get("id"),
365
+ "Budget ID": item.get("budget_id"),
366
+ "Libellé": item.get("libelle"),
367
+ "Montant (EUR)": item.get("montant_euro"),
368
+ "Périodicité": item.get("periodicite"),
369
+ "Débiteur": item.get("debiteur"),
370
+ "UUID": item.get("uuid"),
371
+ "Système": item.get("system_origine"),
372
+ }
373
+
374
+ # Extract external references if needed
375
+ ref_externes = item.get("ref_externes", {}).get("ref_externe", [])
376
+ if isinstance(ref_externes, dict):
377
+ ref_externes = [ref_externes]
378
+ if ref_externes:
379
+ systems = [ref.get("system") for ref in ref_externes]
380
+ row["Systèmes Externes"] = ", ".join(filter(None, systems))
381
+
382
+ charges_data.append(row)
383
+
384
+ charges_df = pd.DataFrame(charges_data)
385
+ if "Montant (EUR)" in charges_df.columns:
386
+ try:
387
+ charges_df["Montant (EUR)"] = pd.to_numeric(
388
+ charges_df["Montant (EUR)"]
389
+ )
390
+ except ValueError:
391
+ print(
392
+ "Warning: Could not convert some charges montants to numeric"
393
+ )
394
+ budget_data["charges"] = charges_df
395
+
396
+ return budget_data
397
+
398
+
399
+ def format_client_info(client_id):
400
+ # Get JSON data using your previous function
401
+ json_data = client_to_json("test.xml", client_id)
402
+ tables = display_nested_json(json_data)
403
+
404
+ pd.set_option("display.max_columns", None)
405
+ pd.set_option("display.width", None)
406
+ pd.set_option(
407
+ "display.float_format",
408
+ lambda x: "{:.2f}".format(x) if isinstance(x, (float, int)) else x,
409
+ )
410
+
411
+ # Return DataFrames directly instead of string representations
412
+ outputs = []
413
+
414
+ # Basic Info
415
+ outputs.append(gr.Markdown("## Client Basic Information"))
416
+ outputs.append(tables["basic_info"])
417
+
418
+ # Contacts
419
+ outputs.append(gr.Markdown("## Contacts Client"))
420
+ outputs.append(tables["contacts"])
421
+
422
+ # Accounts
423
+ outputs.append(gr.Markdown("## Accounts and Positions"))
424
+ outputs.append(
425
+ tables["accounts"]
426
+ if not tables["accounts"].empty
427
+ else pd.DataFrame({"Message": ["No accounts found"]})
428
+ )
429
+
430
+ # Patrimoine - Actifs
431
+ outputs.append(gr.Markdown("## Patrimoine"))
432
+ outputs.append(gr.Markdown("### Actifs"))
433
+ outputs.append(
434
+ tables["patrimoine"]["actifs"]
435
+ if not tables["patrimoine"]["actifs"].empty
436
+ else pd.DataFrame({"Message": ["No actifs found"]})
437
+ )
438
+
439
+ # Patrimoine - Passifs
440
+ outputs.append(gr.Markdown("### Passifs"))
441
+ outputs.append(
442
+ tables["patrimoine"]["passifs"]
443
+ if not tables["patrimoine"]["passifs"].empty
444
+ else pd.DataFrame({"Message": ["No passifs found"]})
445
+ )
446
+
447
+ # Budget - Revenus
448
+ outputs.append(gr.Markdown("## Budget"))
449
+ outputs.append(gr.Markdown("### Revenus"))
450
+ outputs.append(
451
+ tables["budget"]["revenus"]
452
+ if not tables["budget"]["revenus"].empty
453
+ else pd.DataFrame({"Message": ["No revenus found"]})
454
+ )
455
+
456
+ # Budget - Charges
457
+ outputs.append(gr.Markdown("### Charges"))
458
+ outputs.append(
459
+ tables["budget"]["charges"]
460
+ if not tables["budget"]["charges"].empty
461
+ else pd.DataFrame({"Message": ["No charges found"]})
462
+ )
463
+
464
+ return outputs
465
+
466
+
467
+ # Create Gradio interface
468
+ with gr.Blocks(title="Client Information Viewer") as demo:
469
+ gr.Markdown("# Client Information Viewer")
470
+ gr.Markdown(
471
+ "Upload an XML file and select a client to view their detailed information"
472
+ )
473
+
474
+ xml_file = gr.File(label="Upload XML File", file_types=[".xml"])
475
+ client_dropdown = gr.Dropdown(label="Select Client", choices=[], interactive=True)
476
+ view_btn = gr.Button("View Client Info", interactive=False)
477
+
478
+ # Create output containers for each section
479
+ basic_info_header = gr.Markdown()
480
+ basic_info_df = gr.DataFrame()
481
+
482
+ contacts_header = gr.Markdown()
483
+ contacts_df = gr.DataFrame()
484
+
485
+ accounts_header = gr.Markdown()
486
+ accounts_df = gr.DataFrame()
487
+
488
+ actifs_header = gr.Markdown()
489
+ actifs_subheader = gr.Markdown()
490
+ actifs_df = gr.DataFrame()
491
+
492
+ passifs_subheader = gr.Markdown()
493
+ passifs_df = gr.DataFrame()
494
+
495
+ revenus_header = gr.Markdown()
496
+ revenus_subheader = gr.Markdown()
497
+ revenus_df = gr.DataFrame()
498
+
499
+ charges_subheader = gr.Markdown()
500
+ charges_df = gr.DataFrame()
501
+
502
+ # Combine all outputs in order
503
+ output_dfs = [
504
+ basic_info_header,
505
+ basic_info_df,
506
+ contacts_header,
507
+ contacts_df,
508
+ accounts_header,
509
+ accounts_df,
510
+ actifs_header,
511
+ actifs_subheader,
512
+ actifs_df,
513
+ passifs_subheader,
514
+ passifs_df,
515
+ revenus_header,
516
+ revenus_subheader,
517
+ revenus_df,
518
+ charges_subheader,
519
+ charges_df,
520
+ ]
521
+
522
+ # Update dropdown when file is uploaded
523
+ def update_dropdown(file):
524
+ if file is None:
525
+ return gr.Dropdown(choices=[], value=None, interactive=False), gr.Button(
526
+ interactive=False
527
+ )
528
+ clients = get_clients_from_xml(file)
529
+ choices = [(name, id) for id, name in clients]
530
+ return gr.Dropdown(choices=choices, interactive=True), gr.Button(
531
+ interactive=True
532
+ )
533
+
534
+ xml_file.change(
535
+ fn=update_dropdown, inputs=[xml_file], outputs=[client_dropdown, view_btn]
536
+ )
537
+
538
+ # View client info when button is clicked
539
+ view_btn.click(
540
+ fn=format_client_info,
541
+ inputs=client_dropdown,
542
+ outputs=output_dfs,
543
+ )
544
+
545
+ if __name__ == "__main__":
546
+ demo.launch(server_port=7860, share=True)