diff --git a/InvenTree/part/forms.py b/InvenTree/part/forms.py index d0e1046448..2042ce4aff 100644 --- a/InvenTree/part/forms.py +++ b/InvenTree/part/forms.py @@ -12,7 +12,7 @@ class EditPartForm(forms.ModelForm): self.helper = FormHelper() self.helper.form_id = 'id-edit-part-form' - self.helper.form_class = 'blueForms' + #self.helper.form_class = 'blueForms' self.helper.form_method = 'post' #self.helper.form_action = 'submit' @@ -38,7 +38,7 @@ class EditCategoryForm(forms.ModelForm): self.helper = FormHelper() self.helper.form_id = 'id-edit-part-form' - self.helper.form_class = 'blueForms' + #self.helper.form_class = 'blueForms' self.helper.form_method = 'post' #self.helper.form_action = 'submit' diff --git a/InvenTree/part/templates/create_edit_obj.html b/InvenTree/part/templates/create_edit_obj.html new file mode 100644 index 0000000000..cc18a791b3 --- /dev/null +++ b/InvenTree/part/templates/create_edit_obj.html @@ -0,0 +1,19 @@ +{% extends "base.html" %} + +{% load static %} + +{% block content %} + +
+
+{% block obj_title %} + Object title goes here +{% endblock %} +
+
+{% load crispy_forms_tags %} +{% crispy form %} +
+
+ +{% endblock %} \ No newline at end of file diff --git a/InvenTree/part/templates/delete_obj.html b/InvenTree/part/templates/delete_obj.html new file mode 100644 index 0000000000..2b85af7061 --- /dev/null +++ b/InvenTree/part/templates/delete_obj.html @@ -0,0 +1,26 @@ +{% extends "base.html" %} + +{% block content %} + +
+
+{% block del_title %} +Deletion title goes here +{% endblock %} +
+
+

This is a permanent action and cannot be undone.

+ +{% block del_body %} +Deletion body goes here +{% endblock %} + +
{% csrf_token %} + + +
+ +
+
+ +{% endblock %} \ No newline at end of file diff --git a/InvenTree/part/templates/part/category_delete.html b/InvenTree/part/templates/part/category_delete.html index 03be834e30..960edbbaa1 100644 --- a/InvenTree/part/templates/part/category_delete.html +++ b/InvenTree/part/templates/part/category_delete.html @@ -1,12 +1,10 @@ -{% extends 'base.html' %} +{% extends 'delete_obj.html' %} -{% block content %} +{% block del_title %} +Are you sure you want to delete category '{{ category.name }}'? +{% endblock %} -
-
Are you sure you want to delete category '{{ category.name }}'?
-
- -

Deleting this category is a permanent action and cannot be undone.

+{% block del_body %} {% if category.children.all|length > 0 %}

This category contains {{ category.children.all|length }} child categories.
@@ -40,11 +38,4 @@ {% endif %} -

