2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-06-16 20:15:44 +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:
Oliver Walters
2023-03-16 00:21:49 +11:00
parent 76589a2fd8
commit c4bdacbd97
4 changed files with 142 additions and 11 deletions

View File

@ -2083,6 +2083,16 @@ class Part(InvenTreeBarcodeMixin, MetadataMixin, MPTTModel):
return tests 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): def getRequiredTests(self):
"""Return the tests which are required by this part""" """Return the tests which are required by this part"""
return self.getTestTemplates(required=True) return self.getTestTemplates(required=True)

View File

@ -307,6 +307,30 @@ class TestReport(ReportTemplateBase):
return items.exists() 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): def get_context_data(self, request):
"""Return custom context data for the TestReport template""" """Return custom context data for the TestReport template"""
stock_item = self.object_to_print stock_item = self.object_to_print
@ -316,6 +340,9 @@ class TestReport(ReportTemplateBase):
'serial': stock_item.serial, 'serial': stock_item.serial,
'part': stock_item.part, 'part': stock_item.part,
'parameters': stock_item.part.parameters_map(), '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), 'results': stock_item.testResultMap(include_installed=self.include_installed),
'result_list': stock_item.testResultList(include_installed=self.include_installed), 'result_list': stock_item.testResultList(include_installed=self.include_installed),
'installed_items': stock_item.get_installed_items(cascade=True), 'installed_items': stock_item.get_installed_items(cascade=True),

View File

@ -33,6 +33,15 @@ content: "{% trans 'Stock Item Test Report' %}";
color: #F55; color: #F55;
} }
.test-not-found {
color: #33A;
}
.required-test-not-found {
color: #EEE;
background-color: #F55;
}
.container { .container {
padding: 5px; padding: 5px;
border: 1px solid; border: 1px solid;
@ -84,7 +93,7 @@ content: "{% trans 'Stock Item Test Report' %}";
</div> </div>
</div> </div>
{% if resul_list|length > 0 %} {% if test_keys|length > 0 %}
<h3>{% trans "Test Results" %}</h3> <h3>{% trans "Test Results" %}</h3>
<table class='table test-table'> <table class='table test-table'>
@ -101,22 +110,44 @@ content: "{% trans 'Stock Item Test Report' %}";
<tr> <tr>
<td colspan='5'><hr></td> <td colspan='5'><hr></td>
</tr> </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'> <tr class='test-row'>
<td>{{ test.test }}</td> <td>
{% if test.result %} {% 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> <td class='test-pass'>{% trans "Pass" %}</td>
{% else %} {% else %}
<td class='test-fail'>{% trans "Fail" %}</td> <td class='test-fail'>{% trans "Fail" %}</td>
{% endif %} {% endif %}
<td>{{ test.value }}</td> <td>{{ test_result.value }}</td>
<td>{{ test.user.username }}</td> <td>{{ test_result.user.username }}</td>
<td>{{ test.date.date.isoformat }}</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> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
{% else %}
<em>No tests defined for this stock item</em>
{% endif %} {% endif %}
{% if installed_items|length > 0 %} {% if installed_items|length > 0 %}

View File

@ -19,17 +19,52 @@ logger = logging.getLogger('inventree')
@register.simple_tag() @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. """Perform key lookup in the provided dict object.
This function is provided to get around template rendering limitations. This function is provided to get around template rendering limitations.
Ref: https://stackoverflow.com/questions/1906129/dict-keys-with-spaces-in-django-templates Ref: https://stackoverflow.com/questions/1906129/dict-keys-with-spaces-in-django-templates
Arguments: Arguments:
value: A python dict object container: A python dict object
arg: The 'key' to be found within the dict 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() @register.simple_tag()
@ -215,3 +250,31 @@ def render_currency(money, **kwargs):
"""Render a currency / Money object""" """Render a currency / Money object"""
return InvenTree.helpers.render_currency(money, **kwargs) 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)