Post code-cleanup.

This commit is contained in:
lwark
2024-12-06 14:45:22 -06:00
parent 4ed5502c60
commit 51c419e470
11 changed files with 195 additions and 175 deletions

View File

@@ -11,6 +11,12 @@ month = date.today().month
day = date.today().day day = date.today().day
def get_week_of_month() -> int: def get_week_of_month() -> int:
"""
Gets the current week number of the month.
Returns:
int:
"""
for ii, week in enumerate(calendar.monthcalendar(date.today().year, date.today().month)): for ii, week in enumerate(calendar.monthcalendar(date.today().year, date.today().month)):
if day in week: if day in week:
return ii + 1 return ii + 1

View File

@@ -503,7 +503,7 @@ class IridaControl(Control):
""" """
super().make_parent_buttons(parent=parent) super().make_parent_buttons(parent=parent)
rows = parent.layout.rowCount() rows = parent.layout.rowCount() - 2
# logger.debug(f"Parent rows: {rows}") # logger.debug(f"Parent rows: {rows}")
checker = QCheckBox(parent) checker = QCheckBox(parent)
checker.setChecked(True) checker.setChecked(True)

View File

@@ -17,6 +17,25 @@ logger = logging.getLogger(f"submissions.{__name__}")
env = jinja_template_loading() env = jinja_template_loading()
class ReportArchetype(object):
def write_report(self, filename: Path | str, obj: QWidget | None = None):
"""
Writes info to files.
Args:
filename (Path | str): Basename of output file
obj (QWidget | None, optional): Parent object. Defaults to None.
"""
if isinstance(filename, str):
filename = Path(filename)
filename = filename.absolute()
self.writer = ExcelWriter(filename.with_suffix(".xlsx"), engine='openpyxl')
self.df.to_excel(self.writer, sheet_name=self.sheet_name)
# logger.debug(f"Writing report to: {filename}")
self.writer.close()
class ReportMaker(object): class ReportMaker(object):
def __init__(self, start_date: date, end_date: date, organizations: list | None = None): def __init__(self, start_date: date, end_date: date, organizations: list | None = None):
@@ -138,7 +157,7 @@ class ReportMaker(object):
if cell.row > 1: if cell.row > 1:
cell.style = 'Currency' cell.style = 'Currency'
class TurnaroundMaker(object): class TurnaroundMaker(ReportArchetype):
def __init__(self, start_date: date, end_date: date, submission_type:str): def __init__(self, start_date: date, end_date: date, submission_type:str):
self.start_date = start_date self.start_date = start_date
@@ -147,6 +166,7 @@ class TurnaroundMaker(object):
self.subs = BasicSubmission.query(start_date=start_date, end_date=end_date, submission_type_name=submission_type, page_size=0) self.subs = BasicSubmission.query(start_date=start_date, end_date=end_date, submission_type_name=submission_type, page_size=0)
records = [self.build_record(sub) for sub in self.subs] records = [self.build_record(sub) for sub in self.subs]
self.df = DataFrame.from_records(records) self.df = DataFrame.from_records(records)
self.sheet_name = "Turnaround"
@classmethod @classmethod
def build_record(cls, sub: BasicSubmission) -> dict: def build_record(cls, sub: BasicSubmission) -> dict:
@@ -163,18 +183,12 @@ class TurnaroundMaker(object):
return dict(name=str(sub.rsl_plate_num), days=days, submitted_date=sub.submitted_date, return dict(name=str(sub.rsl_plate_num), days=days, submitted_date=sub.submitted_date,
completed_date=sub.completed_date, acceptable=tat_ok) completed_date=sub.completed_date, acceptable=tat_ok)
def write_report(self, filename: Path | str, obj: QWidget | None = None):
"""
Writes info to files.
Args: class ChartReportMaker(ReportArchetype):
filename (Path | str): Basename of output file
obj (QWidget | None, optional): Parent object. Defaults to None. def __init__(self, df: DataFrame, sheet_name):
""" self.df = df
if isinstance(filename, str): self.sheet_name = sheet_name
filename = Path(filename)
filename = filename.absolute()
self.writer = ExcelWriter(filename.with_suffix(".xlsx"), engine='openpyxl')
self.df.to_excel(self.writer, sheet_name="Turnaround")
# logger.debug(f"Writing report to: {filename}")
self.writer.close()

