diff --git a/InvenTree/build/forms.py b/InvenTree/build/forms.py
index 24f193865d..ba7787798d 100644
--- a/InvenTree/build/forms.py
+++ b/InvenTree/build/forms.py
@@ -66,7 +66,7 @@ class BuildOutputCreateForm(HelperForm):
'serial_numbers': 'fa-hashtag',
}
- quantity = forms.IntegerField(
+ output_quantity = forms.IntegerField(
label=_('Quantity'),
help_text=_('Enter quantity for build output'),
)
@@ -86,7 +86,7 @@ class BuildOutputCreateForm(HelperForm):
class Meta:
model = Build
fields = [
- 'quantity',
+ 'output_quantity',
'batch',
'serial_numbers',
'confirm',
diff --git a/InvenTree/build/models.py b/InvenTree/build/models.py
index 6634b69cdf..a18328be1a 100644
--- a/InvenTree/build/models.py
+++ b/InvenTree/build/models.py
@@ -182,6 +182,14 @@ class Build(MPTTModel):
blank=True, help_text=_('Extra build notes')
)
+ @property
+ def active(self):
+ """
+ Return True if this build is active
+ """
+
+ return self.status in BuildStatus.ACTIVE_CODES
+
@property
def bom_items(self):
"""
@@ -594,6 +602,9 @@ class Build(MPTTModel):
- Mark the output as complete
"""
+ # Select the location for the build output
+ location = kwargs.get('location', self.destination)
+
# List the allocated BuildItem objects for the given output
allocated_items = output.items_to_install.all()
@@ -613,6 +624,7 @@ class Build(MPTTModel):
# Ensure that the output is updated correctly
output.build = self
output.is_building = False
+ output.location = location
output.save()
diff --git a/InvenTree/build/templates/build/allocate.html b/InvenTree/build/templates/build/allocate.html
index e811c37ce8..aa45aa5054 100644
--- a/InvenTree/build/templates/build/allocate.html
+++ b/InvenTree/build/templates/build/allocate.html
@@ -21,6 +21,7 @@ InvenTree | Allocate Parts
{% else %}
+ {% if build.active %}
@@ -32,6 +33,7 @@ InvenTree | Allocate Parts
+ {% endif %}
@@ -74,7 +76,7 @@ InvenTree | Allocate Parts
);
{% endfor %}
- {% if build.status == BuildStatus.PENDING %}
+ {% if build.active %}
$("#btn-allocate").on('click', function() {
launchModalForm(
"{% url 'build-auto-allocate' build.id %}",
diff --git a/InvenTree/build/views.py b/InvenTree/build/views.py
index 5dd36a6871..1355738a9c 100644
--- a/InvenTree/build/views.py
+++ b/InvenTree/build/views.py
@@ -188,7 +188,7 @@ class BuildOutputCreate(AjaxUpdateView):
Validation for the form:
"""
- quantity = form.cleaned_data.get('quantity', None)
+ quantity = form.cleaned_data.get('output_quantity', None)
serials = form.cleaned_data.get('serial_numbers', None)
# Check that the serial numbers are valid
@@ -222,7 +222,7 @@ class BuildOutputCreate(AjaxUpdateView):
data = form.cleaned_data
- quantity = data.get('quantity', None)
+ quantity = data.get('output_quantity', None)
batch = data.get('batch', None)
serials = data.get('serial_numbers', None)
diff --git a/InvenTree/part/forms.py b/InvenTree/part/forms.py
index c4523113e5..0b24e5a462 100644
--- a/InvenTree/part/forms.py
+++ b/InvenTree/part/forms.py
@@ -154,11 +154,6 @@ class CreatePartRelatedForm(HelperForm):
'part_2': _('Related Part'),
}
- def save(self):
- """ Disable model saving """
-
- return super(CreatePartRelatedForm, self).save(commit=False)
-
class EditPartAttachmentForm(HelperForm):
""" Form for editing a PartAttachment object """
diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py
index 60e100b563..0c8aeb5665 100644
--- a/InvenTree/part/models.py
+++ b/InvenTree/part/models.py
@@ -1908,24 +1908,3 @@ class PartRelated(models.Model):
'and that the relationship is unique')
raise ValidationError(error_message)
-
- def create_relationship(self, part_1, part_2):
- ''' Create relationship between two parts '''
-
- validate = self.validate(part_1, part_2)
-
- if validate:
- # Add relationship
- self.part_1 = part_1
- self.part_2 = part_2
- self.save()
-
- return validate
-
- @classmethod
- def create(cls, part_1, part_2):
- ''' Create PartRelated object and relationship between two parts '''
-
- related_part = cls()
- related_part.create_relationship(part_1, part_2)
- return related_part
diff --git a/InvenTree/part/test_views.py b/InvenTree/part/test_views.py
index 1ad5c33e45..2a36dd9012 100644
--- a/InvenTree/part/test_views.py
+++ b/InvenTree/part/test_views.py
@@ -5,7 +5,7 @@ from django.urls import reverse
from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group
-from .models import Part
+from .models import Part, PartRelated
class PartViewTestCase(TestCase):
@@ -204,24 +204,31 @@ class PartTests(PartViewTestCase):
class PartRelatedTests(PartViewTestCase):
def test_valid_create(self):
- """ test creation of an attachment for a valid part """
+ """ test creation of a related part """
- response = self.client.get(reverse('part-related-create'), {'part': 1}, HTTP_X_REQUESTED_WITH='XMLHttpRequest')
+ # Test GET view
+ response = self.client.get(reverse('part-related-create'), {'part': 1},
+ HTTP_X_REQUESTED_WITH='XMLHttpRequest')
self.assertEqual(response.status_code, 200)
- # TODO - Create a new attachment using this view
+ # Test POST view with valid form data
+ response = self.client.post(reverse('part-related-create'), {'part_1': 1, 'part_2': 2},
+ HTTP_X_REQUESTED_WITH='XMLHttpRequest')
+ self.assertContains(response, '"form_valid": true', status_code=200)
- def test_invalid_create(self):
- """ test creation of an attachment for an invalid part """
+ # Try to create the same relationship with part_1 and part_2 pks reversed
+ response = self.client.post(reverse('part-related-create'), {'part_1': 2, 'part_2': 1},
+ HTTP_X_REQUESTED_WITH='XMLHttpRequest')
+ self.assertContains(response, '"form_valid": false', status_code=200)
- # TODO
- pass
-
- def test_edit(self):
- """ test editing an attachment """
-
- # TODO
- pass
+ # Try to create part related to itself
+ response = self.client.post(reverse('part-related-create'), {'part_1': 1, 'part_2': 1},
+ HTTP_X_REQUESTED_WITH='XMLHttpRequest')
+ self.assertContains(response, '"form_valid": false', status_code=200)
+
+ # Check final count
+ n = PartRelated.objects.all().count()
+ self.assertEqual(n, 1)
class PartAttachmentTests(PartViewTestCase):
diff --git a/InvenTree/part/views.py b/InvenTree/part/views.py
index bd602448db..2504b056c5 100644
--- a/InvenTree/part/views.py
+++ b/InvenTree/part/views.py
@@ -128,17 +128,6 @@ class PartRelatedCreate(AjaxCreateView):
return form
- def post_save(self):
- """ Save PartRelated model (POST method does not) """
-
- form = self.get_form()
-
- if form.is_valid():
- part_1 = form.cleaned_data['part_1']
- part_2 = form.cleaned_data['part_2']
-
- PartRelated.create(part_1, part_2)
-
class PartRelatedDelete(AjaxDeleteView):
""" View for deleting a PartRelated object """