Marek4321 commited on
Commit
b2ba46b
verified
1 Parent(s): 26e883f

Update report_generator.py

Browse files
Files changed (1) hide show
  1. report_generator.py +64 -99
report_generator.py CHANGED
@@ -5,7 +5,6 @@ from pathlib import Path
5
  import logging
6
  from datetime import datetime
7
  import matplotlib.pyplot as plt
8
- import seaborn as sns
9
  from docx import Document
10
  from docx.shared import Inches, Pt
11
  from docx.enum.text import WD_ALIGN_PARAGRAPH
@@ -21,11 +20,11 @@ class ReportGenerator:
21
  self.output_dir.mkdir(exist_ok=True)
22
  self.logger = logging.getLogger(__name__)
23
 
24
- def generate_excel_report(
25
  self,
26
  analyses: Dict[str, 'OfferAnalysis'],
27
  criteria: List['EvaluationCriterion']
28
- ) -> str:
29
  """
30
  Generuje raport Excel z wynikami oceny.
31
 
@@ -34,7 +33,7 @@ class ReportGenerator:
34
  criteria: Lista kryteri贸w oceny
35
 
36
  Returns:
37
- str: 艢cie偶ka do wygenerowanego pliku Excel
38
  """
39
  try:
40
  # Przygotuj dane do DataFrame
@@ -93,13 +92,13 @@ class ReportGenerator:
93
  worksheet.set_column(i+1, i+1, 50) # Uzasadnienie
94
 
95
  self.logger.info(f"Wygenerowano raport Excel: {excel_path}")
96
- return str(excel_path)
97
 
98
  except Exception as e:
99
  self.logger.error(f"B艂膮d podczas generowania raportu Excel: {str(e)}")
100
  raise
101
 