View File

@@ -2,4 +2,4 @@
Constructs main application. Constructs main application.
''' '''
from .widgets import * from .widgets import *
from .visualizations import * from .visualizations import *

View File

@@ -1,13 +1,14 @@
''' '''
Contains all operations for creating charts, graphs and visual effects. Contains all operations for creating charts, graphs and visual effects.
''' '''
from datetime import timedelta from datetime import timedelta, date
from typing import Generator
from PyQt6.QtWidgets import QWidget from PyQt6.QtWidgets import QWidget
import plotly, logging import plotly, logging
from plotly.graph_objects import Figure from plotly.graph_objects import Figure
import pandas as pd import pandas as pd
from frontend.widgets.functions import select_save_file from frontend.widgets.functions import select_save_file
from tools import divide_chunks
logger = logging.getLogger(f"submissions.{__name__}") logger = logging.getLogger(f"submissions.{__name__}")
@@ -18,31 +19,121 @@ class CustomFigure(Figure):
def __init__(self, df: pd.DataFrame, settings: dict, modes: list, ytitle: str | None = None, parent: QWidget | None = None): def __init__(self, df: pd.DataFrame, settings: dict, modes: list, ytitle: str | None = None, parent: QWidget | None = None):
super().__init__() super().__init__()
# self.settings = settings
try: try:
months = int(settings['months']) months = int(settings['months'])
except KeyError: except KeyError:
months = 6 months = 6
self.df = df self.df = df
self.update_xaxes(range=[settings['start_date'] - timedelta(days=1), settings['end_date']]) self.update_xaxes(range=[settings['start_date'] - timedelta(days=1), settings['end_date']])
self.generic_figure_markers(modes=modes, ytitle=ytitle, months=months)
def save_figure(self, group_name: str = "plotly_output", parent: QWidget | None = None): def generic_figure_markers(self, modes: list = [], ytitle: str | None = None, months: int = 6):
""" """
Writes plotly figure to html file. Adds standard layout to figure.
Args: Args:
figs (): fig (Figure): Input figure.
settings (dict): settings passed down from click modes (list, optional): List of modes included in figure. Defaults to [].
fig (Figure): input figure object ytitle (str, optional): Title for the y-axis. Defaults to None.
group_name (str): controltype
Returns:
Figure: Output figure with updated titles, rangeslider, buttons.
""" """
if modes:
ytitle = modes[0]
# logger.debug("Creating visibles list for each mode.")
self.update_layout(
xaxis_title="Submitted Date (* - Date parsed from fastq file creation date)",
yaxis_title=ytitle,
showlegend=True,
barmode='stack',
updatemenus=[
dict(
type="buttons",
direction="right",
x=0.7,
y=1.2,
showactive=True,
buttons=[button for button in self.make_pyqt_buttons(modes=modes)],
)
]
)
self.update_xaxes(
rangeslider_visible=True,
rangeselector=dict(
buttons=[button for button in self.make_plotly_buttons(months=months)]
)
)
assert isinstance(self, CustomFigure)
output = select_save_file(obj=parent, default_name=group_name, extension="png") def make_plotly_buttons(self, months: int = 6) -> Generator[dict, None, None]:
self.write_image(output.absolute().__str__(), engine="kaleido") """
Creates html buttons to zoom in on date areas
def save_data(self, group_name: str = "plotly_export", parent:QWidget|None=None): Args:
output = select_save_file(obj=parent, default_name=group_name, extension="xlsx") months (int, optional): Number of months of data given. Defaults to 6.
self.df.to_excel(output.absolute().__str__(), engine="openpyxl", index=False)
Yields:
Generator[dict, None, None]: Button details.
"""
rng = [1]
if months > 2:
rng += [iii for iii in range(3, months, 3)]
# logger.debug(f"Making buttons for months: {rng}")
buttons = [dict(count=iii, label=f"{iii}m", step="month", stepmode="backward") for iii in rng]
if months > date.today().month:
buttons += [dict(count=1, label="YTD", step="year", stepmode="todate")]
buttons += [dict(step="all")]
for button in buttons:
yield button
def make_pyqt_buttons(self, modes: list) -> Generator[dict, None, None]:
"""
Creates list of buttons with one for each mode to be used in showing/hiding mode traces.
Args:
modes (list): list of modes used by main parser.
fig_len (int): number of traces in the figure
Returns:
Generator[dict, None, None]: list of buttons.
"""
fig_len = len(self.data)
if len(modes) > 1:
for ii, mode in enumerate(modes):
# NOTE: What I need to do is create a list of bools with the same length as the fig.data
mode_vis = [True] * fig_len
# NOTE: And break it into {len(modes)} chunks
mode_vis = list(divide_chunks(mode_vis, len(modes)))
# NOTE: Then, for each chunk, if the chunk index isn't equal to the index of the current mode, set to false
for jj, sublist in enumerate(mode_vis):
if jj != ii:
mode_vis[jj] = [not elem for elem in mode_vis[jj]]
# NOTE: Finally, flatten list.
mode_vis = [item for sublist in mode_vis for item in sublist]
# NOTE: Now, yield button to add to list
yield dict(label=mode, method="update", args=[
{"visible": mode_vis},
{"yaxis.title.text": mode},
])
# def save_figure(self, group_name: str = "plotly_output", parent: QWidget | None = None):
# """
# Writes plotly figure to html file.
#
# Args:
# figs ():
# settings (dict): settings passed down from click
# fig (Figure): input figure object
# group_name (str): controltype
# """
#
# output = select_save_file(obj=parent, default_name=group_name, extension="png")
# self.write_image(output.absolute().__str__(), engine="kaleido")
#
# def save_data(self, group_name: str = "plotly_export", parent:QWidget|None=None):
# output = select_save_file(obj=parent, default_name=group_name, extension="xlsx")
# self.df.to_excel(output.absolute().__str__(), engine="openpyxl", index=False)
def to_html(self) -> str: def to_html(self) -> str:
""" """

