diff --git a/InvenTree/InvenTree/forms.py b/InvenTree/InvenTree/forms.py index 04e95120e4..6116cd0b36 100644 --- a/InvenTree/InvenTree/forms.py +++ b/InvenTree/InvenTree/forms.py @@ -108,24 +108,6 @@ class HelperForm(forms.ModelForm): self.helper.layout = Layout(*layouts) -class DeleteForm(forms.Form): - """Generic deletion form which provides simple user confirmation.""" - - confirm_delete = forms.BooleanField( - required=False, - initial=False, - label=_('Confirm delete'), - help_text=_('Confirm item deletion') - ) - - class Meta: - """Metaclass options.""" - - fields = [ - 'confirm_delete' - ] - - class EditUserForm(HelperForm): """Form for editing user information.""" diff --git a/InvenTree/InvenTree/views.py b/InvenTree/InvenTree/views.py index cb5d1be51f..5a0c24e373 100644 --- a/InvenTree/InvenTree/views.py +++ b/InvenTree/InvenTree/views.py @@ -34,8 +34,7 @@ from common.settings import currency_code_default, currency_codes from part.models import PartCategory from users.models import RuleSet, check_user_role -from .forms import DeleteForm, EditUserForm, SetPasswordForm -from .helpers import str2bool +from .forms import EditUserForm, SetPasswordForm def auth_request(request): @@ -510,74 +509,6 @@ class AjaxUpdateView(AjaxMixin, UpdateView): return self.renderJsonResponse(request, form, data) -class AjaxDeleteView(AjaxMixin, UpdateView): - """An 'AJAXified DeleteView for removing an object from the DB. - - - Returns a HTML object (not a form!) in JSON format (for delivery to a modal window) - - Handles deletion - """ - - form_class = DeleteForm - ajax_form_title = _("Delete Item") - ajax_template_name = "modal_delete_form.html" - context_object_name = 'item' - - def get_object(self): - """Return object matched to the model of the calling class.""" - try: - self.object = self.model.objects.get(pk=self.kwargs['pk']) - except Exception: - return None - return self.object - - def get_form(self): - """Returns a form instance for the form_class of the calling class.""" - return self.form_class(self.get_form_kwargs()) - - def get(self, request, *args, **kwargs): - """Respond to GET request. - - - Render a DELETE confirmation form to JSON - - Return rendered form to client - """ - super(UpdateView, self).get(request, *args, **kwargs) - - form = self.get_form() - - context = self.get_context_data() - - context[self.context_object_name] = self.get_object() - - return self.renderJsonResponse(request, form, context=context) - - def post(self, request, *args, **kwargs): - """Respond to POST request. - - - DELETE the object - - Render success message to JSON and return to client - """ - obj = self.get_object() - pk = obj.id - - form = self.get_form() - - confirmed = str2bool(request.POST.get('confirm_delete', False)) - context = self.get_context_data() - - if confirmed: - obj.delete() - else: - form.add_error('confirm_delete', _('Check box to confirm item deletion')) - context[self.context_object_name] = self.get_object() - - data = { - 'id': pk, - 'form_valid': confirmed - } - - return self.renderJsonResponse(request, form, data=data, context=context) - - class EditUserView(AjaxUpdateView): """View for editing user information.""" diff --git a/InvenTree/part/templates/part/category.html b/InvenTree/part/templates/part/category.html index 146b22abcc..49e49f2931 100644 --- a/InvenTree/part/templates/part/category.html +++ b/InvenTree/part/templates/part/category.html @@ -347,23 +347,18 @@ {% if category %} $("#cat-edit").click(function () { - editCategory({{ category.pk }}); }); - {% if category.parent %} - var redirect = "{% url 'category-detail' category.parent.id %}"; - {% else %} - var redirect = "{% url 'part-index' %}"; - {% endif %} $('#cat-delete').click(function() { - launchModalForm( - "{% url 'category-delete' category.id %}", - { - redirect: redirect - } - ); + deletePartCategory({{ category.pk }}, { + {% if category.parent %} + redirect: "{% url 'category-detail' category.parent.id %}", + {% else %} + redirect: "{% url 'part-index' %}", + {% endif %} + }); }); {% endif %} diff --git a/InvenTree/part/templates/part/category_delete.html b/InvenTree/part/templates/part/category_delete.html deleted file mode 100644 index a4bc847d20..0000000000 --- a/InvenTree/part/templates/part/category_delete.html +++ /dev/null @@ -1,32 +0,0 @@ -{% extends "modal_delete_form.html" %} -{% load i18n %} - -{% block pre_form_content %} - -
- {% trans "Are you sure you want to delete this part category?" %} -
- -{% if category.children.all|length > 0 %} -
- {% blocktrans with n=category.children.all|length %}This category contains {{ n }} child categories{% endblocktrans %}.
- {% if category.parent %} - {% blocktrans with category=category.parent.name %}If this category is deleted, these child categories will be moved to {{ category }}{% endblocktrans %}. - {% else %} - {% trans "If this category is deleted, these child categories will be moved to the top level part category" %}. - {% endif %} -
-{% endif %} - -{% if category.parts.all|length > 0 %} -
- {% blocktrans with n=category.parts.all|length %}This category contains {{ n }} parts{% endblocktrans %}.
- {% if category.parent %} - {% blocktrans with category=category.parent.name %}If this category is deleted, these parts will be moved to {{ category }}{% endblocktrans %}. - {% else %} - {% trans "If this category is deleted, these parts will be moved to the top level part category" %}. - {% endif %} -
-{% endif %} - -{% endblock %} diff --git a/InvenTree/part/urls.py b/InvenTree/part/urls.py index cc0bdbc4eb..0a0e114219 100644 --- a/InvenTree/part/urls.py +++ b/InvenTree/part/urls.py @@ -33,11 +33,7 @@ category_urls = [ re_path(r'^subcategory/', views.PartIndex.as_view(template_name='part/subcategory.html'), name='category-index-subcategory'), # Category detail views - re_path(r'(?P\d+)/', include([ - re_path(r'^delete/', views.CategoryDelete.as_view(), name='category-delete'), - # Anything else - re_path(r'^.*$', views.CategoryDetail.as_view(), name='category-detail'), - ])) + re_path(r'(?P\d+)/', views.CategoryDetail.as_view(), name='category-detail'), ] # URL list for part web interface diff --git a/InvenTree/part/views.py b/InvenTree/part/views.py index 9b6e699541..da9b372257 100644 --- a/InvenTree/part/views.py +++ b/InvenTree/part/views.py @@ -24,8 +24,8 @@ from common.models import InvenTreeSetting from common.views import FileManagementAjaxView, FileManagementFormView from company.models import SupplierPart from InvenTree.helpers import str2bool -from InvenTree.views import (AjaxDeleteView, AjaxUpdateView, AjaxView, - InvenTreeRoleMixin, QRCodeView) +from InvenTree.views import (AjaxUpdateView, AjaxView, InvenTreeRoleMixin, + QRCodeView) from order.models import PurchaseOrderLineItem from plugin.views import InvenTreePluginViewMixin from stock.models import StockItem, StockLocation @@ -875,18 +875,3 @@ class CategoryDetail(InvenTreeRoleMixin, InvenTreePluginViewMixin, DetailView): context['starred'] = category.is_starred_by(self.request.user) return context - - -class CategoryDelete(AjaxDeleteView): - """Delete view to delete a PartCategory.""" - model = PartCategory - ajax_template_name = 'part/category_delete.html' - ajax_form_title = _('Delete Part Category') - context_object_name = 'category' - success_url = '/part/' - - def get_data(self): - """Return custom context data when the category is deleted""" - return { - 'danger': _('Part category was deleted'), - } diff --git a/InvenTree/stock/templates/stock/item_base.html b/InvenTree/stock/templates/stock/item_base.html index c239ec0d09..19964e8b29 100644 --- a/InvenTree/stock/templates/stock/item_base.html +++ b/InvenTree/stock/templates/stock/item_base.html @@ -581,12 +581,9 @@ $('#stock-add').click(function() { }); $("#stock-delete").click(function () { - launchModalForm( - "{% url 'stock-item-delete' item.id %}", - { - redirect: "{% url 'part-detail' item.part.id %}" - } - ); + deleteStockItem({{ item.pk }}, { + redirect: '{% url "part-detail" item.part.pk %}', + }); }); {% if item.part.can_convert %} @@ -599,7 +596,6 @@ $("#stock-convert").click(function() { }); {% endif %} - {% if item.in_stock %} $("#stock-assign-to-customer").click(function() { diff --git a/InvenTree/stock/templates/stock/item_delete.html b/InvenTree/stock/templates/stock/item_delete.html deleted file mode 100644 index 087e0b5179..0000000000 --- a/InvenTree/stock/templates/stock/item_delete.html +++ /dev/null @@ -1,15 +0,0 @@ -{% extends "modal_delete_form.html" %} - -{% load i18n %} -{% load inventree_extras %} - -{% block pre_form_content %} - -
-{% trans "Are you sure you want to delete this stock item?" %} -
-{% decimal item.quantity as qty %} -{% blocktrans with full_name=item.part.full_name %}This will remove {{qty}} units of {{full_name}} from stock.{% endblocktrans %} -
- -{% endblock %} diff --git a/InvenTree/stock/templates/stock/location.html b/InvenTree/stock/templates/stock/location.html index b8a3a6cc29..5fd8312b2f 100644 --- a/InvenTree/stock/templates/stock/location.html +++ b/InvenTree/stock/templates/stock/location.html @@ -291,14 +291,15 @@ }); $('#location-delete').click(function() { - launchModalForm("{% url 'stock-location-delete' location.id %}", - { - redirect: "{% url 'stock-index' %}" - }); - return false; - }); - {% if location %} + deleteStockLocation({{ location.pk }}, { + {% if location.parent %} + redirect: '{% url "stock-location-detail" location.parent.pk %}', + {% else %} + redirect: '{% url "stock-index" %}', + {% endif %} + }); + }); function adjustLocationStock(action) { inventreeGet( @@ -329,8 +330,6 @@ adjustLocationStock('move'); }); - {% endif %} - $('#show-qr-code').click(function() { launchModalForm("{% url 'stock-location-qr' location.id %}", { diff --git a/InvenTree/stock/templates/stock/location_delete.html b/InvenTree/stock/templates/stock/location_delete.html deleted file mode 100644 index b4e4deb49d..0000000000 --- a/InvenTree/stock/templates/stock/location_delete.html +++ /dev/null @@ -1,34 +0,0 @@ -{% extends "modal_delete_form.html" %} - -{% load i18n %} -{% load inventree_extras %} - -{% block pre_form_content %} -
- {% trans "Are you sure you want to delete this stock location?" %} -
- -{% if location.children.all|length > 0 %} -
- {% blocktrans with n=location.children.all|length %}This location contains {{ n }} child locations{% endblocktrans %}.
- {% if location.parent %} - {% blocktrans with location=location.parent.name %}If this location is deleted, these child locations will be moved to {{ location }}{% endblocktrans %}. - {% else %} - {% trans "If this location is deleted, these child locations will be moved to the top level stock location" %}. - {% endif %} -
-{% endif %} - - -{% if location.stock_items.all|length > 0 %} -
- {% blocktrans with n=location.stock_items.all|length %}This location contains {{ n }} stock items{% endblocktrans %}.
- {% if location.parent %} - {% blocktrans with location=location.parent.name %}If this location is deleted, these stock items will be moved to {{ location }}{% endblocktrans %}. - {% else %} - {% trans "If this location is deleted, these stock items will be moved to the top level stock location" %}. - {% endif %} -
-{% endif %} - -{% endblock %} diff --git a/InvenTree/stock/urls.py b/InvenTree/stock/urls.py index f338116d72..6c4eec8d7e 100644 --- a/InvenTree/stock/urls.py +++ b/InvenTree/stock/urls.py @@ -7,7 +7,6 @@ from stock import views location_urls = [ re_path(r'^(?P\d+)/', include([ - re_path(r'^delete/?', views.StockLocationDelete.as_view(), name='stock-location-delete'), re_path(r'^qr_code/?', views.StockLocationQRCode.as_view(), name='stock-location-qr'), # Anything else - direct to the location detail view @@ -18,7 +17,6 @@ location_urls = [ stock_item_detail_urls = [ re_path(r'^convert/', views.StockItemConvert.as_view(), name='stock-item-convert'), - re_path(r'^delete/', views.StockItemDelete.as_view(), name='stock-item-delete'), re_path(r'^qr_code/', views.StockItemQRCode.as_view(), name='stock-item-qr'), # Anything else - direct to the item detail view diff --git a/InvenTree/stock/views.py b/InvenTree/stock/views.py index b16fd640de..267b8734d1 100644 --- a/InvenTree/stock/views.py +++ b/InvenTree/stock/views.py @@ -6,8 +6,7 @@ from django.utils.translation import gettext_lazy as _ from django.views.generic import DetailView, ListView import common.settings -from InvenTree.views import (AjaxDeleteView, AjaxUpdateView, - InvenTreeRoleMixin, QRCodeView) +from InvenTree.views import AjaxUpdateView, InvenTreeRoleMixin, QRCodeView from plugin.views import InvenTreePluginViewMixin from . import forms as StockForms @@ -163,29 +162,3 @@ class StockItemConvert(AjaxUpdateView): stock_item.convert_to_variant(variant, user=self.request.user) return stock_item - - -class StockLocationDelete(AjaxDeleteView): - """View to delete a StockLocation. - - Presents a deletion confirmation form to the user - """ - - model = StockLocation - success_url = '/stock' - ajax_template_name = 'stock/location_delete.html' - context_object_name = 'location' - ajax_form_title = _('Delete Stock Location') - - -class StockItemDelete(AjaxDeleteView): - """View to delete a StockItem. - - Presents a deletion confirmation form to the user - """ - - model = StockItem - success_url = '/stock/' - ajax_template_name = 'stock/item_delete.html' - context_object_name = 'item' - ajax_form_title = _('Delete Stock Item') diff --git a/InvenTree/templates/js/translated/part.js b/InvenTree/templates/js/translated/part.js index 707903c15a..1cc98fa57c 100644 --- a/InvenTree/templates/js/translated/part.js +++ b/InvenTree/templates/js/translated/part.js @@ -21,6 +21,7 @@ /* exported deletePart, + deletePartCategory, duplicateBom, duplicatePart, editCategory, @@ -317,7 +318,31 @@ function editCategory(pk) { title: '{% trans "Edit Part Category" %}', reload: true, }); +} +/* + * Delete a PartCategory via the API + */ +function deletePartCategory(pk, options={}) { + var url = `/api/part/category/${pk}/`; + + var html = ` +
+ {% trans "Are you sure you want to delete this part category?" %} +
    +
  • {% trans "Any child categories will be moved to the parent of this category" %}
  • +
  • {% trans "Any parts in this category will be moved to the parent of this category" %}
  • +
+
`; + + constructForm(url, { + title: '{% trans "Delete Part Category" %}', + method: 'DELETE', + preFormContent: html, + onSuccess: function(response) { + handleFormSuccess(response, options); + } + }); } diff --git a/InvenTree/templates/js/translated/stock.js b/InvenTree/templates/js/translated/stock.js index 4af520eca4..825e1a8094 100644 --- a/InvenTree/templates/js/translated/stock.js +++ b/InvenTree/templates/js/translated/stock.js @@ -39,6 +39,8 @@ assignStockToCustomer, createNewStockItem, createStockLocation, + deleteStockItem, + deleteStockLocation, duplicateStockItem, editStockItem, editStockLocation, @@ -156,6 +158,34 @@ function createStockLocation(options={}) { } +/* + * Launch an API form to delete a StockLocation + */ +function deleteStockLocation(pk, options={}) { + var url = `/api/stock/location/${pk}/`; + + var html = ` +
+ {% trans "Are you sure you want to delete this stock location?" %} +
    +
  • {% trans "Any child locations will be moved to the parent of this location" %}
  • +
  • {% trans "Any stock items in this location will be moved to the parent of this location" %}
  • +
+
+ `; + + constructForm(url, { + title: '{% trans "Delete Stock Location" %}', + method: 'DELETE', + preFormContent: html, + onSuccess: function(response) { + handleFormSuccess(response, options); + } + }); +} + + + function stockItemFields(options={}) { var fields = { part: { @@ -328,6 +358,28 @@ function duplicateStockItem(pk, options) { } +/* + * Launch a modal form to delete a given StockItem + */ +function deleteStockItem(pk, options={}) { + var url = `/api/stock/${pk}/`; + + var html = ` +
+ {% trans "Are you sure you want to delete this stock item?" %} +
`; + + constructForm(url, { + method: 'DELETE', + title: '{% trans "Delete Stock Item" %}', + preFormContent: html, + onSuccess: function(response) { + handleFormSuccess(response, options); + } + }); +} + + /* * Launch a modal form to edit a given StockItem */