Merge remote-tracking branch 'inventree/master'

This commit is contained in:
Oliver Walters 2022-11-28 20:19:36 +11:00
commit 3eed5309f2
41 changed files with 29458 additions and 28173 deletions

View File

@ -49,12 +49,14 @@ jobs:
# Build the development docker image (using docker-compose.yml)
run: |
docker-compose build
- name: Run Unit Tests
- name: Update Docker Image
run: |
docker-compose run inventree-dev-server invoke update
docker-compose run inventree-dev-server invoke setup-dev
docker-compose up -d
docker-compose run inventree-dev-server invoke wait
- name: Run Unit Tests
run: |
docker-compose run inventree-dev-server invoke test
docker-compose down
- name: Check Data Directory

View File

@ -7,8 +7,6 @@ import shutil
import string
from pathlib import Path
import yaml
logger = logging.getLogger('inventree')
@ -61,6 +59,8 @@ def get_config_file(create=True) -> Path:
def load_config_data() -> map:
"""Load configuration data from the config file."""
import yaml
cfg_file = get_config_file()
with open(cfg_file, 'r') as cfg:

View File

@ -584,7 +584,7 @@ if cache_host: # pragma: no cover
# database user sessions
SESSION_ENGINE = 'user_sessions.backends.db'
LOGOUT_REDIRECT_URL = 'index'
LOGOUT_REDIRECT_URL = get_setting('INVENTREE_LOGOUT_REDIRECT_URL', 'logout_redirect_url', 'index')
SILENCED_SYSTEM_CHECKS = [
'admin.E410',
]

View File

@ -777,13 +777,14 @@ class TestSettings(helpers.InvenTreeTestCase):
"""Test if install of plugins on startup works."""
from plugin import registry
# Check an install run
response = registry.install_plugin_file()
self.assertEqual(response, 'first_run')
if not settings.DOCKER:
# Check an install run
response = registry.install_plugin_file()
self.assertEqual(response, 'first_run')
# Set dynamic setting to True and rerun to launch install
InvenTreeSetting.set_setting('PLUGIN_ON_STARTUP', True, self.user)
registry.reload_plugins(full_reload=True)
# Set dynamic setting to True and rerun to launch install
InvenTreeSetting.set_setting('PLUGIN_ON_STARTUP', True, self.user)
registry.reload_plugins(full_reload=True)
# Check that there was anotehr run
response = registry.install_plugin_file()

View File