102
- def generate_word_report(
103
  self,
104
  analyses: Dict[str, 'OfferAnalysis'],
105
  criteria: List['EvaluationCriterion'],
@@ -114,34 +113,23 @@ class ReportGenerator:
114
  comparison_results: Wyniki por贸wnania ofert
115
 
116
  Returns:
117
- str: 艢cie偶ka do wygenerowanego pliku Word
118
  """
119
  try:
120
- doc = Document()
121
-
122
- # 1. Strona tytu艂owa
123
- title = doc.add_heading('Raport z Oceny Ofert Przetargowych', 0)
124
- title.alignment = WD_ALIGN_PARAGRAPH.CENTER
125
-
126
- doc.add_paragraph(f'Data utworzenia: {datetime.now().strftime("%d.%m.%Y")}')
127
- doc.add_paragraph(f'Liczba ocenionych ofert: {len(analyses)}')
128
 
129
- # 2. Spis tre艣ci
130
- doc.add_page_break()
131
- doc.add_heading('Spis tre艣ci', 1)
132
- # TODO: Doda膰 automatyczny spis tre艣ci
133
 
134
- # 3. Podsumowanie wykonawcze
135
- doc.add_page_break()
136
- doc.add_heading('Podsumowanie wykonawcze', 1)
137
 
138
  # Tabela z kluczowymi wynikami
139
- summary_table = doc.add_table(rows=1, cols=3)
140
- summary_table.style = 'Table Grid'
141
- header_cells = summary_table.rows[0].cells
142
- header_cells[0].text = 'Oferent'
143
- header_cells[1].text = 'Wynik ko艅cowy'
144
- header_cells[2].text = 'Ranking'
145
 
146
  # Posortuj oferty wg wyniku
147
  sorted_offers = sorted(
@@ -151,103 +139,80 @@ class ReportGenerator:
151
  )
152
 
153
  for i, (offer_id, analysis) in enumerate(sorted_offers, 1):
154
- row_cells = summary_table.add_row().cells
155
- row_cells[0].text = offer_id
156
- row_cells[1].text = f"{analysis.total_score:.2f}"
157
- row_cells[2].text = str(i)
158
 
159
- # 4. Szczeg贸艂owa analiza ka偶dej oferty
160
  for offer_id, analysis in analyses.items():
161
- doc.add_page_break()
162
- doc.add_heading(f'Analiza oferty: {offer_id}', 1)
163
 
164
- # Wynik ko艅cowy
165
- doc.add_paragraph(
166
- f'Wynik ko艅cowy: {analysis.total_score:.2f}/100 punkt贸w'
167
- )
168
-
169
- # Mocne strony
170
- doc.add_heading('Mocne strony:', 2)
171
  for strength in analysis.strengths:
172
- doc.add_paragraph(strength, style='List Bullet')
173
 
174
- # S艂abe strony
175
- doc.add_heading('S艂abe strony:', 2)
176
  for weakness in analysis.weaknesses:
177
- doc.add_paragraph(weakness, style='List Bullet')
178
-
179
- # Szczeg贸艂owe oceny
180
- doc.add_heading('Szczeg贸艂owe oceny:', 2)
181
- scores_table = doc.add_table(rows=1, cols=3)
182
- scores_table.style = 'Table Grid'
183
 
184
- header_cells = scores_table.rows[0].cells
185
- header_cells[0].text = 'Kryterium'
186
- header_cells[1].text = 'Ocena'
187
- header_cells[2].text = 'Uzasadnienie'
188
 
189
  for eval in analysis.evaluations:
190
- row_cells = scores_table.add_row().cells
191
- row_cells[0].text = eval.criterion_name
192
- row_cells[1].text = f"{eval.score:.2f}"
193
- row_cells[2].text = eval.justification
194
 
195
- # 5. Por贸wnanie ofert
196
- doc.add_page_break()
197
- doc.add_heading('Por贸wnanie ofert', 1)
198
- doc.add_paragraph(comparison_results)
199
-
200
- # 6. Zapisz dokument
201
- timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
202
- word_path = self.output_dir / f"raport_oceny_{timestamp}.docx"
203
- doc.save(word_path)
204
 
205
- self.logger.info(f"Wygenerowano raport Word: {word_path}")
206
- return str(word_path)
 
207
 
208
  except Exception as e:
209
  self.logger.error(f"B艂膮d podczas generowania raportu Word: {str(e)}")
210
  raise
211
 
212
- def generate_visualizations(
213
- self,
214
- analyses: Dict[str, 'OfferAnalysis']
215
- ) -> List[str]:
216
  """
217
- Generuje wizualizacje wynik贸w dla raport贸w.
218
 
219
  Args:
220
  analyses: S艂ownik z analizami ofert
221
 
222
  Returns:
223
- List[str]: Lista 艣cie偶ek do wygenerowanych wykres贸w
224
  """
225
  try:
226
- plot_paths = []
 
 
227
 
228
- # 1. Wykres radarowy dla wszystkich ofert
229
- self._generate_radar_plot(analyses)
 
230
 
231
- # 2. Wykres s艂upkowy por贸wnawczy
232
- self._generate_bar_plot(analyses)
 
 
 
233
 
234
- # 3. Heatmapa ocen
235
- self._generate_heatmap(analyses)
 
 
 
 
 
 
 
 
236
 
237
- return plot_paths
238
-
239
  except Exception as e:
240
- self.logger.error(f"B艂膮d podczas generowania wizualizacji: {str(e)}")
241
- return []
242
-
243
- def _generate_radar_plot(self, analyses: Dict[str, 'OfferAnalysis']) -> str:
244
- """Generuje wykres radarowy por贸wnuj膮cy oferty"""
245
- pass # TODO: Implementacja wykresu radarowego
246
-
247
- def _generate_bar_plot(self, analyses: Dict[str, 'OfferAnalysis']) -> str:
248
- """Generuje wykres s艂upkowy por贸wnuj膮cy wyniki ko艅cowe"""
249
- pass # TODO: Implementacja wykresu s艂upkowego
250
-
251
- def _generate_heatmap(self, analyses: Dict[str, 'OfferAnalysis']) -> str:
252
- """Generuje heatmap臋 ocen dla wszystkich kryteri贸w"""
253
- pass # TODO: Implementacja heatmapy
 
5
  import logging
6
  from datetime import datetime
7
  import matplotlib.pyplot as plt
 
8
  from docx import Document
9
  from docx.shared import Inches, Pt
10
  from docx.enum.text import WD_ALIGN_PARAGRAPH
 
20
  self.output_dir.mkdir(exist_ok=True)
21
  self.logger = logging.getLogger(__name__)
22
 
23
+ async def generate_excel_report(
24
  self,
25
  analyses: Dict[str, 'OfferAnalysis'],
26
  criteria: List['EvaluationCriterion']
27
+ ) -> pd.DataFrame:
28
  """
29
  Generuje raport Excel z wynikami oceny.
30
 
 
33
  criteria: Lista kryteri贸w oceny
34
 
35
  Returns:
36
+ pd.DataFrame: DataFrame z wynikami
37
  """
38
  try:
39
  # Przygotuj dane do DataFrame
 
92
  worksheet.set_column(i+1, i+1, 50) # Uzasadnienie
93
 
94
  self.logger.info(f"Wygenerowano raport Excel: {excel_path}")
95
+ return df
96
 
97
  except Exception as e:
98
  self.logger.error(f"B艂膮d podczas generowania raportu Excel: {str(e)}")
99
  raise
100
 
101
+ async def generate_word_report(
102
  self,
103
  analyses: Dict[str, 'OfferAnalysis'],
104
  criteria: List['EvaluationCriterion'],
 
113
  comparison_results: Wyniki por贸wnania ofert
114
 
115
  Returns:
116
+ str: Markdown z raportem
117
  """
118
  try:
119
+ # Generuj raport w formacie Markdown
120
+ report_lines = []
 
 
 
 
 
 
121
 
122
+ # 1. Nag艂贸wek
123
+ report_lines.append("# Raport z Oceny Ofert Przetargowych")
124
+ report_lines.append(f"Data utworzenia: {datetime.now().strftime('%d.%m.%Y')}")
125
+ report_lines.append(f"Liczba ocenionych ofert: {len(analyses)}")
126
 
127
+ # 2. Podsumowanie wykonawcze
128
+ report_lines.append("\n## Podsumowanie wykonawcze")
 
129
 
130
  # Tabela z kluczowymi wynikami
131
+ report_lines.append("\n| Oferent | Wynik ko艅cowy | Ranking |")
132
+ report_lines.append("|----------|---------------|---------|")
 
 
 
 
133
 
134
  # Posortuj oferty wg wyniku
135
  sorted_offers = sorted(
 
139
  )
140
 
141
  for i, (offer_id, analysis) in enumerate(sorted_offers, 1):
142
+ report_lines.append(
143
+ f"| {offer_id} | {analysis.total_score:.2f} | {i} |"
144
+ )
 
145
 
146
+ # 3. Szczeg贸艂owa analiza ofert
147
  for offer_id, analysis in analyses.items():
148
+ report_lines.append(f"\n## Analiza oferty: {offer_id}")
149
+ report_lines.append(f"Wynik ko艅cowy: {analysis.total_score:.2f}/100 punkt贸w")
150
 
151
+ report_lines.append("\n### Mocne strony:")
 
 
 
 
 
 
152
  for strength in analysis.strengths:
153
+ report_lines.append(f"* {strength}")
154
 
155
+ report_lines.append("\n### S艂abe strony:")
 
156
  for weakness in analysis.weaknesses:
157
+ report_lines.append(f"* {weakness}")
 
 
 
 
 
158
 
159
+ report_lines.append("\n### Szczeg贸艂owe oceny:")
160
+ report_lines.append("\n| Kryterium | Ocena | Uzasadnienie |")
161
+ report_lines.append("|-----------|--------|--------------|")
 
162
 
163
  for eval in analysis.evaluations:
164
+ report_lines.append(
165
+ f"| {eval.criterion_name} | {eval.score:.2f} | {eval.justification} |"
166
+ )
 
167
 
168
+ # 4. Por贸wnanie ofert
169
+ report_lines.append("\n## Por贸wnanie ofert")
170
+ report_lines.append(str(comparison_results))
 
 
 
 
 
 
171
 
172
+ report = "\n".join(report_lines)
173
+ self.logger.info("Wygenerowano raport Word w formacie Markdown")
174
+ return report
175
 
176
  except Exception as e:
177
  self.logger.error(f"B艂膮d podczas generowania raportu Word: {str(e)}")
178
  raise
179
 
180
+ def _generate_bar_plot(self, analyses: Dict[str, 'OfferAnalysis']) -> str:
 
 
 
181
  """
182
+ Generuje wykres s艂upkowy por贸wnuj膮cy wyniki ko艅cowe.
183
 
184
  Args:
185
  analyses: S艂ownik z analizami ofert
186
 
187
  Returns:
188
+ str: 艢cie偶ka do zapisanego wykresu
189
  """
190
  try:
191
+ # Przygotuj dane
192
+ offer_ids = list(analyses.keys())
193
+ scores = [analysis.total_score for analysis in analyses.values()]
194
 
195
+ # Utw贸rz wykres
196
+ plt.figure(figsize=(10, 6))
197
+ plt.bar(offer_ids, scores)
198
 
199
+ # Dodaj etykiety
200
+ plt.title('Por贸wnanie wynik贸w ko艅cowych')
201
+ plt.xlabel('Oferenci')
202
+ plt.ylabel('Wynik ko艅cowy')
203
+ plt.xticks(rotation=45)
204
 
205
+ # Dodaj warto艣ci nad s艂upkami
206
+ for i, score in enumerate(scores):
207
+ plt.text(i, score, f'{score:.1f}', ha='center', va='bottom')
208
+
209
+ # Zapisz wykres
210
+ plot_path = self.output_dir / 'wyniki_koncowe.png'
211
+ plt.savefig(plot_path, bbox_inches='tight')
212
+ plt.close()
213
+
214
+ return str(plot_path)
215
 
 
 
216
  except Exception as e:
217
+ self.logger.error(f"B艂膮d podczas generowania wykresu: {str(e)}")
218
+ return ""