View File

@@ -19,12 +19,13 @@ class IridaFigure(CustomFigure):
def __init__(self, df: pd.DataFrame, modes: list, settings: dict, ytitle: str | None = None, parent: QWidget | None = None): def __init__(self, df: pd.DataFrame, modes: list, settings: dict, ytitle: str | None = None, parent: QWidget | None = None):
super().__init__(df=df, modes=modes, settings=settings) super().__init__(df=df, modes=modes, settings=settings)
self.df = df
try: try:
months = int(settings['months']) months = int(settings['months'])
except KeyError: except KeyError:
months = 6 months = 6
self.construct_chart(df=df, modes=modes, start_date=settings['start_date'], end_date=settings['end_date']) self.construct_chart(df=df, modes=modes, start_date=settings['start_date'], end_date=settings['end_date'])
self.generic_figure_markers(modes=modes, ytitle=ytitle, months=months)
def construct_chart(self, df: pd.DataFrame, modes: list, start_date: date, end_date:date): def construct_chart(self, df: pd.DataFrame, modes: list, start_date: date, end_date:date):
""" """
@@ -69,94 +70,3 @@ class IridaFigure(CustomFigure):
) )
bar.update_traces(visible=ii == 0) bar.update_traces(visible=ii == 0)
self.add_traces(bar.data) self.add_traces(bar.data)
def generic_figure_markers(self, modes: list = [], ytitle: str | None = None, months: int = 6):
"""
Adds standard layout to figure.
Args:
fig (Figure): Input figure.
modes (list, optional): List of modes included in figure. Defaults to [].
ytitle (str, optional): Title for the y-axis. Defaults to None.
Returns:
Figure: Output figure with updated titles, rangeslider, buttons.
"""
if modes:
ytitle = modes[0]
# logger.debug("Creating visibles list for each mode.")
self.update_layout(
xaxis_title="Submitted Date (* - Date parsed from fastq file creation date)",
yaxis_title=ytitle,
showlegend=True,
barmode='stack',
updatemenus=[
dict(
type="buttons",
direction="right",
x=0.7,
y=1.2,
showactive=True,
buttons=[button for button in self.make_pyqt_buttons(modes=modes)],
)
]
)
self.update_xaxes(
rangeslider_visible=True,
rangeselector=dict(
buttons=[button for button in self.make_plotly_buttons(months=months)]
)
)
assert isinstance(self, CustomFigure)
def make_plotly_buttons(self, months: int = 6) -> Generator[dict, None, None]:
"""
Creates html buttons to zoom in on date areas
Args:
months (int, optional): Number of months of data given. Defaults to 6.
Yields:
Generator[dict, None, None]: Button details.
"""
rng = [1]
if months > 2:
rng += [iii for iii in range(3, months, 3)]
# logger.debug(f"Making buttons for months: {rng}")
buttons = [dict(count=iii, label=f"{iii}m", step="month", stepmode="backward") for iii in rng]
if months > date.today().month:
buttons += [dict(count=1, label="YTD", step="year", stepmode="todate")]
buttons += [dict(step="all")]
for button in buttons:
yield button
def make_pyqt_buttons(self, modes: list) -> Generator[dict, None, None]:
"""
Creates list of buttons with one for each mode to be used in showing/hiding mode traces.
Args:
modes (list): list of modes used by main parser.
fig_len (int): number of traces in the figure
Returns:
Generator[dict, None, None]: list of buttons.
"""
fig_len = len(self.data)
if len(modes) > 1:
for ii, mode in enumerate(modes):
# NOTE: What I need to do is create a list of bools with the same length as the fig.data
mode_vis = [True] * fig_len
# NOTE: And break it into {len(modes)} chunks
mode_vis = list(divide_chunks(mode_vis, len(modes)))
# NOTE: Then, for each chunk, if the chunk index isn't equal to the index of the current mode, set to false
for jj, sublist in enumerate(mode_vis):
if jj != ii:
mode_vis[jj] = [not elem for elem in mode_vis[jj]]
# NOTE: Finally, flatten list.
mode_vis = [item for sublist in mode_vis for item in sublist]
# NOTE: Now, yield button to add to list
yield dict(label=mode, method="update", args=[
{"visible": mode_vis},
{"yaxis.title.text": mode},
])

