mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Merge remote-tracking branch 'inventree/master'
This commit is contained in:
commit
ab53764c81
@ -58,8 +58,10 @@ class RolePermission(permissions.BasePermission):
|
||||
# Extract the model name associated with this request
|
||||
model = view.serializer_class.Meta.model
|
||||
|
||||
# And the specific database table
|
||||
table = model._meta.db_table
|
||||
app_label = model._meta.app_label
|
||||
model_name = model._meta.model_name
|
||||
|
||||
table = f"{app_label}_{model_name}"
|
||||
except AttributeError:
|
||||
# We will assume that if the serializer class does *not* have a Meta,
|
||||
# then we don't need a permission
|
||||
|
@ -16,7 +16,7 @@ from django.urls import reverse_lazy
|
||||
from django.contrib.auth.mixins import PermissionRequiredMixin
|
||||
|
||||
from django.views import View
|
||||
from django.views.generic import UpdateView, CreateView, FormView
|
||||
from django.views.generic import ListView, DetailView, CreateView, FormView, DeleteView, UpdateView
|
||||
from django.views.generic.base import TemplateView
|
||||
|
||||
from part.models import Part, PartCategory
|
||||
@ -113,14 +113,39 @@ class InvenTreeRoleMixin(PermissionRequiredMixin):
|
||||
"""
|
||||
Permission class based on user roles, not user 'permissions'.
|
||||
|
||||
To specify which role is required for the mixin,
|
||||
set the class attribute 'role_required' to something like the following:
|
||||
There are a number of ways that the permissions can be specified for a view:
|
||||
|
||||
role_required = 'part.add'
|
||||
role_required = [
|
||||
'part.change',
|
||||
'build.add',
|
||||
]
|
||||
1. Specify the 'role_required' attribute (e.g. part.change)
|
||||
2. Specify the 'permission_required' attribute (e.g. part.change_bomitem)
|
||||
(Note: This is the "normal" django-esque way of doing this)
|
||||
3. Do nothing. The mixin will attempt to "guess" what permission you require:
|
||||
a) If there is a queryset associated with the View, we have the model!
|
||||
b) The *type* of View tells us the permission level (e.g. AjaxUpdateView = change)
|
||||
c) 1 + 1 = 3
|
||||
d) Use the combination of model + permission as we would in 2)
|
||||
|
||||
1. Specify the 'role_required' attribute
|
||||
=====================================
|
||||
To specify which role is required for the mixin,
|
||||
set the class attribute 'role_required' to something like the following:
|
||||
|
||||
role_required = 'part.add'
|
||||
role_required = [
|
||||
'part.change',
|
||||
'build.add',
|
||||
]
|
||||
|
||||
2. Specify the 'permission_required' attribute
|
||||
===========================================
|
||||
To specify a particular low-level permission,
|
||||
set the class attribute 'permission_required' to something like:
|
||||
|
||||
permission_required = 'company.delete_company'
|
||||
|
||||
3. Do Nothing
|
||||
==========
|
||||
|
||||
See above.
|
||||
"""
|
||||
|
||||
# By default, no roles are required
|
||||
@ -132,10 +157,6 @@ class InvenTreeRoleMixin(PermissionRequiredMixin):
|
||||
Determine if the current user has specified permissions
|
||||
"""
|
||||
|
||||
if self.permission_required:
|
||||
# Ignore role-based permissions
|
||||
return super().has_permission()
|
||||
|
||||
roles_required = []
|
||||
|
||||
if type(self.role_required) is str:
|
||||
@ -163,9 +184,80 @@ class InvenTreeRoleMixin(PermissionRequiredMixin):
|
||||
if not check_user_role(user, role, permission):
|
||||
return False
|
||||
|
||||
# If a permission_required is specified, use that!
|
||||
if self.permission_required:
|
||||
# Ignore role-based permissions
|
||||
return super().has_permission()
|
||||
|
||||
# Ok, so at this point we have not explicitly require a "role" or a "permission"
|
||||
# Instead, we will use the model to introspect the data we need
|
||||
|
||||
model = getattr(self, 'model', None)
|
||||
|
||||
if not model:
|
||||
queryset = getattr(self, 'queryset', None)
|
||||
|
||||
if queryset is not None:
|
||||
model = queryset.model
|
||||
|
||||
# We were able to introspect a database model
|
||||
if model is not None:
|
||||
app_label = model._meta.app_label
|
||||
model_name = model._meta.model_name
|
||||
|
||||
table = f"{app_label}_{model_name}"
|
||||
|
||||
permission = self.get_permission_class()
|
||||
|
||||
if not permission:
|
||||
raise AttributeError(f"permission_class not defined for {type(self).__name__}")
|
||||
|
||||
# Check if the user has the required permission
|
||||
return RuleSet.check_table_permission(user, table, permission)
|
||||
|
||||
# We did not fail any required checks
|
||||
return True
|
||||
|
||||
def get_permission_class(self):
|
||||
"""
|
||||
Return the 'permission_class' required for the current View.
|
||||
|
||||
Must be one of:
|
||||
|
||||
- view
|
||||
- change
|
||||
- add
|
||||
- delete
|
||||
|
||||
This can either be explicitly defined, by setting the
|
||||
'permission_class' attribute,
|
||||
or it can be "guessed" by looking at the type of class
|
||||
"""
|
||||
|
||||
perm = getattr(self, 'permission_class', None)
|
||||
|
||||
# Permission is specified by the class itself
|
||||
if perm:
|
||||
return perm
|
||||
|
||||
# Otherwise, we will need to have a go at guessing...
|
||||
permission_map = {
|
||||
AjaxView: 'view',
|
||||
ListView: 'view',
|
||||
DetailView: 'view',
|
||||
UpdateView: 'change',
|
||||
DeleteView: 'delete',
|
||||
AjaxUpdateView: 'change',
|
||||
AjaxCreateView: 'add',
|
||||
}
|
||||
|
||||
for view_class in permission_map.keys():
|
||||
|
||||
if issubclass(type(self), view_class):
|
||||
return permission_map[view_class]
|
||||
|
||||
return None
|
||||
|
||||
|
||||
class AjaxMixin(InvenTreeRoleMixin):
|
||||
""" AjaxMixin provides basic functionality for rendering a Django form to JSON.
|
||||
|
@ -28,7 +28,6 @@ class BuildIndex(InvenTreeRoleMixin, ListView):
|
||||
model = Build
|
||||
template_name = 'build/index.html'
|
||||
context_object_name = 'builds'
|
||||
role_required = 'build.view'
|
||||
|
||||
def get_queryset(self):
|
||||
""" Return all Build objects (order by date, newest first) """
|
||||
@ -58,7 +57,6 @@ class BuildCancel(AjaxUpdateView):
|
||||
ajax_form_title = _('Cancel Build')
|
||||
context_object_name = 'build'
|
||||
form_class = forms.CancelBuildForm
|
||||
role_required = 'build.change'
|
||||
|
||||
def validate(self, build, form, **kwargs):
|
||||
|
||||
@ -92,7 +90,6 @@ class BuildAutoAllocate(AjaxUpdateView):
|
||||
context_object_name = 'build'
|
||||
ajax_form_title = _('Allocate Stock')
|
||||
ajax_template_name = 'build/auto_allocate.html'
|
||||
role_required = 'build.change'
|
||||
|
||||
def get_initial(self):
|
||||
"""
|
||||
@ -181,7 +178,6 @@ class BuildOutputCreate(AjaxUpdateView):
|
||||
form_class = forms.BuildOutputCreateForm
|
||||
ajax_template_name = 'build/build_output_create.html'
|
||||
ajax_form_title = _('Create Build Output')
|
||||
role_required = 'build.change'
|
||||
|
||||
def validate(self, build, form, **kwargs):
|
||||
"""
|
||||
@ -280,6 +276,7 @@ class BuildOutputDelete(AjaxUpdateView):
|
||||
model = Build
|
||||
form_class = forms.BuildOutputDeleteForm
|
||||
ajax_form_title = _('Delete Build Output')
|
||||
|
||||
role_required = 'build.delete'
|
||||
|
||||
def get_initial(self):
|
||||
@ -340,7 +337,6 @@ class BuildUnallocate(AjaxUpdateView):
|
||||
form_class = forms.UnallocateBuildForm
|
||||
ajax_form_title = _("Unallocate Stock")
|
||||
ajax_template_name = "build/unallocate.html"
|
||||
role_required = 'build.change'
|
||||
|
||||
def get_initial(self):
|
||||
|
||||
@ -408,7 +404,7 @@ class BuildComplete(AjaxUpdateView):
|
||||
|
||||
model = Build
|
||||
form_class = forms.CompleteBuildForm
|
||||
role_required = 'build.change'
|
||||
|
||||
ajax_form_title = _('Complete Build Order')
|
||||
ajax_template_name = 'build/complete.html'
|
||||
|
||||
@ -444,7 +440,6 @@ class BuildOutputComplete(AjaxUpdateView):
|
||||
context_object_name = "build"
|
||||
ajax_form_title = _("Complete Build Output")
|
||||
ajax_template_name = "build/complete_output.html"
|
||||
role_required = 'build.change'
|
||||
|
||||
def get_form(self):
|
||||
|
||||
@ -579,13 +574,15 @@ class BuildOutputComplete(AjaxUpdateView):
|
||||
}
|
||||
|
||||
|
||||
class BuildNotes(UpdateView):
|
||||
class BuildNotes(InvenTreeRoleMixin, UpdateView):
|
||||
""" View for editing the 'notes' field of a Build object.
|
||||
"""
|
||||
|
||||
context_object_name = 'build'
|
||||
template_name = 'build/notes.html'
|
||||
model = Build
|
||||
|
||||
# Override the default permission role for this View
|
||||
role_required = 'build.view'
|
||||
|
||||
fields = ['notes']
|
||||
@ -602,13 +599,12 @@ class BuildNotes(UpdateView):
|
||||
return ctx
|
||||
|
||||
|
||||
class BuildDetail(DetailView):
|
||||
class BuildDetail(InvenTreeRoleMixin, DetailView):
|
||||
""" Detail view of a single Build object. """
|
||||
|
||||
model = Build
|
||||
template_name = 'build/detail.html'
|
||||
context_object_name = 'build'
|
||||
role_required = 'build.view'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
|
||||
@ -623,12 +619,11 @@ class BuildDetail(DetailView):
|
||||
return ctx
|
||||
|
||||
|
||||
class BuildAllocate(DetailView):
|
||||
class BuildAllocate(InvenTreeRoleMixin, DetailView):
|
||||
""" View for allocating parts to a Build """
|
||||
model = Build
|
||||
context_object_name = 'build'
|
||||
template_name = 'build/allocate.html'
|
||||
role_required = ['build.change']
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
""" Provide extra context information for the Build allocation page """
|
||||
@ -652,13 +647,15 @@ class BuildAllocate(DetailView):
|
||||
|
||||
|
||||
class BuildCreate(AjaxCreateView):
|
||||
""" View to create a new Build object """
|
||||
"""
|
||||
View to create a new Build object
|
||||
"""
|
||||
|
||||
model = Build
|
||||
context_object_name = 'build'
|
||||
form_class = forms.EditBuildForm
|
||||
ajax_form_title = _('New Build Order')
|
||||
ajax_template_name = 'modal_form.html'
|
||||
role_required = 'build.add'
|
||||
|
||||
def get_form(self):
|
||||
form = super().get_form()
|
||||
@ -734,7 +731,6 @@ class BuildUpdate(AjaxUpdateView):
|
||||
context_object_name = 'build'
|
||||
ajax_form_title = _('Edit Build Order Details')
|
||||
ajax_template_name = 'modal_form.html'
|
||||
role_required = 'build.change'
|
||||
|
||||
def get_form(self):
|
||||
|
||||
@ -776,7 +772,6 @@ class BuildDelete(AjaxDeleteView):
|
||||
model = Build
|
||||
ajax_template_name = 'build/delete_build.html'
|
||||
ajax_form_title = _('Delete Build Order')
|
||||
role_required = 'build.delete'
|
||||
|
||||
|
||||
class BuildItemDelete(AjaxDeleteView):
|
||||
@ -788,7 +783,6 @@ class BuildItemDelete(AjaxDeleteView):
|
||||
ajax_template_name = 'build/delete_build_item.html'
|
||||
ajax_form_title = _('Unallocate Stock')
|
||||
context_object_name = 'item'
|
||||
role_required = 'build.delete'
|
||||
|
||||
def get_data(self):
|
||||
return {
|
||||
@ -805,7 +799,6 @@ class BuildItemCreate(AjaxCreateView):
|
||||
form_class = forms.EditBuildItemForm
|
||||
ajax_template_name = 'build/create_build_item.html'
|
||||
ajax_form_title = _('Allocate stock to build output')
|
||||
role_required = 'build.add'
|
||||
|
||||
# The output StockItem against which the allocation is being made
|
||||
output = None
|
||||
@ -1021,7 +1014,6 @@ class BuildItemEdit(AjaxUpdateView):
|
||||
ajax_template_name = 'build/edit_build_item.html'
|
||||
form_class = forms.EditBuildItemForm
|
||||
ajax_form_title = _('Edit Stock Allocation')
|
||||
role_required = 'build.change'
|
||||
|
||||
def get_data(self):
|
||||
return {
|
||||
@ -1055,7 +1047,6 @@ class BuildAttachmentCreate(AjaxCreateView):
|
||||
model = BuildOrderAttachment
|
||||
form_class = forms.EditBuildAttachmentForm
|
||||
ajax_form_title = _('Add Build Order Attachment')
|
||||
role_required = 'build.add'
|
||||
|
||||
def save(self, form, **kwargs):
|
||||
"""
|
||||
@ -1105,7 +1096,6 @@ class BuildAttachmentEdit(AjaxUpdateView):
|
||||
model = BuildOrderAttachment
|
||||
form_class = forms.EditBuildAttachmentForm
|
||||
ajax_form_title = _('Edit Attachment')
|
||||
role_required = 'build.change'
|
||||
|
||||
def get_form(self):
|
||||
form = super().get_form()
|
||||
@ -1127,7 +1117,6 @@ class BuildAttachmentDelete(AjaxDeleteView):
|
||||
model = BuildOrderAttachment
|
||||
ajax_form_title = _('Delete Attachment')
|
||||
context_object_name = 'attachment'
|
||||
role_required = 'build.delete'
|
||||
|
||||
def get_data(self):
|
||||
return {
|
||||
|
@ -269,7 +269,6 @@ class SupplierPartEdit(AjaxUpdateView):
|
||||
form_class = EditSupplierPartForm
|
||||
ajax_template_name = 'modal_form.html'
|
||||
ajax_form_title = _('Edit Supplier Part')
|
||||
role_required = 'purchase_order.change'
|
||||
|
||||
def get_form(self):
|
||||
form = super().get_form()
|
||||
@ -294,7 +293,6 @@ class SupplierPartCreate(AjaxCreateView):
|
||||
ajax_template_name = 'company/supplier_part_create.html'
|
||||
ajax_form_title = _('Create new Supplier Part')
|
||||
context_object_name = 'part'
|
||||
role_required = 'purchase_order.add'
|
||||
|
||||
def validate(self, part, form):
|
||||
|
||||
@ -413,6 +411,7 @@ class SupplierPartDelete(AjaxDeleteView):
|
||||
success_url = '/supplier/'
|
||||
ajax_template_name = 'company/partdelete.html'
|
||||
ajax_form_title = _('Delete Supplier Part')
|
||||
|
||||
role_required = 'purchase_order.delete'
|
||||
|
||||
parts = []
|
||||
@ -485,7 +484,6 @@ class PriceBreakCreate(AjaxCreateView):
|
||||
form_class = EditPriceBreakForm
|
||||
ajax_form_title = _('Add Price Break')
|
||||
ajax_template_name = 'modal_form.html'
|
||||
role_required = 'purchase_order.add'
|
||||
|
||||
def get_data(self):
|
||||
return {
|
||||
@ -547,7 +545,6 @@ class PriceBreakEdit(AjaxUpdateView):
|
||||
form_class = EditPriceBreakForm
|
||||
ajax_form_title = _('Edit Price Break')
|
||||
ajax_template_name = 'modal_form.html'
|
||||
role_required = 'purchase_order.change'
|
||||
|
||||
def get_form(self):
|
||||
|
||||
@ -563,4 +560,3 @@ class PriceBreakDelete(AjaxDeleteView):
|
||||
model = SupplierPriceBreak
|
||||
ajax_form_title = _("Delete Price Break")
|
||||
ajax_template_name = 'modal_delete_form.html'
|
||||
role_required = 'purchase_order.delete'
|
||||
|
@ -44,8 +44,6 @@ class PurchaseOrderIndex(InvenTreeRoleMixin, ListView):
|
||||
template_name = 'order/purchase_orders.html'
|
||||
context_object_name = 'orders'
|
||||
|
||||
role_required = 'purchase_order.view'
|
||||
|
||||
def get_queryset(self):
|
||||
""" Retrieve the list of purchase orders,
|
||||
ensure that the most recent ones are returned first. """
|
||||
@ -65,7 +63,6 @@ class SalesOrderIndex(InvenTreeRoleMixin, ListView):
|
||||
model = SalesOrder
|
||||
template_name = 'order/sales_orders.html'
|
||||
context_object_name = 'orders'
|
||||
role_required = 'sales_order.view'
|
||||
|
||||
|
||||
class PurchaseOrderDetail(InvenTreeRoleMixin, DetailView):
|
||||
@ -74,7 +71,6 @@ class PurchaseOrderDetail(InvenTreeRoleMixin, DetailView):
|
||||
context_object_name = 'order'
|
||||
queryset = PurchaseOrder.objects.all().prefetch_related('lines')
|
||||
template_name = 'order/purchase_order_detail.html'
|
||||
role_required = 'purchase_order.view'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
ctx = super().get_context_data(**kwargs)
|
||||
@ -88,7 +84,6 @@ class SalesOrderDetail(InvenTreeRoleMixin, DetailView):
|
||||
context_object_name = 'order'
|
||||
queryset = SalesOrder.objects.all().prefetch_related('lines')
|
||||
template_name = 'order/sales_order_detail.html'
|
||||
role_required = 'sales_order.view'
|
||||
|
||||
|
||||
class PurchaseOrderAttachmentCreate(AjaxCreateView):
|
||||
@ -100,7 +95,6 @@ class PurchaseOrderAttachmentCreate(AjaxCreateView):
|
||||
form_class = order_forms.EditPurchaseOrderAttachmentForm
|
||||
ajax_form_title = _("Add Purchase Order Attachment")
|
||||
ajax_template_name = "modal_form.html"
|
||||
role_required = 'purchase_order.add'
|
||||
|
||||
def save(self, form, **kwargs):
|
||||
|
||||
@ -150,7 +144,6 @@ class SalesOrderAttachmentCreate(AjaxCreateView):
|
||||
model = SalesOrderAttachment
|
||||
form_class = order_forms.EditSalesOrderAttachmentForm
|
||||
ajax_form_title = _('Add Sales Order Attachment')
|
||||
role_required = 'sales_order.add'
|
||||
|
||||
def save(self, form, **kwargs):
|
||||
"""
|
||||
@ -191,7 +184,6 @@ class PurchaseOrderAttachmentEdit(AjaxUpdateView):
|
||||
model = PurchaseOrderAttachment
|
||||
form_class = order_forms.EditPurchaseOrderAttachmentForm
|
||||
ajax_form_title = _("Edit Attachment")
|
||||
role_required = 'purchase_order.change'
|
||||
|
||||
def get_data(self):
|
||||
return {
|
||||
@ -213,7 +205,6 @@ class SalesOrderAttachmentEdit(AjaxUpdateView):
|
||||
model = SalesOrderAttachment
|
||||
form_class = order_forms.EditSalesOrderAttachmentForm
|
||||
ajax_form_title = _("Edit Attachment")
|
||||
role_required = 'sales_order.change'
|
||||
|
||||
def get_data(self):
|
||||
return {
|
||||
@ -235,7 +226,6 @@ class PurchaseOrderAttachmentDelete(AjaxDeleteView):
|
||||
ajax_form_title = _("Delete Attachment")
|
||||
ajax_template_name = "order/delete_attachment.html"
|
||||
context_object_name = "attachment"
|
||||
role_required = 'purchase_order.delete'
|
||||
|
||||
def get_data(self):
|
||||
return {
|
||||
@ -250,7 +240,6 @@ class SalesOrderAttachmentDelete(AjaxDeleteView):
|
||||
ajax_form_title = _("Delete Attachment")
|
||||
ajax_template_name = "order/delete_attachment.html"
|
||||
context_object_name = "attachment"
|
||||
role_required = 'sales_order.delete'
|
||||
|
||||
def get_data(self):
|
||||
return {
|
||||
@ -264,6 +253,8 @@ class PurchaseOrderNotes(InvenTreeRoleMixin, UpdateView):
|
||||
context_object_name = 'order'
|
||||
template_name = 'order/order_notes.html'
|
||||
model = PurchaseOrder
|
||||
|
||||
# Override the default permission roles
|
||||
role_required = 'purchase_order.view'
|
||||
|
||||
fields = ['notes']
|
||||
@ -311,7 +302,6 @@ class PurchaseOrderCreate(AjaxCreateView):
|
||||
model = PurchaseOrder
|
||||
ajax_form_title = _("Create Purchase Order")
|
||||
form_class = order_forms.EditPurchaseOrderForm
|
||||
role_required = 'purchase_order.add'
|
||||
|
||||
def get_initial(self):
|
||||
initials = super().get_initial().copy()
|
||||
@ -347,7 +337,6 @@ class SalesOrderCreate(AjaxCreateView):
|
||||
model = SalesOrder
|
||||
ajax_form_title = _("Create Sales Order")
|
||||
form_class = order_forms.EditSalesOrderForm
|
||||
role_required = 'sales_order.add'
|
||||
|
||||
def get_initial(self):
|
||||
initials = super().get_initial().copy()
|
||||
@ -383,7 +372,6 @@ class PurchaseOrderEdit(AjaxUpdateView):
|
||||
model = PurchaseOrder
|
||||
ajax_form_title = _('Edit Purchase Order')
|
||||
form_class = order_forms.EditPurchaseOrderForm
|
||||
role_required = 'purchase_order.change'
|
||||
|
||||
def get_form(self):
|
||||
|
||||
@ -404,7 +392,6 @@ class SalesOrderEdit(AjaxUpdateView):
|
||||
model = SalesOrder
|
||||
ajax_form_title = _('Edit Sales Order')
|
||||
form_class = order_forms.EditSalesOrderForm
|
||||
role_required = 'sales_order.change'
|
||||
|
||||
def get_form(self):
|
||||
form = super().get_form()
|
||||
@ -422,7 +409,6 @@ class PurchaseOrderCancel(AjaxUpdateView):
|
||||
ajax_form_title = _('Cancel Order')
|
||||
ajax_template_name = 'order/order_cancel.html'
|
||||
form_class = order_forms.CancelPurchaseOrderForm
|
||||
role_required = 'purchase_order.change'
|
||||
|
||||
def validate(self, order, form, **kwargs):
|
||||
|
||||
@ -449,7 +435,6 @@ class SalesOrderCancel(AjaxUpdateView):
|
||||
ajax_form_title = _("Cancel sales order")
|
||||
ajax_template_name = "order/sales_order_cancel.html"
|
||||
form_class = order_forms.CancelSalesOrderForm
|
||||
role_required = 'sales_order.change'
|
||||
|
||||
def validate(self, order, form, **kwargs):
|
||||
|
||||
@ -476,7 +461,6 @@ class PurchaseOrderIssue(AjaxUpdateView):
|
||||
ajax_form_title = _('Issue Order')
|
||||
ajax_template_name = "order/order_issue.html"
|
||||
form_class = order_forms.IssuePurchaseOrderForm
|
||||
role_required = 'purchase_order.change'
|
||||
|
||||
def validate(self, order, form, **kwargs):
|
||||
|
||||
@ -506,7 +490,6 @@ class PurchaseOrderComplete(AjaxUpdateView):
|
||||
ajax_template_name = "order/order_complete.html"
|
||||
ajax_form_title = _("Complete Order")
|
||||
context_object_name = 'order'
|
||||
role_required = 'purchase_order.change'
|
||||
|
||||
def get_context_data(self):
|
||||
|
||||
@ -543,7 +526,6 @@ class SalesOrderShip(AjaxUpdateView):
|
||||
context_object_name = 'order'
|
||||
ajax_template_name = 'order/sales_order_ship.html'
|
||||
ajax_form_title = _('Ship Order')
|
||||
role_required = 'sales_order.change'
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
|
||||
@ -587,6 +569,8 @@ class PurchaseOrderExport(AjaxView):
|
||||
"""
|
||||
|
||||
model = PurchaseOrder
|
||||
|
||||
# Specify role as we cannot introspect from "AjaxView"
|
||||
role_required = 'purchase_order.view'
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
@ -619,6 +603,8 @@ class PurchaseOrderReceive(AjaxUpdateView):
|
||||
form_class = order_forms.ReceivePurchaseOrderForm
|
||||
ajax_form_title = _("Receive Parts")
|
||||
ajax_template_name = "order/receive_parts.html"
|
||||
|
||||
# Specify role as we do not specify a Model against this view
|
||||
role_required = 'purchase_order.change'
|
||||
|
||||
# Where the parts will be going (selected in POST request)
|
||||
@ -1117,7 +1103,6 @@ class POLineItemCreate(AjaxCreateView):
|
||||
context_object_name = 'line'
|
||||
form_class = order_forms.EditPurchaseOrderLineItemForm
|
||||
ajax_form_title = _('Add Line Item')
|
||||
role_required = 'purchase_order.add'
|
||||
|
||||
def validate(self, item, form, **kwargs):
|
||||
|
||||
@ -1201,7 +1186,6 @@ class SOLineItemCreate(AjaxCreateView):
|
||||
context_order_name = 'line'
|
||||
form_class = order_forms.EditSalesOrderLineItemForm
|
||||
ajax_form_title = _('Add Line Item')
|
||||
role_required = 'sales_order.add'
|
||||
|
||||
def get_form(self, *args, **kwargs):
|
||||
|
||||
@ -1253,7 +1237,6 @@ class SOLineItemEdit(AjaxUpdateView):
|
||||
model = SalesOrderLineItem
|
||||
form_class = order_forms.EditSalesOrderLineItemForm
|
||||
ajax_form_title = _('Edit Line Item')
|
||||
role_required = 'sales_order.change'
|
||||
|
||||
def get_form(self):
|
||||
form = super().get_form()
|
||||
@ -1272,7 +1255,6 @@ class POLineItemEdit(AjaxUpdateView):
|
||||
form_class = order_forms.EditPurchaseOrderLineItemForm
|
||||
ajax_template_name = 'modal_form.html'
|
||||
ajax_form_title = _('Edit Line Item')
|
||||
role_required = 'purchase_order.change'
|
||||
|
||||
def get_form(self):
|
||||
form = super().get_form()
|
||||
@ -1290,7 +1272,6 @@ class POLineItemDelete(AjaxDeleteView):
|
||||
model = PurchaseOrderLineItem
|
||||
ajax_form_title = _('Delete Line Item')
|
||||
ajax_template_name = 'order/po_lineitem_delete.html'
|
||||
role_required = 'purchase_order.delete'
|
||||
|
||||
def get_data(self):
|
||||
return {
|
||||
@ -1303,7 +1284,6 @@ class SOLineItemDelete(AjaxDeleteView):
|
||||
model = SalesOrderLineItem
|
||||
ajax_form_title = _("Delete Line Item")
|
||||
ajax_template_name = "order/so_lineitem_delete.html"
|
||||
role_required = 'sales_order.delete'
|
||||
|
||||
def get_data(self):
|
||||
return {
|
||||
@ -1317,7 +1297,6 @@ class SalesOrderAllocationCreate(AjaxCreateView):
|
||||
model = SalesOrderAllocation
|
||||
form_class = order_forms.EditSalesOrderAllocationForm
|
||||
ajax_form_title = _('Allocate Stock to Order')
|
||||
role_required = 'sales_order.add'
|
||||
|
||||
def get_initial(self):
|
||||
initials = super().get_initial().copy()
|
||||
@ -1392,7 +1371,6 @@ class SalesOrderAllocationEdit(AjaxUpdateView):
|
||||
model = SalesOrderAllocation
|
||||
form_class = order_forms.EditSalesOrderAllocationForm
|
||||
ajax_form_title = _('Edit Allocation Quantity')
|
||||
role_required = 'sales_order.change'
|
||||
|
||||
def get_form(self):
|
||||
form = super().get_form()
|
||||
@ -1410,4 +1388,3 @@ class SalesOrderAllocationDelete(AjaxDeleteView):
|
||||
ajax_form_title = _("Remove allocation")
|
||||
context_object_name = 'allocation'
|
||||
ajax_template_name = "order/so_allocation_delete.html"
|
||||
role_required = 'sales_order.delete'
|
||||
|
@ -57,8 +57,6 @@ class PartIndex(InvenTreeRoleMixin, ListView):
|
||||
template_name = 'part/category.html'
|
||||
context_object_name = 'parts'
|
||||
|
||||
role_required = 'part.view'
|
||||
|
||||
def get_queryset(self):
|
||||
return Part.objects.all().select_related('category')
|
||||
|
||||
@ -85,7 +83,6 @@ class PartRelatedCreate(AjaxCreateView):
|
||||
form_class = part_forms.CreatePartRelatedForm
|
||||
ajax_form_title = _("Add Related Part")
|
||||
ajax_template_name = "modal_form.html"
|
||||
role_required = 'part.change'
|
||||
|
||||
def get_initial(self):
|
||||
""" Set parent part as part_1 field """
|
||||
@ -141,6 +138,8 @@ class PartRelatedDelete(AjaxDeleteView):
|
||||
model = PartRelated
|
||||
ajax_form_title = _("Delete Related Part")
|
||||
context_object_name = "related"
|
||||
|
||||
# Explicit role requirement
|
||||
role_required = 'part.change'
|
||||
|
||||
|
||||
@ -154,8 +153,6 @@ class PartAttachmentCreate(AjaxCreateView):
|
||||
ajax_form_title = _("Add part attachment")
|
||||
ajax_template_name = "modal_form.html"
|
||||
|
||||
role_required = 'part.add'
|
||||
|
||||
def save(self, form, **kwargs):
|
||||
"""
|
||||
Record the user that uploaded this attachment
|
||||
@ -208,8 +205,6 @@ class PartAttachmentEdit(AjaxUpdateView):
|
||||
ajax_template_name = 'modal_form.html'
|
||||
ajax_form_title = _('Edit attachment')
|
||||
|
||||
role_required = 'part.change'
|
||||
|
||||
def get_data(self):
|
||||
return {
|
||||
'success': _('Part attachment updated')
|
||||
@ -246,8 +241,6 @@ class PartTestTemplateCreate(AjaxCreateView):
|
||||
form_class = part_forms.EditPartTestTemplateForm
|
||||
ajax_form_title = _("Create Test Template")
|
||||
|
||||
role_required = 'part.add'
|
||||
|
||||
def get_initial(self):
|
||||
|
||||
initials = super().get_initial()
|
||||
@ -275,8 +268,6 @@ class PartTestTemplateEdit(AjaxUpdateView):
|
||||
form_class = part_forms.EditPartTestTemplateForm
|
||||
ajax_form_title = _("Edit Test Template")
|
||||
|
||||
role_required = 'part.change'
|
||||
|
||||
def get_form(self):
|
||||
|
||||
form = super().get_form()
|
||||
@ -291,8 +282,6 @@ class PartTestTemplateDelete(AjaxDeleteView):
|
||||
model = PartTestTemplate
|
||||
ajax_form_title = _("Delete Test Template")
|
||||
|
||||
role_required = 'part.delete'
|
||||
|
||||
|
||||
class PartSetCategory(AjaxUpdateView):
|
||||
""" View for settings the part category for multiple parts at once """
|
||||
@ -386,8 +375,6 @@ class MakePartVariant(AjaxCreateView):
|
||||
ajax_form_title = _('Create Variant')
|
||||
ajax_template_name = 'part/variant_part.html'
|
||||
|
||||
role_required = 'part.add'
|
||||
|
||||
def get_part_template(self):
|
||||
return get_object_or_404(Part, id=self.kwargs['pk'])
|
||||
|
||||
@ -468,8 +455,6 @@ class PartDuplicate(AjaxCreateView):
|
||||
ajax_form_title = _("Duplicate Part")
|
||||
ajax_template_name = "part/copy_part.html"
|
||||
|
||||
role_required = 'part.add'
|
||||
|
||||
def get_data(self):
|
||||
return {
|
||||
'success': _('Copied part')
|
||||
@ -594,8 +579,6 @@ class PartCreate(AjaxCreateView):
|
||||
ajax_form_title = _('Create New Part')
|
||||
ajax_template_name = 'part/create_part.html'
|
||||
|
||||
role_required = 'part.add'
|
||||
|
||||
def get_data(self):
|
||||
return {
|
||||
'success': _("Created new part"),
|
||||
@ -772,8 +755,6 @@ class PartDetail(InvenTreeRoleMixin, DetailView):
|
||||
queryset = Part.objects.all().select_related('category')
|
||||
template_name = 'part/detail.html'
|
||||
|
||||
role_required = 'part.view'
|
||||
|
||||
# Add in some extra context information based on query params
|
||||
def get_context_data(self, **kwargs):
|
||||
""" Provide extra context data to template
|
||||
@ -859,8 +840,6 @@ class PartImageUpload(AjaxUpdateView):
|
||||
|
||||
form_class = part_forms.PartImageForm
|
||||
|
||||
role_required = 'part.change'
|
||||
|
||||
def get_data(self):
|
||||
return {
|
||||
'success': _('Updated part image'),
|
||||
@ -874,8 +853,6 @@ class PartImageSelect(AjaxUpdateView):
|
||||
ajax_template_name = 'part/select_image.html'
|
||||
ajax_form_title = _('Select Part Image')
|
||||
|
||||
role_required = 'part.change'
|
||||
|
||||
fields = [
|
||||
'image',
|
||||
]
|
||||
@ -917,8 +894,6 @@ class PartEdit(AjaxUpdateView):
|
||||
ajax_form_title = _('Edit Part Properties')
|
||||
context_object_name = 'part'
|
||||
|
||||
role_required = 'part.change'
|
||||
|
||||
def get_form(self):
|
||||
""" Create form for Part editing.
|
||||
Overrides default get_form() method to limit the choices
|
||||
@ -948,7 +923,6 @@ class BomDuplicate(AjaxUpdateView):
|
||||
ajax_form_title = _('Duplicate BOM')
|
||||
ajax_template_name = 'part/bom_duplicate.html'
|
||||
form_class = part_forms.BomDuplicateForm
|
||||
role_required = 'part.change'
|
||||
|
||||
def get_form(self):
|
||||
|
||||
@ -1002,8 +976,6 @@ class BomValidate(AjaxUpdateView):
|
||||
context_object_name = 'part'
|
||||
form_class = part_forms.BomValidateForm
|
||||
|
||||
role_required = 'part.change'
|
||||
|
||||
def get_context(self):
|
||||
return {
|
||||
'part': self.get_object(),
|
||||
@ -1854,8 +1826,6 @@ class PartDelete(AjaxDeleteView):
|
||||
ajax_form_title = _('Confirm Part Deletion')
|
||||
context_object_name = 'part'
|
||||
|
||||
role_required = 'part.delete'
|
||||
|
||||
success_url = '/part/'
|
||||
|
||||
def get_data(self):
|
||||
@ -1977,9 +1947,9 @@ class PartPricing(AjaxView):
|
||||
|
||||
|
||||
class PartParameterTemplateCreate(AjaxCreateView):
|
||||
""" View for creating a new PartParameterTemplate """
|
||||
|
||||
role_required = 'part.add'
|
||||
"""
|
||||
View for creating a new PartParameterTemplate
|
||||
"""
|
||||
|
||||
model = PartParameterTemplate
|
||||
form_class = part_forms.EditPartParameterTemplateForm
|
||||
@ -1987,9 +1957,9 @@ class PartParameterTemplateCreate(AjaxCreateView):
|
||||
|
||||
|
||||
class PartParameterTemplateEdit(AjaxUpdateView):
|
||||
""" View for editing a PartParameterTemplate """
|
||||
|
||||
role_required = 'part.change'
|
||||
"""
|
||||
View for editing a PartParameterTemplate
|
||||
"""
|
||||
|
||||
model = PartParameterTemplate
|
||||
form_class = part_forms.EditPartParameterTemplateForm
|
||||
@ -1999,8 +1969,6 @@ class PartParameterTemplateEdit(AjaxUpdateView):
|
||||
class PartParameterTemplateDelete(AjaxDeleteView):
|
||||
""" View for deleting an existing PartParameterTemplate """
|
||||
|
||||
role_required = 'part.delete'
|
||||
|
||||
model = PartParameterTemplate
|
||||
ajax_form_title = _("Delete Part Parameter Template")
|
||||
|
||||
@ -2008,8 +1976,6 @@ class PartParameterTemplateDelete(AjaxDeleteView):
|
||||
class PartParameterCreate(AjaxCreateView):
|
||||
""" View for creating a new PartParameter """
|
||||
|
||||
role_required = 'part.add'
|
||||
|
||||
model = PartParameter
|
||||
form_class = part_forms.EditPartParameterForm
|
||||
ajax_form_title = _('Create Part Parameter')
|
||||
@ -2060,8 +2026,6 @@ class PartParameterCreate(AjaxCreateView):
|
||||
class PartParameterEdit(AjaxUpdateView):
|
||||
""" View for editing a PartParameter """
|
||||
|
||||
role_required = 'part.change'
|
||||
|
||||
model = PartParameter
|
||||
form_class = part_forms.EditPartParameterForm
|
||||
ajax_form_title = _('Edit Part Parameter')
|
||||
@ -2076,8 +2040,6 @@ class PartParameterEdit(AjaxUpdateView):
|
||||
class PartParameterDelete(AjaxDeleteView):
|
||||
""" View for deleting a PartParameter """
|
||||
|
||||
role_required = 'part.change'
|
||||
|
||||
model = PartParameter
|
||||
ajax_template_name = 'part/param_delete.html'
|
||||
ajax_form_title = _('Delete Part Parameter')
|
||||
@ -2091,8 +2053,6 @@ class CategoryDetail(InvenTreeRoleMixin, DetailView):
|
||||
queryset = PartCategory.objects.all().prefetch_related('children')
|
||||
template_name = 'part/category_partlist.html'
|
||||
|
||||
role_required = ['part_category.view', 'part.view']
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
|
||||
context = super(CategoryDetail, self).get_context_data(**kwargs).copy()
|
||||
@ -2135,14 +2095,15 @@ class CategoryParametric(CategoryDetail):
|
||||
|
||||
|
||||
class CategoryEdit(AjaxUpdateView):
|
||||
""" Update view to edit a PartCategory """
|
||||
"""
|
||||
Update view to edit a PartCategory
|
||||
"""
|
||||
|
||||
model = PartCategory
|
||||
form_class = part_forms.EditCategoryForm
|
||||
ajax_template_name = 'modal_form.html'
|
||||
ajax_form_title = _('Edit Part Category')
|
||||
|
||||
role_required = 'part_category.change'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(CategoryEdit, self).get_context_data(**kwargs).copy()
|
||||
|
||||
@ -2173,15 +2134,16 @@ class CategoryEdit(AjaxUpdateView):
|
||||
|
||||
|
||||
class CategoryDelete(AjaxDeleteView):
|
||||
""" Delete view to delete a PartCategory """
|
||||
"""
|
||||
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/'
|
||||
|
||||
role_required = 'part_category.delete'
|
||||
|
||||
def get_data(self):
|
||||
return {
|
||||
'danger': _('Part category was deleted'),
|
||||
@ -2196,8 +2158,6 @@ class CategoryCreate(AjaxCreateView):
|
||||
ajax_template_name = 'modal_form.html'
|
||||
form_class = part_forms.EditCategoryForm
|
||||
|
||||
role_required = 'part_category.add'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
""" Add extra context data to template.
|
||||
|
||||
@ -2236,8 +2196,6 @@ class CategoryCreate(AjaxCreateView):
|
||||
class CategoryParameterTemplateCreate(AjaxCreateView):
|
||||
""" View for creating a new PartCategoryParameterTemplate """
|
||||
|
||||
role_required = 'part_category.change'
|
||||
|
||||
model = PartCategoryParameterTemplate
|
||||
form_class = part_forms.EditCategoryParameterTemplateForm
|
||||
ajax_form_title = _('Create Category Parameter Template')
|
||||
@ -2339,8 +2297,6 @@ class CategoryParameterTemplateCreate(AjaxCreateView):
|
||||
class CategoryParameterTemplateEdit(AjaxUpdateView):
|
||||
""" View for editing a PartCategoryParameterTemplate """
|
||||
|
||||
role_required = 'part_category.change'
|
||||
|
||||
model = PartCategoryParameterTemplate
|
||||
form_class = part_forms.EditCategoryParameterTemplateForm
|
||||
ajax_form_title = _('Edit Category Parameter Template')
|
||||
@ -2398,8 +2354,6 @@ class CategoryParameterTemplateEdit(AjaxUpdateView):
|
||||
class CategoryParameterTemplateDelete(AjaxDeleteView):
|
||||
""" View for deleting an existing PartCategoryParameterTemplate """
|
||||
|
||||
role_required = 'part_category.change'
|
||||
|
||||
model = PartCategoryParameterTemplate
|
||||
ajax_form_title = _("Delete Category Parameter Template")
|
||||
|
||||
@ -2413,14 +2367,15 @@ class CategoryParameterTemplateDelete(AjaxDeleteView):
|
||||
|
||||
|
||||
class BomItemCreate(AjaxCreateView):
|
||||
""" Create view for making a new BomItem object """
|
||||
"""
|
||||
Create view for making a new BomItem object
|
||||
"""
|
||||
|
||||
model = BomItem
|
||||
form_class = part_forms.EditBomItemForm
|
||||
ajax_template_name = 'modal_form.html'
|
||||
ajax_form_title = _('Create BOM Item')
|
||||
|
||||
role_required = 'part.add'
|
||||
|
||||
def get_form(self):
|
||||
""" Override get_form() method to reduce Part selection options.
|
||||
|
||||
@ -2491,8 +2446,6 @@ class BomItemEdit(AjaxUpdateView):
|
||||
ajax_template_name = 'modal_form.html'
|
||||
ajax_form_title = _('Edit BOM item')
|
||||
|
||||
role_required = 'part.change'
|
||||
|
||||
def get_form(self):
|
||||
""" Override get_form() method to filter part selection options
|
||||
|
||||
@ -2543,13 +2496,12 @@ class BomItemEdit(AjaxUpdateView):
|
||||
|
||||
class BomItemDelete(AjaxDeleteView):
|
||||
""" Delete view for removing BomItem """
|
||||
|
||||
model = BomItem
|
||||
ajax_template_name = 'part/bom-delete.html'
|
||||
context_object_name = 'item'
|
||||
ajax_form_title = _('Confim BOM item deletion')
|
||||
|
||||
role_required = 'part.change'
|
||||
|
||||
|
||||
class PartSalePriceBreakCreate(AjaxCreateView):
|
||||
""" View for creating a sale price break for a part """
|
||||
@ -2558,8 +2510,6 @@ class PartSalePriceBreakCreate(AjaxCreateView):
|
||||
form_class = part_forms.EditPartSalePriceBreakForm
|
||||
ajax_form_title = _('Add Price Break')
|
||||
|
||||
role_required = 'part.add'
|
||||
|
||||
def get_data(self):
|
||||
return {
|
||||
'success': _('Added new price break')
|
||||
@ -2608,8 +2558,6 @@ class PartSalePriceBreakEdit(AjaxUpdateView):
|
||||
form_class = part_forms.EditPartSalePriceBreakForm
|
||||
ajax_form_title = _('Edit Price Break')
|
||||
|
||||
role_required = 'part.change'
|
||||
|
||||
def get_form(self):
|
||||
|
||||
form = super().get_form()
|
||||
@ -2624,5 +2572,3 @@ class PartSalePriceBreakDelete(AjaxDeleteView):
|
||||
model = PartSellPriceBreak
|
||||
ajax_form_title = _("Delete Price Break")
|
||||
ajax_template_name = "modal_delete_form.html"
|
||||
|
||||
role_required = 'part.delete'
|
||||
|
@ -45,9 +45,6 @@ stock_tracking_urls = [
|
||||
|
||||
# delete
|
||||
url(r'^(?P<pk>\d+)/delete', views.StockItemTrackingDelete.as_view(), name='stock-tracking-delete'),
|
||||
|
||||
# list
|
||||
url('^.*$', views.StockTrackingIndex.as_view(), name='stock-tracking-list')
|
||||
]
|
||||
|
||||
stock_urls = [
|
||||
|
@ -49,7 +49,6 @@ class StockIndex(InvenTreeRoleMixin, ListView):
|
||||
model = StockItem
|
||||
template_name = 'stock/location.html'
|
||||
context_obect_name = 'locations'
|
||||
role_required = 'stock.view'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(StockIndex, self).get_context_data(**kwargs).copy()
|
||||
@ -75,7 +74,6 @@ class StockLocationDetail(InvenTreeRoleMixin, DetailView):
|
||||
template_name = 'stock/location.html'
|
||||
queryset = StockLocation.objects.all()
|
||||
model = StockLocation
|
||||
role_required = ['stock_location.view', 'stock.view']
|
||||
|
||||
|
||||
class StockItemDetail(InvenTreeRoleMixin, DetailView):
|
||||
@ -87,7 +85,6 @@ class StockItemDetail(InvenTreeRoleMixin, DetailView):
|
||||
template_name = 'stock/item.html'
|
||||
queryset = StockItem.objects.all()
|
||||
model = StockItem
|
||||
role_required = 'stock.view'
|
||||
|
||||
|
||||
class StockItemNotes(InvenTreeRoleMixin, UpdateView):
|
||||
@ -96,6 +93,7 @@ class StockItemNotes(InvenTreeRoleMixin, UpdateView):
|
||||
context_object_name = 'item'
|
||||
template_name = 'stock/item_notes.html'
|
||||
model = StockItem
|
||||
|
||||
role_required = 'stock.view'
|
||||
|
||||
fields = ['notes']
|
||||
@ -123,7 +121,6 @@ class StockLocationEdit(AjaxUpdateView):
|
||||
context_object_name = 'location'
|
||||
ajax_template_name = 'modal_form.html'
|
||||
ajax_form_title = _('Edit Stock Location')
|
||||
role_required = 'stock_location.change'
|
||||
|
||||
def get_form(self):
|
||||
""" Customize form data for StockLocation editing.
|
||||
@ -246,6 +243,7 @@ class StockLocationQRCode(QRCodeView):
|
||||
""" View for displaying a QR code for a StockLocation object """
|
||||
|
||||
ajax_form_title = _("Stock Location QR code")
|
||||
|
||||
role_required = ['stock_location.view', 'stock.view']
|
||||
|
||||
def get_qr_data(self):
|
||||
@ -266,7 +264,6 @@ class StockItemAttachmentCreate(AjaxCreateView):
|
||||
form_class = StockForms.EditStockItemAttachmentForm
|
||||
ajax_form_title = _("Add Stock Item Attachment")
|
||||
ajax_template_name = "modal_form.html"
|
||||
role_required = 'stock.add'
|
||||
|
||||
def save(self, form, **kwargs):
|
||||
""" Record the user that uploaded the attachment """
|
||||
@ -312,7 +309,6 @@ class StockItemAttachmentEdit(AjaxUpdateView):
|
||||
model = StockItemAttachment
|
||||
form_class = StockForms.EditStockItemAttachmentForm
|
||||
ajax_form_title = _("Edit Stock Item Attachment")
|
||||
role_required = 'stock.change'
|
||||
|
||||
def get_form(self):
|
||||
|
||||
@ -331,7 +327,6 @@ class StockItemAttachmentDelete(AjaxDeleteView):
|
||||
ajax_form_title = _("Delete Stock Item Attachment")
|
||||
ajax_template_name = "attachment_delete.html"
|
||||
context_object_name = "attachment"
|
||||
role_required = 'stock.delete'
|
||||
|
||||
def get_data(self):
|
||||
return {
|
||||
@ -348,7 +343,6 @@ class StockItemAssignToCustomer(AjaxUpdateView):
|
||||
ajax_form_title = _("Assign to Customer")
|
||||
context_object_name = "item"
|
||||
form_class = StockForms.AssignStockItemToCustomerForm
|
||||
role_required = 'stock.change'
|
||||
|
||||
def validate(self, item, form, **kwargs):
|
||||
|
||||
@ -382,7 +376,6 @@ class StockItemReturnToStock(AjaxUpdateView):
|
||||
ajax_form_title = _("Return to Stock")
|
||||
context_object_name = "item"
|
||||
form_class = StockForms.ReturnStockItemForm
|
||||
role_required = 'stock.change'
|
||||
|
||||
def validate(self, item, form, **kwargs):
|
||||
|
||||
@ -412,6 +405,7 @@ class StockItemDeleteTestData(AjaxUpdateView):
|
||||
model = StockItem
|
||||
form_class = ConfirmForm
|
||||
ajax_form_title = _("Delete All Test Data")
|
||||
|
||||
role_required = ['stock.change', 'stock.delete']
|
||||
|
||||
def get_form(self):
|
||||
@ -448,7 +442,6 @@ class StockItemTestResultCreate(AjaxCreateView):
|
||||
model = StockItemTestResult
|
||||
form_class = StockForms.EditStockItemTestResultForm
|
||||
ajax_form_title = _("Add Test Result")
|
||||
role_required = 'stock.add'
|
||||
|
||||
def save(self, form, **kwargs):
|
||||
"""
|
||||
@ -489,7 +482,6 @@ class StockItemTestResultEdit(AjaxUpdateView):
|
||||
model = StockItemTestResult
|
||||
form_class = StockForms.EditStockItemTestResultForm
|
||||
ajax_form_title = _("Edit Test Result")
|
||||
role_required = 'stock.change'
|
||||
|
||||
def get_form(self):
|
||||
|
||||
@ -508,7 +500,6 @@ class StockItemTestResultDelete(AjaxDeleteView):
|
||||
model = StockItemTestResult
|
||||
ajax_form_title = _("Delete Test Result")
|
||||
context_object_name = "result"
|
||||
role_required = 'stock.delete'
|
||||
|
||||
|
||||
class StockExportOptions(AjaxView):
|
||||
@ -517,7 +508,6 @@ class StockExportOptions(AjaxView):
|
||||
model = StockLocation
|
||||
ajax_form_title = _('Stock Export Options')
|
||||
form_class = StockForms.ExportOptionsForm
|
||||
role_required = 'stock.view'
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
|
||||
@ -665,7 +655,6 @@ class StockItemInstall(AjaxUpdateView):
|
||||
form_class = StockForms.InstallStockForm
|
||||
ajax_form_title = _('Install Stock Item')
|
||||
ajax_template_name = "stock/item_install.html"
|
||||
role_required = 'stock.change'
|
||||
|
||||
part = None
|
||||
|
||||
@ -1232,7 +1221,6 @@ class StockItemEdit(AjaxUpdateView):
|
||||
context_object_name = 'item'
|
||||
ajax_template_name = 'modal_form.html'
|
||||
ajax_form_title = _('Edit Stock Item')
|
||||
role_required = 'stock.change'
|
||||
|
||||
def get_form(self):
|
||||
""" Get form for StockItem editing.
|
||||
@ -1343,7 +1331,6 @@ class StockItemConvert(AjaxUpdateView):
|
||||
ajax_form_title = _('Convert Stock Item')
|
||||
ajax_template_name = 'stock/stockitem_convert.html'
|
||||
context_object_name = 'item'
|
||||
role_required = 'stock.change'
|
||||
|
||||
def get_form(self):
|
||||
"""
|
||||
@ -1369,7 +1356,6 @@ class StockLocationCreate(AjaxCreateView):
|
||||
context_object_name = 'location'
|
||||
ajax_template_name = 'modal_form.html'
|
||||
ajax_form_title = _('Create new Stock Location')
|
||||
role_required = 'stock_location.add'
|
||||
|
||||
def get_initial(self):
|
||||
initials = super(StockLocationCreate, self).get_initial().copy()
|
||||
@ -1462,7 +1448,6 @@ class StockItemSerialize(AjaxUpdateView):
|
||||
ajax_template_name = 'stock/item_serialize.html'
|
||||
ajax_form_title = _('Serialize Stock')
|
||||
form_class = StockForms.SerializeStockForm
|
||||
role_required = 'stock.change'
|
||||
|
||||
def get_form(self):
|
||||
|
||||
@ -1555,7 +1540,6 @@ class StockItemCreate(AjaxCreateView):
|
||||
context_object_name = 'item'
|
||||
ajax_template_name = 'modal_form.html'
|
||||
ajax_form_title = _('Create new Stock Item')
|
||||
role_required = 'stock.add'
|
||||
|
||||
def get_part(self, form=None):
|
||||
"""
|
||||
@ -1880,7 +1864,6 @@ class StockLocationDelete(AjaxDeleteView):
|
||||
ajax_template_name = 'stock/location_delete.html'
|
||||
context_object_name = 'location'
|
||||
ajax_form_title = _('Delete Stock Location')
|
||||
role_required = 'stock_location.delete'
|
||||
|
||||
|
||||
class StockItemDelete(AjaxDeleteView):
|
||||
@ -1894,7 +1877,6 @@ class StockItemDelete(AjaxDeleteView):
|
||||
ajax_template_name = 'stock/item_delete.html'
|
||||
context_object_name = 'item'
|
||||
ajax_form_title = _('Delete Stock Item')
|
||||
role_required = 'stock.delete'
|
||||
|
||||
|
||||
class StockItemTrackingDelete(AjaxDeleteView):
|
||||
@ -1906,18 +1888,6 @@ class StockItemTrackingDelete(AjaxDeleteView):
|
||||
model = StockItemTracking
|
||||
ajax_template_name = 'stock/tracking_delete.html'
|
||||
ajax_form_title = _('Delete Stock Tracking Entry')
|
||||
role_required = 'stock.delete'
|
||||
|
||||
|
||||
class StockTrackingIndex(InvenTreeRoleMixin, ListView):
|
||||
"""
|
||||
StockTrackingIndex provides a page to display StockItemTracking objects
|
||||
"""
|
||||
|
||||
model = StockItemTracking
|
||||
template_name = 'stock/tracking.html'
|
||||
context_object_name = 'items'
|
||||
role_required = 'stock.view'
|
||||
|
||||
|
||||
class StockItemTrackingEdit(AjaxUpdateView):
|
||||
@ -1926,7 +1896,6 @@ class StockItemTrackingEdit(AjaxUpdateView):
|
||||
model = StockItemTracking
|
||||
ajax_form_title = _('Edit Stock Tracking Entry')
|
||||
form_class = StockForms.TrackingEntryForm
|
||||
role_required = 'stock.change'
|
||||
|
||||
|
||||
class StockItemTrackingCreate(AjaxCreateView):
|
||||
@ -1936,7 +1905,6 @@ class StockItemTrackingCreate(AjaxCreateView):
|
||||
model = StockItemTracking
|
||||
ajax_form_title = _("Add Stock Tracking Entry")
|
||||
form_class = StockForms.TrackingEntryForm
|
||||
role_required = 'stock.add'
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
|
||||
|
@ -68,6 +68,7 @@ class RuleSet(models.Model):
|
||||
'part_partparameter',
|
||||
'part_partrelated',
|
||||
'part_partstar',
|
||||
'company_supplierpart',
|
||||
],
|
||||
'stock_location': [
|
||||
'stock_stocklocation',
|
||||
@ -94,11 +95,11 @@ class RuleSet(models.Model):
|
||||
],
|
||||
'purchase_order': [
|
||||
'company_company',
|
||||
'company_supplierpart',
|
||||
'company_supplierpricebreak',
|
||||
'order_purchaseorder',
|
||||
'order_purchaseorderattachment',
|
||||
'order_purchaseorderlineitem',
|
||||
'company_supplierpart',
|
||||
],
|
||||
'sales_order': [
|
||||
'company_company',
|
||||
@ -342,7 +343,7 @@ def update_group_roles(group, debug=False):
|
||||
content_type = ContentType.objects.get(app_label=app, model=model)
|
||||
permission = Permission.objects.get(content_type=content_type, codename=perm)
|
||||
except ContentType.DoesNotExist:
|
||||
print(f"Error: Could not find permission matching '{permission_string}'")
|
||||
raise ValueError(f"Error: Could not find permission matching '{permission_string}'")
|
||||
permission = None
|
||||
|
||||
return permission
|
||||
|
Loading…
Reference in New Issue
Block a user