Spaces:
Sleeping
Sleeping
Update src/streamlit_app.py
Browse files- src/streamlit_app.py +20 -18
src/streamlit_app.py
CHANGED
|
@@ -2,8 +2,7 @@ import streamlit as st
|
|
| 2 |
import pandas as pd
|
| 3 |
import json
|
| 4 |
from datetime import datetime
|
| 5 |
-
|
| 6 |
-
import pytz # Importa pytz
|
| 7 |
import io
|
| 8 |
import os
|
| 9 |
|
|
@@ -41,10 +40,9 @@ st.markdown(
|
|
| 41 |
unsafe_allow_html=True
|
| 42 |
)
|
| 43 |
|
| 44 |
-
# Definizione del fuso orario per l'Italia
|
| 45 |
-
# Utilizzo pytz
|
| 46 |
ITALY_TIMEZONE = pytz.timezone("Europe/Rome")
|
| 47 |
-
UTC_TIMEZONE = pytz.utc
|
| 48 |
|
| 49 |
# Funzione di conversione
|
| 50 |
def convert_json_to_excel_data(json_file_content: str):
|
|
@@ -64,22 +62,16 @@ def convert_json_to_excel_data(json_file_content: str):
|
|
| 64 |
order_date_formatted = None
|
| 65 |
if order_date_str:
|
| 66 |
try:
|
| 67 |
-
|
| 68 |
-
# In questo caso, il '.000Z' finale indica UTC, quindi lo marchiamo come tale.
|
| 69 |
-
dt_object_naive = datetime.fromisoformat(order_date_str.replace('Z', '')) # Rimuovi 'Z' per parsing fromisoformat base
|
| 70 |
-
|
| 71 |
-
# 2. Rendi l'oggetto datetime consapevole del fuso orario UTC
|
| 72 |
dt_object_utc = UTC_TIMEZONE.localize(dt_object_naive)
|
| 73 |
-
|
| 74 |
-
# 3. Converti al fuso orario italiano
|
| 75 |
dt_object_italy = dt_object_utc.astimezone(ITALY_TIMEZONE)
|
| 76 |
|
| 77 |
-
#
|
| 78 |
order_date_formatted = dt_object_italy.strftime('%d/%m/%Y %H:%M:%S')
|
| 79 |
except ValueError:
|
| 80 |
order_date_formatted = order_date_str
|
| 81 |
st.warning(f"Attenzione: Impossibile parsare la data '{order_date_str}' per un file. Verrà usata la stringa originale.")
|
| 82 |
-
except Exception as tz_error:
|
| 83 |
st.warning(f"Attenzione: Errore nella conversione del fuso orario per '{order_date_str}': {tz_error}. Verrà usata la stringa originale.")
|
| 84 |
order_date_formatted = order_date_str
|
| 85 |
|
|
@@ -87,7 +79,6 @@ def convert_json_to_excel_data(json_file_content: str):
|
|
| 87 |
|
| 88 |
processed_data_for_this_file = []
|
| 89 |
for item in details:
|
| 90 |
-
# LOGICA PER positions.status BASATA SU cancelPosOdA
|
| 91 |
cancel_pos_oda_val = item.get('cancelPosOdA')
|
| 92 |
if cancel_pos_oda_val is None or \
|
| 93 |
(isinstance(cancel_pos_oda_val, bool) and not cancel_pos_oda_val) or \
|
|
@@ -234,7 +225,7 @@ if uploaded_files:
|
|
| 234 |
# Assicurati che il DataFrame abbia tutte le colonne nell'ordine desiderato
|
| 235 |
for col in final_columns_order:
|
| 236 |
if col not in final_df.columns:
|
| 237 |
-
final_df[col] = ""
|
| 238 |
final_df = final_df[final_columns_order]
|
| 239 |
|
| 240 |
# Larghezze delle colonne aggiornate
|
|
@@ -244,7 +235,7 @@ if uploaded_files:
|
|
| 244 |
'company.code': 15,
|
| 245 |
'supplier.partnerRef.code': 18,
|
| 246 |
'supplier.partnerRef.company.code': 25,
|
| 247 |
-
'docDate': 20,
|
| 248 |
'status': 10,
|
| 249 |
'positions.status': 12,
|
| 250 |
'positions.positionId': 12,
|
|
@@ -259,6 +250,10 @@ if uploaded_files:
|
|
| 259 |
'positions.reason.company.code': 25,
|
| 260 |
}
|
| 261 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 262 |
# Scrivi i nomi delle colonne nella riga 2 (indice 1 in xlsxwriter)
|
| 263 |
for col_num, col_name in enumerate(final_df.columns.values):
|
| 264 |
worksheet.write(1, col_num, col_name)
|
|
@@ -268,6 +263,13 @@ if uploaded_files:
|
|
| 268 |
worksheet.set_column(col_num, col_num, col_widths[col_name])
|
| 269 |
else:
|
| 270 |
worksheet.set_column(col_num, col_num, 15)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 271 |
|
| 272 |
# Scrivi i dati a partire dalla riga 3 (indice 2 in xlsxwriter)
|
| 273 |
final_df.to_excel(writer, sheet_name=sheet_name_excel, index=False, header=False, startrow=2)
|
|
@@ -282,7 +284,7 @@ if uploaded_files:
|
|
| 282 |
label="Scarica file Excel Unificato",
|
| 283 |
data=output.getvalue(),
|
| 284 |
file_name=output_file_name,
|
| 285 |
-
mime="application/vnd.openxmlformats-officedocument.
|
| 286 |
)
|
| 287 |
elif not conversion_successful:
|
| 288 |
st.error("Nessun file valido è stato elaborato con successo. Controlla i messaggi di errore sopra.")
|
|
|
|
| 2 |
import pandas as pd
|
| 3 |
import json
|
| 4 |
from datetime import datetime
|
| 5 |
+
import pytz
|
|
|
|
| 6 |
import io
|
| 7 |
import os
|
| 8 |
|
|
|
|
| 40 |
unsafe_allow_html=True
|
| 41 |
)
|
| 42 |
|
| 43 |
+
# Definizione del fuso orario per l'Italia
|
|
|
|
| 44 |
ITALY_TIMEZONE = pytz.timezone("Europe/Rome")
|
| 45 |
+
UTC_TIMEZONE = pytz.utc
|
| 46 |
|
| 47 |
# Funzione di conversione
|
| 48 |
def convert_json_to_excel_data(json_file_content: str):
|
|
|
|
| 62 |
order_date_formatted = None
|
| 63 |
if order_date_str:
|
| 64 |
try:
|
| 65 |
+
dt_object_naive = datetime.fromisoformat(order_date_str.replace('Z', ''))
|
|
|
|
|
|
|
|
|
|
|
|
|
| 66 |
dt_object_utc = UTC_TIMEZONE.localize(dt_object_naive)
|
|
|
|
|
|
|
| 67 |
dt_object_italy = dt_object_utc.astimezone(ITALY_TIMEZONE)
|
| 68 |
|
| 69 |
+
# La stringa di formattazione rimane corretta per Python
|
| 70 |
order_date_formatted = dt_object_italy.strftime('%d/%m/%Y %H:%M:%S')
|
| 71 |
except ValueError:
|
| 72 |
order_date_formatted = order_date_str
|
| 73 |
st.warning(f"Attenzione: Impossibile parsare la data '{order_date_str}' per un file. Verrà usata la stringa originale.")
|
| 74 |
+
except Exception as tz_error:
|
| 75 |
st.warning(f"Attenzione: Errore nella conversione del fuso orario per '{order_date_str}': {tz_error}. Verrà usata la stringa originale.")
|
| 76 |
order_date_formatted = order_date_str
|
| 77 |
|
|
|
|
| 79 |
|
| 80 |
processed_data_for_this_file = []
|
| 81 |
for item in details:
|
|
|
|
| 82 |
cancel_pos_oda_val = item.get('cancelPosOdA')
|
| 83 |
if cancel_pos_oda_val is None or \
|
| 84 |
(isinstance(cancel_pos_oda_val, bool) and not cancel_pos_oda_val) or \
|
|
|
|
| 225 |
# Assicurati che il DataFrame abbia tutte le colonne nell'ordine desiderato
|
| 226 |
for col in final_columns_order:
|
| 227 |
if col not in final_df.columns:
|
| 228 |
+
final_df[col] = ""
|
| 229 |
final_df = final_df[final_columns_order]
|
| 230 |
|
| 231 |
# Larghezze delle colonne aggiornate
|
|
|
|
| 235 |
'company.code': 15,
|
| 236 |
'supplier.partnerRef.code': 18,
|
| 237 |
'supplier.partnerRef.company.code': 25,
|
| 238 |
+
'docDate': 20, # Lascia 20, è abbastanza larga
|
| 239 |
'status': 10,
|
| 240 |
'positions.status': 12,
|
| 241 |
'positions.positionId': 12,
|
|
|
|
| 250 |
'positions.reason.company.code': 25,
|
| 251 |
}
|
| 252 |
|
| 253 |
+
# *** NUOVA PARTE: Formattazione della colonna docDate in Excel ***
|
| 254 |
+
# Crea un formato numerico personalizzato per data e ora completa
|
| 255 |
+
date_time_format = workbook.add_format({'num_format': 'dd/mm/yyyy hh:mm:ss'})
|
| 256 |
+
|
| 257 |
# Scrivi i nomi delle colonne nella riga 2 (indice 1 in xlsxwriter)
|
| 258 |
for col_num, col_name in enumerate(final_df.columns.values):
|
| 259 |
worksheet.write(1, col_num, col_name)
|
|
|
|
| 263 |
worksheet.set_column(col_num, col_num, col_widths[col_name])
|
| 264 |
else:
|
| 265 |
worksheet.set_column(col_num, col_num, 15)
|
| 266 |
+
|
| 267 |
+
# Applica il formato data/ora alla colonna 'docDate'
|
| 268 |
+
if col_name == 'docDate':
|
| 269 |
+
# +1 perché stiamo scrivendo da startrow=2 (quindi la colonna dati inizia da riga 2)
|
| 270 |
+
# Il +1 per l'indice della colonna non serve, è già l'indice corretto
|
| 271 |
+
worksheet.set_column(col_num, col_num, col_widths[col_name], date_time_format)
|
| 272 |
+
|
| 273 |
|
| 274 |
# Scrivi i dati a partire dalla riga 3 (indice 2 in xlsxwriter)
|
| 275 |
final_df.to_excel(writer, sheet_name=sheet_name_excel, index=False, header=False, startrow=2)
|
|
|
|
| 284 |
label="Scarica file Excel Unificato",
|
| 285 |
data=output.getvalue(),
|
| 286 |
file_name=output_file_name,
|
| 287 |
+
mime="application/vnd.openxmlformats-officedocument.spreadsheet1.sheet"
|
| 288 |
)
|
| 289 |
elif not conversion_successful:
|
| 290 |
st.error("Nessun file valido è stato elaborato con successo. Controlla i messaggi di errore sopra.")
|