diff --git a/odex25_project/project_base/report/project_report_templates.xml b/odex25_project/project_base/report/project_report_templates.xml index 3311879a2..069da6a1d 100644 --- a/odex25_project/project_base/report/project_report_templates.xml +++ b/odex25_project/project_base/report/project_report_templates.xml @@ -274,62 +274,64 @@ -
+ +
-
- Project Stages -
- - - - - - - - - - - - - +
+ Project Stages +
+
- Stage - - Start Date - - End Date - - Weight - - Completion - - Task -
+ - - - - - - + + + + + + - - -
- - - - - - - - - % - - - - + Stage + + Start Date + + End Date + + Weight + + Completion + + Task +
-
+ + + + + + + + + + + + + + + + + + % + + + + + + + + + +
+
@@ -371,7 +373,7 @@ Additional Work Amount - + @@ -382,70 +384,72 @@ - - - - - - - - - - - - - + +
- Payment - - Due Date - - Amount - - Tax - - Total - - Payment Status -
+ - - - - - - + + + + + + - - -
- - - - - - - - - - - - - - - - - - - - + Payment + + Due Date + + Amount + + Tax + + Total + + Payment Status +
-
-
-
- Project Details -
- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
Project Details
+ +
+
diff --git a/odex25_project/project_base/report/project_status_report.py b/odex25_project/project_base/report/project_status_report.py index bbf803f7c..88869936c 100644 --- a/odex25_project/project_base/report/project_status_report.py +++ b/odex25_project/project_base/report/project_status_report.py @@ -7,12 +7,11 @@ import base64 import matplotlib # matplotlib.use('Agg') import logging - +from matplotlib import font_manager import os import arabic_reshaper from bidi.algorithm import get_display -from odoo.modules.module import get_module_resource - +from odoo.tools import is_html_empty _logger = logging.getLogger(__name__) @@ -39,12 +38,39 @@ class ReportProjectStatus(models.AbstractModel): 'doc_model': 'project.project', 'docs': projects, 'chart_map': chart_map, + 'is_html_empty': is_html_empty, } - def _get_chart_image(self, project): - _logger.info( - f"Task counts - New: {project.task_count_new}, In Progress: {project.task_count_inprogress}, Done: {project.task_count_finished}") + def get_all_fonts_paths(self): + font_extensions = ('.ttf') + # '.otf', '.woff', '.woff2' + fonts_dict = {} + installed_modules = self.env['ir.module.module'].search([('state', '=', 'installed')]).mapped('name') + installed_modules_set = set(installed_modules) + + from odoo.tools import config + addons_paths = config.get('addons_path', '').split(',') + + for addons_path in addons_paths: + if not addons_path: + continue + addons_path = addons_path.strip() + if not os.path.exists(addons_path): + continue + for module_name in os.listdir(addons_path): + module_path = os.path.join(addons_path, module_name) + if os.path.isdir(module_path) and module_name in installed_modules_set: + for root, dirs, files in os.walk(module_path): + for file in files: + if file.lower().endswith(font_extensions): + full_path = os.path.join(root, file) + font_name = os.path.splitext(file)[0].lower() # Lowercase + fonts_dict[font_name] = full_path + + return fonts_dict + + def _get_chart_image(self, project): task_data = { 'new': project.task_count_new or 0, 'in_progress': project.task_count_inprogress or 0, @@ -52,22 +78,23 @@ class ReportProjectStatus(models.AbstractModel): } if sum(task_data.values()) == 0: - _logger.warning("All task counts are zero, using dummy data") task_data = {'new': 1, 'in_progress': 1, 'done': 1} - # font_path = os.path.join(os.path.dirname(__file__), 'img', 'amiri-regular.ttf') - # if not os.path.exists(font_path): - # font_path = get_module_resource('project_base', 'static/fonts', 'amiri-regular.ttf') - # if not font_path: - # _logger.warning("Arabic font not found. Using default font.") - # font_path = None - # - # if font_path: - # prop = matplotlib.font_manager.FontProperties(fname=font_path) - # else: - # prop = None - fig = plt.figure(figsize=(5, 4)) + fonts = self.get_all_fonts_paths() + prop = None + company_font_name = self.env.company.font + + if company_font_name: + font_path = None + for font_name, path in fonts.items(): + if font_name.startswith(company_font_name.lower()): + font_path = path + break + + if font_path: + font_manager.fontManager.addfont(font_path) + prop = font_manager.FontProperties(fname=font_path) def format_arabic(text): reshaped_text = arabic_reshaper.reshape(text) @@ -79,14 +106,23 @@ class ReportProjectStatus(models.AbstractModel): sizes = [task_data['new'], task_data['in_progress'], task_data['done']] colors = ['#f0312e', '#add8e6', '#90ee90'] - plt.pie(sizes, labels=labels, autopct='%1.1f%%', colors=colors, startangle=90, - textprops= {'fontsize': 16}) - # {'fontproperties': prop, 'fontsize': 16} if prop else + wedges, texts, autotexts = plt.pie( + sizes, + labels=labels, + autopct='%1.1f%%', + colors=colors, + startangle=90, + textprops={'fontproperties': prop, 'fontsize': 12} if prop else {'fontsize': 12} + ) + for autotext in autotexts: + autotext.set_fontsize(12) + if hasattr(autotext, 'set_fontproperties'): + autotext.set_fontproperties(None) + plt.axis('equal') - plt.rcParams['font.size'] = 18 + plt.rcParams['font.size'] = 12 title_text = format_arabic('احصائيات المهام') - plt.title(title_text) - # fontproperties = prop if prop else None + plt.title(title_text, fontproperties=prop, fontsize=16) if prop else plt.title(title_text) buffer = io.BytesIO() plt.savefig(buffer, format='png', bbox_inches='tight', dpi=300)