mirror of
https://github.com/inventree/InvenTree.git
synced 2025-04-28 19:46:46 +00:00
Merge pull request #149 from SchrodingersGat/get_absolute_url
Get absolute url
This commit is contained in:
commit
19001b98f7
@ -13,7 +13,7 @@ before_install:
|
|||||||
- make setup_ci
|
- make setup_ci
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- make test
|
- make coverage
|
||||||
- make style
|
- make style
|
||||||
|
|
||||||
after_success:
|
after_success:
|
||||||
|
@ -74,9 +74,9 @@ class InvenTreeTree(models.Model):
|
|||||||
@property
|
@property
|
||||||
def children(self):
|
def children(self):
|
||||||
contents = ContentType.objects.get_for_model(type(self))
|
contents = ContentType.objects.get_for_model(type(self))
|
||||||
children = contents.get_all_objects_for_this_type(parent=self.id)
|
childs = contents.get_all_objects_for_this_type(parent=self.id)
|
||||||
|
|
||||||
return children
|
return childs
|
||||||
|
|
||||||
def getAcceptableParents(self):
|
def getAcceptableParents(self):
|
||||||
""" Returns a list of acceptable parent items within this model
|
""" Returns a list of acceptable parent items within this model
|
||||||
@ -187,11 +187,8 @@ def FilterChildren(queryset, parent):
|
|||||||
elif str2bool(parent, False):
|
elif str2bool(parent, False):
|
||||||
return queryset.filter(parent=None)
|
return queryset.filter(parent=None)
|
||||||
else:
|
else:
|
||||||
try:
|
|
||||||
parent_id = int(parent)
|
parent_id = int(parent)
|
||||||
if parent_id == 0:
|
if parent_id == 0:
|
||||||
return queryset.filter(parent=None)
|
return queryset.filter(parent=None)
|
||||||
else:
|
else:
|
||||||
return queryset.filter(parent=parent_id)
|
return queryset.filter(parent=parent_id)
|
||||||
except:
|
|
||||||
return queryset
|
|
||||||
|
@ -3,6 +3,7 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
|
|
||||||
|
from django.urls import reverse
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.core.validators import MinValueValidator
|
from django.core.validators import MinValueValidator
|
||||||
|
|
||||||
@ -14,7 +15,7 @@ class Build(models.Model):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return '/build/{pk}/'.format(pk=self.id)
|
return reverse('build-detail', kwargs={'pk': self.id})
|
||||||
|
|
||||||
# Build status codes
|
# Build status codes
|
||||||
PENDING = 10 # Build is pending / active
|
PENDING = 10 # Build is pending / active
|
||||||
|
@ -1,6 +1,56 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
# from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
|
||||||
# Create your tests here.
|
from .models import Build
|
||||||
|
from part.models import Part
|
||||||
|
|
||||||
|
|
||||||
|
class BuildTestSimple(TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
part = Part.objects.create(name='Test part',
|
||||||
|
description='Simple description')
|
||||||
|
Build.objects.create(part=part,
|
||||||
|
batch='B1',
|
||||||
|
status=Build.PENDING,
|
||||||
|
title='Building 7 parts',
|
||||||
|
quantity=7,
|
||||||
|
notes='Some simple notes')
|
||||||
|
|
||||||
|
Build.objects.create(part=part,
|
||||||
|
batch='B2',
|
||||||
|
status=Build.COMPLETE,
|
||||||
|
title='Building 21 parts',
|
||||||
|
quantity=21,
|
||||||
|
notes='Some simple notes')
|
||||||
|
|
||||||
|
def test_build_objects(self):
|
||||||
|
# Ensure the Build objects were correctly created
|
||||||
|
self.assertEqual(Build.objects.count(), 2)
|
||||||
|
b = Build.objects.get(pk=2)
|
||||||
|
self.assertEqual(b.batch, 'B2')
|
||||||
|
self.assertEqual(b.quantity, 21)
|
||||||
|
|
||||||
|
def test_url(self):
|
||||||
|
b1 = Build.objects.get(pk=1)
|
||||||
|
self.assertEqual(b1.get_absolute_url(), '/build/1/')
|
||||||
|
|
||||||
|
def test_is_complete(self):
|
||||||
|
b1 = Build.objects.get(pk=1)
|
||||||
|
b2 = Build.objects.get(pk=2)
|
||||||
|
|
||||||
|
self.assertEqual(b1.is_complete, False)
|
||||||
|
self.assertEqual(b2.is_complete, True)
|
||||||
|
|
||||||
|
def test_is_active(self):
|
||||||
|
b1 = Build.objects.get(pk=1)
|
||||||
|
b2 = Build.objects.get(pk=2)
|
||||||
|
|
||||||
|
self.assertEqual(b1.is_active, True)
|
||||||
|
self.assertEqual(b2.is_active, False)
|
||||||
|
|
||||||
|
def test_required_parts(self):
|
||||||
|
# TODO - Generate BOM for test part
|
||||||
|
pass
|
||||||
|
@ -4,6 +4,7 @@ from __future__ import unicode_literals
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
from django.urls import reverse
|
||||||
|
|
||||||
|
|
||||||
def rename_company_image(instance, filename):
|
def rename_company_image(instance, filename):
|
||||||
@ -56,7 +57,7 @@ class Company(models.Model):
|
|||||||
return "{n} - {d}".format(n=self.name, d=self.description)
|
return "{n} - {d}".format(n=self.name, d=self.description)
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return "/company/{id}/".format(id=self.id)
|
return reverse('company-detail', kwargs={'pk': self.id})
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def part_count(self):
|
def part_count(self):
|
||||||
|
@ -1,3 +1,19 @@
|
|||||||
# from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
|
||||||
# Create your tests here.
|
from .models import Company
|
||||||
|
|
||||||
|
|
||||||
|
class CompanySimpleTest(TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
Company.objects.create(name='ABC Co.',
|
||||||
|
description='Seller of ABC products',
|
||||||
|
website='www.abc-sales.com',
|
||||||
|
address='123 Sales St.',
|
||||||
|
is_customer=False,
|
||||||
|
is_supplier=True)
|
||||||
|
|
||||||
|
def test_company_model(self):
|
||||||
|
c = Company.objects.get(pk=1)
|
||||||
|
self.assertEqual(c.name, 'ABC Co.')
|
||||||
|
self.assertEqual(c.get_absolute_url(), '/company/1/')
|
||||||
|
@ -9,6 +9,7 @@ import tablib
|
|||||||
|
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
|
from django.urls import reverse
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.core.validators import MinValueValidator
|
from django.core.validators import MinValueValidator
|
||||||
@ -25,7 +26,7 @@ class PartCategory(InvenTreeTree):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return '/part/category/{id}/'.format(id=self.id)
|
return reverse('category-detail', kwargs={'pk': self.id})
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = "Part Category"
|
verbose_name = "Part Category"
|
||||||
@ -88,7 +89,7 @@ class Part(models.Model):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return '/part/{id}/'.format(id=self.id)
|
return reverse('part-detail', kwargs={'pk': self.id})
|
||||||
|
|
||||||
# Short name of the part
|
# Short name of the part
|
||||||
name = models.CharField(max_length=100, unique=True, help_text='Part name (must be unique)')
|
name = models.CharField(max_length=100, unique=True, help_text='Part name (must be unique)')
|
||||||
@ -336,7 +337,7 @@ class BomItem(models.Model):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return '/part/bom/{id}/'.format(id=self.id)
|
return reverse('bom-detail', kwargs={'pk': self.id})
|
||||||
|
|
||||||
# A link to the parent part
|
# A link to the parent part
|
||||||
# Each part will get a reverse lookup field 'bom_items'
|
# Each part will get a reverse lookup field 'bom_items'
|
||||||
@ -385,7 +386,7 @@ class SupplierPart(models.Model):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return "/supplier-part/{id}/".format(id=self.id)
|
return reverse('supplier-part-detail', kwargs={'pk': self.id})
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = ('part', 'supplier', 'SKU')
|
unique_together = ('part', 'supplier', 'SKU')
|
||||||
|
7
InvenTree/part/test_bom_item.py
Normal file
7
InvenTree/part/test_bom_item.py
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
|
||||||
|
class BomItemTest(TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
pass
|
66
InvenTree/part/test_category.py
Normal file
66
InvenTree/part/test_category.py
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
from .models import Part, PartCategory
|
||||||
|
|
||||||
|
|
||||||
|
class CategoryTest(TestCase):
|
||||||
|
"""
|
||||||
|
Tests to ensure that the relational category tree functions correctly.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.p1 = PartCategory.objects.create(name='A',
|
||||||
|
description='Most highest level',
|
||||||
|
parent=None)
|
||||||
|
|
||||||
|
self.p2 = PartCategory.objects.create(name='B',
|
||||||
|
description='Sits under second',
|
||||||
|
parent=self.p1)
|
||||||
|
|
||||||
|
self.p3 = PartCategory.objects.create(name='C',
|
||||||
|
description='Third tier category',
|
||||||
|
parent=self.p2)
|
||||||
|
|
||||||
|
# Add two parts in p2
|
||||||
|
Part.objects.create(name='Flange', category=self.p2)
|
||||||
|
Part.objects.create(name='Flob', category=self.p2)
|
||||||
|
|
||||||
|
# Add one part in p3
|
||||||
|
Part.objects.create(name='Blob', category=self.p3)
|
||||||
|
|
||||||
|
def test_parents(self):
|
||||||
|
self.assertEqual(self.p1.parent, None)
|
||||||
|
self.assertEqual(self.p2.parent, self.p1)
|
||||||
|
self.assertEqual(self.p3.parent, self.p2)
|
||||||
|
|
||||||
|
def test_children_count(self):
|
||||||
|
self.assertEqual(self.p1.has_children, True)
|
||||||
|
self.assertEqual(self.p2.has_children, True)
|
||||||
|
self.assertEqual(self.p3.has_children, False)
|
||||||
|
|
||||||
|
def test_unique_childs(self):
|
||||||
|
childs = self.p1.getUniqueChildren()
|
||||||
|
|
||||||
|
self.assertIn(self.p2.id, childs)
|
||||||
|
self.assertIn(self.p2.id, childs)
|
||||||
|
|
||||||
|
def test_unique_parents(self):
|
||||||
|
parents = self.p2.getUniqueParents()
|
||||||
|
|
||||||
|
self.assertIn(self.p1.id, parents)
|
||||||
|
|
||||||
|
def test_path_string(self):
|
||||||
|
self.assertEqual(str(self.p3), 'A/B/C')
|
||||||
|
|
||||||
|
def test_url(self):
|
||||||
|
self.assertEqual(self.p1.get_absolute_url(), '/part/category/1/')
|
||||||
|
|
||||||
|
def test_part_count(self):
|
||||||
|
# No direct parts in the top-level category
|
||||||
|
self.assertEqual(self.p1.has_parts, False)
|
||||||
|
self.assertEqual(self.p2.has_parts, True)
|
||||||
|
self.assertEqual(self.p3.has_parts, True)
|
||||||
|
|
||||||
|
self.assertEqual(self.p1.partcount, 3)
|
||||||
|
self.assertEqual(self.p2.partcount, 3)
|
||||||
|
self.assertEqual(self.p3.partcount, 1)
|
23
InvenTree/part/test_part.py
Normal file
23
InvenTree/part/test_part.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
from .models import Part, PartCategory
|
||||||
|
|
||||||
|
|
||||||
|
class SimplePartTest(TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
|
||||||
|
cat = PartCategory.objects.create(name='TLC', description='Top level category')
|
||||||
|
|
||||||
|
self.px = Part.objects.create(name='x', description='A part called x', buildable=True)
|
||||||
|
self.py = Part.objects.create(name='y', description='A part called y', consumable=False)
|
||||||
|
self.pz = Part.objects.create(name='z', description='A part called z', category=cat)
|
||||||
|
|
||||||
|
def test_metadata(self):
|
||||||
|
self.assertEqual(self.px.name, 'x')
|
||||||
|
self.assertEqual(self.py.get_absolute_url(), '/part/2/')
|
||||||
|
self.assertEqual(str(self.pz), 'z - A part called z')
|
||||||
|
|
||||||
|
def test_category(self):
|
||||||
|
self.assertEqual(self.px.category_path, '')
|
||||||
|
self.assertEqual(self.pz.category_path, 'TLC')
|
7
InvenTree/part/test_supplier_part.py
Normal file
7
InvenTree/part/test_supplier_part.py
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
|
||||||
|
class SupplierPartTest(TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
pass
|
@ -1,3 +0,0 @@
|
|||||||
# from django.test import TestCase
|
|
||||||
|
|
||||||
# Create your tests here.
|
|
@ -70,23 +70,3 @@ part_urls = [
|
|||||||
# Top level part list (display top level parts and categories)
|
# Top level part list (display top level parts and categories)
|
||||||
url(r'^.*$', views.PartIndex.as_view(), name='part-index'),
|
url(r'^.*$', views.PartIndex.as_view(), name='part-index'),
|
||||||
]
|
]
|
||||||
|
|
||||||
"""
|
|
||||||
part_param_urls = [
|
|
||||||
# Detail of a single part parameter
|
|
||||||
url(r'^(?P<pk>[0-9]+)/?$', views.PartParamDetail.as_view(), name='partparameter-detail'),
|
|
||||||
|
|
||||||
# Parameters associated with a particular part
|
|
||||||
url(r'^\?.*/?$', views.PartParamList.as_view()),
|
|
||||||
url(r'^$', views.PartParamList.as_view()),
|
|
||||||
]
|
|
||||||
|
|
||||||
part_param_template_urls = [
|
|
||||||
# Detail of a single part field template
|
|
||||||
url(r'^(?P<pk>[0-9]+)/?$', views.PartTemplateDetail.as_view(), name='partparametertemplate-detail'),
|
|
||||||
|
|
||||||
# List all part field templates
|
|
||||||
url(r'^\?.*/?$', views.PartTemplateList.as_view()),
|
|
||||||
url(r'^$', views.PartTemplateList.as_view())
|
|
||||||
]
|
|
||||||
"""
|
|
||||||
|
@ -3,6 +3,7 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
|
from django.urls import reverse
|
||||||
|
|
||||||
from django.db import models, transaction
|
from django.db import models, transaction
|
||||||
from django.core.validators import MinValueValidator
|
from django.core.validators import MinValueValidator
|
||||||
@ -25,7 +26,7 @@ class StockLocation(InvenTreeTree):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return '/stock/location/{id}/'.format(id=self.id)
|
return reverse('stock-location-detail', kwargs={'pk': self.id})
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def stock_items(self):
|
def stock_items(self):
|
||||||
@ -109,7 +110,7 @@ class StockItem(models.Model):
|
|||||||
})
|
})
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return '/stock/item/{id}/'.format(id=self.id)
|
return reverse('stock-item-detail', kwargs={'pk': self.id})
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = [
|
unique_together = [
|
||||||
@ -331,7 +332,7 @@ class StockItemTracking(models.Model):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return '/stock/track/{id}/'.format(id=self.id)
|
return reverse('stock-tracking-detail', kwargs={'pk': self.id})
|
||||||
|
|
||||||
# Stock item
|
# Stock item
|
||||||
item = models.ForeignKey(StockItem, on_delete=models.CASCADE,
|
item = models.ForeignKey(StockItem, on_delete=models.CASCADE,
|
||||||
|
7
InvenTree/stock/test_stock_item.py
Normal file
7
InvenTree/stock/test_stock_item.py
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
|
||||||
|
class StockItemTest(TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
pass
|
7
InvenTree/stock/test_stock_location.py
Normal file
7
InvenTree/stock/test_stock_location.py
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
|
||||||
|
class StockLocationTest(TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
pass
|
7
InvenTree/stock/test_stock_tracking.py
Normal file
7
InvenTree/stock/test_stock_tracking.py
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
|
||||||
|
class StockTrackingTest(TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
pass
|
@ -1,3 +0,0 @@
|
|||||||
# from django.test import TestCase
|
|
||||||
|
|
||||||
# Create your tests here.
|
|
11
Makefile
11
Makefile
@ -11,11 +11,8 @@ style:
|
|||||||
flake8 InvenTree --ignore=C901,E501
|
flake8 InvenTree --ignore=C901,E501
|
||||||
|
|
||||||
test:
|
test:
|
||||||
# Perform Django system checks
|
|
||||||
python InvenTree/manage.py check
|
python InvenTree/manage.py check
|
||||||
|
python manage.py test build company part stock
|
||||||
# Run the test framework (through coverage script)
|
|
||||||
coverage run InvenTree/manage.py test
|
|
||||||
|
|
||||||
migrate:
|
migrate:
|
||||||
python InvenTree/manage.py makemigrations company
|
python InvenTree/manage.py makemigrations company
|
||||||
@ -26,7 +23,6 @@ migrate:
|
|||||||
python InvenTree/manage.py check
|
python InvenTree/manage.py check
|
||||||
|
|
||||||
install:
|
install:
|
||||||
# TODO: replace this with a proper setup.py
|
|
||||||
pip install -U -r requirements/base.txt
|
pip install -U -r requirements/base.txt
|
||||||
|
|
||||||
# Generate a secret key
|
# Generate a secret key
|
||||||
@ -37,5 +33,10 @@ setup: install migrate
|
|||||||
setup_ci:
|
setup_ci:
|
||||||
pip install -U -r requirements/build.txt
|
pip install -U -r requirements/build.txt
|
||||||
|
|
||||||
|
coverage:
|
||||||
|
python InvenTree/manage.py check
|
||||||
|
coverage run InvenTree/manage.py test build company part stock
|
||||||
|
coverage html
|
||||||
|
|
||||||
superuser:
|
superuser:
|
||||||
python InvenTree/manage.py createsuperuser
|
python InvenTree/manage.py createsuperuser
|
||||||
|
Loading…
x
Reference in New Issue
Block a user