{% csrf_token %} - - -
-
-
- {% endblock %} \ No newline at end of file diff --git a/InvenTree/part/templates/part/category_detail.html b/InvenTree/part/templates/part/category_detail.html index 830ddb5b25..ed9fc8f996 100644 --- a/InvenTree/part/templates/part/category_detail.html +++ b/InvenTree/part/templates/part/category_detail.html @@ -17,10 +17,10 @@
- + - + diff --git a/InvenTree/part/templates/part/category_edit.html b/InvenTree/part/templates/part/category_edit.html index 101ec0a167..fb71df0161 100644 --- a/InvenTree/part/templates/part/category_edit.html +++ b/InvenTree/part/templates/part/category_edit.html @@ -1,16 +1,5 @@ -{% extends "base.html" %} - -{% block content %} - -{% include "part/cat_link.html" with category=category %} - -
-
Edit details for category '{{ category.name }}'
-
-{% load crispy_forms_tags %} - -{% crispy form %} -
-
+{% extends "create_edit_obj.html" %} +{% block obj_title %} +Edit category '{{ category.name }}' {% endblock %} \ No newline at end of file diff --git a/InvenTree/part/templates/part/category_new.html b/InvenTree/part/templates/part/category_new.html index e46bdea222..807352cd58 100644 --- a/InvenTree/part/templates/part/category_new.html +++ b/InvenTree/part/templates/part/category_new.html @@ -1,16 +1,5 @@ -{% extends "base.html" %} - -{% load static %} - -{% block content %} - -{% include "part/cat_link.html" with category=category %} - -
-
Create a new part category{% if category %} in category '{{ category.name }}'{% endif %}
-
- -{% load crispy_forms_tags %} -{% crispy form %} +{% extends "create_edit_obj.html" %} +{% block obj_title %} +Create a new part category{% if category %} in category '{{ category.name }}'{% endif %} {% endblock %} \ No newline at end of file diff --git a/InvenTree/part/templates/part/create.html b/InvenTree/part/templates/part/create.html index 35155906fe..1b6fc8ae89 100644 --- a/InvenTree/part/templates/part/create.html +++ b/InvenTree/part/templates/part/create.html @@ -1,18 +1,5 @@ -{% extends "base.html" %} - -{% load static %} - -{% block content %} - -{% include "part/cat_link.html" with category=category %} - -
-
Create a new part{% if category %} in category '{{ category.name }}'{% endif %}
-
- -{% load crispy_forms_tags %} -{% crispy form %} - -
+{% extends "create_edit_obj.html" %} +{% block obj_title %} +Create a new part{% if category %} in category '{{ category.name }}'{% endif %} {% endblock %} diff --git a/InvenTree/part/templates/part/delete.html b/InvenTree/part/templates/part/delete.html index b46eedd5f6..df28dc82d8 100644 --- a/InvenTree/part/templates/part/delete.html +++ b/InvenTree/part/templates/part/delete.html @@ -1,12 +1,11 @@ -{% extends 'part/part_base.html' %} +{% extends "delete_obj.html" %} -{% block details %} -
-
Are you sure you want to delete part '{{ part.name }}'?
-
+{% block del_title %} + Are you sure you want to delete part '{{ part.name }}'? +{% endblock %} -

Deleting this part is a permanent action and cannot be undone.

+{% block del_body %} {% if part.usedInCount > 0 %}

This part is used in BOMs for {{ part.usedInCount }} other parts. If you delete this part, the BOMs for the following parts will be updated: @@ -41,11 +40,4 @@

There are {{ part.serials.all|length }} unique parts tracked for '{{ part.name }}'. Deleting this part will permanently remove this tracking information.

