Better xlsx reports
This commit is contained in:
BIN
requirements.txt
BIN
requirements.txt
Binary file not shown.
@@ -1,4 +1,4 @@
|
|||||||
# __init__.py
|
# __init__.py
|
||||||
|
|
||||||
# Version of the realpython-reader package
|
# Version of the realpython-reader package
|
||||||
__version__ = "1.1.2"
|
__version__ = "1.2.1"
|
||||||
|
|||||||
@@ -2,16 +2,14 @@ from . import models
|
|||||||
import pandas as pd
|
import pandas as pd
|
||||||
import sqlalchemy.exc
|
import sqlalchemy.exc
|
||||||
import sqlite3
|
import sqlite3
|
||||||
# from sqlalchemy.exc import IntegrityError, OperationalError
|
|
||||||
# from sqlite3 import IntegrityError, OperationalError
|
|
||||||
import logging
|
import logging
|
||||||
from datetime import date, datetime, timedelta
|
from datetime import date, datetime, timedelta
|
||||||
from sqlalchemy import and_
|
from sqlalchemy import and_
|
||||||
import uuid
|
import uuid
|
||||||
import base64
|
# import base64
|
||||||
from sqlalchemy import JSON
|
from sqlalchemy import JSON
|
||||||
import json
|
import json
|
||||||
from dateutil.relativedelta import relativedelta
|
# from dateutil.relativedelta import relativedelta
|
||||||
from getpass import getuser
|
from getpass import getuser
|
||||||
|
|
||||||
logger = logging.getLogger(f"submissions.{__name__}")
|
logger = logging.getLogger(f"submissions.{__name__}")
|
||||||
@@ -94,11 +92,14 @@ def construct_submission_info(ctx:dict, info_dict:dict) -> models.BasicSubmissio
|
|||||||
instance = ctx['database_session'].query(models.BasicSubmission).filter(models.BasicSubmission.rsl_plate_num==info_dict['rsl_plate_num']).first()
|
instance = ctx['database_session'].query(models.BasicSubmission).filter(models.BasicSubmission.rsl_plate_num==info_dict['rsl_plate_num']).first()
|
||||||
msg = "This submission already exists.\nWould you like to overwrite?"
|
msg = "This submission already exists.\nWould you like to overwrite?"
|
||||||
# get model based on submission type converted above
|
# get model based on submission type converted above
|
||||||
|
logger.debug(f"Looking at models for submission type: {query}")
|
||||||
model = getattr(models, query)
|
model = getattr(models, query)
|
||||||
|
logger.debug(f"We've got the model: {type(model)}")
|
||||||
info_dict['submission_type'] = info_dict['submission_type'].replace(" ", "_").lower()
|
info_dict['submission_type'] = info_dict['submission_type'].replace(" ", "_").lower()
|
||||||
# if query return nothing, ie doesn't already exist in db
|
# if query return nothing, ie doesn't already exist in db
|
||||||
if instance == None:
|
if instance == None:
|
||||||
instance = model()
|
instance = model()
|
||||||
|
logger.debug(f"Submission doesn't exist yet, creating new instance: {instance}")
|
||||||
msg = None
|
msg = None
|
||||||
for item in info_dict:
|
for item in info_dict:
|
||||||
logger.debug(f"Setting {item} to {info_dict[item]}")
|
logger.debug(f"Setting {item} to {info_dict[item]}")
|
||||||
@@ -133,11 +134,11 @@ def construct_submission_info(ctx:dict, info_dict:dict) -> models.BasicSubmissio
|
|||||||
logger.debug(f"Could not set attribute: {item} to {info_dict[item]}")
|
logger.debug(f"Could not set attribute: {item} to {info_dict[item]}")
|
||||||
continue
|
continue
|
||||||
# calculate cost of the run: immutable cost + mutable times number of columns
|
# calculate cost of the run: immutable cost + mutable times number of columns
|
||||||
try:
|
try:
|
||||||
instance.run_cost = instance.extraction_kit.immutable_cost + (instance.extraction_kit.mutable_cost * ((instance.sample_count / 8)/12))
|
instance.run_cost = instance.extraction_kit.immutable_cost + (instance.extraction_kit.mutable_cost * ((instance.sample_count / 8)/12))
|
||||||
except TypeError:
|
except (TypeError, AttributeError):
|
||||||
logger.debug(f"Looks like that kit doesn't have cost breakdown yet, using full plate cost.")
|
logger.debug(f"Looks like that kit doesn't have cost breakdown yet, using full plate cost.")
|
||||||
instance.run_cost = instance.extraction_kit.cost_per_run
|
instance.run_cost = instance.extraction_kit.cost_per_run
|
||||||
logger.debug(f"Constructed instance: {instance.to_string()}")
|
logger.debug(f"Constructed instance: {instance.to_string()}")
|
||||||
logger.debug(msg)
|
logger.debug(msg)
|
||||||
return instance, {'message':msg}
|
return instance, {'message':msg}
|
||||||
|
|||||||
@@ -15,9 +15,12 @@ from PyQt6.QtWebEngineWidgets import QWebEngineView
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import plotly
|
import plotly
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
|
from openpyxl.utils import get_column_letter
|
||||||
|
from openpyxl.styles import NamedStyle
|
||||||
from xhtml2pdf import pisa
|
from xhtml2pdf import pisa
|
||||||
# import plotly.express as px
|
# import plotly.express as px
|
||||||
import yaml
|
import yaml
|
||||||
|
import pprint
|
||||||
|
|
||||||
from backend.excel.parser import SheetParser
|
from backend.excel.parser import SheetParser
|
||||||
from backend.excel.reports import convert_control_by_mode, convert_data_list_to_df
|
from backend.excel.reports import convert_control_by_mode, convert_data_list_to_df
|
||||||
@@ -35,7 +38,7 @@ import difflib
|
|||||||
from datetime import date
|
from datetime import date
|
||||||
from frontend.visualizations.charts import create_charts
|
from frontend.visualizations.charts import create_charts
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(f'submissions.{__name__}')
|
||||||
logger.info("Hello, I am a logger")
|
logger.info("Hello, I am a logger")
|
||||||
|
|
||||||
class App(QMainWindow):
|
class App(QMainWindow):
|
||||||
@@ -64,6 +67,7 @@ class App(QMainWindow):
|
|||||||
self._connectActions()
|
self._connectActions()
|
||||||
self.controls_getter()
|
self.controls_getter()
|
||||||
self.show()
|
self.show()
|
||||||
|
|
||||||
|
|
||||||
def _createMenuBar(self):
|
def _createMenuBar(self):
|
||||||
"""
|
"""
|
||||||
@@ -261,10 +265,11 @@ class App(QMainWindow):
|
|||||||
logger.debug("Will not add reagent.")
|
logger.debug("Will not add reagent.")
|
||||||
if wanted_reagent != None:
|
if wanted_reagent != None:
|
||||||
parsed_reagents.append(wanted_reagent)
|
parsed_reagents.append(wanted_reagent)
|
||||||
logger.debug(info)
|
# logger.debug(info)
|
||||||
# move samples into preliminary submission dict
|
# move samples into preliminary submission dict
|
||||||
info['samples'] = self.samples
|
info['samples'] = self.samples
|
||||||
# construct submission object
|
# construct submission object
|
||||||
|
logger.debug(f"Here is the info_dict: {pprint.pformat(info)}")
|
||||||
base_submission, output = construct_submission_info(ctx=self.ctx, info_dict=info)
|
base_submission, output = construct_submission_info(ctx=self.ctx, info_dict=info)
|
||||||
# check output message for issues
|
# check output message for issues
|
||||||
if output['message'] != None:
|
if output['message'] != None:
|
||||||
@@ -376,7 +381,31 @@ class App(QMainWindow):
|
|||||||
# df.to_excel(fname, engine='openpyxl')
|
# df.to_excel(fname, engine='openpyxl')
|
||||||
with open(fname, "w+b") as f:
|
with open(fname, "w+b") as f:
|
||||||
pisa.CreatePDF(html, dest=f)
|
pisa.CreatePDF(html, dest=f)
|
||||||
df.to_excel(fname.with_suffix(".xlsx"), engine='openpyxl')
|
writer = pd.ExcelWriter(fname.with_suffix(".xlsx"), engine='openpyxl')
|
||||||
|
df.to_excel(writer, sheet_name="Report")
|
||||||
|
worksheet = writer.sheets['Report']
|
||||||
|
for idx, col in enumerate(df): # loop through all columns
|
||||||
|
series = df[col]
|
||||||
|
max_len = max((
|
||||||
|
series.astype(str).map(len).max(), # len of largest item
|
||||||
|
len(str(series.name)) # len of column name/header
|
||||||
|
)) + 20 # adding a little extra space
|
||||||
|
try:
|
||||||
|
worksheet.column_dimensions[get_column_letter(idx)].width = max_len
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
# set_column(idx, idx, max_len) # set column width
|
||||||
|
# colu = worksheet.column_dimensions["C"]
|
||||||
|
# style = NamedStyle(name="custom_currency", number_format='Currency')
|
||||||
|
for cell in worksheet['C']:
|
||||||
|
# try:
|
||||||
|
# check = int(cell.row)
|
||||||
|
# except TypeError:
|
||||||
|
# continue
|
||||||
|
if cell.row > 3:
|
||||||
|
cell.style = 'Currency'
|
||||||
|
writer.close()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{# template for constructing submission details #}
|
{# template for constructing submission details #}
|
||||||
|
|
||||||
{% for key, value in sub.items() if key != 'reagents' and key != 'samples' %}
|
{% for key, value in sub.items() if key != 'reagents' and key != 'samples' %}
|
||||||
{{ key }}: {{ value }}
|
{% if key=='Cost' %} {{ key }}: {{ "${:,.2f}".format(value) }} {% else %} {{ key }}: {{ value }} {% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
Reagents:
|
Reagents:
|
||||||
{% for item in sub['reagents'] %}
|
{% for item in sub['reagents'] %}
|
||||||
|
|||||||
Reference in New Issue
Block a user