mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Converting more forms to the API (#3181)
* Delete category via the API * Delete StockLocation via the API * Delete StockItem via the API - Removes the final instance of AjaxDelete * Remove URL path * Add missing code
This commit is contained in:
parent
63f1e58ca9
commit
090f4f4387
@ -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."""
|
||||
|
||||
|
@ -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."""
|
||||
|
||||
|
@ -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 %}
|
||||
|
@ -1,32 +0,0 @@
|
||||
{% extends "modal_delete_form.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block pre_form_content %}
|
||||
|
||||
<div class='alert alert-block alert-danger'>
|
||||
{% trans "Are you sure you want to delete this part category?" %}
|
||||
</div>
|
||||
|
||||
{% if category.children.all|length > 0 %}
|
||||
<div class='alert alert-block alert-warning'>
|
||||
{% blocktrans with n=category.children.all|length %}This category contains {{ n }} child categories{% endblocktrans %}.<br>
|
||||
{% 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 %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if category.parts.all|length > 0 %}
|
||||
<div class='alert alert-block alert-warning'>
|
||||
{% blocktrans with n=category.parts.all|length %}This category contains {{ n }} parts{% endblocktrans %}.<br>
|
||||
{% 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 %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
@ -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<pk>\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<pk>\d+)/', views.CategoryDetail.as_view(), name='category-detail'),
|
||||
]
|
||||
|
||||
# URL list for part web interface
|
||||
|
@ -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'),
|
||||
}
|
||||
|
@ -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() {
|
||||
|
||||
|
@ -1,15 +0,0 @@
|
||||
{% extends "modal_delete_form.html" %}
|
||||
|
||||
{% load i18n %}
|
||||
{% load inventree_extras %}
|
||||
|
||||
{% block pre_form_content %}
|
||||
|
||||
<div class='alert alert-danger alert-block'>
|
||||
{% trans "Are you sure you want to delete this stock item?" %}
|
||||
<br>
|
||||
{% decimal item.quantity as qty %}
|
||||
{% blocktrans with full_name=item.part.full_name %}This will remove <strong>{{qty}}</strong> units of <strong>{{full_name}}</strong> from stock.{% endblocktrans %}
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
@ -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 %}",
|
||||
{
|
||||
|
@ -1,34 +0,0 @@
|
||||
{% extends "modal_delete_form.html" %}
|
||||
|
||||
{% load i18n %}
|
||||
{% load inventree_extras %}
|
||||
|
||||
{% block pre_form_content %}
|
||||
<div class='alert alert-block alert-danger'>
|
||||
{% trans "Are you sure you want to delete this stock location?" %}
|
||||
</div>
|
||||
|
||||
{% if location.children.all|length > 0 %}
|
||||
<div class='alert alert-block alert-warning'>
|
||||
{% blocktrans with n=location.children.all|length %}This location contains {{ n }} child locations{% endblocktrans %}.<br>
|
||||
{% 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 %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if location.stock_items.all|length > 0 %}
|
||||
<div class='alert alert-block alert-warning'>
|
||||
{% blocktrans with n=location.stock_items.all|length %}This location contains {{ n }} stock items{% endblocktrans %}.<br>
|
||||
{% 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 %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
@ -7,7 +7,6 @@ from stock import views
|
||||
location_urls = [
|
||||
|
||||
re_path(r'^(?P<pk>\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
|
||||
|
@ -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')
|
||||
|
@ -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 = `
|
||||
<div class='alert alert-block alert-danger'>
|
||||
{% trans "Are you sure you want to delete this part category?" %}
|
||||
<ul>
|
||||
<li>{% trans "Any child categories will be moved to the parent of this category" %}</li>
|
||||
<li>{% trans "Any parts in this category will be moved to the parent of this category" %}</li>
|
||||
</ul>
|
||||
</div>`;
|
||||
|
||||
constructForm(url, {
|
||||
title: '{% trans "Delete Part Category" %}',
|
||||
method: 'DELETE',
|
||||
preFormContent: html,
|
||||
onSuccess: function(response) {
|
||||
handleFormSuccess(response, options);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 = `
|
||||
<div class='alert alert-block alert-danger'>
|
||||
{% trans "Are you sure you want to delete this stock location?" %}
|
||||
<ul>
|
||||
<li>{% trans "Any child locations will be moved to the parent of this location" %}</li>
|
||||
<li>{% trans "Any stock items in this location will be moved to the parent of this location" %}</li>
|
||||
</ul>
|
||||
</div>
|
||||
`;
|
||||
|
||||
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 = `
|
||||
<div class='alert alert-block alert-danger'>
|
||||
{% trans "Are you sure you want to delete this stock item?" %}
|
||||
</div>`;
|
||||
|
||||
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
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user