{% endif %} -
{% csrf_token %} - - -
- -
-
{% endblock %} \ No newline at end of file diff --git a/InvenTree/part/templates/part/edit.html b/InvenTree/part/templates/part/edit.html index 4e943ff22f..63917e7846 100644 --- a/InvenTree/part/templates/part/edit.html +++ b/InvenTree/part/templates/part/edit.html @@ -1,15 +1,5 @@ -{% extends "part/part_base.html" %} - -{% block details %} - -
-
Edit details for part '{{ part.name }}'
-
- -{% load crispy_forms_tags %} - -{% crispy form %} - -
+{% extends "create_edit_obj.html" %} +{% block obj_title %} +Edit details for part '{{ part.name }}' {% endblock %} \ No newline at end of file diff --git a/InvenTree/part/templates/part/index.html b/InvenTree/part/templates/part/index.html index e2c2c6c70b..6d7496e679 100644 --- a/InvenTree/part/templates/part/index.html +++ b/InvenTree/part/templates/part/index.html @@ -11,10 +11,10 @@
{% endblock %} diff --git a/InvenTree/part/urls.py b/InvenTree/part/urls.py index 2277f24f77..c3971aab91 100644 --- a/InvenTree/part/urls.py +++ b/InvenTree/part/urls.py @@ -4,8 +4,6 @@ from django.views.generic.base import RedirectView from . import views from . import api -app_nam='part' - # URL list for part category API part_cat_api_urls = [ @@ -63,7 +61,7 @@ part_category_urls = [ part_urls = [ # Create a new category - url(r'^new_category/?', views.CategoryCreate.as_view(), name='category-create'), + url(r'^category/new/?', views.CategoryCreate.as_view(), name='category-create'), # Create a new part url(r'^new/?', views.PartCreate.as_view(), name='part-create'), diff --git a/InvenTree/supplier/forms.py b/InvenTree/supplier/forms.py new file mode 100644 index 0000000000..96007a41c8 --- /dev/null +++ b/InvenTree/supplier/forms.py @@ -0,0 +1,57 @@ +from django import forms +from crispy_forms.helper import FormHelper +from crispy_forms.layout import Submit + +from .models import Supplier, SupplierPart + + +class EditSupplierForm(forms.ModelForm): + + def __init__(self, *args, **kwargs): + super(EditSupplierForm, 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 = Supplier + fields = [ + 'name', + 'description', + 'website', + 'address', + 'phone', + 'email', + 'contact', + 'notes' + ] + + +class EditSupplierPartForm(forms.ModelForm): + def __init__(self, *args, **kwargs): + super(EditSupplierPartForm, 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 = SupplierPart + fields = [ + 'supplier', + 'SKU', + 'part', + 'description', + 'URL', + 'manufacturer', + 'MPN', + ] \ No newline at end of file diff --git a/InvenTree/supplier/models.py b/InvenTree/supplier/models.py index 1a3a10b86a..459965f309 100644 --- a/InvenTree/supplier/models.py +++ b/InvenTree/supplier/models.py @@ -10,7 +10,9 @@ from part.models import Part class Supplier(Company): """ Represents a manufacturer or supplier """ - pass + + def get_absolute_url(self): + return "/supplier/{id}/".format(id=self.id) class Manufacturer(Company): @@ -32,12 +34,15 @@ class SupplierPart(models.Model): - A Part may be available from multiple suppliers """ + def get_absolute_url(self): + return "/supplier/part/{id}/".format(id=self.id) + class Meta: unique_together = ('part', 'supplier', 'SKU') # Link to an actual part # The part will have a field 'supplier_parts' which links to the supplier part options - part = models.ForeignKey(Part, null=True, blank=True, on_delete=models.CASCADE, + part = models.ForeignKey(Part, null=True, blank=True, on_delete=models.SET_NULL, related_name='supplier_parts') supplier = models.ForeignKey(Supplier, on_delete=models.CASCADE, @@ -46,7 +51,7 @@ class SupplierPart(models.Model): SKU = models.CharField(max_length=100) - manufacturer = models.ForeignKey(Manufacturer, blank=True, null=True, on_delete=models.CASCADE) + manufacturer = models.ForeignKey(Manufacturer, blank=True, null=True, on_delete=models.SET_NULL) MPN = models.CharField(max_length=100, blank=True) URL = models.URLField(blank=True) diff --git a/InvenTree/supplier/templates/supplier/create.html b/InvenTree/supplier/templates/supplier/create.html new file mode 100644 index 0000000000..b01ab9e9f9 --- /dev/null +++ b/InvenTree/supplier/templates/supplier/create.html @@ -0,0 +1,5 @@ +{% extends "create_edit_obj.html" %} + +{% block obj_title %} +Create a new supplier +{% endblock %} diff --git a/InvenTree/supplier/templates/supplier/delete.html b/InvenTree/supplier/templates/supplier/delete.html new file mode 100644 index 0000000000..1e3d63fec7 --- /dev/null +++ b/InvenTree/supplier/templates/supplier/delete.html @@ -0,0 +1,17 @@ +{% extends "delete_obj.html" %} + +{% block del_title %} +Are you sure you want to delete supplier '{{ supplier.name }}'? +{% endblock %} + +{% block del_body %} +{% if supplier.parts.all|length > 0 %} +

There are {{ supplier.parts.all|length }} parts sourced from this supplier.
+If this supplier is deleted, these child categories will also be deleted.

+
    +{% for part in supplier.parts.all %} +
  • {{ part.SKU }}Part - {{ part.part.name }}
  • +{% endfor %} +
+{% endif %} +{% endblock %} \ No newline at end of file diff --git a/InvenTree/supplier/templates/supplier/detail.html b/InvenTree/supplier/templates/supplier/detail.html index 8674c34878..bba1a8b892 100644 --- a/InvenTree/supplier/templates/supplier/detail.html +++ b/InvenTree/supplier/templates/supplier/detail.html @@ -6,6 +6,12 @@