View File

@@ -16,6 +16,7 @@ class PCRFigure(CustomFigure):
def __init__(self, df: pd.DataFrame, modes: list, settings: dict, ytitle: str | None = None, parent: QWidget | None = None, def __init__(self, df: pd.DataFrame, modes: list, settings: dict, ytitle: str | None = None, parent: QWidget | None = None,
months: int = 6): months: int = 6):
super().__init__(df=df, modes=modes, settings=settings) super().__init__(df=df, modes=modes, settings=settings)
self.df = df
try: try:
months = int(settings['months']) months = int(settings['months'])
except KeyError: except KeyError:

View File

@@ -1,18 +1,17 @@
""" """
Handles display of control charts Handles display of control charts
""" """
from datetime import date
from pprint import pformat from pprint import pformat
from PyQt6.QtWebEngineWidgets import QWebEngineView
from PyQt6.QtWidgets import ( from PyQt6.QtWidgets import (
QWidget, QComboBox, QPushButton, QGridLayout QWidget, QComboBox, QPushButton
) )
from PyQt6.QtCore import QSignalBlocker from PyQt6.QtCore import QSignalBlocker
from backend import ChartReportMaker
from backend.db import ControlType, IridaControl from backend.db import ControlType, IridaControl
import logging import logging
from tools import Report, report_result, Result from tools import Report, report_result
from frontend.visualizations import CustomFigure from frontend.visualizations import CustomFigure
from .misc import StartEndDatePicker
from .info_tab import InfoPane from .info_tab import InfoPane
logger = logging.getLogger(f"submissions.{__name__}") logger = logging.getLogger(f"submissions.{__name__}")
@@ -27,13 +26,8 @@ class ControlsViewer(InfoPane):
if not self.archetype: if not self.archetype:
return return
logger.debug(f"Archetype set as: {self.archetype}") logger.debug(f"Archetype set as: {self.archetype}")
# self.app = self.parent().parent()
# logger.debug(f"\n\n{self.app}\n\n") # logger.debug(f"\n\n{self.app}\n\n")
# self.report = Report()
# self.datepicker = StartEndDatePicker(default_start=-180)
# self.webengineview = QWebEngineView()
# NOTE: set tab2 layout # NOTE: set tab2 layout
# self.layout = QGridLayout(self)
self.control_sub_typer = QComboBox() self.control_sub_typer = QComboBox()
# NOTE: fetch types of controls # NOTE: fetch types of controls
con_sub_types = [item for item in self.archetype.targets.keys()] con_sub_types = [item for item in self.archetype.targets.keys()]
@@ -46,7 +40,6 @@ class ControlsViewer(InfoPane):
self.mode_sub_typer = QComboBox() self.mode_sub_typer = QComboBox()
self.mode_sub_typer.setEnabled(False) self.mode_sub_typer.setEnabled(False)
# NOTE: add widgets to tab2 layout # NOTE: add widgets to tab2 layout
# self.layout.addWidget(self.datepicker, 0, 0, 1, 2)
self.save_button = QPushButton("Save Chart", parent=self) self.save_button = QPushButton("Save Chart", parent=self)
self.layout.addWidget(self.save_button, 0, 2, 1, 1) self.layout.addWidget(self.save_button, 0, 2, 1, 1)
self.export_button = QPushButton("Save Data", parent=self) self.export_button = QPushButton("Save Data", parent=self)
@@ -55,21 +48,17 @@ class ControlsViewer(InfoPane):
self.layout.addWidget(self.mode_typer, 2, 0, 1, 4) self.layout.addWidget(self.mode_typer, 2, 0, 1, 4)
self.layout.addWidget(self.mode_sub_typer, 3, 0, 1, 4) self.layout.addWidget(self.mode_sub_typer, 3, 0, 1, 4)
self.archetype.get_instance_class().make_parent_buttons(parent=self) self.archetype.get_instance_class().make_parent_buttons(parent=self)
# self.layout.addWidget(self.webengineview, self.layout.rowCount(), 0, 1, 4)
# self.setLayout(self.layout)
self.update_data() self.update_data()
self.control_sub_typer.currentIndexChanged.connect(self.update_data) self.control_sub_typer.currentIndexChanged.connect(self.update_data)
self.mode_typer.currentIndexChanged.connect(self.update_data) self.mode_typer.currentIndexChanged.connect(self.update_data)
# self.datepicker.start_date.dateChanged.connect(self.update_data) self.save_button.pressed.connect(self.save_png)
# self.datepicker.end_date.dateChanged.connect(self.update_data) self.export_button.pressed.connect(self.save_excel)
self.save_button.pressed.connect(self.save_chart_function)
self.export_button.pressed.connect(self.save_data_function)
def save_chart_function(self): # def save_chart_function(self):
self.fig.save_figure(parent=self) # self.fig.save_figure(parent=self)
#
def save_data_function(self): # def save_data_function(self):
self.fig.save_data(parent=self) # self.fig.save_data(parent=self)
@report_result @report_result
def update_data(self, *args, **kwargs): def update_data(self, *args, **kwargs):
@@ -117,20 +106,6 @@ class ControlsViewer(InfoPane):
self.chart_maker_function() self.chart_maker_function()
# return report # return report
@classmethod
def diff_month(self, d1: date, d2: date) -> float:
"""
Gets the number of months difference between two different dates
Args:
d1 (date): Start date.
d2 (date): End date.
Returns:
float: Number of months difference
"""
return abs((d1.year - d2.year) * 12 + d1.month - d2.month)
@report_result @report_result
def chart_maker_function(self, *args, **kwargs): def chart_maker_function(self, *args, **kwargs):
# TODO: Generalize this by moving as much code as possible to IridaControl # TODO: Generalize this by moving as much code as possible to IridaControl
@@ -158,6 +133,7 @@ class ControlsViewer(InfoPane):
mode=self.mode, mode=self.mode,
sub_mode=self.mode_sub_type, parent=self, months=months) sub_mode=self.mode_sub_type, parent=self, months=months)
self.fig = self.archetype.get_instance_class().make_chart(chart_settings=chart_settings, parent=self, ctx=self.app.ctx) self.fig = self.archetype.get_instance_class().make_chart(chart_settings=chart_settings, parent=self, ctx=self.app.ctx)
self.report_obj = ChartReportMaker(df=self.fig.df, sheet_name=self.archetype.name)
if issubclass(self.fig.__class__, CustomFigure): if issubclass(self.fig.__class__, CustomFigure):
self.save_button.setEnabled(True) self.save_button.setEnabled(True)
# logger.debug(f"Updating figure...") # logger.debug(f"Updating figure...")

