From 989611cae268c9fdc5cf5834930e13d92d0da8c2 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Mon, 29 Apr 2019 22:19:13 +1000 Subject: [PATCH] Added BuildItemAllocation Model - Used to link stock items to a build --- InvenTree/build/forms.py | 2 +- .../migrations/0003_builditemallocation.py | 25 +++++++ InvenTree/build/migrations/0004_build_url.py | 18 +++++ InvenTree/build/models.py | 70 +++++++++++++++---- 4 files changed, 99 insertions(+), 16 deletions(-) create mode 100644 InvenTree/build/migrations/0003_builditemallocation.py create mode 100644 InvenTree/build/migrations/0004_build_url.py diff --git a/InvenTree/build/forms.py b/InvenTree/build/forms.py index 6254f0745c..05b1c99034 100644 --- a/InvenTree/build/forms.py +++ b/InvenTree/build/forms.py @@ -22,6 +22,6 @@ class EditBuildForm(HelperForm): 'quantity', 'batch', 'notes', - # 'status', + 'status', # 'completion_date', ] diff --git a/InvenTree/build/migrations/0003_builditemallocation.py b/InvenTree/build/migrations/0003_builditemallocation.py new file mode 100644 index 0000000000..add13c7ac1 --- /dev/null +++ b/InvenTree/build/migrations/0003_builditemallocation.py @@ -0,0 +1,25 @@ +# Generated by Django 2.2 on 2019-04-29 12:14 + +import django.core.validators +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('stock', '0009_auto_20190428_0841'), + ('build', '0002_auto_20190412_2030'), + ] + + operations = [ + migrations.CreateModel( + name='BuildItemAllocation', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('quantity', models.PositiveIntegerField(default=1, help_text='Stock quantity to allocate to build', validators=[django.core.validators.MinValueValidator(1)])), + ('build', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='allocated_stock', to='build.Build')), + ('stock', models.ForeignKey(help_text='Stock Item to allocate to build', on_delete=django.db.models.deletion.CASCADE, related_name='allocations', to='stock.StockItem')), + ], + ), + ] diff --git a/InvenTree/build/migrations/0004_build_url.py b/InvenTree/build/migrations/0004_build_url.py new file mode 100644 index 0000000000..187ac938d1 --- /dev/null +++ b/InvenTree/build/migrations/0004_build_url.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2 on 2019-04-29 12:18 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('build', '0003_builditemallocation'), + ] + + operations = [ + migrations.AddField( + model_name='build', + name='URL', + field=models.URLField(blank=True, help_text='Link to external URL'), + ), + ] diff --git a/InvenTree/build/models.py b/InvenTree/build/models.py index 880c1b08b1..6d83f74bf3 100644 --- a/InvenTree/build/models.py +++ b/InvenTree/build/models.py @@ -14,6 +14,17 @@ from django.core.validators import MinValueValidator class Build(models.Model): """ 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 + status: Build status code + batch: Batch code transferred to build parts (optional) + creation_date: Date the build was created (auto) + completion_date: Date the build was completed + URL: External URL for extra information + notes: Text notes """ def get_absolute_url(self): @@ -23,16 +34,15 @@ class Build(models.Model): related_name='builds', limit_choices_to={'buildable': True}, ) - """ A reference to the part being built - only parts marked as 'buildable' may be selected """ - #: Brief title describing the build title = models.CharField(max_length=100, help_text='Brief description of the build') - #: Number of output parts to build - quantity = models.PositiveIntegerField(default=1, - validators=[MinValueValidator(1)], - help_text='Number of parts to build') - + quantity = models.PositiveIntegerField( + default=1, + validators=[MinValueValidator(1)], + help_text='Number of parts to build' + ) + # Build status codes PENDING = 10 # Build is pending / active HOLDING = 20 # Build is currently being held @@ -46,23 +56,21 @@ class Build(models.Model): COMPLETE: _("Complete"), } - #: Status of the build (ref BUILD_STATUS_CODES) status = models.PositiveIntegerField(default=PENDING, choices=BUILD_STATUS_CODES.items(), validators=[MinValueValidator(0)]) - - #: Batch number for the build (optional) + batch = models.CharField(max_length=100, blank=True, null=True, help_text='Batch code for this build output') - - #: Date the build model was 'created' + creation_date = models.DateField(auto_now=True, editable=False) - - #: Date the build was 'completed' (and parts removed from stock) + completion_date = models.DateField(null=True, blank=True) + + URL = models.URLField(blank=True, help_text='Link to external URL') - #: Notes attached to each build output notes = models.TextField(blank=True) + """ Notes attached to each build output """ @property def required_parts(self): @@ -106,3 +114,35 @@ class Build(models.Model): def is_complete(self): """ Returns True if the build status is COMPLETE """ return self.status == self.COMPLETE + + +class BuildItemAllocation(models.Model): + """ A BuildItemAllocation links multiple StockItem objects to a Build. + These are used to allocate part stock to a build. + Once the Build is completed, the parts are removed from stock and the + BuildItemAllocation objects are removed. + + Attributes: + build: Link to a Build object + stock: Link to a StockItem object + quantity: Number of units allocated + """ + + build = models.ForeignKey( + Build, + on_delete=models.CASCADE, + related_name='allocated_stock', + ) + + stock = models.ForeignKey( + 'stock.StockItem', + on_delete=models.CASCADE, + related_name='allocations', + help_text='Stock Item to allocate to build', + ) + + quantity = models.PositiveIntegerField( + default=1, + validators=[MinValueValidator(1)], + help_text='Stock quantity to allocate to build' + )