mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
* Add limit to default location annotation
Limits the number of results from the default_location filter to 1
* Add unit test to verify annotation functionality
(cherry picked from commit 2cb8f4128e
)
Co-authored-by: Lavissa <lavissawow@gmail.com>
This commit is contained in:
parent
0f3b719c80
commit
88c6696fd2
@ -299,15 +299,12 @@ def annotate_default_location(reference=''):
|
|||||||
rght__gt=OuterRef(f'{reference}rght'),
|
rght__gt=OuterRef(f'{reference}rght'),
|
||||||
level__lte=OuterRef(f'{reference}level'),
|
level__lte=OuterRef(f'{reference}level'),
|
||||||
parent__isnull=False,
|
parent__isnull=False,
|
||||||
)
|
default_location__isnull=False,
|
||||||
|
).order_by('-level')
|
||||||
|
|
||||||
return Coalesce(
|
return Coalesce(
|
||||||
F(f'{reference}default_location'),
|
F(f'{reference}default_location'),
|
||||||
Subquery(
|
Subquery(subquery.values('default_location')[:1]),
|
||||||
subquery.order_by('-level')
|
|
||||||
.filter(default_location__isnull=False)
|
|
||||||
.values('default_location')
|
|
||||||
),
|
|
||||||
Value(None),
|
Value(None),
|
||||||
output_field=IntegerField(),
|
output_field=IntegerField(),
|
||||||
)
|
)
|
||||||
|
@ -505,6 +505,82 @@ class PartCategoryAPITest(InvenTreeAPITestCase):
|
|||||||
self.assertEqual(item['parent'], parent)
|
self.assertEqual(item['parent'], parent)
|
||||||
self.assertEqual(item['subcategories'], subcategories)
|
self.assertEqual(item['subcategories'], subcategories)
|
||||||
|
|
||||||
|
def test_part_category_default_location(self):
|
||||||
|
"""Test default location propagation through location trees."""
|
||||||
|
"""Making a tree structure like this:
|
||||||
|
main
|
||||||
|
loc 2
|
||||||
|
sub1
|
||||||
|
sub2
|
||||||
|
loc 3
|
||||||
|
sub3
|
||||||
|
loc 4
|
||||||
|
sub4
|
||||||
|
sub5
|
||||||
|
Expected behaviour:
|
||||||
|
main parent loc: Out of test scope. Parent category data not controlled by the test
|
||||||
|
sub1 parent loc: loc 2
|
||||||
|
sub2 parent loc: loc 2
|
||||||
|
sub3 parent loc: loc 3
|
||||||
|
sub4 parent loc: loc 4
|
||||||
|
sub5 parent loc: loc 3
|
||||||
|
"""
|
||||||
|
main = PartCategory.objects.create(
|
||||||
|
name='main',
|
||||||
|
parent=PartCategory.objects.first(),
|
||||||
|
default_location=StockLocation.objects.get(id=2),
|
||||||
|
)
|
||||||
|
sub1 = PartCategory.objects.create(name='sub1', parent=main)
|
||||||
|
sub2 = PartCategory.objects.create(
|
||||||
|
name='sub2', parent=sub1, default_location=StockLocation.objects.get(id=3)
|
||||||
|
)
|
||||||
|
sub3 = PartCategory.objects.create(
|
||||||
|
name='sub3', parent=sub2, default_location=StockLocation.objects.get(id=4)
|
||||||
|
)
|
||||||
|
sub4 = PartCategory.objects.create(name='sub4', parent=sub3)
|
||||||
|
sub5 = PartCategory.objects.create(name='sub5', parent=sub2)
|
||||||
|
part = Part.objects.create(name='test', category=sub4)
|
||||||
|
PartCategory.objects.rebuild()
|
||||||
|
|
||||||
|
# This query will trigger an internal server error if annotation results are not limited to 1
|
||||||
|
url = reverse('api-part-list')
|
||||||
|
response = self.get(url, expected_code=200)
|
||||||
|
|
||||||
|
# sub1, expect main to be propagated
|
||||||
|
url = reverse('api-part-category-detail', kwargs={'pk': sub1.pk})
|
||||||
|
response = self.get(url, expected_code=200)
|
||||||
|
self.assertEqual(
|
||||||
|
response.data['parent_default_location'], main.default_location.pk
|
||||||
|
)
|
||||||
|
|
||||||
|
# sub2, expect main to be propagated
|
||||||
|
url = reverse('api-part-category-detail', kwargs={'pk': sub2.pk})
|
||||||
|
response = self.get(url, expected_code=200)
|
||||||
|
self.assertEqual(
|
||||||
|
response.data['parent_default_location'], main.default_location.pk
|
||||||
|
)
|
||||||
|
|
||||||
|
# sub3, expect sub2 to be propagated
|
||||||
|
url = reverse('api-part-category-detail', kwargs={'pk': sub3.pk})
|
||||||
|
response = self.get(url, expected_code=200)
|
||||||
|
self.assertEqual(
|
||||||
|
response.data['parent_default_location'], sub2.default_location.pk
|
||||||
|
)
|
||||||
|
|
||||||
|
# sub4, expect sub3 to be propagated
|
||||||
|
url = reverse('api-part-category-detail', kwargs={'pk': sub4.pk})
|
||||||
|
response = self.get(url, expected_code=200)
|
||||||
|
self.assertEqual(
|
||||||
|
response.data['parent_default_location'], sub3.default_location.pk
|
||||||
|
)
|
||||||
|
|
||||||
|
# sub5, expect sub2 to be propagated
|
||||||
|
url = reverse('api-part-category-detail', kwargs={'pk': sub5.pk})
|
||||||
|
response = self.get(url, expected_code=200)
|
||||||
|
self.assertEqual(
|
||||||
|
response.data['parent_default_location'], sub2.default_location.pk
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class PartOptionsAPITest(InvenTreeAPITestCase):
|
class PartOptionsAPITest(InvenTreeAPITestCase):
|
||||||
"""Tests for the various OPTIONS endpoints in the /part/ API.
|
"""Tests for the various OPTIONS endpoints in the /part/ API.
|
||||||
|
Loading…
Reference in New Issue
Block a user