mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Improvements for default StockItem test report template
- Fix bug in template - Handle potential errors in template tags - Add more helpers to report tags - Improve test result rendering
This commit is contained in:
parent
76589a2fd8
commit
c4bdacbd97
@ -2083,6 +2083,16 @@ class Part(InvenTreeBarcodeMixin, MetadataMixin, MPTTModel):
|
||||
|
||||
return tests
|
||||
|
||||
def getTestTemplateMap(self, **kwargs):
|
||||
"""Return a map of all test templates associated with this Part"""
|
||||
|
||||
templates = {}
|
||||
|
||||
for template in self.getTestTemplates(**kwargs):
|
||||
templates[template.key] = template
|
||||
|
||||
return templates
|
||||
|
||||
def getRequiredTests(self):
|
||||
"""Return the tests which are required by this part"""
|
||||
return self.getTestTemplates(required=True)
|
||||
|
@ -307,6 +307,30 @@ class TestReport(ReportTemplateBase):
|
||||
|
||||
return items.exists()
|
||||
|
||||
def get_test_keys(self, stock_item):
|
||||
"""Construct a flattened list of test 'keys' for this StockItem:
|
||||
|
||||
- First, any 'required' tests
|
||||
- Second, any 'non required' tests
|
||||
- Finally, any test results which do not match a test
|
||||
"""
|
||||
|
||||
keys = []
|
||||
|
||||
for test in stock_item.part.getTestTemplates(required=True):
|
||||
if test.key not in keys:
|
||||
keys.append(test.key)
|
||||
|
||||
for test in stock_item.part.getTestTemplates(required=False):
|
||||
if test.key not in keys:
|
||||
keys.append(test.key)
|
||||
|
||||
for result in stock_item.testResultList(include_installed=self.include_installed):
|
||||
if result.key not in keys:
|
||||
keys.append(result.key)
|
||||
|
||||
return list(keys)
|
||||
|
||||
def get_context_data(self, request):
|
||||
"""Return custom context data for the TestReport template"""
|
||||
stock_item = self.object_to_print
|
||||
@ -316,6 +340,9 @@ class TestReport(ReportTemplateBase):
|
||||
'serial': stock_item.serial,
|
||||
'part': stock_item.part,
|
||||
'parameters': stock_item.part.parameters_map(),
|
||||
'test_keys': self.get_test_keys(stock_item),
|
||||
'test_template_list': stock_item.part.getTestTemplates(),
|
||||
'test_template_map': stock_item.part.getTestTemplateMap(),
|
||||
'results': stock_item.testResultMap(include_installed=self.include_installed),
|
||||
'result_list': stock_item.testResultList(include_installed=self.include_installed),
|
||||
'installed_items': stock_item.get_installed_items(cascade=True),
|
||||
|
@ -33,6 +33,15 @@ content: "{% trans 'Stock Item Test Report' %}";
|
||||
color: #F55;
|
||||
}
|
||||
|
||||
.test-not-found {
|
||||
color: #33A;
|
||||
}
|
||||
|
||||
.required-test-not-found {
|
||||
color: #EEE;
|
||||
background-color: #F55;
|
||||
}
|
||||
|
||||
.container {
|
||||
padding: 5px;
|
||||
border: 1px solid;
|
||||
@ -84,7 +93,7 @@ content: "{% trans 'Stock Item Test Report' %}";
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if resul_list|length > 0 %}
|
||||
{% if test_keys|length > 0 %}
|
||||
<h3>{% trans "Test Results" %}</h3>
|
||||
|
||||
<table class='table test-table'>
|
||||
@ -101,22 +110,44 @@ content: "{% trans 'Stock Item Test Report' %}";
|
||||
<tr>
|
||||
<td colspan='5'><hr></td>
|
||||
</tr>
|
||||
{% for test in result_list %}
|
||||
{% for key in test_keys %}
|
||||
<!-- test key = {{ key }} -->
|
||||
{% getkey test_template_map key as test_template %}
|
||||
{% getkey results key as test_result %}
|
||||
<tr class='test-row'>
|
||||
<td>{{ test.test }}</td>
|
||||
{% if test.result %}
|
||||
<td>
|
||||
{% if test_template %}
|
||||
{% render_html_text test_template.test_name bold=test_template.required %}
|
||||
{% elif test_result %}
|
||||
{% render_html_text test_result.test italic=True %}
|
||||
{% else %}
|
||||
<!-- No matching test template or result for {{ key }} -->
|
||||
<span style='color: red;'>{{ key }}</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
{% if test_result %}
|
||||
{% if test_result.result %}
|
||||
<td class='test-pass'>{% trans "Pass" %}</td>
|
||||
{% else %}
|
||||
<td class='test-fail'>{% trans "Fail" %}</td>
|
||||
{% endif %}
|
||||
<td>{{ test.value }}</td>
|
||||
<td>{{ test.user.username }}</td>
|
||||
<td>{{ test.date.date.isoformat }}</td>
|
||||
<td>{{ test_result.value }}</td>
|
||||
<td>{{ test_result.user.username }}</td>
|
||||
<td>{{ test_result.date.date.isoformat }}</td>
|
||||
{% else %}
|
||||
{% if test_template.required %}
|
||||
<td colspan='4' class='required-test-not-found'>{% trans "No result (required)" %}</td>
|
||||
{% else %}
|
||||
<td colspan='4' class='test-not-found'>{% trans "No result" %}</td>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
{% else %}
|
||||
<em>No tests defined for this stock item</em>
|
||||
{% endif %}
|
||||
|
||||
{% if installed_items|length > 0 %}
|
||||
|
@ -19,17 +19,52 @@ logger = logging.getLogger('inventree')
|
||||
|
||||
|
||||
@register.simple_tag()
|
||||
def getkey(value: dict, arg):
|
||||
def getindex(container: list, index: int):
|
||||
"""Return the value contained at the specified index of the list.
|
||||
|
||||
This function is provideed to get around template rendering limitations.
|
||||
|
||||
Arguments:
|
||||
container: A python list object
|
||||
index: The index to retrieve from the list
|
||||
"""
|
||||
|
||||
# Index *must* be an integer
|
||||
try:
|
||||
index = int(index)
|
||||
except ValueError:
|
||||
return None
|
||||
|
||||
if index < 0 or index >= len(container):
|
||||
return None
|
||||
|
||||
try:
|
||||
value = container[index]
|
||||
except IndexError:
|
||||
value = None
|
||||
|
||||
return value
|
||||
|
||||
|
||||
@register.simple_tag()
|
||||
def getkey(container: dict, key):
|
||||
"""Perform key lookup in the provided dict object.
|
||||
|
||||
This function is provided to get around template rendering limitations.
|
||||
Ref: https://stackoverflow.com/questions/1906129/dict-keys-with-spaces-in-django-templates
|
||||
|
||||
Arguments:
|
||||
value: A python dict object
|
||||
arg: The 'key' to be found within the dict
|
||||
container: A python dict object
|
||||
key: The 'key' to be found within the dict
|
||||
"""
|
||||
return value[arg]
|
||||
if type(container) is not dict:
|
||||
logger.warning("getkey() called with non-dict object")
|
||||
return None
|
||||
|
||||
if key in container:
|
||||
return container[key]
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
@register.simple_tag()
|
||||
@ -215,3 +250,31 @@ def render_currency(money, **kwargs):
|
||||
"""Render a currency / Money object"""
|
||||
|
||||
return InvenTree.helpers.render_currency(money, **kwargs)
|
||||
|
||||
|
||||
@register.simple_tag
|
||||
def render_html_text(text: str, **kwargs):
|
||||
"""Render a text item with some simple html tags.
|
||||
|
||||
kwargs:
|
||||
bold: Boolean, whether bold (or not)
|
||||
italic: Boolean, whether italic (or not)
|
||||
heading: str, heading level e.g. 'h3'
|
||||
"""
|
||||
|
||||
tags = []
|
||||
|
||||
if kwargs.get('bold', False):
|
||||
tags.append('strong')
|
||||
|
||||
if kwargs.get('italic', False):
|
||||
tags.append('em')
|
||||
|
||||
if heading := kwargs.get('heading', ''):
|
||||
tags.append(heading)
|
||||
|
||||
output = ''.join([f'<{tag}>' for tag in tags])
|
||||
output += text
|
||||
output += ''.join([f'</{tag}>' for tag in tags])
|
||||
|
||||
return mark_safe(output)
|
||||
|
Loading…
Reference in New Issue
Block a user