This article will guide you through understanding internal reports in QBench, including how to enable, configure, and run them using the code editor.
QBench offers two primary types of reports:
- Laboratory Results Reports – Typically known as a Certificate of Analysis (CoA), these reports provide customers (internal or external) with the results of a specific sample.
- Internal Reports – Designed for internal use, these reports help management analyze laboratory performance and operational data within the LIMS.
This guide focuses on the second type: Internal Reports.
Internal reports are created similarly to other template-generated items in QBench but offer additional features. They are optimized for easy printing and are not automatically generated as PDFs, giving users greater flexibility in how they view and share report content.
Enable Internal Reports
To create, use, or edit internal reports in QBench, you must first enable the feature. Navigate to Configuration > Application > General and check the box labeled "Enable Internal Reports."
Please note that internal reports must be configured before they appear in the user interface. (Good news—pre-built internal reports will be available out-of-the-box soon!)
How to Run Internal Reports
To run an internal report, first ensure that internal reports are enabled and that at least one active report is configured on your site.
Then, navigate to Analytics > Internal Reports and select the report you want to run.
The screenshot below demonstrates how to run a report titled "My Internal Report."
How to Configure an Internal Report
This guide will walk you through setting up a basic Internal Report to display metrics for a selected time period. The time period and other filter criteria are built into the Internal Report interface for easy customization.
Step 1: Create a New Internal Report
- Go to Configuration > Application > Templates > Internal Reports.
- Click Create New Internal Report to start building your report.
Step 2: Configure Filter Fields
- Open the Filter Config tab.
- Add a new filter for the Order entity using the Date Received field.
- This filter will allow users to select a date range for retrieving relevant data in the report.
Understanding Filter Fields
- Filter Fields help refine and control the data displayed in your report by applying specific criteria.
- You can add filter fields for any QBench entity, including Orders, Samples, Tests, and more.
- Filters can be applied to any date field, providing flexible and precise data control.
- Before running the report, users will choose a date range, and only entities with filter values within that range will appear in the results.
Step 3: Design the Report
- Navigate to the Design tab.
- Open the Code Editor and paste the provided code to customize the report layout and functionality.
<link href="//dpe4x5tiyshba.cloudfront.net/qbenchassets/qbc/assets/css/bootstrap-qbench-12pt.min.css" rel="stylesheet" type="text/css" />
<style>
table {
width: 100%;
font-size: 10pt;
}
table th:first-child, table td:first-child {
text-align: left;
}
th, td {
padding: 5px;
text-align: center;
}
thead {
border-bottom: 1px solid black;
}
.first {
text-align: left !important;
}
.title {
font-size: 14pt;
text-align: center;
font-weight: bold;
padding-top: 15px;
}
.total-row {
border-top: 1px solid #ccc;
}
</style>
{% set orders = QBOrderService().get_list(params.get('order')) %}
<button id="generateCSV">Generate CSV</button>
<i class="fa fa-spinner fa-spin fa-3x" style="display:hide;"></i>
<div class="title">My Internal Report</div>
{# Create table to display report data #}
<table id="data-table">
<thead>
<tr>
<th>Order ID</th>
<th>Date Received</th>
<th>Tests</th>
<th>Samples</th>
</tr>
</thead>
<tbody>
{# Track total number of Tests and Samples #}
{% set total_tests = [] %}
{% set total_samples = [] %}
{# Loop over filtered Orders #}
{% for order in orders %}
{% set samples = order.samples %}
{% set tests = [] %}
{% for sample in samples %}
{% for test in sample.tests %}
{% set _ = tests.append(test) %}
{% endfor %}
{% endfor %}
{# Display Order infomation in the table #}
<tr>
<td>{{order.id}}</td>
<td>{{order.date_received|local_time("%m/%d/%Y") if order.date_received else ''}}</td>
<td>{{tests|length}}</td>
<td>{{samples|length}}</td>
</tr>
{% set _ = total_tests.append(tests|length) %}
{% set _ = total_samples.append(samples|length) %}
{% endfor %}
{# Display Totals #}
<tr class="total-row">
<td colspan="2"><b>Total</b></td>
<td>{{total_tests|sum}}</td>
<td>{{total_samples|sum}}</td>
</tr>
</tbody>
</table>
By following these steps, your Internal Report will be fully configured to generate accurate and filtered data based on user-selected criteria. The end result will look something like:
Important Notes About the Template Code
- QBOrderService Class:
This is one of many built-in classes available for creating Internal Reports. It provides two key functions for data retrieval:- get() – Retrieves a single record.
- get_list() – Retrieves a list of records.
These functions are essential for pulling data into your report.
- params Variable:
Every Internal Report Template includes a params variable, which stores the filter selections made by the user when generating the report. This allows dynamic filtering of the data based on user input.
Generating the Report
- Save and Activate:
- Save your changes as a new version and set this version as Active.
- Run the Report:
- Navigate to Analytics > Internal Reports > Samples Report.
- You’ll be prompted to select a date range for when orders were created.
- Generate Results:
- After selecting the date range, click Submit.
- Your Internal Report will begin generating and display the results based on the selected filters.
This streamlined process ensures your report is configured correctly and ready to deliver insightful data.
QB Service Classes
QBench offers built-in Jinja service classes that simplify data retrieval from the database. Each service provides two core methods for accessing records:
- .get() – Retrieves a single record based on a specific ID or condition.
- .get_list() – Retrieves multiple records that match defined parameters.
See all the provided Jinja service classes below:
- QBOrderService
- QBSampleService
- QBTestService
- QBInvoiceService
- QBBatchService
- QBInventoryItemService
- QBInventoryStockService
- QBEquipmentService
- QBLogTypeService
- QBLogEntryService
Referencing Elements with jQuery in Internal Reports
Internal Reports run inside an iFrame, which requires a different approach when using jQuery to access page elements. While jQuery is supported, the standard syntax below will not work in this context:
<span id="hw-span">Hello World</span>
<script>
setTimeout(() => {
$("#hw-span").text("Yehllo world"); },
3000);
</script>
This is because jQuery requires the correct context to interact with elements inside an iFrame. To achieve this, you need to create a custom jFrame variable that functions like a standard jQuery selector. Here's an example:
<span id="hw-span">Hello World</span>
<script>
const jFrame = selector => {
return $(selector, $("iframe").contents()); // Ensure "iframe" is the correct selector string. It may different in your use case.
};
setTimeout(() => {
jFrame("#hw-span").text("Yehllo world"); },
3000);
</script>
Exporting Internal Reports to CSV
A common use case for internal reports is exporting the generated HTML data into a CSV file for easy sharing and analysis within the lab.
The example below demonstrates how to convert an HTML table into a CSV file and automatically download it to your device.
First, add the button to your report template code:
<button id="generateCSV">Generate CSV</button>
<i class="fa fa-spinner fa-spin fa-3x" style="display:hide;"></i>
Finally, add the following script:
<script>
const iFrameDoc = document.getElementById($('iframe').attr('id')).contentWindow.document;
const generateCSVBtn = iFrameDoc.getElementById('generateCSV');
generateCSVBtn.addEventListener('click', async () => {
$(generateCSVBtn).button('loading');
// Create CSV
var csv = []
var rows = iFrameDoc.querySelectorAll('table#data-table tr');
for (let row of rows) {
csv_row = []
for (let td of row.children) {
csv_row.push(td.outerText.replaceAll(',', ''))
}
csv.push(csv_row.join(','))
}
var csv_string = csv.join('\n')
// Download it
let filename = `my_internal_report_${new Date().toLocaleDateString()}.csv`;
let link = document.createElement('a');
link.style.display = 'none';
link.setAttribute('target', '_blank');
link.setAttribute('href', 'data:text/csv;charset=utf-8,' + encodeURIComponent(csv_string));
link.setAttribute('download', filename);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
$(generateCSVBtn).button('reset');
});
</script>
Comments
0 comments
Article is closed for comments.