View File

@@ -1,6 +1,7 @@
""" """
A pane to show info e.g. cost reports and turnaround times. A pane to show info e.g. cost reports and turnaround times.
""" """
from datetime import date
from PyQt6.QtCore import QSignalBlocker from PyQt6.QtCore import QSignalBlocker
from PyQt6.QtWebEngineWidgets import QWebEngineView from PyQt6.QtWebEngineWidgets import QWebEngineView
from PyQt6.QtWidgets import QWidget, QGridLayout from PyQt6.QtWidgets import QWidget, QGridLayout
@@ -25,7 +26,8 @@ class InfoPane(QWidget):
self.datepicker.end_date.dateChanged.connect(self.update_data) self.datepicker.end_date.dateChanged.connect(self.update_data)
self.layout = QGridLayout(self) self.layout = QGridLayout(self)
self.layout.addWidget(self.datepicker, 0, 0, 1, 2) self.layout.addWidget(self.datepicker, 0, 0, 1, 2)
self.layout.addWidget(self.webview, 4, 0, 1, 4) # NOTE: Placed in lower row to allow for addition of custom rows.
self.layout.addWidget(self.webview, 5, 0, 1, 4)
self.setLayout(self.layout) self.setLayout(self.layout)
@report_result @report_result
@@ -45,6 +47,20 @@ class InfoPane(QWidget):
report.add_result(Result(owner=self.__str__(), msg=msg, status="Warning")) report.add_result(Result(owner=self.__str__(), msg=msg, status="Warning"))
return report return report
@classmethod
def diff_month(self, d1: date, d2: date) -> float:
"""
Gets the number of months difference between two different dates
Args:
d1 (date): Start date.
d2 (date): End date.
Returns:
float: Number of months difference
"""
return abs((d1.year - d2.year) * 12 + d1.month - d2.month)
def save_excel(self): 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") 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) self.report_obj.write_report(fname, obj=self)

