pasquale991 commited on
Commit
488a502
·
verified ·
1 Parent(s): 5049b40

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +52 -28
src/streamlit_app.py CHANGED
@@ -1,10 +1,19 @@
1
  import streamlit as st
2
  import pandas as pd
3
  import json
4
- from datetime import datetime # Importa datetime
5
  import io
6
  import os
7
 
 
 
 
 
 
 
 
 
 
8
  # --- CSS personalizzato per sfondo giallo e testo blu ---
9
  st.markdown(
10
  """
@@ -36,7 +45,7 @@ st.markdown(
36
  }
37
  </style>
38
  """,
39
- unsafe_allow_html=True # Necessario per iniettare CSS
40
  )
41
 
42
 
@@ -45,7 +54,6 @@ def convert_json_to_excel_data(json_file_content: str):
45
  try:
46
  json_data = json.loads(json_file_content)
47
 
48
- # Preleviamo companyCode e partnerCode dal JSON
49
  company_code = json_data.get('companyCode')
50
  order_info = json_data.get('order', {})
51
  partner_code = order_info.get('partnerCode')
@@ -58,20 +66,29 @@ def convert_json_to_excel_data(json_file_content: str):
58
  dt_object = datetime.fromisoformat(order_date_str.replace('Z', '+00:00'))
59
  order_date_formatted = dt_object.strftime('%d/%m/%Y')
60
  except ValueError:
61
- order_date_formatted = order_date_str # Usiamo la stringa originale
62
  st.warning(f"Attenzione: Impossibile parsare la data '{order_date_str}' per un file. Verrà usata la stringa originale.")
63
 
64
  details = order_info.get('details', [])
65
 
66
  processed_data_for_this_file = []
67
  for item in details:
 
 
 
 
 
 
 
 
 
 
68
  row = {
69
- # site.code sarà fornito dall'interfaccia utente
70
  'company.code': company_code,
71
  'supplier.partnerRef.code': partner_code,
72
  'docDate': order_date_formatted,
73
- 'status': 'CREATED', # Colonna 'status' hardcoded a 'CREATED'
74
- 'positions.status': 'CREATED', # Colonna 'positions.status' hardcoded a 'CREATED'
75
  'positions.positionId': item.get('positionId'),
76
  'positions.stock.item.itemNumber': item.get('itemCode'),
77
  'positions.stock.quantity': item.get('quantity'),
@@ -80,18 +97,18 @@ def convert_json_to_excel_data(json_file_content: str):
80
  'positions.stock.accountingInfo.availability': item.get('availability'),
81
  'positions.stock.refOrder': item.get('refOrder'),
82
  'positions.stock.reasonCode': item.get('reasonCode'),
83
- 'positions.stock.cancelPosOda': False if item.get('cancelPosOdA') is None else bool(item.get('cancelPosOdA'))
84
  }
85
  processed_data_for_this_file.append(row)
86
 
87
  if not processed_data_for_this_file:
88
- return pd.DataFrame() # Restituisce un DataFrame vuoto per questo file
89
 
90
  return pd.DataFrame(processed_data_for_this_file)
91
 
92
  except json.JSONDecodeError as e:
93
  st.error(f"Errore nel file JSON: {e}. Assicurati che il contenuto sia un JSON valido.")
94
- return None # Ritorna None in caso di errore critico
95
  except KeyError as ke:
96
  st.error(f"Errore: Chiave JSON mancante o struttura inattesa: {ke}. Assicurati che il JSON abbia la struttura attesa (es. 'order.details').")
97
  return None
