From 043848dd572fce65748eb54793e39a1987a8ba0a Mon Sep 17 00:00:00 2001 From: Shaelyn Tolkamp <46355612+tolkamps1@users.noreply.github.com> Date: Mon, 9 Dec 2024 09:38:16 -0800 Subject: [PATCH] [Track-305] Add sorting to report factory (#2469) - Add sorting to report factory - Sort AS items by referral date --- .../reports/anticipated_schedule_report.py | 10 ++++- .../src/api/reports/report_factory.py | 41 ++++++++++++++++--- .../api/reports/resource_forecast_report.py | 11 +++-- .../api/reports/thirty_sixty_ninety_report.py | 2 +- 4 files changed, 52 insertions(+), 12 deletions(-) diff --git a/epictrack-api/src/api/reports/anticipated_schedule_report.py b/epictrack-api/src/api/reports/anticipated_schedule_report.py index 3e327a819..6e2c9dfae 100644 --- a/epictrack-api/src/api/reports/anticipated_schedule_report.py +++ b/epictrack-api/src/api/reports/anticipated_schedule_report.py @@ -77,8 +77,16 @@ def __init__(self, filters, color_intensity): "work_type_id" ] group_by = "phase_name" + item_sort_key = "referral_date" template_name = "anticipated_schedule.docx" - super().__init__(data_keys, group_by, template_name, filters, color_intensity) + super().__init__( + data_keys=data_keys, + group_by=group_by, + item_sort_key=item_sort_key, + template_name=template_name, + filters=filters, + color_intensity=color_intensity + ) self.report_title = "Anticipated EA Referral Schedule" def _fetch_data(self, report_date): diff --git a/epictrack-api/src/api/reports/report_factory.py b/epictrack-api/src/api/reports/report_factory.py index c8cb426d6..25602ccea 100644 --- a/epictrack-api/src/api/reports/report_factory.py +++ b/epictrack-api/src/api/reports/report_factory.py @@ -13,10 +13,21 @@ class ReportFactory(ABC): """Basic representation of report generator.""" - def __init__(self, data_keys, group_by=None, template_name=None, filters=None, color_intensity=None): + def __init__( + self, + data_keys=None, + group_by=None, + group_sort_order=None, + item_sort_key=None, + template_name=None, + filters=None, + color_intensity=None + ): """Constructor""" self.data_keys = data_keys self.group_by = group_by + self.group_sort_order = group_sort_order # Custom group order + self.item_sort_key = item_sort_key # Sort items within groups if template_name is not None: self.template_path = Path(__file__, f"../report_templates/{template_name}") self.filters = filters @@ -34,6 +45,7 @@ def _format_data(self, data, report_title=None): excluded_items = [] if self.filters and "exclude" in self.filters: excluded_items = self.filters["exclude"] + if report_title == "Anticipated EA Referral Schedule": for item in data: obj = {} @@ -44,8 +56,8 @@ def _format_data(self, data, report_title=None): else: obj[k] = item[k] if self.group_by: - obj["sl_no"] = len(formatted_data[obj.get(self.group_by)]) + 1 - formatted_data[obj.get(self.group_by)].append(obj) + obj["sl_no"] = len(formatted_data[obj.get(self.group_by, -1)]) + 1 + formatted_data[obj.get(self.group_by, -1)].append(obj) else: formatted_data.append(obj) else: @@ -54,11 +66,28 @@ def _format_data(self, data, report_title=None): k: getattr(item, k) for k in self.data_keys if k not in excluded_items } if self.group_by: - obj["sl_no"] = len(formatted_data[obj.get(self.group_by)]) + 1 - formatted_data[obj.get(self.group_by)].append(obj) + obj["sl_no"] = len(formatted_data[obj.get(self.group_by, -1)]) + 1 + formatted_data[obj.get(self.group_by, -1)].append(obj) else: formatted_data.append(obj) - + if self.group_by: + # Sort items within each group + for group, items in formatted_data.items(): + if self.item_sort_key: + formatted_data[group] = sorted( + items, + key=lambda x: x[self.item_sort_key] + ) + # Sort groups + if self.group_sort_order: + formatted_data = dict( + sorted( + formatted_data.items(), + key=lambda x: self.group_sort_order.index(x[0]) + if x[0] in self.group_sort_order + else len(self.group_sort_order), # Move other groups last + ) + ) return formatted_data def _deserialize_work_issues(self, work_issues): diff --git a/epictrack-api/src/api/reports/resource_forecast_report.py b/epictrack-api/src/api/reports/resource_forecast_report.py index a7760581d..22db98501 100644 --- a/epictrack-api/src/api/reports/resource_forecast_report.py +++ b/epictrack-api/src/api/reports/resource_forecast_report.py @@ -68,15 +68,18 @@ def __init__(self, filters, color_intensity): "ea_type_label", "sector(sub)", "ea_type_sort_order", - # "responsible_epd", - # "cairt_lead", - # "work_lead", "fte_positions_construction", "fte_positions_operation", "work_type_id", ] group_by = "work_id" - super().__init__(data_keys, group_by, None, filters, color_intensity) + super().__init__( + data_keys=data_keys, + group_by=group_by, + template_name=None, + filters=filters, + color_intensity=color_intensity + ) self.excluded_items = [] if self.filters and "exclude" in self.filters: self.excluded_items = self.filters["exclude"] diff --git a/epictrack-api/src/api/reports/thirty_sixty_ninety_report.py b/epictrack-api/src/api/reports/thirty_sixty_ninety_report.py index dd542f86f..51bc21b56 100644 --- a/epictrack-api/src/api/reports/thirty_sixty_ninety_report.py +++ b/epictrack-api/src/api/reports/thirty_sixty_ninety_report.py @@ -63,7 +63,7 @@ def __init__(self, filters, color_intensity): "project_id", "status_date_updated", ] - super().__init__(data_keys, filters=filters, color_intensity=color_intensity) + super().__init__(data_keys=data_keys, filters=filters, color_intensity=color_intensity) self.report_date = None self.report_title = "30-60-90" self.pecp_configuration_ids = (