{{ supplier.name }}

{{ supplier.description }}

+

+ +

+

+ +

@@ -38,7 +44,7 @@ -{% if supplier.parts.all|length > 0 %} +

Supplier Parts

@@ -50,14 +56,20 @@ {% for part in supplier.parts.all %} - + {% endfor %}
SKU
{{ part.SKU }}{{ part.part.name }} + {% if part.part %} + {{ part.part.name }} + {% endif %} + Manufacturer name goes here MPN goes here {{ part.URL }}
-{% else %} -There are currently no parts sourced from this supplier. -{% endif %} + +
+ + + {% endblock %} \ No newline at end of file diff --git a/InvenTree/supplier/templates/supplier/edit.html b/InvenTree/supplier/templates/supplier/edit.html new file mode 100644 index 0000000000..3e07e93362 --- /dev/null +++ b/InvenTree/supplier/templates/supplier/edit.html @@ -0,0 +1,5 @@ +{% extends "create_edit_obj.html" %} + +{% block obj_title %} +Edit details for supplier '{{ supplier.name }}' +{% endblock %} \ No newline at end of file diff --git a/InvenTree/supplier/templates/supplier/index.html b/InvenTree/supplier/templates/supplier/index.html index 7ea5193e6c..bce8b9d96e 100644 --- a/InvenTree/supplier/templates/supplier/index.html +++ b/InvenTree/supplier/templates/supplier/index.html @@ -19,4 +19,10 @@ {% endfor %} + + {% endblock %} \ No newline at end of file diff --git a/InvenTree/supplier/templates/supplier/partcreate.html b/InvenTree/supplier/templates/supplier/partcreate.html new file mode 100644 index 0000000000..bee5cbefc8 --- /dev/null +++ b/InvenTree/supplier/templates/supplier/partcreate.html @@ -0,0 +1,5 @@ +{% extends "create_edit_obj.html" %} + +{% block obj_title %} +Create a new supplier part +{% endblock %} \ No newline at end of file diff --git a/InvenTree/supplier/templates/supplier/partdelete.html b/InvenTree/supplier/templates/supplier/partdelete.html new file mode 100644 index 0000000000..53d8edac13 --- /dev/null +++ b/InvenTree/supplier/templates/supplier/partdelete.html @@ -0,0 +1,5 @@ +{% extends 'delete_obj.html' %} + +{% block del_title %} +Are you sure you want to delete this supplier part? +{% endblock %} \ No newline at end of file diff --git a/InvenTree/supplier/templates/supplier/partdetail.html b/InvenTree/supplier/templates/supplier/partdetail.html index d561c4c395..3c1fa315e0 100644 --- a/InvenTree/supplier/templates/supplier/partdetail.html +++ b/InvenTree/supplier/templates/supplier/partdetail.html @@ -2,13 +2,39 @@ {% block content %} - +

Supplier part information

+ + + + + + + + +{% if part.URL %} + +{% endif %} +{% if part.description %} + +{% endif %} +{% if part.manufacturer %} + + +{% endif %} +
SKU{{ part.SKU }}
Supplier{{ part.supplier.name }}
Part + {% if part.part %} + {{ part.part.name }} + {% endif %} +
{{ part.URL }}
Description{{ part.description }}
ManufacturerTODO
MPNTODO
+ +
+ +

+ +

+

+ +

