diff --git a/InvenTree/part/forms.py b/InvenTree/part/forms.py
index 2042ce4aff..379682e3dd 100644
--- a/InvenTree/part/forms.py
+++ b/InvenTree/part/forms.py
@@ -2,7 +2,7 @@ from django import forms
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit
-from .models import Part, PartCategory
+from .models import Part, PartCategory, BomItem
class EditPartForm(forms.ModelForm):
@@ -50,4 +50,26 @@ class EditCategoryForm(forms.ModelForm):
'parent',
'name',
'description'
+ ]
+
+
+class EditBomItemForm(forms.ModelForm):
+
+ def __init__(self, *args, **kwargs):
+ super(EditBomItemForm, self).__init__(*args, **kwargs)
+ self.helper = FormHelper()
+
+ self.helper.form_id = 'id-edit-part-form'
+ #self.helper.form_class = 'blueForms'
+ self.helper.form_method = 'post'
+ #self.helper.form_action = 'submit'
+
+ self.helper.add_input(Submit('submit', 'Submit'))
+
+ class Meta:
+ model = BomItem
+ fields = [
+ 'part',
+ 'sub_part',
+ 'quantity'
]
\ No newline at end of file
diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py
index 9064cd4b40..f08f8da4d8 100644
--- a/InvenTree/part/models.py
+++ b/InvenTree/part/models.py
@@ -201,6 +201,9 @@ class BomItem(models.Model):
which parts are required (and in what quatity) to make it
"""
+ def get_absolute_url(self):
+ return '/part/bom/{id}/'.format(id=self.id)
+
# A link to the parent part
# Each part will get a reverse lookup field 'bom_items'
part = models.ForeignKey(Part, on_delete=models.CASCADE, related_name='bom_items')
diff --git a/InvenTree/part/templates/part/bom-create.html b/InvenTree/part/templates/part/bom-create.html
new file mode 100644
index 0000000000..7db3161c84
--- /dev/null
+++ b/InvenTree/part/templates/part/bom-create.html
@@ -0,0 +1,5 @@
+{% extends 'create_edit_obj.html' %}
+
+{% block obj_title %}
+Create a new BOM item
+{% endblock %}
\ No newline at end of file
diff --git a/InvenTree/part/templates/part/bom-delete.html b/InvenTree/part/templates/part/bom-delete.html
new file mode 100644
index 0000000000..4cf9c8524e
--- /dev/null
+++ b/InvenTree/part/templates/part/bom-delete.html
@@ -0,0 +1,15 @@
+{% extends "delete_obj.html" %}
+
+{% block del_title %}
+ Are you sure you want to delete this BOM item?
+{% endblock %}
+
+{% block del_body %}
+ Deleting this entry will remove the BOM row from the following part:
+
+
+ -
+ {{ item.part.name }} - {{ item.part.description }}
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/InvenTree/part/templates/part/bom-detail.html b/InvenTree/part/templates/part/bom-detail.html
new file mode 100644
index 0000000000..93eb5c2e18
--- /dev/null
+++ b/InvenTree/part/templates/part/bom-detail.html
@@ -0,0 +1,18 @@
+{% extends "base.html" %}
+
+{% block content %}
+
+BOM Item
+
+
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/InvenTree/part/templates/part/bom-edit.html b/InvenTree/part/templates/part/bom-edit.html
new file mode 100644
index 0000000000..91a503004c
--- /dev/null
+++ b/InvenTree/part/templates/part/bom-edit.html
@@ -0,0 +1,5 @@
+{% extends 'create_edit_obj.html' %}
+
+{% block obj_title %}
+Edit details for BOM item
+{% endblock %}
\ No newline at end of file
diff --git a/InvenTree/part/templates/part/bom.html b/InvenTree/part/templates/part/bom.html
index f3db81216f..24046b5ca4 100644
--- a/InvenTree/part/templates/part/bom.html
+++ b/InvenTree/part/templates/part/bom.html
@@ -21,4 +21,10 @@
{% endfor %}
+
+
{% endblock %}
\ No newline at end of file
diff --git a/InvenTree/part/templates/part/used_in.html b/InvenTree/part/templates/part/used_in.html
index 1168f0c26b..2b3f55ef19 100644
--- a/InvenTree/part/templates/part/used_in.html
+++ b/InvenTree/part/templates/part/used_in.html
@@ -13,7 +13,7 @@ This part is used to make the following parts:
{% for item in part.used_in.all %}
- {{ item.part.name }} |
+ {{ item.part.name }} |
{{ item.part.description }} |
{% endfor %}
diff --git a/InvenTree/part/urls.py b/InvenTree/part/urls.py
index c3971aab91..c98cba695b 100644
--- a/InvenTree/part/urls.py
+++ b/InvenTree/part/urls.py
@@ -57,6 +57,13 @@ part_category_urls = [
url('^.*$', views.CategoryDetail.as_view(), name='category-detail'),
]
+part_bom_urls = [
+ url(r'^edit/?', views.BomItemEdit.as_view(), name='bom-item-edit'),
+ url('^delete/?', views.BomItemDelete.as_view(), name='bom-item-delete'),
+
+ url(r'^.*$', views.BomItemDetail.as_view(), name='bom-item-detail'),
+]
+
# URL list for part web interface
part_urls = [
@@ -66,12 +73,17 @@ part_urls = [
# Create a new part
url(r'^new/?', views.PartCreate.as_view(), name='part-create'),
- # Individual
+ # Create a new BOM item
+ url(r'^bom/new/?', views.BomItemCreate.as_view(), name='bom-item-create'),
+
+ # Individual part
url(r'^(?P\d+)/', include(part_detail_urls)),
# Part category
url(r'^category/(?P\d+)/', include(part_category_urls)),
+ url(r'^bom/(?P\d+)/', include(part_bom_urls)),
+
# Top level part list (display top level parts and categories)
url('', views.PartIndex.as_view(), name='part-index'),
diff --git a/InvenTree/part/views.py b/InvenTree/part/views.py
index e0022d2593..5ade502688 100644
--- a/InvenTree/part/views.py
+++ b/InvenTree/part/views.py
@@ -1,5 +1,6 @@
from InvenTree.models import FilterChildren
-from .models import PartCategory, Part
+
+from .models import PartCategory, Part, BomItem
from django.shortcuts import get_object_or_404, render
from django.http import HttpResponseRedirect
@@ -8,7 +9,7 @@ from django.urls import reverse
from django.views.generic import DetailView, ListView
from django.views.generic.edit import UpdateView, DeleteView, CreateView
-from .forms import EditPartForm, EditCategoryForm
+from .forms import EditPartForm, EditCategoryForm, EditBomItemForm
class PartIndex(ListView):
model = Part
@@ -146,3 +147,47 @@ class CategoryCreate(CreateView):
initials['parent'] = get_object_or_404(PartCategory, pk=parent_id)
return initials
+
+
+class BomItemDetail(DetailView):
+ context_object_name ='item'
+ queryset = BomItem.objects.all()
+ template_name = 'part/bom-detail.html'
+
+
+class BomItemCreate(CreateView):
+ model = BomItem
+ form_class = EditBomItemForm
+ template_name = 'part/bom-create.html'
+
+ def get_initial(self):
+ # Look for initial values
+ initials = super(BomItemCreate, self).get_initial().copy()
+
+ # Parent part for this item?
+ parent_id = self.request.GET.get('parent', None)
+
+ if parent_id:
+ initials['part'] = get_object_or_404(Part, pk=parent_id)
+
+ return initials
+
+
+class BomItemEdit(UpdateView):
+ model = BomItem
+ form_class = EditBomItemForm
+ template_name = 'part/bom-edit.html'
+
+
+class BomItemDelete(DeleteView):
+ model = BomItem
+ template_name = 'part/bom-delete.html'
+ context_object_name = 'item'
+
+ success_url = '/part'
+
+ def post(self, request, *args, **kwargs):
+ if 'confirm' in request.POST:
+ return super(BomItemDelete, self).post(request, *args, **kwargs)
+ else:
+ return HttpResponseRedirect(self.get_object().get_absolute_url())