pasquale991 commited on
Commit
3708ecb
·
verified ·
1 Parent(s): a539f96

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +27 -19
src/streamlit_app.py CHANGED
@@ -4,6 +4,7 @@ import json
4
  from datetime import datetime
5
  import io
6
  import os
 
7
 
8
  # --- Inizializzazione Session State ---
9
  if 'file_uploader_key' not in st.session_state:
@@ -39,6 +40,9 @@ st.markdown(
39
  unsafe_allow_html=True
40
  )
41
 
 
 
 
42
  # Funzione di conversione
43
  def convert_json_to_excel_data(json_file_content: str):
44
  try:
@@ -57,9 +61,19 @@ def convert_json_to_excel_data(json_file_content: str):
57
  order_date_formatted = None
58
  if order_date_str:
59
  try:
60
- dt_object = datetime.fromisoformat(order_date_str.replace('Z', '+00:00'))
61
- # Formattazione per includere data e ora
62
- order_date_formatted = dt_object.strftime('%d/%m/%Y %H:%M:%S')
 
 
 
 
 
 
 
 
 
 
63
  except ValueError:
64
  order_date_formatted = order_date_str
65
  st.warning(f"Attenzione: Impossibile parsare la data '{order_date_str}' per un file. Verrà usata la stringa originale.")
@@ -68,7 +82,7 @@ def convert_json_to_excel_data(json_file_content: str):
68
 
69
  processed_data_for_this_file = []
70
  for item in details:
71
- # NUOVA LOGICA PER positions.status BASATA SU cancelPosOdA
72
  cancel_pos_oda_val = item.get('cancelPosOdA')
73
  if cancel_pos_oda_val is None or \
74
  (isinstance(cancel_pos_oda_val, bool) and not cancel_pos_oda_val) or \
@@ -86,8 +100,8 @@ def convert_json_to_excel_data(json_file_content: str):
86
  'supplier.partnerRef.code': partner_code,
87
  'supplier.partnerRef.company.code': company_code,
88
  'docDate': order_date_formatted,
89
- 'status': 'CREATED', # Questo si riferisce allo status dell'intera testata dell'ordine
90
- 'positions.status': positions_status_value, # Qui applichiamo il valore condizionale
91
  'positions.positionId': item.get('positionId'),
92
  'positions.stock.item.itemNumber': item.get('itemCode'),
93
  'positions.stock.quantity': item.get('quantity'),
@@ -96,9 +110,8 @@ def convert_json_to_excel_data(json_file_content: str):
96
  'positions.stock.accountingInfo.availability': item.get('availability'),
97
  'positions.stock.item.company.code': company_code,
98
  'positions.spare.string1': item.get('refOrder'),
99
- 'positions.reason.code': item.get('reasonCode'), # Naming corretto
100
  'positions.reason.company.code': company_code,
101
- # RIMOZIONE COMPLETA DI 'positions.stock.cancelPosOda'
102
  }
103
  processed_data_for_this_file.append(row)
104
 
@@ -167,9 +180,6 @@ if uploaded_files:
167
 
168
  # --- Post-processing per la formattazione Excel ---
169
 
170
- # Rimuoviamo la riga per cancelPosOda in quanto non serve più
171
- # final_df['positions.stock.cancelPosOda'] = final_df['positions.stock.cancelPosOda'].apply(lambda x: str(x).capitalize())
172
-
173
  # Definizione delle colonne di testata
174
  header_columns = [
175
  'site.code', 'docNumber', 'company.code', 'supplier.partnerRef.code',
@@ -205,7 +215,7 @@ if uploaded_files:
205
  'supplier.partnerRef.company.code',
206
  'docDate',
207
  'status',
208
- 'positions.status', # Questo campo ora ha la logica condizionale
209
  'positions.positionId',
210
  'positions.stock.item.itemNumber',
211
  'positions.stock.quantity',
@@ -214,9 +224,8 @@ if uploaded_files:
214
  'positions.stock.accountingInfo.availability',
215
  'positions.stock.item.company.code',
216
  'positions.spare.string1',
217
- 'positions.reason.code', # Naming corretto
218
  'positions.reason.company.code',
219
- # RIMOZIONE COMPLETA DI 'positions.stock.cancelPosOda' dalla lista delle colonne
220
  ]
221
 
222
  # Assicurati che il DataFrame abbia tutte le colonne nell'ordine desiderato
@@ -234,7 +243,7 @@ if uploaded_files:
234
  'supplier.partnerRef.company.code': 25,
235
  'docDate': 20,
236
  'status': 10,
237
- 'positions.status': 12, # Larghezza per status
238
  'positions.positionId': 12,
239
  'positions.stock.item.itemNumber': 25,
240
  'positions.stock.quantity': 10,
@@ -245,18 +254,17 @@ if uploaded_files:
245
  'positions.spare.string1': 15,
246
  'positions.reason.code': 15,
247
  'positions.reason.company.code': 25,
248
- # RIMOZIONE COMPLETA DI 'positions.stock.cancelPosOda' dalla lista delle larghezze
249
  }
250
 
251
  # Scrivi i nomi delle colonne nella riga 2 (indice 1 in xlsxwriter)
252
  for col_num, col_name in enumerate(final_df.columns.values):
253
- worksheet.write(1, col_num, col_name) # Scrivi header in riga 2
254
 
255
  # Imposta le larghezze delle colonne
256
  if col_name in col_widths:
257
  worksheet.set_column(col_num, col_num, col_widths[col_name])
258
  else:
259
- worksheet.set_column(col_num, col_num, 15) # Larghezza di default
260
 
261
  # Scrivi i dati a partire dalla riga 3 (indice 2 in xlsxwriter)
