Returned to pdf exports from details.
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
## 202409.05
|
## 202409.05
|
||||||
|
|
||||||
|
- Replaced some lists with generators to improve speed, added javascript to templates for click events.
|
||||||
- Added in custom field for BasicSubmission which will allow limited new fields to be added to generic submission types.
|
- Added in custom field for BasicSubmission which will allow limited new fields to be added to generic submission types.
|
||||||
|
|
||||||
## 202409.04
|
## 202409.04
|
||||||
|
|||||||
@@ -1042,7 +1042,7 @@ class BasicSubmission(BaseClass):
|
|||||||
# return [item.to_sub_dict() for item in self.submission_sample_associations]
|
# return [item.to_sub_dict() for item in self.submission_sample_associations]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_details_template(cls, base_dict: dict) -> Tuple[dict, Template]:
|
def get_details_template(cls, base_dict: dict) -> Template:
|
||||||
"""
|
"""
|
||||||
Get the details jinja template for the correct class
|
Get the details jinja template for the correct class
|
||||||
|
|
||||||
@@ -1357,13 +1357,13 @@ class BasicSubmission(BaseClass):
|
|||||||
if fname.name == "":
|
if fname.name == "":
|
||||||
# logger.debug(f"export cancelled.")
|
# logger.debug(f"export cancelled.")
|
||||||
return
|
return
|
||||||
if full_backup:
|
# if full_backup:
|
||||||
backup = self.to_dict(full_data=True)
|
# backup = self.to_dict(full_data=True)
|
||||||
try:
|
# try:
|
||||||
with open(self.__backup_path__.joinpath(fname.with_suffix(".yml")), "w") as f:
|
# with open(self.__backup_path__.joinpath(fname.with_suffix(".yml")), "w") as f:
|
||||||
yaml.dump(backup, f)
|
# yaml.dump(backup, f)
|
||||||
except KeyError as e:
|
# except KeyError as e:
|
||||||
logger.error(f"Problem saving yml backup file: {e}")
|
# logger.error(f"Problem saving yml backup file: {e}")
|
||||||
writer = pyd.to_writer()
|
writer = pyd.to_writer()
|
||||||
writer.xl.save(filename=fname.with_suffix(".xlsx"))
|
writer.xl.save(filename=fname.with_suffix(".xlsx"))
|
||||||
|
|
||||||
@@ -1632,6 +1632,8 @@ class Wastewater(BasicSubmission):
|
|||||||
dict: Updated information
|
dict: Updated information
|
||||||
"""
|
"""
|
||||||
input_dict = super().finalize_details(input_dict)
|
input_dict = super().finalize_details(input_dict)
|
||||||
|
# NOTE: Currently this is preserving the generator items, can we come up with a better way?
|
||||||
|
input_dict['samples'] = [sample for sample in input_dict['samples']]
|
||||||
dummy_samples = []
|
dummy_samples = []
|
||||||
for item in input_dict['samples']:
|
for item in input_dict['samples']:
|
||||||
# logger.debug(f"Sample dict: {item}")
|
# logger.debug(f"Sample dict: {item}")
|
||||||
@@ -1681,12 +1683,10 @@ class Wastewater(BasicSubmission):
|
|||||||
for sample in self.samples:
|
for sample in self.samples:
|
||||||
# logger.debug(f"Running update on: {sample}")
|
# logger.debug(f"Running update on: {sample}")
|
||||||
try:
|
try:
|
||||||
# sample_dict = [item for item in parser.samples if item['sample'] == sample.rsl_number][0]
|
|
||||||
sample_dict = next(item for item in parser.samples if item['sample'] == sample.rsl_number)
|
sample_dict = next(item for item in parser.samples if item['sample'] == sample.rsl_number)
|
||||||
except StopIteration:
|
except StopIteration:
|
||||||
continue
|
continue
|
||||||
self.update_subsampassoc(sample=sample, input_dict=sample_dict)
|
self.update_subsampassoc(sample=sample, input_dict=sample_dict)
|
||||||
# self.report.add_result(Result(msg=f"We added PCR info to {sub.rsl_plate_num}.", status='Information'))
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def custom_docx_writer(cls, input_dict: dict, tpl_obj=None) -> dict:
|
def custom_docx_writer(cls, input_dict: dict, tpl_obj=None) -> dict:
|
||||||
@@ -1703,6 +1703,7 @@ class Wastewater(BasicSubmission):
|
|||||||
from backend.excel.writer import DocxWriter
|
from backend.excel.writer import DocxWriter
|
||||||
input_dict = super().custom_docx_writer(input_dict)
|
input_dict = super().custom_docx_writer(input_dict)
|
||||||
well_24 = []
|
well_24 = []
|
||||||
|
input_dict['samples'] = [item for item in input_dict['samples']]
|
||||||
samples_copy = deepcopy(input_dict['samples'])
|
samples_copy = deepcopy(input_dict['samples'])
|
||||||
for sample in sorted(samples_copy, key=itemgetter('column', 'row')):
|
for sample in sorted(samples_copy, key=itemgetter('column', 'row')):
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -519,6 +519,7 @@ class DocxWriter(object):
|
|||||||
Args:
|
Args:
|
||||||
base_dict (dict): dictionary of info to be written to template.
|
base_dict (dict): dictionary of info to be written to template.
|
||||||
"""
|
"""
|
||||||
|
logger.debug(f"Incoming base dict: {pformat(base_dict)}")
|
||||||
self.sub_obj = BasicSubmission.find_polymorphic_subclass(polymorphic_identity=base_dict['submission_type'])
|
self.sub_obj = BasicSubmission.find_polymorphic_subclass(polymorphic_identity=base_dict['submission_type'])
|
||||||
env = jinja_template_loading()
|
env = jinja_template_loading()
|
||||||
temp_name = f"{base_dict['submission_type'].replace(' ', '').lower()}_subdocument.docx"
|
temp_name = f"{base_dict['submission_type'].replace(' ', '').lower()}_subdocument.docx"
|
||||||
@@ -528,8 +529,8 @@ class DocxWriter(object):
|
|||||||
if subdocument.exists():
|
if subdocument.exists():
|
||||||
main_template = self.create_merged_template(main_template, subdocument)
|
main_template = self.create_merged_template(main_template, subdocument)
|
||||||
self.template = DocxTemplate(main_template)
|
self.template = DocxTemplate(main_template)
|
||||||
base_dict['platemap'] = self.create_plate_map(base_dict['samples'], rows=8, columns=12)
|
base_dict['platemap'] = [item for item in self.create_plate_map(base_dict['samples'], rows=8, columns=12)]
|
||||||
# logger.debug(pformat(base_dict['plate_map']))
|
# logger.debug(pformat(base_dict['platemap']))
|
||||||
try:
|
try:
|
||||||
base_dict['excluded'] += ["platemap"]
|
base_dict['excluded'] += ["platemap"]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
|||||||
@@ -739,11 +739,22 @@ class PydSubmission(BaseModel, extra='allow'):
|
|||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
# logger.debug("Extracting 'value' from attributes")
|
# logger.debug("Extracting 'value' from attributes")
|
||||||
output = {k: (getattr(self, k) if not isinstance(getattr(self, k), dict) else getattr(self, k)['value']) for
|
output = {k: self.filter_field(k) for k in fields}
|
||||||
k in fields}
|
|
||||||
|
|
||||||
return output
|
return output
|
||||||
|
|
||||||
|
def filter_field(self, key:str):
|
||||||
|
item = getattr(self, key)
|
||||||
|
# logger.debug(f"Attempting deconstruction of {key}: {item} with type {type(item)}")
|
||||||
|
match item:
|
||||||
|
case dict():
|
||||||
|
try:
|
||||||
|
item = item['value']
|
||||||
|
except KeyError:
|
||||||
|
logger.error(f"Couldn't get dict value: {item}")
|
||||||
|
case _:
|
||||||
|
pass
|
||||||
|
return item
|
||||||
|
|
||||||
def find_missing(self) -> Tuple[dict, dict]:
|
def find_missing(self) -> Tuple[dict, dict]:
|
||||||
"""
|
"""
|
||||||
Retrieves info and reagents marked as missing.
|
Retrieves info and reagents marked as missing.
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
"""
|
"""
|
||||||
Webview to show submission and sample details.
|
Webview to show submission and sample details.
|
||||||
"""
|
"""
|
||||||
from PyQt6.QtGui import QColor
|
from PyQt6.QtGui import QColor, QPageSize, QPageLayout
|
||||||
|
from PyQt6.QtPrintSupport import QPrinter
|
||||||
from PyQt6.QtWidgets import (QDialog, QPushButton, QVBoxLayout,
|
from PyQt6.QtWidgets import (QDialog, QPushButton, QVBoxLayout,
|
||||||
QDialogButtonBox, QTextEdit, QGridLayout)
|
QDialogButtonBox, QTextEdit, QGridLayout)
|
||||||
from PyQt6.QtWebEngineWidgets import QWebEngineView
|
from PyQt6.QtWebEngineWidgets import QWebEngineView
|
||||||
from PyQt6.QtWebChannel import QWebChannel
|
from PyQt6.QtWebChannel import QWebChannel
|
||||||
from PyQt6.QtCore import Qt, pyqtSlot
|
from PyQt6.QtCore import Qt, pyqtSlot, QMarginsF
|
||||||
from jinja2 import TemplateNotFound
|
from jinja2 import TemplateNotFound
|
||||||
|
|
||||||
from backend.db.models import BasicSubmission, BasicSample, Reagent, KitType
|
from backend.db.models import BasicSubmission, BasicSample, Reagent, KitType
|
||||||
@@ -43,7 +44,7 @@ class SubmissionDetails(QDialog):
|
|||||||
self.layout = QGridLayout()
|
self.layout = QGridLayout()
|
||||||
# self.setFixedSize(900, 500)
|
# self.setFixedSize(900, 500)
|
||||||
# NOTE: button to export a pdf version
|
# NOTE: button to export a pdf version
|
||||||
self.btn = QPushButton("Export DOCX")
|
self.btn = QPushButton("Export PDF")
|
||||||
self.btn.setFixedWidth(775)
|
self.btn.setFixedWidth(775)
|
||||||
self.btn.clicked.connect(self.export)
|
self.btn.clicked.connect(self.export)
|
||||||
self.back = QPushButton("Back")
|
self.back = QPushButton("Back")
|
||||||
@@ -151,7 +152,8 @@ class SubmissionDetails(QDialog):
|
|||||||
self.base_dict = submission.finalize_details(self.base_dict)
|
self.base_dict = submission.finalize_details(self.base_dict)
|
||||||
# logger.debug(f"Creating barcode.")
|
# logger.debug(f"Creating barcode.")
|
||||||
# logger.debug(f"Making platemap...")
|
# logger.debug(f"Making platemap...")
|
||||||
self.base_dict['platemap'] = BasicSubmission.make_plate_map(sample_list=submission.hitpick_plate())
|
self.base_dict['platemap'] = submission.make_plate_map(sample_list=submission.hitpick_plate())
|
||||||
|
self.base_dict['excluded'] = submission.get_default_info("details_ignore")
|
||||||
self.base_dict, self.template = submission.get_details_template(base_dict=self.base_dict)
|
self.base_dict, self.template = submission.get_details_template(base_dict=self.base_dict)
|
||||||
template_path = Path(self.template.environment.loader.__getattribute__("searchpath")[0])
|
template_path = Path(self.template.environment.loader.__getattribute__("searchpath")[0])
|
||||||
with open(template_path.joinpath("css", "styles.css"), "r") as f:
|
with open(template_path.joinpath("css", "styles.css"), "r") as f:
|
||||||
@@ -159,11 +161,10 @@ class SubmissionDetails(QDialog):
|
|||||||
# logger.debug(f"Submission_details: {pformat(self.base_dict)}")
|
# logger.debug(f"Submission_details: {pformat(self.base_dict)}")
|
||||||
# logger.debug(f"User is power user: {is_power_user()}")
|
# logger.debug(f"User is power user: {is_power_user()}")
|
||||||
self.html = self.template.render(sub=self.base_dict, signing_permission=is_power_user(), css=css)
|
self.html = self.template.render(sub=self.base_dict, signing_permission=is_power_user(), css=css)
|
||||||
with open("test.html", "w") as f:
|
# with open("test.html", "w") as f:
|
||||||
f.write(self.html)
|
# f.write(self.html)
|
||||||
self.webview.setHtml(self.html)
|
self.webview.setHtml(self.html)
|
||||||
|
|
||||||
|
|
||||||
@pyqtSlot(str)
|
@pyqtSlot(str)
|
||||||
def sign_off(self, submission: str | BasicSubmission):
|
def sign_off(self, submission: str | BasicSubmission):
|
||||||
# logger.debug(f"Signing off on {submission} - ({getuser()})")
|
# logger.debug(f"Signing off on {submission} - ({getuser()})")
|
||||||
@@ -177,18 +178,12 @@ class SubmissionDetails(QDialog):
|
|||||||
"""
|
"""
|
||||||
Renders submission to html, then creates and saves .pdf file to user selected file.
|
Renders submission to html, then creates and saves .pdf file to user selected file.
|
||||||
"""
|
"""
|
||||||
export_plate = BasicSubmission.query(rsl_plate_num=self.export_plate)
|
fname = select_save_file(obj=self, default_name=self.export_plate, extension="pdf")
|
||||||
base_dict = export_plate.to_dict(full_data=True)
|
page_layout = QPageLayout()
|
||||||
base_dict['excluded'] = export_plate.get_default_info('details_ignore')
|
page_layout.setPageSize(QPageSize(QPageSize.PageSizeId.A4))
|
||||||
logger.debug(f"base dict: {pformat(base_dict)}")
|
page_layout.setOrientation(QPageLayout.Orientation.Portrait)
|
||||||
writer = DocxWriter(base_dict=base_dict)
|
page_layout.setMargins(QMarginsF(25, 25, 25, 25))
|
||||||
fname = select_save_file(obj=self, default_name=base_dict['plate_number'], extension="docx")
|
self.webview.page().printToPdf(fname.with_suffix(".pdf").__str__(), page_layout)
|
||||||
writer.save(fname)
|
|
||||||
# try:
|
|
||||||
# html_to_pdf(html=self.html, output_file=fname)
|
|
||||||
# except PermissionError as e:
|
|
||||||
# logger.error(f"Error saving pdf: {e}")
|
|
||||||
|
|
||||||
|
|
||||||
class SubmissionComment(QDialog):
|
class SubmissionComment(QDialog):
|
||||||
"""
|
"""
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user