diff --git a/InvenTree/part/forms.py b/InvenTree/part/forms.py index 0363b4ab37..e97386d229 100644 --- a/InvenTree/part/forms.py +++ b/InvenTree/part/forms.py @@ -90,7 +90,8 @@ class EditCategoryForm(HelperForm): fields = [ 'parent', 'name', - 'description' + 'description', + 'default_location' ] diff --git a/InvenTree/part/migrations/0015_partcategory_default_location.py b/InvenTree/part/migrations/0015_partcategory_default_location.py new file mode 100644 index 0000000000..33a47cc440 --- /dev/null +++ b/InvenTree/part/migrations/0015_partcategory_default_location.py @@ -0,0 +1,20 @@ +# Generated by Django 2.2 on 2019-05-04 08:57 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('stock', '0013_remove_stockitem_uuid'), + ('part', '0014_auto_20190502_2039'), + ] + + operations = [ + migrations.AddField( + model_name='partcategory', + name='default_location', + field=models.ForeignKey(blank=True, help_text='Default location for parts in this category', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='default_categories', to='stock.StockLocation'), + ), + ] diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py index e2823ba93b..8bc519d616 100644 --- a/InvenTree/part/models.py +++ b/InvenTree/part/models.py @@ -30,6 +30,13 @@ class PartCategory(InvenTreeTree): """ PartCategory provides hierarchical organization of Part objects. """ + default_location = models.ForeignKey( + 'stock.StockLocation', related_name="default_categories", + null=True, blank=True, + on_delete=models.SET_NULL, + help_text='Default location for parts in this category' + ) + def get_absolute_url(self): return reverse('category-detail', kwargs={'pk': self.id}) @@ -141,6 +148,29 @@ class Part(models.Model): help_text='Where is this item normally stored?', related_name='default_parts') + def get_default_location(self): + """ Get the default location for a Part (may be None). + + If the Part does not specify a default location, + look at the Category this part is in. + The PartCategory object may also specify a default stock location + """ + + if self.default_location: + return self.default_location + elif self.category: + # Traverse up the category tree until we find a default location + cat = self.category + + while cat: + if cat.default_location: + return cat.default_location + else: + cat = cat.parent + + # Default case - no default category found + return None + # Default supplier part default_supplier = models.ForeignKey('part.SupplierPart', on_delete=models.SET_NULL, diff --git a/InvenTree/part/templates/part/category.html b/InvenTree/part/templates/part/category.html index d03d18be44..7dad872114 100644 --- a/InvenTree/part/templates/part/category.html +++ b/InvenTree/part/templates/part/category.html @@ -8,8 +8,11 @@ {% if category %}
{{ category.description }}
+ {% if category.default_location %} +Default Location: {{ category.default_location }}
+ {% endif %} {% else %} -