2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-05-06 15:28:49 +00:00

Refactor stock item test result form for API (#3143)

* Fix "polarity" of modal form submit button

(cherry picked from commit 0e4550f28895af626715723e450792881f7fd882)

* Use existing API functionality to delete all test results for a particular StockItem

* Remove outdated forms / views
This commit is contained in:
Oliver 2022-06-06 21:27:19 +10:00 committed by GitHub
parent 121c5d107e
commit ea83d4b290
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 48 additions and 135 deletions

View File

@ -16,13 +16,12 @@ from allauth.exceptions import ImmediateHttpResponse
from allauth.socialaccount.adapter import DefaultSocialAccountAdapter from allauth.socialaccount.adapter import DefaultSocialAccountAdapter
from allauth_2fa.adapter import OTPAdapter from allauth_2fa.adapter import OTPAdapter
from allauth_2fa.utils import user_has_valid_totp_device from allauth_2fa.utils import user_has_valid_totp_device
from crispy_forms.bootstrap import (AppendedText, Div, PrependedAppendedText, from crispy_forms.bootstrap import (AppendedText, PrependedAppendedText,
PrependedText, StrictButton) PrependedText)
from crispy_forms.helper import FormHelper from crispy_forms.helper import FormHelper
from crispy_forms.layout import Field, Layout from crispy_forms.layout import Field, Layout
from common.models import InvenTreeSetting from common.models import InvenTreeSetting
from part.models import PartCategory
logger = logging.getLogger('inventree') logger = logging.getLogger('inventree')
@ -109,22 +108,6 @@ class HelperForm(forms.ModelForm):
self.helper.layout = Layout(*layouts) self.helper.layout = Layout(*layouts)
class ConfirmForm(forms.Form):
"""Generic confirmation form."""
confirm = forms.BooleanField(
required=False, initial=False,
help_text=_("Confirm")
)
class Meta:
"""Metaclass options."""
fields = [
'confirm'
]
class DeleteForm(forms.Form): class DeleteForm(forms.Form):
"""Generic deletion form which provides simple user confirmation.""" """Generic deletion form which provides simple user confirmation."""
@ -185,39 +168,6 @@ class SetPasswordForm(HelperForm):
] ]
class SettingCategorySelectForm(forms.ModelForm):
"""Form for setting category settings."""
category = forms.ModelChoiceField(queryset=PartCategory.objects.all())
class Meta:
"""Metaclass options."""
model = PartCategory
fields = [
'category'
]
def __init__(self, *args, **kwargs):
"""Setup form layout."""
super().__init__(*args, **kwargs)
self.helper = FormHelper()
# Form rendering
self.helper.form_show_labels = False
self.helper.layout = Layout(
Div(
Div(Field('category'),
css_class='col-sm-6',
style='width: 70%;'),
Div(StrictButton(_('Select Category'), css_class='btn btn-primary', type='submit'),
css_class='col-sm-6',
style='width: 30%; padding-left: 0;'),
css_class='row',
),
)
# override allauth # override allauth
class CustomSignupForm(SignupForm): class CustomSignupForm(SignupForm):
"""Override to use dynamic settings.""" """Override to use dynamic settings."""

View File

@ -37,7 +37,7 @@ from .views import (AppearanceSelectView, CurrencyRefreshView,
CustomSessionDeleteOtherView, CustomSessionDeleteView, CustomSessionDeleteOtherView, CustomSessionDeleteView,
DatabaseStatsView, DynamicJsView, EditUserView, IndexView, DatabaseStatsView, DynamicJsView, EditUserView, IndexView,
NotificationsView, SearchView, SetPasswordView, NotificationsView, SearchView, SetPasswordView,
SettingCategorySelectView, SettingsView, auth_request) SettingsView, auth_request)
admin.site.site_header = "InvenTree Admin" admin.site.site_header = "InvenTree Admin"
@ -74,8 +74,6 @@ settings_urls = [
re_path(r'^appearance/?', AppearanceSelectView.as_view(), name='settings-appearance'), re_path(r'^appearance/?', AppearanceSelectView.as_view(), name='settings-appearance'),
re_path(r'^currencies-refresh/', CurrencyRefreshView.as_view(), name='settings-currencies-refresh'), re_path(r'^currencies-refresh/', CurrencyRefreshView.as_view(), name='settings-currencies-refresh'),
re_path(r'^category/', SettingCategorySelectView.as_view(), name='settings-category'),
# Catch any other urls # Catch any other urls
re_path(r'^.*$', SettingsView.as_view(template_name='InvenTree/settings/settings.html'), name='settings'), re_path(r'^.*$', SettingsView.as_view(template_name='InvenTree/settings/settings.html'), name='settings'),
] ]

View File

