mirror of
https://github.com/inventree/InvenTree.git
synced 2025-04-29 20:16:44 +00:00
Merge pull request #1327 from SchrodingersGat/installed-test-results
Read test results from installed items
This commit is contained in:
commit
b95d6a4ab2
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 3.0.7 on 2021-02-19 04:49
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('report', '0012_buildreport'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='testreport',
|
||||||
|
name='include_installed',
|
||||||
|
field=models.BooleanField(default=False, help_text='Include test results for stock items installed inside assembled item', verbose_name='Include Installed Tests'),
|
||||||
|
),
|
||||||
|
]
|
@ -281,6 +281,12 @@ class TestReport(ReportTemplateBase):
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
include_installed = models.BooleanField(
|
||||||
|
default=False,
|
||||||
|
verbose_name=_('Include Installed Tests'),
|
||||||
|
help_text=_('Include test results for stock items installed inside assembled item')
|
||||||
|
)
|
||||||
|
|
||||||
def matches_stock_item(self, item):
|
def matches_stock_item(self, item):
|
||||||
"""
|
"""
|
||||||
Test if this report template matches a given StockItem objects
|
Test if this report template matches a given StockItem objects
|
||||||
@ -304,8 +310,8 @@ class TestReport(ReportTemplateBase):
|
|||||||
return {
|
return {
|
||||||
'stock_item': stock_item,
|
'stock_item': stock_item,
|
||||||
'part': stock_item.part,
|
'part': stock_item.part,
|
||||||
'results': stock_item.testResultMap(),
|
'results': stock_item.testResultMap(include_installed=self.include_installed),
|
||||||
'result_list': stock_item.testResultList()
|
'result_list': stock_item.testResultList(include_installed=self.include_installed)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -707,6 +707,41 @@ class StockItem(MPTTModel):
|
|||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def get_installed_items(self, cascade=False):
|
||||||
|
"""
|
||||||
|
Return all stock items which are *installed* in this one!
|
||||||
|
|
||||||
|
Args:
|
||||||
|
cascade - Include items which are installed in items which are installed in items
|
||||||
|
|
||||||
|
Note: This function is recursive, and may result in a number of database hits!
|
||||||
|
"""
|
||||||
|
|
||||||
|
installed = set()
|
||||||
|
|
||||||
|
items = StockItem.objects.filter(belongs_to=self)
|
||||||
|
|
||||||
|
for item in items:
|
||||||
|
|
||||||
|
# Prevent duplication or recursion
|
||||||
|
if item == self or item in installed:
|
||||||
|
continue
|
||||||
|
|
||||||
|
installed.add(item)
|
||||||
|
|
||||||
|
if cascade:
|
||||||
|
sub_items = item.get_installed_items(cascade=True)
|
||||||
|
|
||||||
|
for sub_item in sub_items:
|
||||||
|
|
||||||
|
# Prevent recursion
|
||||||
|
if sub_item == self or sub_item in installed:
|
||||||
|
continue
|
||||||
|
|
||||||
|
installed.add(sub_item)
|
||||||
|
|
||||||
|
return installed
|
||||||
|
|
||||||
def installedItemCount(self):
|
def installedItemCount(self):
|
||||||
"""
|
"""
|
||||||
Return the number of stock items installed inside this one.
|
Return the number of stock items installed inside this one.
|
||||||
@ -1305,6 +1340,9 @@ class StockItem(MPTTModel):
|
|||||||
as all named tests are accessible.
|
as all named tests are accessible.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# Do we wish to include test results from installed items?
|
||||||
|
include_installed = kwargs.pop('include_installed', False)
|
||||||
|
|
||||||
# Filter results by "date", so that newer results
|
# Filter results by "date", so that newer results
|
||||||
# will override older ones.
|
# will override older ones.
|
||||||
results = self.getTestResults(**kwargs).order_by('date')
|
results = self.getTestResults(**kwargs).order_by('date')
|
||||||
@ -1315,6 +1353,20 @@ class StockItem(MPTTModel):
|
|||||||
key = helpers.generateTestKey(result.test)
|
key = helpers.generateTestKey(result.test)
|
||||||
result_map[key] = result
|
result_map[key] = result
|
||||||
|
|
||||||
|
# Do we wish to "cascade" and include test results from installed stock items?
|
||||||
|
cascade = kwargs.get('cascade', False)
|
||||||
|
|
||||||
|
if include_installed:
|
||||||
|
installed_items = self.get_installed_items(cascade=cascade)
|
||||||
|
|
||||||
|
for item in installed_items:
|
||||||
|
item_results = item.testResultMap()
|
||||||
|
|
||||||
|
for key in item_results.keys():
|
||||||
|
# Results from sub items should not override master ones
|
||||||
|
if key not in result_map.keys():
|
||||||
|
result_map[key] = item_results[key]
|
||||||
|
|
||||||
return result_map
|
return result_map
|
||||||
|
|
||||||
def testResultList(self, **kwargs):
|
def testResultList(self, **kwargs):
|
||||||
|
@ -622,3 +622,62 @@ class TestResultTest(StockTest):
|
|||||||
item3 = StockItem.objects.get(serial=100, part=item2.part)
|
item3 = StockItem.objects.get(serial=100, part=item2.part)
|
||||||
|
|
||||||
self.assertEqual(item3.test_results.count(), 4)
|
self.assertEqual(item3.test_results.count(), 4)
|
||||||
|
|
||||||
|
def test_installed_tests(self):
|
||||||
|
"""
|
||||||
|
Test test results for stock in stock.
|
||||||
|
|
||||||
|
Or, test "test results" for "stock items" installed "inside" a "stock item"
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Get a "master" stock item
|
||||||
|
item = StockItem.objects.get(pk=105)
|
||||||
|
|
||||||
|
tests = item.testResultMap(include_installed=False)
|
||||||
|
self.assertEqual(len(tests), 3)
|
||||||
|
|
||||||
|
# There are no "sub items" intalled at this stage
|
||||||
|
tests = item.testResultMap(include_installed=False)
|
||||||
|
self.assertEqual(len(tests), 3)
|
||||||
|
|
||||||
|
# Create a stock item which is installed *inside* the master item
|
||||||
|
sub_item = StockItem.objects.create(
|
||||||
|
part=item.part,
|
||||||
|
quantity=1,
|
||||||
|
belongs_to=item,
|
||||||
|
location=None
|
||||||
|
)
|
||||||
|
|
||||||
|
# Now, create some test results against the sub item
|
||||||
|
|
||||||
|
# First test is overshadowed by the same test for the parent part
|
||||||
|
StockItemTestResult.objects.create(
|
||||||
|
stock_item=sub_item,
|
||||||
|
test='firmware version',
|
||||||
|
date=datetime.datetime.now().date(),
|
||||||
|
result=True
|
||||||
|
)
|
||||||
|
|
||||||
|
# Should return the same number of tests as before
|
||||||
|
tests = item.testResultMap(include_installed=True)
|
||||||
|
self.assertEqual(len(tests), 3)
|
||||||
|
|
||||||
|
# Now, add a *unique* test result for the sub item
|
||||||
|
StockItemTestResult.objects.create(
|
||||||
|
stock_item=sub_item,
|
||||||
|
test='some new test',
|
||||||
|
date=datetime.datetime.now().date(),
|
||||||
|
result=False,
|
||||||
|
value='abcde',
|
||||||
|
)
|
||||||
|
|
||||||
|
tests = item.testResultMap(include_installed=True)
|
||||||
|
self.assertEqual(len(tests), 4)
|
||||||
|
|
||||||
|
self.assertIn('somenewtest', tests)
|
||||||
|
self.assertEqual(sub_item.test_results.count(), 2)
|
||||||
|
|
||||||
|
# Check that asking for test result map for *top item only* still works
|
||||||
|
tests = item.testResultMap(include_installed=False)
|
||||||
|
self.assertEqual(len(tests), 3)
|
||||||
|
self.assertNotIn('somenewtest', tests)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user