+ {% endblock %} \ No newline at end of file diff --git a/InvenTree/supplier/templates/supplier/partedit.html b/InvenTree/supplier/templates/supplier/partedit.html new file mode 100644 index 0000000000..f4c78cd39d --- /dev/null +++ b/InvenTree/supplier/templates/supplier/partedit.html @@ -0,0 +1,5 @@ +{% extends "create_edit_obj.html" %} + +{% block obj_title %} +Edit supplier part '{{ part.SKU }}' +{% endblock %} \ No newline at end of file diff --git a/InvenTree/supplier/urls.py b/InvenTree/supplier/urls.py index 3548c59f5d..81ece4a1aa 100644 --- a/InvenTree/supplier/urls.py +++ b/InvenTree/supplier/urls.py @@ -49,14 +49,25 @@ supplier_api_urls = [ """ supplier_detail_urls = [ - #url(r'edit/?', views.SupplierEdit.as_view(), name='supplier-edit'), - #url(r'delete/?', views.SupplierDelete.as_view(), name='supplier-delete'), + url(r'edit/?', views.SupplierEdit.as_view(), name='supplier-edit'), + url(r'delete/?', views.SupplierDelete.as_view(), name='supplier-delete'), url(r'^.*$', views.SupplierDetail.as_view(), name='supplier-detail'), ] +supplier_part_detail_urls = [ + url(r'edit/?', views.SupplierPartEdit.as_view(), name='supplier-part-edit'), + url(r'delete/?', views.SupplierPartDelete.as_view(), name='supplier-part-delete'), + + url('^.*$', views.SupplierPartDetail.as_view(), name='supplier-part-detail'), +] + supplier_urls = [ - url(r'^part/(?P\d+)/', views.partDetail, name='supplier-part-detail'), + url(r'part/(?P\d+)/', include(supplier_part_detail_urls)), + + url(r'part/new/?', views.SupplierPartCreate.as_view(), name='supplier-part-create'), + + url(r'new/?', views.SupplierCreate.as_view(), name='supplier-create'), url(r'^(?P\d+)/', include(supplier_detail_urls)), diff --git a/InvenTree/supplier/views.py b/InvenTree/supplier/views.py index d90fe28309..d3e03e1b66 100644 --- a/InvenTree/supplier/views.py +++ b/InvenTree/supplier/views.py @@ -7,6 +7,9 @@ from django.views.generic.edit import UpdateView, DeleteView, CreateView from .models import Supplier, SupplierPart +from .forms import EditSupplierForm +from .forms import EditSupplierPartForm + class SupplierIndex(ListView): model = Supplier template_name = 'supplier/index.html' @@ -18,16 +21,75 @@ class SupplierIndex(ListView): class SupplierDetail(DetailView): - context_obect = 'supplier' + context_obect_name = 'supplier' template_name = 'supplier/detail.html' queryset = Supplier.objects.all() + model = Supplier -def partDetail(request, pk): - """ The supplier part-detail page shows detailed information - on a particular supplier part - """ +class SupplierEdit(UpdateView): + model = Supplier + form_class = EditSupplierForm + template_name = 'supplier/edit.html' + context_object_name = 'supplier' - part = get_object_or_404(SupplierPart, pk=pk) - return render(request, 'supplier/partdetail.html', {'part': part}) \ No newline at end of file +class SupplierCreate(CreateView): + model = Supplier + form_class = EditSupplierForm + template_name = "supplier/create.html" + + +class SupplierDelete(DeleteView): + model = Supplier + success_url = '/supplier/' + template_name = 'supplier/delete.html' + + def post(self, request, *args, **kwargs): + if 'confirm' in request.POST: + return super(SupplierDelete, self).post(request, *args, **kwargs) + else: + return HttpResponseRedirect(self.get_object().get_absolute_url()) + + +class SupplierPartDetail(DetailView): + model = SupplierPart + template_name = 'supplier/partdetail.html' + context_object_name = 'part' + queryset = SupplierPart.objects.all() + + +class SupplierPartEdit(UpdateView): + model = SupplierPart + template_name = 'supplier/partedit.html' + context_object_name = 'part' + form_class = EditSupplierPartForm + + +class SupplierPartCreate(CreateView): + model = SupplierPart + form_class = EditSupplierPartForm + template_name = 'supplier/partcreate.html' + context_object_name = 'part' + + def get_initial(self): + initials = super(SupplierPartCreate, self).get_initial().copy() + + supplier_id = self.request.GET.get('supplier', None) + + if supplier_id: + initials['supplier'] = get_object_or_404(Supplier, pk=supplier_id) + + return initials + + +class SupplierPartDelete(DeleteView): + model = SupplierPart + success_url = '/supplier/' + template_name = 'supplier/partdelete.html' + + def post(self, request, *args, **kwargs): + if 'confirm' in request.POST: + return super(SupplierPartDelete, self).post(request, *args, **kwargs) + else: + return HttpResponseRedirect(self.get_object().get_absolute_url())