Coverage for src/backend/InvenTree/stock/migrations/0106_auto_20240207_0353.py: 24%
57 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 17:47 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 17:47 +0000
1# Generated by Django 4.2.9 on 2024-02-07 03:53
3from django.db import migrations
6def set_template(apps, schema_editor):
7 """Matching existing StockItemTestResult objects to their associated template.
9 - Use the 'key' value from the associated test object.
10 - Look at the referenced part first
11 - If no matches, look at parent part template(s)
12 - If still no matches, create a new PartTestTemplate object
13 """
14 import time
15 import InvenTree.helpers
17 StockItemTestResult = apps.get_model('stock', 'stockitemtestresult')
18 PartTestTemplate = apps.get_model('part', 'parttesttemplate')
19 Part = apps.get_model('part', 'part')
21 # Look at any test results which do not match a template
22 results = StockItemTestResult.objects.filter(template=None)
24 parts = results.values_list('stock_item__part', flat=True).distinct()
26 n_results = results.count()
28 if n_results == 0: 28 ↛ 31line 28 didn't jump to line 31 because the condition on line 28 was always true
29 return
31 print(f"\n{n_results} StockItemTestResult objects do not have matching templates!")
32 print(f"Updating test results for {len(parts)} unique parts...")
34 # Keep a map of test templates
35 part_tree_map = {}
37 t1 = time.time()
39 new_templates = 0
41 # For each part with missing templates, work out what templates are missing
42 for pk in parts:
43 part = Part.objects.get(pk=pk)
44 tree_id = part.tree_id
45 # Find all results matching this part
46 part_results = results.filter(stock_item__part=part)
47 test_names = part_results.values_list('test', flat=True).distinct()
49 key_map = part_tree_map.get(tree_id, None) or {}
51 for name in test_names:
52 template = None
54 key = InvenTree.helpers.generateTestKey(name)
56 if template := key_map.get(key, None):
57 # We have a template for this key
58 pass
60 elif template := PartTestTemplate.objects.filter(part__tree_id=part.tree_id, key=key).first():
61 # We have found an existing template for this test
62 pass
64 elif template := PartTestTemplate.objects.filter(
65 part__tree_id=part.tree_id,
66 part__lft__lte=part.lft,
67 part__rght__gte=part.rght,
68 key=key).first():
69 # We have found an existing template for this test
70 pass
72 # Create a new template, based on the available test information
73 else:
75 # Find the parent part template
76 top_level_part = part
78 while top_level_part.variant_of:
79 top_level_part = top_level_part.variant_of
81 template = PartTestTemplate.objects.create(
82 part=top_level_part,
83 test_name=name,
84 key=key,
85 )
87 new_templates += 1
89 # Finally, update all matching results
90 part_results.filter(test=name).update(template=template)
92 # Update the key map for this part tree
93 key_map[key] = template
95 # Update the part tree map
96 part_tree_map[tree_id] = key_map
98 t2 = time.time()
99 dt = t2 - t1
101 print(f"Updated {n_results} StockItemTestResult objects in {dt:.3f} seconds.")
103 if new_templates > 0:
104 print(f"Created {new_templates} new templates!")
106 # Check that there are now zero reamining results without templates
107 results = StockItemTestResult.objects.filter(template=None)
108 assert(results.count() == 0)
111def remove_template(apps, schema_editor):
112 """Remove template links from existing StockItemTestResult objects."""
114 StockItemTestResult = apps.get_model('stock', 'stockitemtestresult')
115 results = StockItemTestResult.objects.all()
116 results.update(template=None)
118 if results.count() > 0:
119 print(f"\nRemoved template links from {results.count()} StockItemTestResult objects")
122class Migration(migrations.Migration):
124 atomic = False
126 dependencies = [
127 ('stock', '0105_stockitemtestresult_template'),
128 ('part', '0121_auto_20240207_0344')
129 ]
131 operations = [
132 migrations.RunPython(set_template, reverse_code=remove_template),
133 ]