@ -258,7 +258,12 @@ class BaseInvenTreeSetting(models.Model):
"""
setting = cls.get_setting_definition(key, **kwargs)
return setting.get('default', '')
default = setting.get('default', '')
if callable(default):
return default()
else:
return default
@classmethod
def get_setting_choices(cls, key, **kwargs):
@ -1100,6 +1105,27 @@ class InvenTreeSetting(BaseInvenTreeSetting):
'validator': bool,
},
'PRICING_PURCHASE_HISTORY_OVERRIDES_SUPPLIER': {
'name': _('Purchase History Override'),
'description': _('Historical purchase order pricing overrides supplier price breaks'),
'default': False,
'validator': bool,
},
'PRICING_USE_VARIANT_PRICING': {
'name': _('Use Variant Pricing'),
'description': _('Include variant pricing in overall pricing calculations'),
'default': True,
'validator': bool,
},
'PRICING_ACTIVE_VARIANTS': {
'name': _('Active Variants Only'),
'description': _('Only use active variant parts for calculating variant pricing'),
'default': False,
'validator': bool,
},
'PRICING_UPDATE_DAYS': {
'name': _('Pricing Rebuild Time'),
'description': _('Number of days before part pricing is automatically updated'),
@ -1345,7 +1371,7 @@ class InvenTreeSetting(BaseInvenTreeSetting):
'PLUGIN_ON_STARTUP': {
'name': _('Check plugins on startup'),
'description': _('Check that all plugins are installed on startup - enable in container environments'),
'default': False,
'default': settings.DOCKER,
'validator': bool,
'requires_restart': True,
},

View File

@ -71,9 +71,9 @@ class SupplierPartAdmin(ImportExportModelAdmin):
list_display = ('part', 'supplier', 'SKU')
search_fields = [
'company__name',
'supplier__name',
'part__name',
'MPN',
'manufacturer_part__MPN',
'SKU',
]

View File

@ -171,6 +171,12 @@ login_default_protocol: http
remote_login_enabled: False
remote_login_header: HTTP_REMOTE_USER
# Logout redirect configuration
# This setting may be required if using remote / proxy login to redirect requests
# during the logout process (default is 'index'). Please read the docs for more details
# https://docs.djangoproject.com/en/stable/ref/settings/#logout-redirect-url
#logout_redirect_url: 'index'
# Permit custom authentication backends
#authentication_backends:
# - 'django.contrib.auth.backends.ModelBackend'

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -2571,10 +2571,17 @@ class PartPricing(models.Model):
variant_min = None
variant_max = None
active_only = InvenTreeSetting.get_setting('PRICING_ACTIVE_VARIANTS', False)
if self.part.is_template:
variants = self.part.get_descendants(include_self=False)
for v in variants:
if active_only and not v.active:
# Ignore inactive variant parts
continue
v_min = self.convert(v.pricing.overall_min)
v_max = self.convert(v.pricing.overall_max)
@ -2605,19 +2612,27 @@ class PartPricing(models.Model):
self.bom_cost_min,
self.purchase_cost_min,
self.internal_cost_min,
self.variant_cost_min
]
max_costs = [
self.bom_cost_max,
self.purchase_cost_max,
self.internal_cost_max,
self.variant_cost_max
]
if InvenTreeSetting.get_setting('PRICING_USE_SUPPLIER_PRICING', True):
min_costs.append(self.supplier_price_min)
max_costs.append(self.supplier_price_max)
purchase_history_override = InvenTreeSetting.get_setting('PRICING_PURCHASE_HISTORY_OVERRIDES_SUPPLIER', False, cache=False)
if InvenTreeSetting.get_setting('PRICING_USE_SUPPLIER_PRICING', True, cache=False):
# Add supplier pricing data, *unless* historical pricing information should override
if self.purchase_cost_min is None or not purchase_history_override:
min_costs.append(self.supplier_price_min)
if self.purchase_cost_max is None or not purchase_history_override:
max_costs.append(self.supplier_price_max)
if InvenTreeSetting.get_setting('PRICING_USE_VARIANT_PRICING', True, cache=False):
min_costs.append(self.variant_cost_min)
max_costs.append(self.variant_cost_max)
# Calculate overall minimum cost
for cost in min_costs:

View File

@ -16,6 +16,10 @@
{% include "InvenTree/settings/setting.html" with key="PRICING_DECIMAL_PLACES" %}
{% include "InvenTree/settings/setting.html" with key="PRICING_UPDATE_DAYS" icon='fa-calendar-alt' %}
{% include "InvenTree/settings/setting.html" with key="PRICING_USE_SUPPLIER_PRICING" icon='fa-check-circle' %}
{% include "InvenTree/settings/setting.html" with key="PRICING_PURCHASE_HISTORY_OVERRIDES_SUPPLIER" icon='fa-shopping-cart' %}
{% include "InvenTree/settings/setting.html" with key="PRICING_USE_VARIANT_PRICING" icon='fa-check-circle' %}
{% include "InvenTree/settings/setting.html" with key="PRICING_ACTIVE_VARIANTS" %}
</tbody>
</table>
</div>

View File

@ -957,10 +957,10 @@ function loadBomTable(table, options={}) {
}
});
var total = `${top_total}`;
var total = `${formatDecimal(top_total)}`;
if (top_total != all_total) {
total += ` / ${all_total}`;
total += ` / ${formatDecimal(all_total)}`;
}
return total;

View File

@ -695,6 +695,11 @@ function loadVariantPricingChart(options={}) {
options.params.ancestor = part;
if (global_settings.PRICING_ACTIVE_VARIANTS) {
// Filter variants by "active" status
options.params.active = true;
}
table.inventreeTable({
url: '{% url "api-part-list" %}',
name: 'variantpricingtable',

View File

@ -130,6 +130,10 @@ function getAvailableTableFilters(tableKey) {
title: '{% trans "Include sublocations" %}',
description: '{% trans "Include locations" %}',
},
structural: {
type: 'bool',
title: '{% trans "Structural" %}',
},
};
}
@ -141,6 +145,10 @@ function getAvailableTableFilters(tableKey) {
title: '{% trans "Include subcategories" %}',
description: '{% trans "Include subcategories" %}',
},
structural: {
type: 'bool',
title: '{% trans "Structural" %}',
},
starred: {
type: 'bool',
title: '{% trans "Subscribed" %}',

View File

@ -132,6 +132,8 @@ There are several options to deploy InvenTree.
<div align="center"><h4>
<a href="https://inventree.readthedocs.io/en/latest/start/docker/">Docker</a>
<span> · </span>
<a href="https://marketplace.digitalocean.com/apps/inventree?refcode=d6172576d014"><img src="https://www.deploytodo.com/do-btn-blue-ghost.svg" alt="Deploy to DO" width="auto" height="40" /></a>
<span> · </span>
<a href="https://inventree.readthedocs.io/en/latest/start/install/">Bare Metal</a>
</h4></div>

View File

@ -55,10 +55,21 @@ root_command() {
# Check if os and version is supported
get_distribution
echo "### Detected distribution: $OS $VER"
SUPPORTED=true
SUPPORTED=true # is thos OS supported?
NEEDS_LIBSSL1_1=false # does this OS need libssl1.1?
DIST_OS=${OS,,}
DIST_VER=$VER
case "$OS" in
Ubuntu)
if [[ $VER != "20.04" ]]; then
if [[ $VER == "22.04" ]]; then
SUPPORTED=true
NEEDS_LIBSSL1_1=true
DIST_VER="20.04"
elif [[ $VER == "20.04" ]]; then
SUPPORTED=true
else
SUPPORTED=false
fi
;;
@ -93,10 +104,19 @@ root_command() {
fi
done
if [[ $NEEDS_LIBSSL1_1 == "true" ]]; then
echo "### Pathching for libssl1.1"
echo "deb http://security.ubuntu.com/ubuntu focal-security main" | sudo tee /etc/apt/sources.list.d/focal-security.list
do_call "sudo apt-get update"
do_call "sudo apt-get install libssl1.1"
sudo rm /etc/apt/sources.list.d/focal-security.list
fi
echo "### Getting and adding key"
wget -qO- https://dl.packager.io/srv/$publisher/InvenTree/key | sudo apt-key add -
echo "### Adding package source"
do_call "sudo wget -O /etc/apt/sources.list.d/inventree.list https://dl.packager.io/srv/$publisher/InvenTree/$source_url/installer/${OS,,}/${VER}.repo"
do_call "sudo wget -O /etc/apt/sources.list.d/inventree.list https://dl.packager.io/srv/$publisher/InvenTree/$source_url/installer/$DIST_OS/$DIST_VER.repo"
echo "### Updateing package lists"
do_call "sudo apt-get update"

View File

@ -45,10 +45,21 @@ echo "### Installer for InvenTree - source: $publisher/$source_url"
# Check if os and version is supported
get_distribution
echo "### Detected distribution: $OS $VER"
SUPPORTED=true
SUPPORTED=true # is thos OS supported?
NEEDS_LIBSSL1_1=false # does this OS need libssl1.1?
DIST_OS=${OS,,}
DIST_VER=$VER
case "$OS" in
Ubuntu)
if [[ $VER != "20.04" ]]; then
if [[ $VER == "22.04" ]]; then
SUPPORTED=true
NEEDS_LIBSSL1_1=true
DIST_VER="20.04"
elif [[ $VER == "20.04" ]]; then
SUPPORTED=true
else
SUPPORTED=false
fi
;;
@ -83,10 +94,19 @@ for pkg in $REQS; do
fi
done
if [[ $NEEDS_LIBSSL1_1 == "true" ]]; then
echo "### Pathching for libssl1.1"
echo "deb http://security.ubuntu.com/ubuntu focal-security main" | sudo tee /etc/apt/sources.list.d/focal-security.list
do_call "sudo apt-get update"
do_call "sudo apt-get install libssl1.1"
sudo rm /etc/apt/sources.list.d/focal-security.list
fi
echo "### Getting and adding key"
wget -qO- https://dl.packager.io/srv/$publisher/InvenTree/key | sudo apt-key add -
echo "### Adding package source"
do_call "sudo wget -O /etc/apt/sources.list.d/inventree.list https://dl.packager.io/srv/$publisher/InvenTree/$source_url/installer/${OS,,}/${VER}.repo"
do_call "sudo wget -O /etc/apt/sources.list.d/inventree.list https://dl.packager.io/srv/$publisher/InvenTree/$source_url/installer/$DIST_OS/$DIST_VER.repo"
echo "### Updateing package lists"
do_call "sudo apt-get update"