View File

@@ -1,10 +1,10 @@
from PyQt6.QtCore import QSignalBlocker """
from PyQt6.QtWebEngineWidgets import QWebEngineView Pane showing turnaround time summary.
from PyQt6.QtWidgets import QWidget, QGridLayout, QPushButton, QLabel, QComboBox """
from PyQt6.QtWidgets import QWidget, QPushButton, QComboBox, QLabel
from .info_tab import InfoPane from .info_tab import InfoPane
from backend.excel.reports import TurnaroundMaker from backend.excel.reports import TurnaroundMaker
from pandas import DataFrame from backend.db import SubmissionType
from backend.db import BasicSubmission, SubmissionType
from frontend.visualizations.turnaround_chart import TurnaroundChart from frontend.visualizations.turnaround_chart import TurnaroundChart
import logging import logging
@@ -26,12 +26,14 @@ class TurnaroundTime(InfoPane):
self.submission_typer = QComboBox(self) self.submission_typer = QComboBox(self)
subs = ["All"] + [item.name for item in SubmissionType.query()] subs = ["All"] + [item.name for item in SubmissionType.query()]
self.submission_typer.addItems(subs) self.submission_typer.addItems(subs)
self.layout.addWidget(QLabel("Submission Type"), 1, 0, 1, 1)
self.layout.addWidget(self.submission_typer, 1, 1, 1, 3) self.layout.addWidget(self.submission_typer, 1, 1, 1, 3)
self.submission_typer.currentTextChanged.connect(self.update_data) self.submission_typer.currentTextChanged.connect(self.update_data)
self.update_data() self.update_data()
def update_data(self): def update_data(self):
super().update_data() super().update_data()
months = self.diff_month(self.start_date, self.end_date)
chart_settings = dict(start_date=self.start_date, end_date=self.end_date) chart_settings = dict(start_date=self.start_date, end_date=self.end_date)
if self.submission_typer.currentText() == "All": if self.submission_typer.currentText() == "All":
submission_type = None submission_type = None
@@ -44,5 +46,5 @@ class TurnaroundTime(InfoPane):
threshold = subtype_obj.defaults['turnaround_time'] + 0.5 threshold = subtype_obj.defaults['turnaround_time'] + 0.5
else: else:
threshold = None threshold = None
self.fig = TurnaroundChart(df=self.report_obj.df, settings=chart_settings, modes=[], threshold=threshold) self.fig = TurnaroundChart(df=self.report_obj.df, settings=chart_settings, modes=[], threshold=threshold, months=months)
self.webview.setHtml(self.fig.to_html()) self.webview.setHtml(self.fig.to_html())

