diff --git a/src/submissions/frontend/visualizations/turnaround_chart.py b/src/submissions/frontend/visualizations/turnaround_chart.py new file mode 100644 index 0000000..24bdb06 --- /dev/null +++ b/src/submissions/frontend/visualizations/turnaround_chart.py @@ -0,0 +1,39 @@ +from pprint import pformat +from . import CustomFigure +import plotly.express as px +import pandas as pd +import numpy as np +from PyQt6.QtWidgets import QWidget +import logging + +logger = logging.getLogger(f"submissions.{__name__}") + + +class TurnaroundChart(CustomFigure): + + def __init__(self, df: pd.DataFrame, modes: list, settings: dict, ytitle: str | None = None, + parent: QWidget | None = None, + months: int = 6): + super().__init__(df=df, modes=modes, settings=settings) + try: + months = int(settings['months']) + except KeyError: + months = 6 + # logger.debug(f"DF: {self.df}") + self.construct_chart(df=df) + self.add_hline(y=3.5) + # self.update_xaxes() + self.update_layout(showlegend=False) + + def construct_chart(self, df: pd.DataFrame): + # logger.debug(f"PCR df:\n {df}") + df = df.sort_values(by=['submitted_date', 'name']) + try: + scatter = px.scatter(data_frame=df, x='name', y="days", + hover_data=["name", "submitted_date", "completed_date", "days"], + color="acceptable", color_discrete_map={True: "green", False: "red"} + ) + except ValueError: + scatter = px.scatter() + self.add_traces(scatter.data) + self.update_traces(marker={'size': 15}) diff --git a/src/submissions/frontend/widgets/info_tab.py b/src/submissions/frontend/widgets/info_tab.py new file mode 100644 index 0000000..679e170 --- /dev/null +++ b/src/submissions/frontend/widgets/info_tab.py @@ -0,0 +1,45 @@ +from PyQt6.QtWebEngineWidgets import QWebEngineView +from PyQt6.QtWidgets import QWidget, QGridLayout, QPushButton +from tools import Report +from .misc import StartEndDatePicker, save_pdf +from .functions import select_save_file +import logging + +logger = logging.getLogger(f"submissions.{__name__}") + + +class InfoPane(QWidget): + + def __init__(self, parent: QWidget) -> None: + super().__init__(parent) + self.app = self.parent().parent() + # logger.debug(f"\n\n{self.app}\n\n") + self.report = Report() + self.datepicker = StartEndDatePicker(default_start=-31) + self.webview = QWebEngineView() + self.datepicker.start_date.dateChanged.connect(self.date_changed) + self.datepicker.end_date.dateChanged.connect(self.date_changed) + self.layout = QGridLayout(self) + self.layout.addWidget(self.datepicker, 0, 0, 1, 2) + self.save_excel_button = QPushButton("Save Excel", parent=self) + self.save_excel_button.pressed.connect(self.save_excel) + self.save_pdf_button = QPushButton("Save PDF", parent=self) + self.save_pdf_button.pressed.connect(self.save_pdf) + self.layout.addWidget(self.save_excel_button, 0, 2, 1, 1) + self.layout.addWidget(self.save_pdf_button, 0, 3, 1, 1) + self.layout.addWidget(self.webview, 2, 0, 1, 4) + self.setLayout(self.layout) + + def date_changed(self): + self.start_date = self.datepicker.start_date.date().toPyDate() + self.end_date = self.datepicker.end_date.date().toPyDate() + + def save_excel(self): + fname = select_save_file(self, default_name=f"Report {self.start_date.strftime('%Y%m%d')} - {self.end_date.strftime('%Y%m%d')}", extension="xlsx") + self.report_obj.write_report(fname, obj=self) + + def save_pdf(self): + fname = select_save_file(obj=self, + default_name=f"Report {self.start_date.strftime('%Y%m%d')} - {self.end_date.strftime('%Y%m%d')}", + extension="pdf") + save_pdf(obj=self.webview, filename=fname) \ No newline at end of file diff --git a/src/submissions/frontend/widgets/turnaround.py b/src/submissions/frontend/widgets/turnaround.py new file mode 100644 index 0000000..9768651 --- /dev/null +++ b/src/submissions/frontend/widgets/turnaround.py @@ -0,0 +1,36 @@ +from PyQt6.QtCore import QSignalBlocker +from PyQt6.QtWebEngineWidgets import QWebEngineView +from PyQt6.QtWidgets import QWidget, QGridLayout, QPushButton, QLabel +from .info_tab import InfoPane +from backend.excel.reports import TurnaroundMaker +from pandas import DataFrame +from backend.db import BasicSubmission +from frontend.visualizations.turnaround_chart import TurnaroundChart +import logging + +logger = logging.getLogger(f"submissions.{__name__}") + + +class TurnaroundTime(InfoPane): + + def __init__(self, parent: QWidget): + super().__init__(parent) + self.chart = None + self.report_object = None + self.date_changed() + + def date_changed(self): + if self.datepicker.start_date.date() > self.datepicker.end_date.date(): + logger.warning("Start date after end date is not allowed!") + lastmonth = self.datepicker.end_date.date().addDays(-31) + # NOTE: block signal that will rerun controls getter and set start date + # Without triggering this function again + with QSignalBlocker(self.datepicker.start_date) as blocker: + self.datepicker.start_date.setDate(lastmonth) + self.date_changed() + return + super().date_changed() + chart_settings = dict(start_date=self.start_date, end_date=self.end_date) + self.report_obj = TurnaroundMaker(start_date=self.start_date, end_date=self.end_date) + self.chart = TurnaroundChart(df=self.report_obj.df, settings=chart_settings, modes=[]) + self.webview.setHtml(self.chart.to_html())