@@ -105,31 +122,35 @@ st.write("Carica i tuoi file JSON degli ordini ODA e scarica il foglio Excel for
105
 
106
  # Sezione per l'input del solo siteCode
107
  st.header("1. Qual è il Site Code? Inseriscilo qui:")
 
108
  user_site_code = st.text_input("Site Code", key="site_code_input")
109
 
110
  st.header("2. Carica i tuoi file JSON")
111
- # Permette di caricare più file
112
- uploaded_files = st.file_uploader("Scegli uno o più file JSON per lo stesso siteCode di tipo 'Ordine_Acquisto'", type=["json"], accept_multiple_files=True)
 
 
 
 
 
113
 
114
- all_processed_data = [] # Lista per contenere tutti i DataFrame processati
115
 
116
  if uploaded_files:
117
- # Controlliamo che il campo siteCode sia riempito prima di procedere
118
  if not user_site_code:
119
  st.warning("Per favor, compila il campo 'Site Code' prima di caricare i file.")
120
  else:
121
  st.info(f"Caricati {len(uploaded_files)} file. Elaborazione in corso...")
122
 
123
- conversion_successful = True # Variabile per tracciare se ci sono stati errori
124
 
125
  for uploaded_file in uploaded_files:
126
  file_name = uploaded_file.name
127
 
128
- # Verifica che il nome del file inizi con "Ordine_Acquisto"
129
  if not file_name.lower().startswith("ordine_acquisto"):
130
  st.error(f"Errore: Il file '{file_name}' non inizia con 'Ordine_Acquisto'. Verrà ignorato.")
131
  conversion_successful = False
132
- continue # Passa al prossimo file
133
 
134
  try:
135
  json_content_bytes = uploaded_file.read()
@@ -138,10 +159,8 @@ if uploaded_files:
138
  df_this_file = convert_json_to_excel_data(json_content_string)
139
 
140
  if df_this_file is not None:
141
- # Aggiungi il valore siteCode fornito dall'utente a questo DataFrame
142
  df_this_file['site.code'] = user_site_code
143
 
144
- # Riordina le colonne per avere i nuovi nomi nell'ordine corretto
145
  final_columns_order = [
146
  'site.code', 'docDate', 'company.code', 'supplier.partnerRef.code',
147
  'status',
@@ -176,10 +195,8 @@ if uploaded_files:
176
  workbook = writer.book
177
  worksheet = writer.sheets[sheet_name_excel]
178
 
179
- header_format = workbook.add_format({
180
- 'bold': True, 'font_color': '#FFFFFF', 'bg_color': '#1E90FF', # Blu acceso
181
- 'align': 'center', 'valign': 'vcenter', 'border': 1
182
- })
183
 
184
  col_widths = {
185
  'site.code': 10, 'docDate': 12, 'company.code': 15, 'supplier.partnerRef.code': 18,
@@ -194,7 +211,8 @@ if uploaded_files:
194
  }
195
 
196
  for col_num, col_name in enumerate(final_df.columns.values):
197
- worksheet.write(0, col_num, col_name, header_format)
 
198
  if col_name in col_widths:
199
  worksheet.set_column(col_num, col_num, col_widths[col_name])
200
  else:
@@ -203,14 +221,13 @@ if uploaded_files:
203
  writer.close()
204
  output.seek(0)
205
 
206
- # Genera il timestamp attuale e formatta il nome del file
207
  timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
208
  output_file_name = f"PurchaseOrder_{timestamp}.xlsx"
209
 
210
  st.download_button(
211
  label="Scarica file Excel Unificato",
212
  data=output.getvalue(),
213
- file_name=output_file_name, # Usa il nome del file con timestamp
214
  mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
215
  )
216
  elif not conversion_successful:
@@ -220,6 +237,13 @@ if uploaded_files:
220
  else:
221
  st.info("Carica i tuoi file JSON per iniziare. I file devono essere della stessa tipologia!")
222
 
223
- st.markdown("---")
224
- st.markdown("Buona Fortuna")
 
 
 
 
 
 
 
225
  st.markdown("Sviluppato con Streamlit e Python.")
 
1
  import streamlit as st
2
  import pandas as pd
3
  import json
4
+ from datetime import datetime
5
  import io
6
  import os
7
 
8
+ # --- Inizializzazione Session State per il pulsante CLEAN ---
9
+ # È fondamentale inizializzare le chiavi di session_state usate per i widget di input
10
+ # Se la chiave 'uploaded_files_key' non esiste, la inizializza a None (stato iniziale del file_uploader)
11
+ if 'uploaded_files_key' not in st.session_state:
12
+ st.session_state.uploaded_files_key = [] # Inizializza a lista vuota per il file_uploader
13
+ if 'site_code_input' not in st.session_state:
14
+ st.session_state.site_code_input = "" # Inizializza a stringa vuota per il text_input
15
+
16
+
17
  # --- CSS personalizzato per sfondo giallo e testo blu ---
18
  st.markdown(
19
  """
 
45
  }
46
  </style>
47
  """,
48
+ # unsafe_allow_html=True # Necessario per iniettare CSS
49
  )
50
 
51
 
 
54
  try:
55
  json_data = json.loads(json_file_content)
56
 
 
57
  company_code = json_data.get('companyCode')
58
  order_info = json_data.get('order', {})
59
  partner_code = order_info.get('partnerCode')
 
66
  dt_object = datetime.fromisoformat(order_date_str.replace('Z', '+00:00'))
67
  order_date_formatted = dt_object.strftime('%d/%m/%Y')
68
  except ValueError:
69
+ order_date_formatted = order_date_str
70
  st.warning(f"Attenzione: Impossibile parsare la data '{order_date_str}' per un file. Verrà usata la stringa originale.")
71
 
72
  details = order_info.get('details', [])
73
 
74
  processed_data_for_this_file = []
75
  for item in details:
76
+ # Gestione robusta di cancelPosOdA per garantire True/False
77
+ cancel_pos_oda_val = item.get('cancelPosOdA')
78
+ if cancel_pos_oda_val is None:
79
+ cancel_pos_oda_processed = False
80
+ elif isinstance(cancel_pos_oda_val, str):
81
+ # Converte "true" (case-insensitive) in True, altrimenti in False
82
+ cancel_pos_oda_processed = cancel_pos_oda_val.lower() == 'true'
83
+ else: # Per booleani nativi o interi (0/1)
84
+ cancel_pos_oda_processed = bool(cancel_pos_oda_val)
85
+
86
  row = {
 
87
  'company.code': company_code,
88
  'supplier.partnerRef.code': partner_code,
89
  'docDate': order_date_formatted,
90
+ 'status': 'CREATED',
91
+ 'positions.status': 'CREATED',
92
  'positions.positionId': item.get('positionId'),
93
  'positions.stock.item.itemNumber': item.get('itemCode'),
94
  'positions.stock.quantity': item.get('quantity'),
 
97
  'positions.stock.accountingInfo.availability': item.get('availability'),
98
  'positions.stock.refOrder': item.get('refOrder'),
99
  'positions.stock.reasonCode': item.get('reasonCode'),
100
+ 'positions.stock.cancelPosOda': cancel_pos_oda_processed # Usa il valore processato
101
  }
102
  processed_data_for_this_file.append(row)
103
 
104
  if not processed_data_for_this_file:
105
+ return pd.DataFrame()
106
 
107
  return pd.DataFrame(processed_data_for_this_file)
108
 
109
  except json.JSONDecodeError as e:
110
  st.error(f"Errore nel file JSON: {e}. Assicurati che il contenuto sia un JSON valido.")
111
+ return None
112
  except KeyError as ke:
113
  st.error(f"Errore: Chiave JSON mancante o struttura inattesa: {ke}. Assicurati che il JSON abbia la struttura attesa (es. 'order.details').")
114
  return None
 
122
 
123
  # Sezione per l'input del solo siteCode
124
  st.header("1. Qual è il Site Code? Inseriscilo qui:")
125
+ # Collega il text_input al session_state
126
  user_site_code = st.text_input("Site Code", key="site_code_input")
127
 
128
  st.header("2. Carica i tuoi file JSON")
129
+ # Collega il file_uploader al session_state per permettere il reset
130
+ uploaded_files = st.file_uploader(
131
+ "Scegli uno o più file JSON per lo stesso siteCode di tipo 'Ordine_Acquisto'",
132
+ type=["json"],
133
+ accept_multiple_files=True,
134
+ key="uploaded_files_key" # Usa la chiave di session_state
135
+ )
136
 
137
+ all_processed_data = []
138
 
139
  if uploaded_files:
 
140
  if not user_site_code:
141
  st.warning("Per favor, compila il campo 'Site Code' prima di caricare i file.")
142
  else:
143
  st.info(f"Caricati {len(uploaded_files)} file. Elaborazione in corso...")
144
 
145
+ conversion_successful = True
146
 
147
  for uploaded_file in uploaded_files:
148
  file_name = uploaded_file.name
149
 
 
150
  if not file_name.lower().startswith("ordine_acquisto"):
151
  st.error(f"Errore: Il file '{file_name}' non inizia con 'Ordine_Acquisto'. Verrà ignorato.")
152
  conversion_successful = False
153
+ continue
154
 
155
  try:
156
  json_content_bytes = uploaded_file.read()
 
159
  df_this_file = convert_json_to_excel_data(json_content_string)
160
 
161
  if df_this_file is not None:
 
162
  df_this_file['site.code'] = user_site_code
163
 
 
164
  final_columns_order = [
165
  'site.code', 'docDate', 'company.code', 'supplier.partnerRef.code',
166
  'status',
 
195
  workbook = writer.book
196
  worksheet = writer.sheets[sheet_name_excel]
197
 
198
+ # --- RIMOZIONE: Formattazione header ---
199
+ # Il formato verrà applicato di default senza stile speciale
 
 
200
 
201
  col_widths = {
202
  'site.code': 10, 'docDate': 12, 'company.code': 15, 'supplier.partnerRef.code': 18,
 
211
  }
212
 
213
  for col_num, col_name in enumerate(final_df.columns.values):
214
+ # RIMOZIONE: Applica il formato header. Ora scriverà solo il nome della colonna
215
+ worksheet.write(0, col_num, col_name)
216
  if col_name in col_widths:
217
  worksheet.set_column(col_num, col_num, col_widths[col_name])
218
  else:
 
221
  writer.close()
222
  output.seek(0)
223
 
 
224
  timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
225
  output_file_name = f"PurchaseOrder_{timestamp}.xlsx"
226
 
227
  st.download_button(
228
  label="Scarica file Excel Unificato",
229
  data=output.getvalue(),
230
+ file_name=output_file_name,
231
  mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
232
  )
233
  elif not conversion_successful:
 
237
  else:
238
  st.info("Carica i tuoi file JSON per iniziare. I file devono essere della stessa tipologia!")
239
 
240
+
241
+ # --- Pulsante CLEAN ---
242
+ st.markdown("---") # Linea separatrice
243
+ def clear_inputs():
244
+ st.session_state.uploaded_files_key = [] # Resetta il file uploader
245
+ st.session_state.site_code_input = "" # Resetta il campo Site Code
246
+
247
+ st.button("Pulisci Input (RESET)", on_click=clear_inputs)
248
+
249
  st.markdown("Sviluppato con Streamlit e Python.")