diff --git a/InvenTree/InvenTree/views.py b/InvenTree/InvenTree/views.py
index bb7c1e6f5d..b4bc6ebe06 100644
--- a/InvenTree/InvenTree/views.py
+++ b/InvenTree/InvenTree/views.py
@@ -128,9 +128,13 @@ class InvenTreeRoleMixin(PermissionRequiredMixin):
def has_permission(self):
"""
- Determine if the current user
+ 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:
diff --git a/InvenTree/company/templates/company/company_base.html b/InvenTree/company/templates/company/company_base.html
index f20107277d..cdca22fa36 100644
--- a/InvenTree/company/templates/company/company_base.html
+++ b/InvenTree/company/templates/company/company_base.html
@@ -23,23 +23,27 @@ InvenTree | {% trans "Company" %} - {{ company.name }}
{{ company.name }}
- {% if user.is_staff and roles.company.change %}
+ {% if user.is_staff and perms.company.change_company %}
{% endif %}
{{ company.description }}
- {% if company.is_supplier %}
+ {% if company.is_supplier and roles.purchase_order.add %}
{% endif %}
+ {% if perms.company.change_company %}
+ {% endif %}
+ {% if perms.company.delete_company %}
+ {% endif %}
{% endblock %}
diff --git a/InvenTree/company/templates/company/detail_part.html b/InvenTree/company/templates/company/detail_part.html
index e07304dd13..463bf5814d 100644
--- a/InvenTree/company/templates/company/detail_part.html
+++ b/InvenTree/company/templates/company/detail_part.html
@@ -9,17 +9,25 @@
+{% if roles.purchase_order.change %}
+{% endif %}
diff --git a/InvenTree/company/templates/company/index.html b/InvenTree/company/templates/company/index.html
index 253085568e..f110950c0b 100644
--- a/InvenTree/company/templates/company/index.html
+++ b/InvenTree/company/templates/company/index.html
@@ -12,12 +12,13 @@ InvenTree | {% trans "Supplier List" %}
{{ title }}
+{% if pagetype == 'manufacturers' and roles.purchase_order.add or pagetype == 'suppliers' and roles.purchase_order.add or pagetype == 'customers' and roles.sales_order.add %}
-
+{% endif %}
diff --git a/InvenTree/company/templates/company/purchase_orders.html b/InvenTree/company/templates/company/purchase_orders.html
index bab5cd4bce..a0ef1612fa 100644
--- a/InvenTree/company/templates/company/purchase_orders.html
+++ b/InvenTree/company/templates/company/purchase_orders.html
@@ -9,6 +9,7 @@
{% trans "Purchase Orders" %}
+{% if roles.purchase_order.add %}
+{% endif %}
diff --git a/InvenTree/company/templates/company/sales_orders.html b/InvenTree/company/templates/company/sales_orders.html
index 0b64bed2f5..03c64d5b88 100644
--- a/InvenTree/company/templates/company/sales_orders.html
+++ b/InvenTree/company/templates/company/sales_orders.html
@@ -9,6 +9,7 @@
{% trans "Sales Orders" %}
+{% if roles.sales_order.add %}
+{% endif %}
diff --git a/InvenTree/company/templates/company/supplier_part_base.html b/InvenTree/company/templates/company/supplier_part_base.html
index ca09caee93..7476a7c606 100644
--- a/InvenTree/company/templates/company/supplier_part_base.html
+++ b/InvenTree/company/templates/company/supplier_part_base.html
@@ -18,19 +18,27 @@ src="{% static 'img/blank_image.png' %}"
{% block page_data %}
{% trans "Supplier Part" %}
{{ part.supplier.name }} - {{ part.SKU }}
+
+{% if roles.purchase_order.change %}
+ {% if roles.purchase_order.add %}
+ {% endif %}
+ {% if roles.purchase_order.delete %}
+ {% endif %}
+{% endif %}
+
{% endblock %}
{% block page_details %}
diff --git a/InvenTree/company/templates/company/supplier_part_orders.html b/InvenTree/company/templates/company/supplier_part_orders.html
index 5c2ea6d1d4..29eb8ee874 100644
--- a/InvenTree/company/templates/company/supplier_part_orders.html
+++ b/InvenTree/company/templates/company/supplier_part_orders.html
@@ -10,11 +10,13 @@
+{% if roles.purchase_order.add %}
+{% endif %}
diff --git a/InvenTree/company/templates/company/supplier_part_pricing.html b/InvenTree/company/templates/company/supplier_part_pricing.html
index f9f5063190..97022024f5 100644
--- a/InvenTree/company/templates/company/supplier_part_pricing.html
+++ b/InvenTree/company/templates/company/supplier_part_pricing.html
@@ -11,9 +11,11 @@
+{% if roles.purchase_order.add %}
{% trans "Add Price Break" %}
+{% endif %}
diff --git a/InvenTree/company/test_views.py b/InvenTree/company/test_views.py
index b9bb69e503..d895c18957 100644
--- a/InvenTree/company/test_views.py
+++ b/InvenTree/company/test_views.py
@@ -6,6 +6,7 @@ from __future__ import unicode_literals
from django.test import TestCase
from django.urls import reverse
from django.contrib.auth import get_user_model
+from django.contrib.auth.models import Group
from .models import SupplierPart
@@ -25,7 +26,24 @@ class CompanyViewTest(TestCase):
# Create a user
User = get_user_model()
- User.objects.create_user('username', 'user@email.com', 'password')
+ self.user = User.objects.create_user(
+ username='username',
+ email='user@email.com',
+ password='password'
+ )
+
+ # Put the user into a group with the correct permissions
+ group = Group.objects.create(name='mygroup')
+ self.user.groups.add(group)
+
+ # Give the group *all* the permissions!
+ for rule in group.rule_sets.all():
+ rule.can_view = True
+ rule.can_change = True
+ rule.can_add = True
+ rule.can_delete = True
+
+ rule.save()
self.client.login(username='username', password='password')
diff --git a/InvenTree/company/views.py b/InvenTree/company/views.py
index 9ef6adea0e..dce341d184 100644
--- a/InvenTree/company/views.py
+++ b/InvenTree/company/views.py
@@ -14,6 +14,7 @@ from django.forms import HiddenInput
from InvenTree.views import AjaxCreateView, AjaxUpdateView, AjaxDeleteView
from InvenTree.helpers import str2bool
+from InvenTree.views import InvenTreeRoleMixin
from common.models import Currency
@@ -29,7 +30,7 @@ from .forms import EditSupplierPartForm
from .forms import EditPriceBreakForm
-class CompanyIndex(ListView):
+class CompanyIndex(InvenTreeRoleMixin, ListView):
""" View for displaying list of companies
"""
@@ -37,6 +38,7 @@ class CompanyIndex(ListView):
template_name = 'company/index.html'
context_object_name = 'companies'
paginate_by = 50
+ permission_required = 'company.view_company'
def get_context_data(self, **kwargs):
@@ -116,8 +118,8 @@ class CompanyNotes(UpdateView):
context_object_name = 'company'
template_name = 'company/notes.html'
model = Company
-
fields = ['notes']
+ permission_required = 'company.view_company'
def get_success_url(self):
return reverse('company-notes', kwargs={'pk': self.get_object().id})
@@ -137,6 +139,7 @@ class CompanyDetail(DetailView):
template_name = 'company/detail.html'
queryset = Company.objects.all()
model = Company
+ permission_required = 'company.view_company'
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
@@ -150,6 +153,7 @@ class CompanyImage(AjaxUpdateView):
ajax_template_name = 'modal_form.html'
ajax_form_title = _('Update Company Image')
form_class = CompanyImageForm
+ permission_required = 'company.change_company'
def get_data(self):
return {
@@ -164,6 +168,7 @@ class CompanyEdit(AjaxUpdateView):
context_object_name = 'company'
ajax_template_name = 'modal_form.html'
ajax_form_title = _('Edit Company')
+ permission_required = 'company.change_company'
def get_data(self):
return {
@@ -177,6 +182,7 @@ class CompanyCreate(AjaxCreateView):
context_object_name = 'company'
form_class = EditCompanyForm
ajax_template_name = 'modal_form.html'
+ permission_required = 'company.add_company'
def get_form_title(self):
@@ -230,6 +236,7 @@ class CompanyDelete(AjaxDeleteView):
ajax_template_name = 'company/delete.html'
ajax_form_title = _('Delete Company')
context_object_name = 'company'
+ permission_required = 'company.delete_company'
def get_data(self):
return {
@@ -243,6 +250,7 @@ class SupplierPartDetail(DetailView):
template_name = 'company/supplier_part_detail.html'
context_object_name = 'part'
queryset = SupplierPart.objects.all()
+ permission_required = 'purchase_order.view'
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
@@ -258,6 +266,7 @@ class SupplierPartEdit(AjaxUpdateView):
form_class = EditSupplierPartForm
ajax_template_name = 'modal_form.html'
ajax_form_title = _('Edit Supplier Part')
+ role_required = 'purchase_order.change'
class SupplierPartCreate(AjaxCreateView):
@@ -268,6 +277,7 @@ class SupplierPartCreate(AjaxCreateView):
ajax_template_name = 'modal_form.html'
ajax_form_title = _('Create new Supplier Part')
context_object_name = 'part'
+ role_required = 'purchase_order.add'
def get_form(self):
""" Create Form instance to create a new SupplierPart object.
@@ -327,6 +337,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 = []
@@ -398,6 +409,7 @@ 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 {
@@ -440,6 +452,7 @@ 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):
@@ -455,3 +468,4 @@ class PriceBreakDelete(AjaxDeleteView):
model = SupplierPriceBreak
ajax_form_title = _("Delete Price Break")
ajax_template_name = 'modal_delete_form.html'
+ role_required = 'purchase_order.delete'
diff --git a/InvenTree/order/templates/order/sales_order_detail.html b/InvenTree/order/templates/order/sales_order_detail.html
index b6cc761cc7..d21a4e950e 100644
--- a/InvenTree/order/templates/order/sales_order_detail.html
+++ b/InvenTree/order/templates/order/sales_order_detail.html
@@ -13,9 +13,11 @@
{% trans "Sales Order Items" %}
+{% if roles.sales_order.change %}
{% trans "Add Line Item" %}
+{% endif %}