Change the manner in which active parts are filtered for BOM

- Prevented BOM from displaying for an inactive part
- Now manually filter the queryset in the form view
This commit is contained in:
Oliver Walters 2019-06-28 10:00:23 +10:00
parent ed2461adf1
commit b6a6e2dae7
5 changed files with 70 additions and 7 deletions

View File

@ -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'),
),
]

View File

@ -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

View File

@ -37,7 +37,7 @@
<button class='btn btn-default' type='button' title='Import BOM data' id='bom-upload'><span class='glyphicon glyphicon-open-file'></span></button>
<button class='btn btn-default' type='button' title='New BOM Item' id='bom-item-new'><span class='glyphicon glyphicon-plus'></span></button>
<button class='btn btn-default' type='button' title='Finish Editing' id='editing-finished'><span class='glyphicon glyphicon-ok'></span></button>
{% else %}
{% elif part.active %}
<button class='btn btn-default' type='button' title='Edit BOM' id='edit-bom'><span class='glyphicon glyphicon-edit'></span></button>
{% if part.is_bom_valid == False %}
<button class='btn btn-default' id='validate-bom' type='button'><span class='glyphicon glyphicon-check'></span></button>
@ -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 () {

View File

@ -123,7 +123,7 @@
<td><b>Total Available</b></td>
<td><b>{{ part.net_stock }}</b></td>
</tr>
{% if part.assembly %}
{% if part.assembly %}
<tr>
<td colspan='2'>
<h4>Build Status</h4>

View File

@ -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 """