mirror of
https://github.com/inventree/InvenTree.git
synced 2025-06-17 04:25:42 +00:00
Merge branch 'inventree:master' into matmair/issue2694
This commit is contained in:
@ -282,6 +282,7 @@ INSTALLED_APPS = [
|
||||
|
||||
MIDDLEWARE = CONFIG.get('middleware', [
|
||||
'django.middleware.security.SecurityMiddleware',
|
||||
'x_forwarded_for.middleware.XForwardedForMiddleware',
|
||||
'user_sessions.middleware.SessionMiddleware', # db user sessions
|
||||
'django.middleware.locale.LocaleMiddleware',
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
@ -545,11 +546,19 @@ if "sqlite" in db_engine:
|
||||
# Provide OPTIONS dict back to the database configuration dict
|
||||
db_config['OPTIONS'] = db_options
|
||||
|
||||
# Set testing options for the database
|
||||
db_config['TEST'] = {
|
||||
'CHARSET': 'utf8',
|
||||
}
|
||||
|
||||
# Set collation option for mysql test database
|
||||
if 'mysql' in db_engine:
|
||||
db_config['TEST']['COLLATION'] = 'utf8_general_ci'
|
||||
|
||||
DATABASES = {
|
||||
'default': db_config
|
||||
}
|
||||
|
||||
|
||||
_cache_config = CONFIG.get("cache", {})
|
||||
_cache_host = _cache_config.get("host", os.getenv("INVENTREE_CACHE_HOST"))
|
||||
_cache_port = _cache_config.get(
|
||||
@ -662,6 +671,7 @@ LANGUAGE_CODE = CONFIG.get('language', 'en-us')
|
||||
|
||||
# If a new language translation is supported, it must be added here
|
||||
LANGUAGES = [
|
||||
('cs', _('Czech')),
|
||||
('de', _('German')),
|
||||
('el', _('Greek')),
|
||||
('en', _('English')),
|
||||
|
@ -1,4 +1,4 @@
|
||||
/*! jQuery UI - v1.12.1 - 2021-07-18
|
||||
/*! jQuery UI - v1.13.0 - 2021-10-07
|
||||
* http://jqueryui.com
|
||||
* Includes: widget.js, position.js, disable-selection.js, keycode.js, unique-id.js, widgets/resizable.js, widgets/autocomplete.js, widgets/menu.js, widgets/mouse.js
|
||||
* Copyright jQuery Foundation and other contributors; Licensed MIT */
|
||||
@ -17,11 +17,11 @@
|
||||
|
||||
$.ui = $.ui || {};
|
||||
|
||||
var version = $.ui.version = "1.12.1";
|
||||
var version = $.ui.version = "1.13.1";
|
||||
|
||||
|
||||
/*!
|
||||
* jQuery UI Widget 1.12.1
|
||||
* jQuery UI Widget 1.13.0
|
||||
* http://jqueryui.com
|
||||
*
|
||||
* Copyright jQuery Foundation and other contributors
|
||||
@ -744,7 +744,7 @@ var widget = $.widget;
|
||||
|
||||
|
||||
/*!
|
||||
* jQuery UI Position 1.12.1
|
||||
* jQuery UI Position 1.13.1
|
||||
* http://jqueryui.com
|
||||
*
|
||||
* Copyright jQuery Foundation and other contributors
|
||||
@ -1232,7 +1232,7 @@ var position = $.ui.position;
|
||||
|
||||
|
||||
/*!
|
||||
* jQuery UI Disable Selection 1.12.1
|
||||
* jQuery UI Disable Selection 1.13.0
|
||||
* http://jqueryui.com
|
||||
*
|
||||
* Copyright jQuery Foundation and other contributors
|
||||
@ -1268,7 +1268,7 @@ var disableSelection = $.fn.extend( {
|
||||
|
||||
|
||||
/*!
|
||||
* jQuery UI Keycode 1.12.1
|
||||
* jQuery UI Keycode 1.13.0
|
||||
* http://jqueryui.com
|
||||
*
|
||||
* Copyright jQuery Foundation and other contributors
|
||||
@ -1303,7 +1303,7 @@ var keycode = $.ui.keyCode = {
|
||||
|
||||
|
||||
/*!
|
||||
* jQuery UI Unique ID 1.12.1
|
||||
* jQuery UI Unique ID 1.13.0
|
||||
* http://jqueryui.com
|
||||
*
|
||||
* Copyright jQuery Foundation and other contributors
|
||||
@ -1347,7 +1347,7 @@ var uniqueId = $.fn.extend( {
|
||||
var ie = $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
|
||||
|
||||
/*!
|
||||
* jQuery UI Mouse 1.12.1
|
||||
* jQuery UI Mouse 1.13.0
|
||||
* http://jqueryui.com
|
||||
*
|
||||
* Copyright jQuery Foundation and other contributors
|
||||
@ -1368,7 +1368,7 @@ $( document ).on( "mouseup", function() {
|
||||
} );
|
||||
|
||||
var widgetsMouse = $.widget( "ui.mouse", {
|
||||
version: "1.12.1",
|
||||
version: "1.13.0",
|
||||
options: {
|
||||
cancel: "input, textarea, button, select, option",
|
||||
distance: 1,
|
||||
@ -1592,7 +1592,7 @@ var plugin = $.ui.plugin = {
|
||||
|
||||
|
||||
/*!
|
||||
* jQuery UI Resizable 1.12.1
|
||||
* jQuery UI Resizable 1.13.0
|
||||
* http://jqueryui.com
|
||||
*
|
||||
* Copyright jQuery Foundation and other contributors
|
||||
@ -1612,7 +1612,7 @@ var plugin = $.ui.plugin = {
|
||||
|
||||
|
||||
$.widget( "ui.resizable", $.ui.mouse, {
|
||||
version: "1.12.1",
|
||||
version: "1.13.0",
|
||||
widgetEventPrefix: "resize",
|
||||
options: {
|
||||
alsoResize: false,
|
||||
@ -2806,7 +2806,7 @@ var safeActiveElement = $.ui.safeActiveElement = function( document ) {
|
||||
|
||||
|
||||
/*!
|
||||
* jQuery UI Menu 1.12.1
|
||||
* jQuery UI Menu 1.13.0
|
||||
* http://jqueryui.com
|
||||
*
|
||||
* Copyright jQuery Foundation and other contributors
|
||||
@ -2826,7 +2826,7 @@ var safeActiveElement = $.ui.safeActiveElement = function( document ) {
|
||||
|
||||
|
||||
var widgetsMenu = $.widget( "ui.menu", {
|
||||
version: "1.12.1",
|
||||
version: "1.13.0",
|
||||
defaultElement: "<ul>",
|
||||
delay: 300,
|
||||
options: {
|
||||
@ -3461,7 +3461,7 @@ var widgetsMenu = $.widget( "ui.menu", {
|
||||
|
||||
|
||||
/*!
|
||||
* jQuery UI Autocomplete 1.12.1
|
||||
* jQuery UI Autocomplete 1.13.0
|
||||
* http://jqueryui.com
|
||||
*
|
||||
* Copyright jQuery Foundation and other contributors
|
||||
@ -3481,7 +3481,7 @@ var widgetsMenu = $.widget( "ui.menu", {
|
||||
|
||||
|
||||
$.widget( "ui.autocomplete", {
|
||||
version: "1.12.1",
|
||||
version: "1.13.0",
|
||||
defaultElement: "<input>",
|
||||
options: {
|
||||
appendTo: null,
|
||||
|
File diff suppressed because one or more lines are too long
@ -2,7 +2,7 @@
|
||||
"name": "jquery-ui",
|
||||
"title": "jQuery UI",
|
||||
"description": "A curated set of user interface interactions, effects, widgets, and themes built on top of the jQuery JavaScript Library.",
|
||||
"version": "1.12.1",
|
||||
"version": "1.13.0",
|
||||
"homepage": "http://jqueryui.com",
|
||||
"author": {
|
||||
"name": "jQuery Foundation and other contributors",
|
||||
|
BIN
InvenTree/locale/cs/LC_MESSAGES/django.mo
Normal file
BIN
InvenTree/locale/cs/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
10114
InvenTree/locale/cs/LC_MESSAGES/django.po
Normal file
10114
InvenTree/locale/cs/LC_MESSAGES/django.po
Normal file
File diff suppressed because it is too large
Load Diff
@ -777,7 +777,8 @@ class Part(MPTTModel):
|
||||
# User can decide whether duplicate IPN (Internal Part Number) values are allowed
|
||||
allow_duplicate_ipn = common.models.InvenTreeSetting.get_setting('PART_ALLOW_DUPLICATE_IPN')
|
||||
|
||||
if self.IPN is not None and not allow_duplicate_ipn:
|
||||
# Raise an error if an IPN is set, and it is a duplicate
|
||||
if self.IPN and not allow_duplicate_ipn:
|
||||
parts = Part.objects.filter(IPN__iexact=self.IPN)
|
||||
parts = parts.exclude(pk=self.pk)
|
||||
|
||||
@ -798,6 +799,10 @@ class Part(MPTTModel):
|
||||
|
||||
super().clean()
|
||||
|
||||
# Strip IPN field
|
||||
if type(self.IPN) is str:
|
||||
self.IPN = self.IPN.strip()
|
||||
|
||||
if self.trackable:
|
||||
for part in self.get_used_in().all():
|
||||
|
||||
|
@ -349,6 +349,26 @@ class PartSettingsTest(TestCase):
|
||||
part = Part(name='Hello', description='A thing', IPN='IPN123', revision='C')
|
||||
part.full_clean()
|
||||
|
||||
# Any duplicate IPN should raise an error
|
||||
Part.objects.create(name='xyz', revision='1', description='A part', IPN='UNIQUE')
|
||||
|
||||
# Case insensitive, so variations on spelling should throw an error
|
||||
for ipn in ['UNiquE', 'uniQuE', 'unique']:
|
||||
with self.assertRaises(ValidationError):
|
||||
Part.objects.create(name='xyz', revision='2', description='A part', IPN=ipn)
|
||||
|
||||
with self.assertRaises(ValidationError):
|
||||
Part.objects.create(name='zyx', description='A part', IPN='UNIQUE')
|
||||
|
||||
# However, *blank* / empty IPN values should be allowed, even if duplicates are not
|
||||
# Note that leading / trailling whitespace characters are trimmed, too
|
||||
Part.objects.create(name='abc', revision='1', description='A part', IPN=None)
|
||||
Part.objects.create(name='abc', revision='2', description='A part', IPN='')
|
||||
Part.objects.create(name='abc', revision='3', description='A part', IPN=None)
|
||||
Part.objects.create(name='abc', revision='4', description='A part', IPN=' ')
|
||||
Part.objects.create(name='abc', revision='5', description='A part', IPN=' ')
|
||||
Part.objects.create(name='abc', revision='6', description='A part', IPN=' ')
|
||||
|
||||
|
||||
class PartSubscriptionTests(TestCase):
|
||||
|
||||
|
@ -94,6 +94,14 @@ class IntegrationPluginBase(MixinBase, plugin_base.InvenTreePluginBase):
|
||||
"""
|
||||
return getattr(self, 'is_package', False)
|
||||
|
||||
@property
|
||||
def is_sample(self):
|
||||
"""
|
||||
Is this plugin part of the samples?
|
||||
"""
|
||||
path = str(self.package_path)
|
||||
return path.startswith('plugin/samples/')
|
||||
|
||||
# region properties
|
||||
@property
|
||||
def slug(self):
|
||||
|
@ -453,10 +453,12 @@ class StockItem(MPTTModel):
|
||||
|
||||
super().clean()
|
||||
|
||||
if self.serial is not None and type(self.serial) is str:
|
||||
# Strip serial number field
|
||||
if type(self.serial) is str:
|
||||
self.serial = self.serial.strip()
|
||||
|
||||
if self.batch is not None and type(self.batch) is str:
|
||||
# Strip batch code field
|
||||
if type(self.batch) is str:
|
||||
self.batch = self.batch.strip()
|
||||
|
||||
try:
|
||||
|
@ -77,6 +77,12 @@
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if plugin.is_sample %}
|
||||
<a class='sidebar-selector' id='select-plugin-{{plugin_key}}' data-bs-parent="#sidebar">
|
||||
<span class='badge bg-info rounded-pill'>{% trans "code sample" %}</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
{% if plugin.website %}
|
||||
<a href="{{ plugin.website }}"><span class="fas fa-globe"></span></a>
|
||||
{% endif %}
|
||||
|
Reference in New Issue
Block a user