diff --git a/InvenTree/build/migrations/0013_auto_20200425_0507.py b/InvenTree/build/migrations/0013_auto_20200425_0507.py new file mode 100644 index 0000000000..d960e416c8 --- /dev/null +++ b/InvenTree/build/migrations/0013_auto_20200425_0507.py @@ -0,0 +1,55 @@ +# Generated by Django 3.0.5 on 2020-04-25 05:07 + +from django.db import migrations, models +import django.db.models.deletion +import mptt.fields +from build.models import Build + + +def update_tree(apps, schema_editor): + # Update the Build MPTT model + Build.objects.rebuild() + + +def nupdate_tree(apps, schema_editor): + pass + + +class Migration(migrations.Migration): + + dependencies = [ + ('build', '0012_build_sales_order'), + ] + + operations = [ + migrations.AddField( + model_name='build', + name='level', + field=models.PositiveIntegerField(default=0, editable=False), + preserve_default=False, + ), + migrations.AddField( + model_name='build', + name='lft', + field=models.PositiveIntegerField(default=0, editable=False), + preserve_default=False, + ), + migrations.AddField( + model_name='build', + name='parent', + field=mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='children', to='build.Build'), + ), + migrations.AddField( + model_name='build', + name='rght', + field=models.PositiveIntegerField(default=0, editable=False), + preserve_default=False, + ), + migrations.AddField( + model_name='build', + name='tree_id', + field=models.PositiveIntegerField(db_index=True, default=0, editable=False), + preserve_default=False, + ), + migrations.RunPython(update_tree, reverse_code=nupdate_tree), + ] diff --git a/InvenTree/build/models.py b/InvenTree/build/models.py index 06a382bbc1..a8b00fcb47 100644 --- a/InvenTree/build/models.py +++ b/InvenTree/build/models.py @@ -18,6 +18,8 @@ from django.core.validators import MinValueValidator from markdownx.models import MarkdownxField +from mptt.models import MPTTModel, TreeForeignKey + from InvenTree.status_codes import BuildStatus from InvenTree.fields import InvenTreeURLField from InvenTree.helpers import decimal2string @@ -26,13 +28,14 @@ from stock.models import StockItem from part.models import Part, BomItem -class Build(models.Model): +class Build(MPTTModel): """ A Build object organises the creation of new parts from the component parts. Attributes: part: The part to be built (from component BOM items) title: Brief title describing the build (required) quantity: Number of units to be built + parent: Reference to a Build object for which this Build is required sales_order: References to a SalesOrder object for which this Build is required (e.g. the output of this build will be used to fulfil a sales order) take_from: Location to take stock from to make this build (if blank, can take from anywhere) status: Build status code @@ -44,7 +47,7 @@ class Build(models.Model): """ def __str__(self): - return "Build {q} x {part}".format(q=decimal2string(self.quantity), part=str(self.part)) + return "{q} x {part}".format(q=decimal2string(self.quantity), part=str(self.part.full_name)) def get_absolute_url(self): return reverse('build-detail', kwargs={'pk': self.id}) @@ -55,6 +58,13 @@ class Build(models.Model): help_text=_('Brief description of the build') ) + parent = TreeForeignKey( + 'self', + on_delete=models.DO_NOTHING, + blank=True, null=True, + related_name='children' + ) + part = models.ForeignKey( 'part.Part', on_delete=models.CASCADE, diff --git a/InvenTree/build/templates/build/build_base.html b/InvenTree/build/templates/build/build_base.html index dfe3719d98..f83b6c3e79 100644 --- a/InvenTree/build/templates/build/build_base.html +++ b/InvenTree/build/templates/build/build_base.html @@ -75,6 +75,13 @@ src="{% static 'img/blank_image.png' %}" {% trans "Status" %} {% build_status_label build.status %} + {% if build.parent %} + + + {% trans "Parent Build" %} + {{ build.parent }} + + {% endif %} {% if build.sales_order %}