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
f64758eb03
@ -4,6 +4,10 @@ Contributions to InvenTree are welcomed - please follow the guidelines below.
|
|||||||
|
|
||||||
No pushing to master! New featues must be submitted in a separate branch (one branch per feature).
|
No pushing to master! New featues must be submitted in a separate branch (one branch per feature).
|
||||||
|
|
||||||
|
## Include Migration Files
|
||||||
|
|
||||||
|
Any required migration files **must** be included in the commit, or the pull-request will be rejected. If you change the underlying database schema, make sure you run `make migrate` and commit the migration files before submitting the PR.
|
||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
Any new code should be covered by unit tests - a submitted PR may not be accepted if the code coverage is decreased.
|
Any new code should be covered by unit tests - a submitted PR may not be accepted if the code coverage is decreased.
|
||||||
|
@ -61,6 +61,7 @@ settings_urls = [
|
|||||||
url(r'^user/?', SettingsView.as_view(template_name='InvenTree/settings/user.html'), name='settings-user'),
|
url(r'^user/?', SettingsView.as_view(template_name='InvenTree/settings/user.html'), name='settings-user'),
|
||||||
url(r'^currency/?', SettingsView.as_view(template_name='InvenTree/settings/currency.html'), name='settings-currency'),
|
url(r'^currency/?', SettingsView.as_view(template_name='InvenTree/settings/currency.html'), name='settings-currency'),
|
||||||
url(r'^part/?', SettingsView.as_view(template_name='InvenTree/settings/part.html'), name='settings-part'),
|
url(r'^part/?', SettingsView.as_view(template_name='InvenTree/settings/part.html'), name='settings-part'),
|
||||||
|
url(r'^other/?', SettingsView.as_view(template_name='InvenTree/settings/other.html'), name='settings-other'),
|
||||||
|
|
||||||
# Catch any other urls
|
# Catch any other urls
|
||||||
url(r'^.*$', SettingsView.as_view(template_name='InvenTree/settings/user.html'), name='settings'),
|
url(r'^.*$', SettingsView.as_view(template_name='InvenTree/settings/user.html'), name='settings'),
|
||||||
|
@ -16,6 +16,7 @@ from django.views.generic import UpdateView, CreateView
|
|||||||
from django.views.generic.base import TemplateView
|
from django.views.generic.base import TemplateView
|
||||||
|
|
||||||
from part.models import Part
|
from part.models import Part
|
||||||
|
from common.models import InvenTreeSetting
|
||||||
|
|
||||||
from .forms import DeleteForm, EditUserForm, SetPasswordForm
|
from .forms import DeleteForm, EditUserForm, SetPasswordForm
|
||||||
from .helpers import str2bool
|
from .helpers import str2bool
|
||||||
@ -511,3 +512,11 @@ class SettingsView(TemplateView):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
template_name = "InvenTree/settings.html"
|
template_name = "InvenTree/settings.html"
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
|
||||||
|
ctx = super().get_context_data(**kwargs).copy()
|
||||||
|
|
||||||
|
ctx['settings'] = InvenTreeSetting.objects.all().order_by('key')
|
||||||
|
|
||||||
|
return ctx
|
||||||
|
@ -5,11 +5,17 @@ from django.contrib import admin
|
|||||||
|
|
||||||
from import_export.admin import ImportExportModelAdmin
|
from import_export.admin import ImportExportModelAdmin
|
||||||
|
|
||||||
from .models import Currency
|
from .models import Currency, InvenTreeSetting
|
||||||
|
|
||||||
|
|
||||||
class CurrencyAdmin(ImportExportModelAdmin):
|
class CurrencyAdmin(ImportExportModelAdmin):
|
||||||
list_display = ('symbol', 'suffix', 'description', 'value', 'base')
|
list_display = ('symbol', 'suffix', 'description', 'value', 'base')
|
||||||
|
|
||||||
|
|
||||||
|
class SettingsAdmin(ImportExportModelAdmin):
|
||||||
|
|
||||||
|
list_display = ('key', 'value', 'description')
|
||||||
|
|
||||||
|
|
||||||
admin.site.register(Currency, CurrencyAdmin)
|
admin.site.register(Currency, CurrencyAdmin)
|
||||||
|
admin.site.register(InvenTreeSetting, SettingsAdmin)
|
||||||
|
21
InvenTree/common/migrations/0004_inventreesetting.py
Normal file
21
InvenTree/common/migrations/0004_inventreesetting.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# Generated by Django 2.2.5 on 2019-09-15 12:44
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('common', '0003_auto_20190902_2310'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='InvenTreeSetting',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('key', models.CharField(help_text='Settings key', max_length=50, unique=True)),
|
||||||
|
('value', models.CharField(blank=True, help_text='Settings value', max_length=200)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
23
InvenTree/common/migrations/0005_auto_20190915_1256.py
Normal file
23
InvenTree/common/migrations/0005_auto_20190915_1256.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# Generated by Django 2.2.5 on 2019-09-15 12:56
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('common', '0004_inventreesetting'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='inventreesetting',
|
||||||
|
name='description',
|
||||||
|
field=models.CharField(blank=True, help_text='Settings description', max_length=200),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='inventreesetting',
|
||||||
|
name='key',
|
||||||
|
field=models.CharField(help_text='Settings key (must be unique - case insensitive', max_length=50, unique=True),
|
||||||
|
),
|
||||||
|
]
|
@ -9,6 +9,79 @@ from __future__ import unicode_literals
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
from django.core.validators import MinValueValidator, MaxValueValidator
|
from django.core.validators import MinValueValidator, MaxValueValidator
|
||||||
|
from django.core.exceptions import ValidationError
|
||||||
|
|
||||||
|
|
||||||
|
class InvenTreeSetting(models.Model):
|
||||||
|
"""
|
||||||
|
An InvenTreeSetting object is a key:value pair used for storing
|
||||||
|
single values (e.g. one-off settings values).
|
||||||
|
|
||||||
|
The class provides a way of retrieving the value for a particular key,
|
||||||
|
even if that key does not exist.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_setting(cls, key, backup_value=None):
|
||||||
|
"""
|
||||||
|
Get the value of a particular setting.
|
||||||
|
If it does not exist, return the backup value (default = None)
|
||||||
|
"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
setting = InvenTreeSetting.objects.get(key__iexact=key)
|
||||||
|
return setting.value
|
||||||
|
except InvenTreeSetting.DoesNotExist:
|
||||||
|
return backup_value
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def set_setting(cls, key, value, user, create=True):
|
||||||
|
"""
|
||||||
|
Set the value of a particular setting.
|
||||||
|
If it does not exist, option to create it.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
key: settings key
|
||||||
|
value: New value
|
||||||
|
user: User object (must be staff member to update a core setting)
|
||||||
|
create: If True, create a new setting if the specified key does not exist.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if not user.is_staff:
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
setting = InvenTreeSetting.objects.get(key__iexact=key)
|
||||||
|
except InvenTreeSetting.DoesNotExist:
|
||||||
|
|
||||||
|
if create:
|
||||||
|
setting = InvenTreeSetting(key=key)
|
||||||
|
else:
|
||||||
|
return
|
||||||
|
|
||||||
|
setting.value = value
|
||||||
|
setting.save()
|
||||||
|
|
||||||
|
key = models.CharField(max_length=50, blank=False, unique=True, help_text=_('Settings key (must be unique - case insensitive'))
|
||||||
|
|
||||||
|
value = models.CharField(max_length=200, blank=True, unique=False, help_text=_('Settings value'))
|
||||||
|
|
||||||
|
description = models.CharField(max_length=200, blank=True, unique=False, help_text=_('Settings description'))
|
||||||
|
|
||||||
|
def validate_unique(self, exclude=None):
|
||||||
|
""" Ensure that the key:value pair is unique.
|
||||||
|
In addition to the base validators, this ensures that the 'key'
|
||||||
|
is unique, using a case-insensitive comparison.
|
||||||
|
"""
|
||||||
|
|
||||||
|
super().validate_unique(exclude)
|
||||||
|
|
||||||
|
try:
|
||||||
|
setting = InvenTreeSetting.objects.exclude(id=self.id).filter(key__iexact=self.key)
|
||||||
|
if setting.exists():
|
||||||
|
raise ValidationError({'key': _('Key string must be unique')})
|
||||||
|
except InvenTreeSetting.DoesNotExist:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Currency(models.Model):
|
class Currency(models.Model):
|
||||||
|
37
InvenTree/templates/InvenTree/settings/other.html
Normal file
37
InvenTree/templates/InvenTree/settings/other.html
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
{% extends "InvenTree/settings/settings.html" %}
|
||||||
|
|
||||||
|
{% block tabs %}
|
||||||
|
{% include "InvenTree/settings/tabs.html" with tab='other' %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block settings %}
|
||||||
|
|
||||||
|
<h4>InvenTree Settings</h4>
|
||||||
|
|
||||||
|
<table class='table table-striped table-condensed' id='other-table'>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Setting</th>
|
||||||
|
<th>Value</th>
|
||||||
|
<th>Description</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for setting in settings %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ setting.key }}</td>
|
||||||
|
<td>{{ setting.value }}</td>
|
||||||
|
<td>{{ setting.description }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block js_ready %}
|
||||||
|
{{ block.super }}
|
||||||
|
|
||||||
|
$("#other-table").bootstrapTable();
|
||||||
|
|
||||||
|
{% endblock %}
|
@ -8,4 +8,9 @@
|
|||||||
<li{% ifequal tab 'part' %} class='active'{% endifequal %}>
|
<li{% ifequal tab 'part' %} class='active'{% endifequal %}>
|
||||||
<a href="{% url 'settings-part' %}"><span class='glyphicon glyphicon-briefcase'></span> Part</a>
|
<a href="{% url 'settings-part' %}"><span class='glyphicon glyphicon-briefcase'></span> Part</a>
|
||||||
</li>
|
</li>
|
||||||
|
{% if user.is_staff %}
|
||||||
|
<li{% ifequal tab 'other' %} class='active'{% endifequal %}>
|
||||||
|
<a href="{% url 'settings-other' %}"><span class='glyphicon glyphicon-cog'></span>Other</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
Loading…
Reference in New Issue
Block a user