mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Merged master
This commit is contained in:
commit
e92e5dfe8f
@ -9,7 +9,7 @@
|
||||
{% if category %}
|
||||
<h3>
|
||||
{{ category.name }}
|
||||
{% if user.is_staff and roles.part.change %}
|
||||
{% if user.is_staff and roles.part_category.change %}
|
||||
<a href="{% url 'admin:part_partcategory_change' category.pk %}"><span title="{% trans 'Admin view' %}" class='fas fa-user-shield'></span></a>
|
||||
{% endif %}
|
||||
</h3>
|
||||
@ -20,18 +20,18 @@
|
||||
{% endif %}
|
||||
<p>
|
||||
<div class='btn-group action-buttons'>
|
||||
{% if roles.part.add %}
|
||||
{% if roles.part_category.add %}
|
||||
<button class='btn btn-default' id='cat-create' title='{% trans "Create new part category" %}'>
|
||||
<span class='fas fa-plus-circle icon-green'/>
|
||||
</button>
|
||||
{% endif %}
|
||||
{% if category %}
|
||||
{% if roles.part.change %}
|
||||
{% if roles.part_category.change %}
|
||||
<button class='btn btn-default' id='cat-edit' title='{% trans "Edit part category" %}'>
|
||||
<span class='fas fa-edit icon-blue'/>
|
||||
</button>
|
||||
{% endif %}
|
||||
{% if roles.part.delete %}
|
||||
{% if roles.part_category.delete %}
|
||||
<button class='btn btn-default' id='cat-delete' title='{% trans "Delete part category" %}'>
|
||||
<span class='fas fa-trash-alt icon-red'/>
|
||||
</button>
|
||||
|
@ -37,7 +37,7 @@
|
||||
{% if roles.part.change %}
|
||||
<button title='{% trans "Edit" %}' class='btn btn-default btn-glyph param-edit' url="{% url 'part-param-edit' param.id %}" type='button'><span class='fas fa-edit'/></button>
|
||||
{% endif %}
|
||||
{% if roles.part.delete %}
|
||||
{% if roles.part.change %}
|
||||
<button title='{% trans "Delete" %}' class='btn btn-default btn-glyph param-delete' url="{% url 'part-param-delete' param.id %}" type='button'><span class='fas fa-trash-alt icon-red'/></button>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
@ -231,7 +231,7 @@ class PartAttachmentDelete(AjaxDeleteView):
|
||||
ajax_template_name = "attachment_delete.html"
|
||||
context_object_name = "attachment"
|
||||
|
||||
role_required = 'part.delete'
|
||||
role_required = 'part.change'
|
||||
|
||||
def get_data(self):
|
||||
return {
|
||||
@ -2073,7 +2073,7 @@ class PartParameterEdit(AjaxUpdateView):
|
||||
class PartParameterDelete(AjaxDeleteView):
|
||||
""" View for deleting a PartParameter """
|
||||
|
||||
role_required = 'part.delete'
|
||||
role_required = 'part.change'
|
||||
|
||||
model = PartParameter
|
||||
ajax_template_name = 'part/param_delete.html'
|
||||
@ -2088,7 +2088,7 @@ class CategoryDetail(InvenTreeRoleMixin, DetailView):
|
||||
queryset = PartCategory.objects.all().prefetch_related('children')
|
||||
template_name = 'part/category_partlist.html'
|
||||
|
||||
role_required = 'part.view'
|
||||
role_required = ['part_category.view', 'part.view']
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
|
||||
@ -2138,7 +2138,7 @@ class CategoryEdit(AjaxUpdateView):
|
||||
ajax_template_name = 'modal_form.html'
|
||||
ajax_form_title = _('Edit Part Category')
|
||||
|
||||
role_required = 'part.change'
|
||||
role_required = 'part_category.change'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(CategoryEdit, self).get_context_data(**kwargs).copy()
|
||||
@ -2177,7 +2177,7 @@ class CategoryDelete(AjaxDeleteView):
|
||||
context_object_name = 'category'
|
||||
success_url = '/part/'
|
||||
|
||||
role_required = 'part.delete'
|
||||
role_required = 'part_category.delete'
|
||||
|
||||
def get_data(self):
|
||||
return {
|
||||
@ -2193,7 +2193,7 @@ class CategoryCreate(AjaxCreateView):
|
||||
ajax_template_name = 'modal_form.html'
|
||||
form_class = part_forms.EditCategoryForm
|
||||
|
||||
role_required = 'part.add'
|
||||
role_required = 'part_category.add'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
""" Add extra context data to template.
|
||||
@ -2233,7 +2233,7 @@ class CategoryCreate(AjaxCreateView):
|
||||
class CategoryParameterTemplateCreate(AjaxCreateView):
|
||||
""" View for creating a new PartCategoryParameterTemplate """
|
||||
|
||||
role_required = 'part.add'
|
||||
role_required = 'part_category.change'
|
||||
|
||||
model = PartCategoryParameterTemplate
|
||||
form_class = part_forms.EditCategoryParameterTemplateForm
|
||||
@ -2336,7 +2336,7 @@ class CategoryParameterTemplateCreate(AjaxCreateView):
|
||||
class CategoryParameterTemplateEdit(AjaxUpdateView):
|
||||
""" View for editing a PartCategoryParameterTemplate """
|
||||
|
||||
role_required = 'part.change'
|
||||
role_required = 'part_category.change'
|
||||
|
||||
model = PartCategoryParameterTemplate
|
||||
form_class = part_forms.EditCategoryParameterTemplateForm
|
||||
@ -2395,7 +2395,7 @@ class CategoryParameterTemplateEdit(AjaxUpdateView):
|
||||
class CategoryParameterTemplateDelete(AjaxDeleteView):
|
||||
""" View for deleting an existing PartCategoryParameterTemplate """
|
||||
|
||||
role_required = 'part.delete'
|
||||
role_required = 'part_category.change'
|
||||
|
||||
model = PartCategoryParameterTemplate
|
||||
ajax_form_title = _("Delete Category Parameter Template")
|
||||
@ -2554,7 +2554,7 @@ class BomItemDelete(AjaxDeleteView):
|
||||
context_object_name = 'item'
|
||||
ajax_form_title = _('Confim BOM item deletion')
|
||||
|
||||
role_required = 'part.delete'
|
||||
role_required = 'part.change'
|
||||
|
||||
|
||||
class PartSalePriceBreakCreate(AjaxCreateView):
|
||||
|
@ -7,7 +7,7 @@ import django.db.models.deletion
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('users', '0004_owner_model'),
|
||||
('users', '0005_owner_model'),
|
||||
('stock', '0056_stockitem_expiry_date'),
|
||||
]
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
{% if location %}
|
||||
<h3>
|
||||
{{ location.name }}
|
||||
{% if user.is_staff and roles.stock.change %}
|
||||
{% if user.is_staff and roles.stock_location.change %}
|
||||
<a href="{% url 'admin:stock_stocklocation_change' location.pk %}"><span title="{% trans 'Admin view' %}" class='fas fa-user-shield'></span></a>
|
||||
{% endif %}
|
||||
</h3>
|
||||
@ -31,7 +31,7 @@
|
||||
{% endif %}
|
||||
<div class='btn-group action-buttons' role='group'>
|
||||
{% if owner_control.value == "False" or owner_control.value == "True" and user in owners or user.is_superuser or not location %}
|
||||
{% if roles.stock.add %}
|
||||
{% if roles.stock_location.add %}
|
||||
<button class='btn btn-default' id='location-create' title='{% trans "Create new stock location" %}'>
|
||||
<span class='fas fa-plus-circle icon-green'/>
|
||||
</button>
|
||||
@ -57,6 +57,8 @@
|
||||
{% trans "Count stock" %}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if roles.stock_location.change %}
|
||||
<div class='btn-group'>
|
||||
<button id='location-actions' title='{% trans "Location actions" %}' class='btn btn-default dropdown-toggle' type='button' data-toggle="dropdown"><span class='fas fa-sitemap'></span> <span class='caret'></span></button>
|
||||
<ul class='dropdown-menu' role='menu'>
|
||||
|
@ -1,6 +1,6 @@
|
||||
{% extends "collapse.html" %}
|
||||
|
||||
{% if roles.stock.view %}
|
||||
{% if roles.stock_location.view or roles.stock.view %}
|
||||
{% block collapse_title %}
|
||||
Sub-Locations<span class='badge'>{{ children|length }}</span>
|
||||
{% endblock %}
|
||||
|
@ -77,7 +77,7 @@ class StockLocationDetail(InvenTreeRoleMixin, DetailView):
|
||||
template_name = 'stock/location.html'
|
||||
queryset = StockLocation.objects.all()
|
||||
model = StockLocation
|
||||
role_required = 'stock.view'
|
||||
role_required = ['stock_location.view', 'stock.view']
|
||||
|
||||
|
||||
class StockItemDetail(InvenTreeRoleMixin, DetailView):
|
||||
@ -125,7 +125,7 @@ class StockLocationEdit(AjaxUpdateView):
|
||||
context_object_name = 'location'
|
||||
ajax_template_name = 'modal_form.html'
|
||||
ajax_form_title = _('Edit Stock Location')
|
||||
role_required = 'stock.change'
|
||||
role_required = 'stock_location.change'
|
||||
|
||||
def get_form(self):
|
||||
""" Customize form data for StockLocation editing.
|
||||
@ -248,7 +248,7 @@ class StockLocationQRCode(QRCodeView):
|
||||
""" View for displaying a QR code for a StockLocation object """
|
||||
|
||||
ajax_form_title = _("Stock Location QR code")
|
||||
role_required = 'stock.view'
|
||||
role_required = ['stock_location.view', 'stock.view']
|
||||
|
||||
def get_qr_data(self):
|
||||
""" Generate QR code data for the StockLocation """
|
||||
@ -1543,7 +1543,7 @@ class StockLocationCreate(AjaxCreateView):
|
||||
context_object_name = 'location'
|
||||
ajax_template_name = 'modal_form.html'
|
||||
ajax_form_title = _('Create new Stock Location')
|
||||
role_required = 'stock.add'
|
||||
role_required = 'stock_location.add'
|
||||
|
||||
def get_initial(self):
|
||||
initials = super(StockLocationCreate, self).get_initial().copy()
|
||||
@ -2049,7 +2049,7 @@ class StockLocationDelete(AjaxDeleteView):
|
||||
ajax_template_name = 'stock/location_delete.html'
|
||||
context_object_name = 'location'
|
||||
ajax_form_title = _('Delete Stock Location')
|
||||
role_required = 'stock.delete'
|
||||
role_required = 'stock_location.delete'
|
||||
|
||||
|
||||
class StockItemDelete(AjaxDeleteView):
|
||||
|
@ -30,6 +30,8 @@ class RuleSetInline(admin.TabularInline):
|
||||
max_num = len(RuleSet.RULESET_CHOICES)
|
||||
min_num = 1
|
||||
extra = 0
|
||||
# TODO: find better way to order inlines
|
||||
ordering = ['name']
|
||||
|
||||
|
||||
class InvenTreeGroupAdminForm(forms.ModelForm):
|
||||
@ -87,7 +89,8 @@ class RoleGroupAdmin(admin.ModelAdmin):
|
||||
RuleSetInline,
|
||||
]
|
||||
|
||||
list_display = ('name', 'admin', 'part', 'stock', 'build', 'purchase_order', 'sales_order')
|
||||
list_display = ('name', 'admin', 'part_category', 'part', 'stock_location',
|
||||
'stock_item', 'build', 'purchase_order', 'sales_order')
|
||||
|
||||
def get_rule_set(self, obj, rule_set_type):
|
||||
''' Return list of permissions for the given ruleset '''
|
||||
@ -130,10 +133,16 @@ class RoleGroupAdmin(admin.ModelAdmin):
|
||||
def admin(self, obj):
|
||||
return self.get_rule_set(obj, 'admin')
|
||||
|
||||
def part_category(self, obj):
|
||||
return self.get_rule_set(obj, 'part_category')
|
||||
|
||||
def part(self, obj):
|
||||
return self.get_rule_set(obj, 'part')
|
||||
|
||||
def stock(self, obj):
|
||||
def stock_location(self, obj):
|
||||
return self.get_rule_set(obj, 'stock_location')
|
||||
|
||||
def stock_item(self, obj):
|
||||
return self.get_rule_set(obj, 'stock')
|
||||
|
||||
def build(self, obj):
|
||||
|
18
InvenTree/users/migrations/0004_auto_20210113_1909.py
Normal file
18
InvenTree/users/migrations/0004_auto_20210113_1909.py
Normal file
@ -0,0 +1,18 @@
|
||||
# Generated by Django 3.0.7 on 2021-01-13 19:09
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('users', '0003_auto_20201005_2227'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='ruleset',
|
||||
name='name',
|
||||
field=models.CharField(choices=[('admin', 'Admin'), ('part_category', 'Part Categories'), ('part', 'Parts'), ('stock_location', 'Stock Locations'), ('stock', 'Stock Items'), ('build', 'Build Orders'), ('purchase_order', 'Purchase Orders'), ('sales_order', 'Sales Orders')], help_text='Permission set', max_length=50),
|
||||
),
|
||||
]
|
@ -1,27 +0,0 @@
|
||||
# Generated by Django 3.0.7 on 2021-01-11 18:54
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('contenttypes', '0002_remove_content_type_name'),
|
||||
('users', '0003_auto_20201005_2227'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Owner',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('owner_id', models.PositiveIntegerField(blank=True, null=True)),
|
||||
('owner_type', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType')),
|
||||
],
|
||||
),
|
||||
migrations.AddConstraint(
|
||||
model_name='owner',
|
||||
constraint=models.UniqueConstraint(fields=('owner_type', 'owner_id'), name='unique_owner'),
|
||||
),
|
||||
]
|
@ -29,8 +29,10 @@ class RuleSet(models.Model):
|
||||
|
||||
RULESET_CHOICES = [
|
||||
('admin', _('Admin')),
|
||||
('part_category', _('Part Categories')),
|
||||
('part', _('Parts')),
|
||||
('stock', _('Stock')),
|
||||
('stock_location', _('Stock Locations')),
|
||||
('stock', _('Stock Items')),
|
||||
('build', _('Build Orders')),
|
||||
('purchase_order', _('Purchase Orders')),
|
||||
('sales_order', _('Sales Orders')),
|
||||
@ -52,21 +54,25 @@ class RuleSet(models.Model):
|
||||
'authtoken_token',
|
||||
'users_ruleset',
|
||||
],
|
||||
'part_category': [
|
||||
'part_partcategory',
|
||||
'part_partcategoryparametertemplate',
|
||||
],
|
||||
'part': [
|
||||
'part_part',
|
||||
'part_bomitem',
|
||||
'part_partcategory',
|
||||
'part_partattachment',
|
||||
'part_partsellpricebreak',
|
||||
'part_parttesttemplate',
|
||||
'part_partparametertemplate',
|
||||
'part_partparameter',
|
||||
'part_partrelated',
|
||||
'part_partcategoryparametertemplate',
|
||||
],
|
||||
'stock_location': [
|
||||
'stock_stocklocation',
|
||||
],
|
||||
'stock': [
|
||||
'stock_stockitem',
|
||||
'stock_stocklocation',
|
||||
'stock_stockitemattachment',
|
||||
'stock_stockitemtracking',
|
||||
'stock_stockitemtestresult',
|
||||
|
Loading…
Reference in New Issue
Block a user