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: + + +{% 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

+ + + + +
Parent{{ item.part.name }}
Child{{ item.sub_part.name }}
Quantity{{ item.quantity }}
+ +
+ + + +
+ +{% 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())