262
  final_df.to_excel(writer, sheet_name=sheet_name_excel, index=False, header=False, startrow=2)
@@ -278,7 +286,7 @@ if uploaded_files:
278
  else:
279
  st.info("Nessun dato valido estratto dai file selezionati.")
280
  else:
281
- st.info("Carica i tuoi file JSON per iniziare. I file devono essere della stessa tipologia!")
282
 
283
  # --- Funzione per il reset ---
284
  def clear_inputs():
 
4
  from datetime import datetime
5
  import io
6
  import os
7
+ from zoneinfo import ZoneInfo # Importa ZoneInfo da zoneinfo
8
 
9
  # --- Inizializzazione Session State ---
10
  if 'file_uploader_key' not in st.session_state:
 
40
  unsafe_allow_html=True
41
  )
42
 
43
+ # Definizione del fuso orario per l'Italia (Europe/Rome gestisce automaticamente DST)
44
+ ITALY_TIMEZONE = ZoneInfo("Europe/Rome")
45
+
46
  # Funzione di conversione
47
  def convert_json_to_excel_data(json_file_content: str):
48
  try:
 
61
  order_date_formatted = None
62
  if order_date_str:
63
  try:
64
+ # 1. Parsa la stringa ISO, che gestisce già 'Z' (UTC)
65
+ dt_object_utc = datetime.fromisoformat(order_date_str)
66
+
67
+ # 2. Assicurati che l'oggetto datetime sia consapevole del fuso orario UTC
68
+ if dt_object_utc.tzinfo is None:
69
+ # Se non ha informazioni sul fuso orario, assumi UTC (per casi senza 'Z')
70
+ dt_object_utc = dt_object_utc.replace(tzinfo=ZoneInfo("UTC"))
71
+
72
+ # 3. Converti al fuso orario italiano
73
+ dt_object_italy = dt_object_utc.astimezone(ITALY_TIMEZONE)
74
+
75
+ # 4. Formatta per includere data e ora locale
76
+ order_date_formatted = dt_object_italy.strftime('%d/%m/%Y %H:%M:%S')
77
  except ValueError:
78
  order_date_formatted = order_date_str
79
  st.warning(f"Attenzione: Impossibile parsare la data '{order_date_str}' per un file. Verrà usata la stringa originale.")
 
82
 
83
  processed_data_for_this_file = []
84
  for item in details:
85
+ # LOGICA PER positions.status BASATA SU cancelPosOdA
86
  cancel_pos_oda_val = item.get('cancelPosOdA')
87
  if cancel_pos_oda_val is None or \
88
  (isinstance(cancel_pos_oda_val, bool) and not cancel_pos_oda_val) or \
 
100
  'supplier.partnerRef.code': partner_code,
101
  'supplier.partnerRef.company.code': company_code,
102
  'docDate': order_date_formatted,
103
+ 'status': 'CREATED',
104
+ 'positions.status': positions_status_value,
105
  'positions.positionId': item.get('positionId'),
106
  'positions.stock.item.itemNumber': item.get('itemCode'),
107
  'positions.stock.quantity': item.get('quantity'),
 
110
  'positions.stock.accountingInfo.availability': item.get('availability'),
111
  'positions.stock.item.company.code': company_code,
112
  'positions.spare.string1': item.get('refOrder'),
113
+ 'positions.reason.code': item.get('reasonCode'),
114
  'positions.reason.company.code': company_code,
 
115
  }
116
  processed_data_for_this_file.append(row)
117
 
 
180
 
181
  # --- Post-processing per la formattazione Excel ---
182
 
 
 
 
183
  # Definizione delle colonne di testata
184
  header_columns = [
185
  'site.code', 'docNumber', 'company.code', 'supplier.partnerRef.code',
 
215
  'supplier.partnerRef.company.code',
216
  'docDate',
217
  'status',
218
+ 'positions.status',
219
  'positions.positionId',
220
  'positions.stock.item.itemNumber',
221
  'positions.stock.quantity',
 
224
  'positions.stock.accountingInfo.availability',
225
  'positions.stock.item.company.code',
226
  'positions.spare.string1',
227
+ 'positions.reason.code',
228
  'positions.reason.company.code',
 
229
  ]
230
 
231
  # Assicurati che il DataFrame abbia tutte le colonne nell'ordine desiderato
 
243
  'supplier.partnerRef.company.code': 25,
244
  'docDate': 20,
245
  'status': 10,
246
+ 'positions.status': 12,
247
  'positions.positionId': 12,
248
  'positions.stock.item.itemNumber': 25,
249
  'positions.stock.quantity': 10,
 
254
  'positions.spare.string1': 15,
255
  'positions.reason.code': 15,
256
  'positions.reason.company.code': 25,
 
257
  }
258
 
259
  # Scrivi i nomi delle colonne nella riga 2 (indice 1 in xlsxwriter)
260
  for col_num, col_name in enumerate(final_df.columns.values):
261
+ worksheet.write(1, col_num, col_name)
262
 
263
  # Imposta le larghezze delle colonne
264
  if col_name in col_widths:
265
  worksheet.set_column(col_num, col_num, col_widths[col_name])
266
  else:
267
+ worksheet.set_column(col_num, col_num, 15)
268
 
269
  # Scrivi i dati a partire dalla riga 3 (indice 2 in xlsxwriter)
270
  final_df.to_excel(writer, sheet_name=sheet_name_excel, index=False, header=False, startrow=2)
 
286
  else:
287
  st.info("Nessun dato valido estratto dai file selezionati.")
288
  else:
289
+ st.info("Carica i tuoi file JSON per iniziare.")
290
 
291
  # --- Funzione per il reset ---
292
  def clear_inputs():