Spaces:
Sleeping
Sleeping
Update src/streamlit_app.py
Browse files- src/streamlit_app.py +22 -27
src/streamlit_app.py
CHANGED
|
@@ -16,29 +16,29 @@ st.markdown(
|
|
| 16 |
"""
|
| 17 |
<style>
|
| 18 |
.stApp {
|
| 19 |
-
background-color: #FFFFCC;
|
| 20 |
background-attachment: fixed;
|
| 21 |
}
|
| 22 |
h1, h2 {
|
| 23 |
-
color: #1E90FF;
|
| 24 |
}
|
| 25 |
p, label {
|
| 26 |
-
color: #000080;
|
| 27 |
}
|
| 28 |
.stButton>button {
|
| 29 |
color: white;
|
| 30 |
-
background-color: #1E90FF;
|
| 31 |
border: none;
|
| 32 |
border-radius: 5px;
|
| 33 |
padding: 10px 20px;
|
| 34 |
font-size: 16px;
|
| 35 |
}
|
| 36 |
.stButton>button:hover {
|
| 37 |
-
background-color: #4169E1;
|
| 38 |
}
|
| 39 |
</style>
|
| 40 |
""",
|
| 41 |
-
unsafe_allow_html=True
|
| 42 |
)
|
| 43 |
|
| 44 |
# Funzione di conversione
|
|
@@ -55,7 +55,7 @@ def convert_json_to_excel_data(json_file_content: str):
|
|
| 55 |
|
| 56 |
order_number = outbound_info.get('orderNumber')
|
| 57 |
order_doc_date_str = outbound_info.get('orderDocDate')
|
| 58 |
-
order_type_json = outbound_info.get('orderType')
|
| 59 |
|
| 60 |
# Fissi: deliveryType (non nel JSON), service (nel JSON ma fisso PDB), serviceType (nel JSON ma fisso Standard)
|
| 61 |
delivery_type_fixed = "DELIVERY"
|
|
@@ -113,14 +113,14 @@ def convert_json_to_excel_data(json_file_content: str):
|
|
| 113 |
'siteCode': site_code_json,
|
| 114 |
'companyCode': company_code_json,
|
| 115 |
'orderNumber': order_number,
|
| 116 |
-
'orderType': order_type_json,
|
| 117 |
-
'deliveryType': delivery_type_fixed,
|
| 118 |
'orderDocDate': order_doc_date_formatted,
|
| 119 |
'orderDateDetail': order_date_detail,
|
| 120 |
'dueDate': due_date_formatted,
|
| 121 |
'reasonCode': reason_code,
|
| 122 |
-
'service': service_fixed,
|
| 123 |
-
'serviceType': service_type_fixed,
|
| 124 |
'paymentInfo.value': payment_info_value,
|
| 125 |
'customer.code': customer_code,
|
| 126 |
'consignee.name': consignee_name,
|
|
@@ -175,7 +175,6 @@ st.markdown("**(Il Site Code verrà letto direttamente dal JSON)**")
|
|
| 175 |
|
| 176 |
|
| 177 |
st.header("1. Carica i tuoi file JSON")
|
| 178 |
-
# Passiamo la chiave dinamica al file_uploader
|
| 179 |
uploaded_files = st.file_uploader(
|
| 180 |
"Scegli uno o più file JSON di tipo 'Ordine_Outbound'",
|
| 181 |
type=["json"],
|
|
@@ -193,7 +192,6 @@ if uploaded_files:
|
|
| 193 |
for uploaded_file in uploaded_files:
|
| 194 |
file_name = uploaded_file.name
|
| 195 |
|
| 196 |
-
# Verifica che il nome del file inizi con "Ordine_Outbound"
|
| 197 |
if not file_name.lower().startswith("ordine_outbound"):
|
| 198 |
st.error(f"Errore: Il file '{file_name}' non inizia con 'Ordine_Outbound'. Verrà ignorato.")
|
| 199 |
conversion_successful = False
|
|
@@ -205,12 +203,11 @@ if uploaded_files:
|
|
| 205 |
|
| 206 |
df_this_file = convert_json_to_excel_data(json_content_string)
|
| 207 |
|
| 208 |
-
if df_this_file is not None and not df_this_file.empty:
|
| 209 |
all_processed_data.append(df_this_file)
|
| 210 |
-
elif df_this_file is None:
|
| 211 |
conversion_successful = False
|
| 212 |
st.error(f"Impossibile convertire il file '{file_name}'. Controlla i log per i dettagli.")
|
| 213 |
-
# else: df_this_file era vuoto, nessun errore ma nessun dato da aggiungere
|
| 214 |
|
| 215 |
except Exception as e:
|
| 216 |
st.error(f"Si è verificato un errore imprevisto durante la lettura o l'elaborazione del file '{file_name}': {e}")
|
|
@@ -220,17 +217,18 @@ if uploaded_files:
|
|
| 220 |
final_df = pd.concat(all_processed_data, ignore_index=True)
|
| 221 |
st.success(f"Elaborazione di {len(all_processed_data)} file JSON completata! Pronto per il download.")
|
| 222 |
|
|
|
|
|
|
|
|
|
|
| 223 |
output = io.BytesIO()
|
| 224 |
writer = pd.ExcelWriter(output, engine='xlsxwriter')
|
| 225 |
|
| 226 |
-
sheet_name_excel = 'OutboundOrder'
|
| 227 |
final_df.to_excel(writer, sheet_name=sheet_name_excel, index=False)
|
| 228 |
|
| 229 |
workbook = writer.book
|
| 230 |
worksheet = writer.sheets[sheet_name_excel]
|
| 231 |
|
| 232 |
-
# Ordine delle colonne e larghezze per l'Excel Outbound
|
| 233 |
-
# Basato sul mapping fornito, con siteCode/companyCode in testa
|
| 234 |
final_columns_order = [
|
| 235 |
'siteCode', 'companyCode', 'orderNumber', 'orderType', 'deliveryType',
|
| 236 |
'orderDocDate', 'orderDateDetail', 'dueDate', 'reasonCode',
|
|
@@ -244,12 +242,9 @@ if uploaded_files:
|
|
| 244 |
'reasonCodeShp', 'infoDelivery', 'bookingInfo'
|
| 245 |
]
|
| 246 |
|
| 247 |
-
# Filtra solo le colonne effettivamente presenti nel DataFrame dopo la conversione
|
| 248 |
-
# e riordinale
|
| 249 |
cols_present_and_ordered = [col for col in final_columns_order if col in final_df.columns]
|
| 250 |
final_df = final_df[cols_present_and_ordered]
|
| 251 |
|
| 252 |
-
# Larghezze colonne ottimizzate per Outbound
|
| 253 |
col_widths = {
|
| 254 |
'siteCode': 10, 'companyCode': 15, 'orderNumber': 15, 'orderType': 10, 'deliveryType': 12,
|
| 255 |
'orderDocDate': 15, 'orderDateDetail': 15, 'dueDate': 12, 'reasonCode': 12,
|
|
@@ -263,19 +258,18 @@ if uploaded_files:
|
|
| 263 |
'reasonCodeShp': 15, 'infoDelivery': 20, 'bookingInfo': 20
|
| 264 |
}
|
| 265 |
|
| 266 |
-
# Applica le intestazioni e le larghezze delle colonne
|
| 267 |
for col_num, col_name in enumerate(final_df.columns.values):
|
| 268 |
worksheet.write(0, col_num, col_name)
|
| 269 |
if col_name in col_widths:
|
| 270 |
worksheet.set_column(col_num, col_num, col_widths[col_name])
|
| 271 |
else:
|
| 272 |
-
worksheet.set_column(col_num, col_num, 15)
|
| 273 |
|
| 274 |
writer.close()
|
| 275 |
output.seek(0)
|
| 276 |
|
| 277 |
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
| 278 |
-
output_file_name = f"OrdiniOutbound_{timestamp}.xlsx"
|
| 279 |
|
| 280 |
st.download_button(
|
| 281 |
label="Scarica file Excel Unificato",
|
|
@@ -291,11 +285,12 @@ else:
|
|
| 291 |
st.info("Carica i tuoi file JSON per iniziare.")
|
| 292 |
|
| 293 |
|
| 294 |
-
# --- Funzione per il reset:
|
| 295 |
def clear_inputs():
|
| 296 |
st.session_state.file_uploader_key += 1
|
| 297 |
st.session_state.site_code_input = ""
|
| 298 |
-
st.rerun()
|
|
|
|
| 299 |
|
| 300 |
st.markdown("---")
|
| 301 |
st.button("Pulisci Input (RESET)", on_click=clear_inputs)
|
|
|
|
| 16 |
"""
|
| 17 |
<style>
|
| 18 |
.stApp {
|
| 19 |
+
background-color: #FFFFCC; /* Giallo pastello */
|
| 20 |
background-attachment: fixed;
|
| 21 |
}
|
| 22 |
h1, h2 {
|
| 23 |
+
color: #1E90FF; /* Blu acceso */
|
| 24 |
}
|
| 25 |
p, label {
|
| 26 |
+
color: #000080; /* Blu scuro */
|
| 27 |
}
|
| 28 |
.stButton>button {
|
| 29 |
color: white;
|
| 30 |
+
background-color: #1E90FF; /* Blu acceso */
|
| 31 |
border: none;
|
| 32 |
border-radius: 5px;
|
| 33 |
padding: 10px 20px;
|
| 34 |
font-size: 16px;
|
| 35 |
}
|
| 36 |
.stButton>button:hover {
|
| 37 |
+
background-color: #4169E1; /* Blu medio al passaggio del mouse */
|
| 38 |
}
|
| 39 |
</style>
|
| 40 |
""",
|
| 41 |
+
unsafe_allow_html=True # QUESTA RIGA DEVE ESSERCI
|
| 42 |
)
|
| 43 |
|
| 44 |
# Funzione di conversione
|
|
|
|
| 55 |
|
| 56 |
order_number = outbound_info.get('orderNumber')
|
| 57 |
order_doc_date_str = outbound_info.get('orderDocDate')
|
| 58 |
+
order_type_json = outbound_info.get('orderType')
|
| 59 |
|
| 60 |
# Fissi: deliveryType (non nel JSON), service (nel JSON ma fisso PDB), serviceType (nel JSON ma fisso Standard)
|
| 61 |
delivery_type_fixed = "DELIVERY"
|
|
|
|
| 113 |
'siteCode': site_code_json,
|
| 114 |
'companyCode': company_code_json,
|
| 115 |
'orderNumber': order_number,
|
| 116 |
+
'orderType': order_type_json,
|
| 117 |
+
'deliveryType': delivery_type_fixed,
|
| 118 |
'orderDocDate': order_doc_date_formatted,
|
| 119 |
'orderDateDetail': order_date_detail,
|
| 120 |
'dueDate': due_date_formatted,
|
| 121 |
'reasonCode': reason_code,
|
| 122 |
+
'service': service_fixed,
|
| 123 |
+
'serviceType': service_type_fixed,
|
| 124 |
'paymentInfo.value': payment_info_value,
|
| 125 |
'customer.code': customer_code,
|
| 126 |
'consignee.name': consignee_name,
|
|
|
|
| 175 |
|
| 176 |
|
| 177 |
st.header("1. Carica i tuoi file JSON")
|
|
|
|
| 178 |
uploaded_files = st.file_uploader(
|
| 179 |
"Scegli uno o più file JSON di tipo 'Ordine_Outbound'",
|
| 180 |
type=["json"],
|
|
|
|
| 192 |
for uploaded_file in uploaded_files:
|
| 193 |
file_name = uploaded_file.name
|
| 194 |
|
|
|
|
| 195 |
if not file_name.lower().startswith("ordine_outbound"):
|
| 196 |
st.error(f"Errore: Il file '{file_name}' non inizia con 'Ordine_Outbound'. Verrà ignorato.")
|
| 197 |
conversion_successful = False
|
|
|
|
| 203 |
|
| 204 |
df_this_file = convert_json_to_excel_data(json_content_string)
|
| 205 |
|
| 206 |
+
if df_this_file is not None and not df_this_file.empty:
|
| 207 |
all_processed_data.append(df_this_file)
|
| 208 |
+
elif df_this_file is None:
|
| 209 |
conversion_successful = False
|
| 210 |
st.error(f"Impossibile convertire il file '{file_name}'. Controlla i log per i dettagli.")
|
|
|
|
| 211 |
|
| 212 |
except Exception as e:
|
| 213 |
st.error(f"Si è verificato un errore imprevisto durante la lettura o l'elaborazione del file '{file_name}': {e}")
|
|
|
|
| 217 |
final_df = pd.concat(all_processed_data, ignore_index=True)
|
| 218 |
st.success(f"Elaborazione di {len(all_processed_data)} file JSON completata! Pronto per il download.")
|
| 219 |
|
| 220 |
+
# --- Qui non c'è la colonna 'positions.stock.cancelPosOda' ---
|
| 221 |
+
# Quindi non c'è bisogno di .capitalize()
|
| 222 |
+
|
| 223 |
output = io.BytesIO()
|
| 224 |
writer = pd.ExcelWriter(output, engine='xlsxwriter')
|
| 225 |
|
| 226 |
+
sheet_name_excel = 'OutboundOrder'
|
| 227 |
final_df.to_excel(writer, sheet_name=sheet_name_excel, index=False)
|
| 228 |
|
| 229 |
workbook = writer.book
|
| 230 |
worksheet = writer.sheets[sheet_name_excel]
|
| 231 |
|
|
|
|
|
|
|
| 232 |
final_columns_order = [
|
| 233 |
'siteCode', 'companyCode', 'orderNumber', 'orderType', 'deliveryType',
|
| 234 |
'orderDocDate', 'orderDateDetail', 'dueDate', 'reasonCode',
|
|
|
|
| 242 |
'reasonCodeShp', 'infoDelivery', 'bookingInfo'
|
| 243 |
]
|
| 244 |
|
|
|
|
|
|
|
| 245 |
cols_present_and_ordered = [col for col in final_columns_order if col in final_df.columns]
|
| 246 |
final_df = final_df[cols_present_and_ordered]
|
| 247 |
|
|
|
|
| 248 |
col_widths = {
|
| 249 |
'siteCode': 10, 'companyCode': 15, 'orderNumber': 15, 'orderType': 10, 'deliveryType': 12,
|
| 250 |
'orderDocDate': 15, 'orderDateDetail': 15, 'dueDate': 12, 'reasonCode': 12,
|
|
|
|
| 258 |
'reasonCodeShp': 15, 'infoDelivery': 20, 'bookingInfo': 20
|
| 259 |
}
|
| 260 |
|
|
|
|
| 261 |
for col_num, col_name in enumerate(final_df.columns.values):
|
| 262 |
worksheet.write(0, col_num, col_name)
|
| 263 |
if col_name in col_widths:
|
| 264 |
worksheet.set_column(col_num, col_num, col_widths[col_name])
|
| 265 |
else:
|
| 266 |
+
worksheet.set_column(col_num, col_num, 15)
|
| 267 |
|
| 268 |
writer.close()
|
| 269 |
output.seek(0)
|
| 270 |
|
| 271 |
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
| 272 |
+
output_file_name = f"OrdiniOutbound_{timestamp}.xlsx"
|
| 273 |
|
| 274 |
st.download_button(
|
| 275 |
label="Scarica file Excel Unificato",
|
|
|
|
| 285 |
st.info("Carica i tuoi file JSON per iniziare.")
|
| 286 |
|
| 287 |
|
| 288 |
+
# --- Funzione per il reset: ora senza st.rerun() ---
|
| 289 |
def clear_inputs():
|
| 290 |
st.session_state.file_uploader_key += 1
|
| 291 |
st.session_state.site_code_input = ""
|
| 292 |
+
# st.rerun() # Rimosso per evitare l'avviso a schermo
|
| 293 |
+
st.experimental_singleton.get(st.runtime.Runtime).forward_app("Rerun from button click") # Forzatura nascosta per test
|
| 294 |
|
| 295 |
st.markdown("---")
|
| 296 |
st.button("Pulisci Input (RESET)", on_click=clear_inputs)
|