diff --git a/InvenTree/part/migrations/0013_auto_20190628_0951.py b/InvenTree/part/migrations/0013_auto_20190628_0951.py
new file mode 100644
index 0000000000..df9f8fdb14
--- /dev/null
+++ b/InvenTree/part/migrations/0013_auto_20190628_0951.py
@@ -0,0 +1,24 @@
+# Generated by Django 2.2.2 on 2019-06-27 23:51
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('part', '0012_auto_20190627_2144'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='bomitem',
+ name='part',
+ field=models.ForeignKey(help_text='Select parent part', limit_choices_to={'assembly': True}, on_delete=django.db.models.deletion.CASCADE, related_name='bom_items', to='part.Part'),
+ ),
+ migrations.AlterField(
+ model_name='bomitem',
+ name='sub_part',
+ field=models.ForeignKey(help_text='Select part to be used in BOM', limit_choices_to={'component': True}, on_delete=django.db.models.deletion.CASCADE, related_name='used_in', to='part.Part'),
+ ),
+ ]
diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py
index 5f31e8a912..cc5bfc0db1 100644
--- a/InvenTree/part/models.py
+++ b/InvenTree/part/models.py
@@ -987,7 +987,6 @@ class BomItem(models.Model):
help_text='Select parent part',
limit_choices_to={
'assembly': True,
- 'active': True,
})
# A link to the child item (sub-part)
@@ -996,7 +995,6 @@ class BomItem(models.Model):
help_text='Select part to be used in BOM',
limit_choices_to={
'component': True,
- 'active': True
})
# Quantity required
diff --git a/InvenTree/part/templates/part/bom.html b/InvenTree/part/templates/part/bom.html
index 1605deda68..2591b986ee 100644
--- a/InvenTree/part/templates/part/bom.html
+++ b/InvenTree/part/templates/part/bom.html
@@ -37,7 +37,7 @@
- {% else %}
+ {% elif part.active %}
{% if part.is_bom_valid == False %}
@@ -125,7 +125,7 @@
});
$("#edit-bom").click(function () {
- location.href = "{% url 'part-bom' part.id %}?edit=True";
+ location.href = "{% url 'part-bom' part.id %}?edit=1";
});
$(".download-bom").click(function () {
diff --git a/InvenTree/part/templates/part/part_base.html b/InvenTree/part/templates/part/part_base.html
index 7339b5afb7..27852b5859 100644
--- a/InvenTree/part/templates/part/part_base.html
+++ b/InvenTree/part/templates/part/part_base.html
@@ -123,7 +123,7 @@
Total Available
{{ part.net_stock }}
- {% if part.assembly %}
+ {% if part.assembly %}
Build Status
diff --git a/InvenTree/part/views.py b/InvenTree/part/views.py
index 07f013d852..99ea6680e3 100644
--- a/InvenTree/part/views.py
+++ b/InvenTree/part/views.py
@@ -511,13 +511,15 @@ class PartDetail(DetailView):
- If '?editing=True', set 'editing_enabled' context variable
"""
context = super(PartDetail, self).get_context_data(**kwargs)
+
+ part = self.get_object()
if str2bool(self.request.GET.get('edit', '')):
- context['editing_enabled'] = 1
+ # Allow BOM editing if the part is active
+ context['editing_enabled'] = 1 if part.active else 0
else:
context['editing_enabled'] = 0
- part = self.get_object()
context['starred'] = part.isStarredBy(self.request.user)
context['disabled'] = not part.active
@@ -1025,11 +1027,16 @@ class BomItemCreate(AjaxCreateView):
try:
part = Part.objects.get(id=part_id)
+ # Only allow active parts to be selected
+ query = form.fields['part'].queryset.filter(active=True)
+ form.fields['part'].queryset = query
+
# Don't allow selection of sub_part objects which are already added to the Bom!
query = form.fields['sub_part'].queryset
# Don't allow a part to be added to its own BOM
query = query.exclude(id=part.id)
+ query = query.filter(active=True)
# Eliminate any options that are already in the BOM!
query = query.exclude(id__in=[item.id for item in part.required_parts()])
@@ -1069,6 +1076,40 @@ class BomItemEdit(AjaxUpdateView):
ajax_template_name = 'modal_form.html'
ajax_form_title = 'Edit BOM item'
+ def get_form(self):
+ """ Override get_form() method to reduce Part selection options.
+
+ - Do not allow part to be added to its own BOM
+ - Remove any Part items that are already in the BOM
+ """
+
+ form = super(AjaxCreateView, self).get_form()
+
+ part_id = form['part'].value()
+
+ try:
+ part = Part.objects.get(id=part_id)
+
+ # Only allow active parts to be selected
+ query = form.fields['part'].queryset.filter(active=True)
+ form.fields['part'].queryset = query
+
+ # Don't allow selection of sub_part objects which are already added to the Bom!
+ query = form.fields['sub_part'].queryset
+
+ # Don't allow a part to be added to its own BOM
+ query = query.exclude(id=part.id)
+ query = query.filter(active=True)
+
+ # Eliminate any options that are already in the BOM!
+ query = query.exclude(id__in=[item.id for item in part.required_parts()])
+
+ form.fields['sub_part'].queryset = query
+ except Part.DoesNotExist:
+ pass
+
+ return form
+
class BomItemDelete(AjaxDeleteView):
""" Delete view for removing BomItem """