View File

@@ -2,7 +2,6 @@
Contains miscellaenous functions used by both frontend and backend. Contains miscellaenous functions used by both frontend and backend.
''' '''
from __future__ import annotations from __future__ import annotations
from datetime import date, datetime, timedelta from datetime import date, datetime, timedelta
from json import JSONDecodeError from json import JSONDecodeError
from pprint import pprint from pprint import pprint
@@ -13,7 +12,6 @@ from jinja2 import Environment, FileSystemLoader
from logging import handlers from logging import handlers
from pathlib import Path from pathlib import Path
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from sqlalchemy.orm.state import InstanceState
from sqlalchemy import create_engine, text, MetaData from sqlalchemy import create_engine, text, MetaData
from pydantic import field_validator, BaseModel, Field from pydantic import field_validator, BaseModel, Field
from pydantic_settings import BaseSettings, SettingsConfigDict from pydantic_settings import BaseSettings, SettingsConfigDict
@@ -893,11 +891,21 @@ def yaml_regex_creator(loader, node):
return f"(?P<{name}>RSL(?:-|_)?{abbr}(?:-|_)?20\d{2}-?\d{2}-?\d{2}(?:(_|-)?\d?([^_0123456789\sA-QS-Z]|$)?R?\d?)?)" return f"(?P<{name}>RSL(?:-|_)?{abbr}(?:-|_)?20\d{2}-?\d{2}-?\d{2}(?:(_|-)?\d?([^_0123456789\sA-QS-Z]|$)?R?\d?)?)"
def super_splitter(input:str, ioi:str, idx:int) -> str: def super_splitter(ins_str:str, substring:str, idx:int) -> str:
"""
Args:
ins_str (str): input string
substring (str): substring to split on
idx (int): the occurrence of the substring to return
Returns:
"""
try: try:
return input.split(ioi)[idx] return ins_str.split(substring)[idx]
except IndexError: except IndexError:
return input return ins_str
ctx = get_config(None) ctx = get_config(None)
@@ -1021,7 +1029,3 @@ def create_holidays_for_year(year: int|None=None) -> List[date]:
holidays.append(easter(year) - timedelta(days=2)) holidays.append(easter(year) - timedelta(days=2))
holidays.append(easter(year) + timedelta(days=1)) holidays.append(easter(year) + timedelta(days=1))
return sorted(holidays) return sorted(holidays)