@ -17,8 +17,8 @@ from django.urls import reverse_lazy
from django.utils.timezone import now from django.utils.timezone import now
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.views import View from django.views import View
from django.views.generic import (CreateView, DeleteView, DetailView, FormView, from django.views.generic import (CreateView, DeleteView, DetailView, ListView,
ListView, UpdateView) UpdateView)
from django.views.generic.base import RedirectView, TemplateView from django.views.generic.base import RedirectView, TemplateView
from allauth.account.forms import AddEmailForm from allauth.account.forms import AddEmailForm
@ -34,8 +34,7 @@ from common.settings import currency_code_default, currency_codes
from part.models import PartCategory from part.models import PartCategory
from users.models import RuleSet, check_user_role from users.models import RuleSet, check_user_role
from .forms import (DeleteForm, EditUserForm, SetPasswordForm, from .forms import DeleteForm, EditUserForm, SetPasswordForm
SettingCategorySelectForm)
from .helpers import str2bool from .helpers import str2bool
@ -801,40 +800,6 @@ class AppearanceSelectView(RedirectView):
return redirect(reverse_lazy('settings')) return redirect(reverse_lazy('settings'))
class SettingCategorySelectView(FormView):
"""View for selecting categories in settings."""
form_class = SettingCategorySelectForm
success_url = reverse_lazy('settings-category')
template_name = "InvenTree/settings/category.html"
def get_initial(self):
"""Set category selection."""
initial = super().get_initial()
category = self.request.GET.get('category', None)
if category:
initial['category'] = category
return initial
def post(self, request, *args, **kwargs):
"""Handle POST request (which contains category selection).
Pass the selected category to the page template
"""
form = self.get_form()
if form.is_valid():
context = self.get_context_data()
context['category'] = form.cleaned_data['category']
return super(SettingCategorySelectView, self).render_to_response(context)
return self.form_invalid(form)
class DatabaseStatsView(AjaxView): class DatabaseStatsView(AjaxView):
"""View for displaying database statistics.""" """View for displaying database statistics."""

View File

@ -265,10 +265,49 @@
{% if user.is_staff %} {% if user.is_staff %}
$("#delete-test-results").click(function() { $("#delete-test-results").click(function() {
launchModalForm(
"{% url 'stock-item-delete-test-data' item.id %}", var url = '{% url "api-stock-test-result-list" %}';
inventreeGet(
url,
{ {
success: reloadTable, stock_item: {{ item.pk }},
},
{
success: function(response) {
var results = [];
// Ensure that we are only deleting the correct test results
response.forEach(function(item) {
if (item.stock_item == {{ item.pk }}) {
results.push(item);
}
});
var html = `
<div class='alert alert-block alert-danger'>
{% trans "Delete all test results for this stock item" %}
</div>`;
constructFormBody({}, {
method: 'DELETE',
title: '{% trans "Delete Test Data" %}',
preFormContent: html,
onSubmit: function(fields, opts) {
inventreeMultiDelete(
url,
results,
{
modal: opts.modal,
success: function() {
reloadTable();
}
}
)
}
});
}
} }
); );
}); });

View File

@ -20,7 +20,6 @@ stock_item_detail_urls = [
re_path(r'^convert/', views.StockItemConvert.as_view(), name='stock-item-convert'), 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'^delete/', views.StockItemDelete.as_view(), name='stock-item-delete'),
re_path(r'^qr_code/', views.StockItemQRCode.as_view(), name='stock-item-qr'), re_path(r'^qr_code/', views.StockItemQRCode.as_view(), name='stock-item-qr'),
re_path(r'^delete_test_data/', views.StockItemDeleteTestData.as_view(), name='stock-item-delete-test-data'),
# Anything else - direct to the item detail view # Anything else - direct to the item detail view
re_path('^.*$', views.StockItemDetail.as_view(), name='stock-item-detail'), re_path('^.*$', views.StockItemDetail.as_view(), name='stock-item-detail'),

View File

@ -6,8 +6,6 @@ from django.utils.translation import gettext_lazy as _
from django.views.generic import DetailView, ListView from django.views.generic import DetailView, ListView
import common.settings import common.settings
from InvenTree.forms import ConfirmForm
from InvenTree.helpers import str2bool
from InvenTree.views import (AjaxDeleteView, AjaxUpdateView, from InvenTree.views import (AjaxDeleteView, AjaxUpdateView,
InvenTreeRoleMixin, QRCodeView) InvenTreeRoleMixin, QRCodeView)
from plugin.views import InvenTreePluginViewMixin from plugin.views import InvenTreePluginViewMixin
@ -123,42 +121,6 @@ class StockLocationQRCode(QRCodeView):
return None return None
class StockItemDeleteTestData(AjaxUpdateView):
"""View for deleting all test data."""
model = StockItem
form_class = ConfirmForm
ajax_form_title = _("Delete All Test Data")
role_required = ['stock.change', 'stock.delete']
def get_form(self):
"""Require confirm."""
return ConfirmForm()
def post(self, request, *args, **kwargs):
"""Delete test data."""
valid = False
stock_item = StockItem.objects.get(pk=self.kwargs['pk'])
form = self.get_form()
confirm = str2bool(request.POST.get('confirm', False))
if confirm is not True:
form.add_error('confirm', _('Confirm test data deletion'))
form.add_error(None, _('Check the confirmation box'))
else:
stock_item.test_results.all().delete()
valid = True
data = {
'form_valid': valid,
}
return self.renderJsonResponse(request, form, data)
class StockItemQRCode(QRCodeView): class StockItemQRCode(QRCodeView):
"""View for displaying a QR code for a StockItem object.""" """View for displaying a QR code for a StockItem object."""