mirror of
https://github.com/inventree/InvenTree.git
synced 2025-12-18 04:45:12 -06:00
Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d4d9aa9d1b | ||
|
|
54f2072e97 | ||
|
|
d1042cde0e | ||
|
|
5f4275679d | ||
|
|
1ba0bee1ea | ||
|
|
ea7aa93a28 | ||
|
|
9eccf69456 | ||
|
|
9cebfa85df | ||
|
|
af3cf62b8e | ||
|
|
f20a1245e7 | ||
|
|
92a4989a8d | ||
|
|
be3b22ce36 | ||
|
|
258b8e4ecc | ||
|
|
7df92aad03 | ||
|
|
2dac705779 |
7
.github/actions/setup/action.yaml
vendored
7
.github/actions/setup/action.yaml
vendored
@@ -49,9 +49,10 @@ runs:
|
||||
shell: bash
|
||||
run: |
|
||||
python3 -m pip install -U pip
|
||||
pip3 install invoke wheel uv
|
||||
- name: Set the VIRTUAL_ENV variable for uv to work
|
||||
run: echo "VIRTUAL_ENV=${Python_ROOT_DIR}" >> $GITHUB_ENV
|
||||
pip3 install -U invoke wheel
|
||||
pip3 install 'uv<0.3.0'
|
||||
- name: Allow uv to use the system Python by default
|
||||
run: echo "UV_SYSTEM_PYTHON=1" >> $GITHUB_ENV
|
||||
shell: bash
|
||||
- name: Install Specific Python Dependencies
|
||||
if: ${{ inputs.pip-dependency }}
|
||||
|
||||
7
.github/workflows/docker.yaml
vendored
7
.github/workflows/docker.yaml
vendored
@@ -73,7 +73,7 @@ jobs:
|
||||
python-version: ${{ env.python_version }}
|
||||
- name: Version Check
|
||||
run: |
|
||||
pip install --require-hashes -r .github/requirements.txt
|
||||
pip install --require-hashes -r contrib/dev_reqs/requirements.txt
|
||||
python3 .github/scripts/version_check.py
|
||||
echo "git_commit_hash=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
|
||||
echo "git_commit_date=$(git show -s --format=%ci)" >> $GITHUB_ENV
|
||||
@@ -85,12 +85,17 @@ jobs:
|
||||
docker run --rm inventree-test invoke --list
|
||||
docker run --rm inventree-test gunicorn --version
|
||||
docker run --rm inventree-test pg_dump --version
|
||||
docker run --rm inventree-test test -f /home/inventree/init.sh
|
||||
docker run --rm inventree-test test -f /home/inventree/tasks.py
|
||||
docker run --rm inventree-test test -f /home/inventree/gunicorn.conf.py
|
||||
docker run --rm inventree-test test -f /home/inventree/src/backend/requirements.txt
|
||||
docker run --rm inventree-test test -f /home/inventree/src/backend/InvenTree/manage.py
|
||||
- name: Build Docker Image
|
||||
# Build the development docker image (using docker-compose.yml)
|
||||
run: docker compose --project-directory . -f contrib/container/dev-docker-compose.yml build --no-cache
|
||||
- name: Update Docker Image
|
||||
run: |
|
||||
docker compose --project-directory . -f contrib/container/dev-docker-compose.yml run inventree-dev-server invoke install
|
||||
docker compose --project-directory . -f contrib/container/dev-docker-compose.yml run inventree-dev-server invoke update
|
||||
docker compose --project-directory . -f contrib/container/dev-docker-compose.yml run inventree-dev-server invoke setup-dev
|
||||
docker compose --project-directory . -f contrib/container/dev-docker-compose.yml up -d
|
||||
|
||||
8
.github/workflows/qc_checks.yaml
vendored
8
.github/workflows/qc_checks.yaml
vendored
@@ -104,7 +104,7 @@ jobs:
|
||||
uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # pin@v3.0.1
|
||||
- name: Check Version
|
||||
run: |
|
||||
pip install --require-hashes -r .github/requirements.txt
|
||||
pip install --require-hashes -r contrib/dev_reqs/requirements.txt
|
||||
python3 .github/scripts/version_check.py
|
||||
|
||||
mkdocs:
|
||||
@@ -122,7 +122,7 @@ jobs:
|
||||
python-version: ${{ env.python_version }}
|
||||
- name: Check Config
|
||||
run: |
|
||||
pip install --require-hashes -r .github/requirements.txt
|
||||
pip install --require-hashes -r contrib/dev_reqs/requirements.txt
|
||||
pip install --require-hashes -r docs/requirements.txt
|
||||
python docs/ci/check_mkdocs_config.py
|
||||
- name: Check Links
|
||||
@@ -168,7 +168,7 @@ jobs:
|
||||
- name: Download public schema
|
||||
if: needs.paths-filter.outputs.api == 'false'
|
||||
run: |
|
||||
pip install --require-hashes -r .github/requirements.txt >/dev/null 2>&1
|
||||
pip install --require-hashes -r contrib/dev_reqs/requirements.txt >/dev/null 2>&1
|
||||
version="$(python3 .github/scripts/version_check.py only_version 2>&1)"
|
||||
echo "Version: $version"
|
||||
url="https://raw.githubusercontent.com/inventree/schema/main/export/${version}/api.yaml"
|
||||
@@ -187,7 +187,7 @@ jobs:
|
||||
id: version
|
||||
if: github.ref == 'refs/heads/master' && needs.paths-filter.outputs.api == 'true'
|
||||
run: |
|
||||
pip install --require-hashes -r .github/requirements.txt >/dev/null 2>&1
|
||||
pip install --require-hashes -r contrib/dev_reqs/requirements.txt >/dev/null 2>&1
|
||||
version="$(python3 .github/scripts/version_check.py only_version 2>&1)"
|
||||
echo "Version: $version"
|
||||
echo "version=$version" >> "$GITHUB_OUTPUT"
|
||||
|
||||
11
.github/workflows/release.yaml
vendored
11
.github/workflows/release.yaml
vendored
@@ -5,12 +5,12 @@ on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
stable:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
steps:
|
||||
@@ -18,7 +18,7 @@ jobs:
|
||||
uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # pin@v4.1.5
|
||||
- name: Version Check
|
||||
run: |
|
||||
pip install --require-hashes -r .github/requirements.txt
|
||||
pip install --require-hashes -r contrib/dev_reqs/requirements.txt
|
||||
python3 .github/scripts/version_check.py
|
||||
- name: Push to Stable Branch
|
||||
uses: ad-m/github-push-action@d91a481090679876dfc4178fef17f286781251df # pin@v0.8.0
|
||||
@@ -30,6 +30,9 @@ jobs:
|
||||
|
||||
publish-build:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # pin@v4.1.5
|
||||
- name: Environment Setup
|
||||
|
||||
@@ -39,8 +39,8 @@ repos:
|
||||
files: src/backend/requirements\.(in|txt)$
|
||||
- id: pip-compile
|
||||
name: pip-compile requirements.txt
|
||||
args: [.github/requirements.in, -o, .github/requirements.txt,--python-version=3.9, --no-strip-extras, --generate-hashes]
|
||||
files: .github/requirements\.(in|txt)$
|
||||
args: [contrib/dev_reqs/requirements.in, -o, contrib/dev_reqs/requirements.txt,--python-version=3.9, --no-strip-extras, --generate-hashes]
|
||||
files: contrib/dev_reqs/requirements\.(in|txt)$
|
||||
- id: pip-compile
|
||||
name: pip-compile requirements.txt
|
||||
args: [docs/requirements.in, -o, docs/requirements.txt,--python-version=3.9, --no-strip-extras, --generate-hashes]
|
||||
|
||||
@@ -128,6 +128,7 @@ COPY --from=prebuild /root/.local /root/.local
|
||||
|
||||
# Copy source code
|
||||
COPY src/backend/InvenTree ${INVENTREE_BACKEND_DIR}/InvenTree
|
||||
COPY src/backend/requirements.txt ${INVENTREE_BACKEND_DIR}/requirements.txt
|
||||
COPY --from=frontend ${INVENTREE_BACKEND_DIR}/InvenTree/web/static/web ${INVENTREE_BACKEND_DIR}/InvenTree/web/static/web
|
||||
|
||||
# Launch the production server
|
||||
|
||||
@@ -114,7 +114,7 @@ services:
|
||||
env_file:
|
||||
- .env
|
||||
volumes:
|
||||
- ./Caddyfile:/etc/caddy/Caddyfile:ro
|
||||
- ./Caddyfile:/etc/caddy/Caddyfile:ro,z
|
||||
- ${INVENTREE_EXT_VOLUME}/static:/var/www/static:z
|
||||
- ${INVENTREE_EXT_VOLUME}/media:/var/www/media:z
|
||||
- ${INVENTREE_EXT_VOLUME}:/var/log:z
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# uv pip compile .github/requirements.in -o .github/requirements.txt --python-version=3.9 --no-strip-extras --generate-hashes
|
||||
# uv pip compile contrib/dev_reqs/requirements.in -o contrib/dev_reqs/requirements.txt --python-version=3.9 --no-strip-extras --generate-hashes
|
||||
certifi==2024.2.2 \
|
||||
--hash=sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f \
|
||||
--hash=sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1
|
||||
@@ -44,6 +44,18 @@ function detect_ip() {
|
||||
echo "IP address is ${INVENTREE_IP}"
|
||||
}
|
||||
|
||||
function detect_python() {
|
||||
# Detect if there is already a python version installed in /opt/inventree/env/lib
|
||||
if test -f "${APP_HOME}/env/bin/python"; then
|
||||
echo "# Python environment already present"
|
||||
# Extract earliest python version initialised from /opt/inventree/env/lib
|
||||
SETUP_PYTHON=$(ls -1 ${APP_HOME}/env/bin/python* | sort | head -n 1)
|
||||
echo "# Found earliest version: ${SETUP_PYTHON}"
|
||||
else
|
||||
echo "# No python environment found - using ${SETUP_PYTHON}"
|
||||
fi
|
||||
}
|
||||
|
||||
function get_env() {
|
||||
envname=$1
|
||||
|
||||
@@ -90,7 +102,7 @@ function detect_envs() {
|
||||
echo "# Using existing config file: ${INVENTREE_CONFIG_FILE}"
|
||||
|
||||
# Install parser
|
||||
pip install --require-hashes -r ${APP_HOME}/.github/requirements.txt -q
|
||||
pip install --require-hashes -r ${APP_HOME}/contrib/dev_reqs/requirements.txt -q
|
||||
|
||||
# Load config
|
||||
local CONF=$(cat ${INVENTREE_CONFIG_FILE} | jc --yaml)
|
||||
@@ -163,12 +175,20 @@ function create_initscripts() {
|
||||
sudo -u ${APP_USER} --preserve-env=$SETUP_ENVS bash -c "cd ${APP_HOME} && ${SETUP_PYTHON} -m venv env"
|
||||
sudo -u ${APP_USER} --preserve-env=$SETUP_ENVS bash -c "cd ${APP_HOME} && env/bin/pip install invoke wheel"
|
||||
|
||||
# Check INSTALLER_EXTRA exists and load it
|
||||
if test -f "${APP_HOME}/INSTALLER_EXTRA"; then
|
||||
echo "# Loading extra packages from INSTALLER_EXTRA"
|
||||
source ${APP_HOME}/INSTALLER_EXTRA
|
||||
fi
|
||||
|
||||
if [ -n "${SETUP_EXTRA_PIP}" ]; then
|
||||
echo "# Installing extra pip packages"
|
||||
if [ -n "${SETUP_DEBUG}" ]; then
|
||||
echo "# Extra pip packages: ${SETUP_EXTRA_PIP}"
|
||||
fi
|
||||
sudo -u ${APP_USER} --preserve-env=$SETUP_ENVS bash -c "cd ${APP_HOME} && env/bin/pip install ${SETUP_EXTRA_PIP}"
|
||||
# Write extra packages to INSTALLER_EXTRA
|
||||
echo "SETUP_EXTRA_PIP='${SETUP_EXTRA_PIP}'" >>${APP_HOME}/INSTALLER_EXTRA
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -283,6 +303,20 @@ function set_env() {
|
||||
chown ${APP_USER}:${APP_GROUP} ${DATA_DIR} ${INVENTREE_CONFIG_FILE}
|
||||
}
|
||||
|
||||
function set_site() {
|
||||
# Ensure IP is known
|
||||
if [ -z "${INVENTREE_IP}" ]; then
|
||||
echo "# No IP address found - skipping"
|
||||
return
|
||||
fi
|
||||
|
||||
# Check if INVENTREE_SITE_URL in inventree config
|
||||
if [ -z "$(inventree config:get INVENTREE_SITE_URL)" ]; then
|
||||
echo "# Setting up InvenTree site URL"
|
||||
inventree config:set INVENTREE_SITE_URL=http://${INVENTREE_IP}
|
||||
fi
|
||||
}
|
||||
|
||||
function final_message() {
|
||||
echo -e "####################################################################################"
|
||||
echo -e "This InvenTree install uses nginx, the settings for the webserver can be found in"
|
||||
|
||||
@@ -33,6 +33,7 @@ detect_envs
|
||||
detect_docker
|
||||
detect_initcmd
|
||||
detect_ip
|
||||
detect_python
|
||||
|
||||
# create processes
|
||||
create_initscripts
|
||||
@@ -45,6 +46,7 @@ update_or_install
|
||||
if [ "${SETUP_CONF_LOADED}" = "true" ]; then
|
||||
set_env
|
||||
fi
|
||||
set_site
|
||||
start_inventree
|
||||
|
||||
# show info
|
||||
|
||||
@@ -96,7 +96,7 @@ The HEAD of the "stable" branch represents the latest stable release code.
|
||||
|
||||
## API versioning
|
||||
|
||||
The [API version](https://github.com/inventree/InvenTree/blob/master/src/backend/InvenTree/InvenTree/api_version.py) needs to be bumped every time when the API is changed.
|
||||
The [API version](https://github.com/inventree/InvenTree/blob/0.15.x/src/backend/InvenTree/InvenTree/api_version.py) needs to be bumped every time when the API is changed.
|
||||
|
||||
## Environment
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ Please read all release notes and watch out for warnings - we generally provide
|
||||
|
||||
#### Plugins
|
||||
|
||||
General classes and mechanisms are provided under the `plugin` [namespaces](https://github.com/inventree/InvenTree/blob/master/src/backend/InvenTree/plugin/__init__.py). These include:
|
||||
General classes and mechanisms are provided under the `plugin` [namespaces](https://github.com/inventree/InvenTree/blob/0.15.x/src/backend/InvenTree/plugin/__init__.py). These include:
|
||||
|
||||
```python
|
||||
# Management objects
|
||||
@@ -44,7 +44,7 @@ MixinNotImplementedError # Is raised if a mixin was not implemented (core mec
|
||||
|
||||
#### Mixins
|
||||
|
||||
Mixins are split up internally to keep the source tree clean and enable better testing separation. All public APIs that should be used are exposed under `plugin.mixins`. These include all built-in mixins and notification methods. An up-to-date reference can be found in the source code (current master can be [found here](https://github.com/inventree/InvenTree/blob/master/src/backend/InvenTree/plugin/mixins/__init__.py)).
|
||||
Mixins are split up internally to keep the source tree clean and enable better testing separation. All public APIs that should be used are exposed under `plugin.mixins`. These include all built-in mixins and notification methods. An up-to-date reference can be found in the source code (current master can be [found here](https://github.com/inventree/InvenTree/blob/0.15.x/src/backend/InvenTree/plugin/mixins/__init__.py)).
|
||||
|
||||
#### Models and other internal InvenTree APIs
|
||||
|
||||
|
||||
@@ -28,4 +28,4 @@ If a locate plugin is installed and activated, the [InvenTree mobile app](../../
|
||||
|
||||
### Implementation
|
||||
|
||||
Refer to the [InvenTree source code](https://github.com/inventree/InvenTree/blob/master/src/backend/InvenTree/plugin/samples/locate/locate_sample.py) for a simple implementation example.
|
||||
Refer to the [InvenTree source code](https://github.com/inventree/InvenTree/blob/0.15.x/src/backend/InvenTree/plugin/samples/locate/locate_sample.py) for a simple implementation example.
|
||||
|
||||
@@ -16,7 +16,7 @@ Additionally the `add_label_context` method, allowing custom context data to be
|
||||
|
||||
### Example
|
||||
|
||||
A sample plugin which provides additional context data to the report templates can be found [in the InvenTree source code](https://github.com/inventree/InvenTree/blob/master/src/backend/InvenTree/plugin/samples/integration/report_plugin_sample.py):
|
||||
A sample plugin which provides additional context data to the report templates can be found [in the InvenTree source code](https://github.com/inventree/InvenTree/blob/0.15.x/src/backend/InvenTree/plugin/samples/integration/report_plugin_sample.py):
|
||||
|
||||
```python
|
||||
"""Sample plugin for extending reporting functionality"""
|
||||
|
||||
@@ -59,4 +59,4 @@ class ScheduledTaskPlugin(ScheduleMixin, SettingsMixin, InvenTreePlugin):
|
||||
```
|
||||
|
||||
!!! info "More Info"
|
||||
For more information on any of the methods described below, refer to the InvenTree source code. [A working example is available as a starting point](https://github.com/inventree/InvenTree/blob/master/src/backend/InvenTree/plugin/samples/integration/scheduled_task.py).
|
||||
For more information on any of the methods described below, refer to the InvenTree source code. [A working example is available as a starting point](https://github.com/inventree/InvenTree/blob/0.15.x/src/backend/InvenTree/plugin/samples/integration/scheduled_task.py).
|
||||
|
||||
@@ -65,7 +65,7 @@ Additionally, add the following imports after the extended line.
|
||||
#### Blocks
|
||||
The page_base file is split into multiple sections called blocks. This allows you to implement sections of the webpage while getting many items like navbars, sidebars, and general layout provided for you.
|
||||
|
||||
The current default page base can be found [here](https://github.com/inventree/InvenTree/blob/master/src/backend/InvenTree/templates/page_base.html). Look through this file to determine overridable blocks. The [stock app](https://github.com/inventree/InvenTree/tree/master/src/backend/InvenTree/stock) offers a great example of implementing these blocks.
|
||||
The current default page base can be found [here](https://github.com/inventree/InvenTree/blob/0.15.x/src/backend/InvenTree/templates/page_base.html). Look through this file to determine overridable blocks. The [stock app](https://github.com/inventree/InvenTree/tree/master/src/backend/InvenTree/stock) offers a great example of implementing these blocks.
|
||||
|
||||
!!! warning "Sidebar Block"
|
||||
You may notice that implementing the `sidebar` block doesn't initially work. Be sure to enable the sidebar using JavaScript. This can be achieved by appending the following code, replacing `label` with a label of your choosing, to the end of your template file.
|
||||
|
||||
@@ -9,7 +9,7 @@ The `ValidationMixin` class enables plugins to perform custom validation of obje
|
||||
Any of the methods described below can be implemented in a custom plugin to provide functionality as required.
|
||||
|
||||
!!! info "More Info"
|
||||
For more information on any of the methods described below, refer to the InvenTree source code. [A working example is available as a starting point](https://github.com/inventree/InvenTree/blob/master/src/backend/InvenTree/plugin/samples/integration/validation_sample.py).
|
||||
For more information on any of the methods described below, refer to the InvenTree source code. [A working example is available as a starting point](https://github.com/inventree/InvenTree/blob/0.15.x/src/backend/InvenTree/plugin/samples/integration/validation_sample.py).
|
||||
|
||||
!!! info "Multi Plugin Support"
|
||||
It is possible to have multiple plugins loaded simultaneously which support validation methods. For example when validating a field, if one plugin returns a null value (`None`) then the *next* plugin (if available) will be queried.
|
||||
|
||||
@@ -183,4 +183,4 @@ Finally added a `{% raw %}|floatformat:0{% endraw %}` to the quantity that remov
|
||||
|
||||
A default *BOM Report* template is provided out of the box, which is useful for generating simple test reports. Furthermore, it may be used as a starting point for developing custom BOM reports:
|
||||
|
||||
View the [source code](https://github.com/inventree/InvenTree/blob/master/src/backend/InvenTree/report/templates/report/inventree_bill_of_materials_report.html) for the default test report template.
|
||||
View the [source code](https://github.com/inventree/InvenTree/blob/0.15.x/src/backend/InvenTree/report/templates/report/inventree_bill_of_materials_report.html) for the default test report template.
|
||||
|
||||
@@ -321,4 +321,4 @@ This will result a report page like this:
|
||||
|
||||
A default *Build Report* template is provided out of the box, which is useful for generating simple test reports. Furthermore, it may be used as a starting point for developing custom BOM reports:
|
||||
|
||||
View the [source code](https://github.com/inventree/InvenTree/blob/master/src/backend/InvenTree/report/templates/report/inventree_build_order_base.html) for the default build report template.
|
||||
View the [source code](https://github.com/inventree/InvenTree/blob/0.15.x/src/backend/InvenTree/report/templates/report/inventree_build_order_base.html) for the default build report template.
|
||||
|
||||
@@ -12,7 +12,7 @@ Some common functions are provided for use in custom report and label templates.
|
||||
```
|
||||
|
||||
!!! tip "Use the Source, Luke"
|
||||
To see the full range of available helper functions, refer to the source file [report.py](https://github.com/inventree/InvenTree/blob/master/src/backend/InvenTree/report/templatetags/report.py) where these functions are defined!
|
||||
To see the full range of available helper functions, refer to the source file [report.py](https://github.com/inventree/InvenTree/blob/0.15.x/src/backend/InvenTree/report/templatetags/report.py) where these functions are defined!
|
||||
|
||||
## Assigning Variables
|
||||
|
||||
|
||||
@@ -62,4 +62,4 @@ Price: {% render_currency line.total_line_price %}
|
||||
|
||||
A default *Purchase Order Report* template is provided out of the box, which is useful for generating simple test reports. Furthermore, it may be used as a starting point for developing custom BOM reports:
|
||||
|
||||
View the [source code](https://github.com/inventree/InvenTree/blob/master/src/backend/InvenTree/report/templates/report/inventree_po_report_base.html) for the default purchase order report template.
|
||||
View the [source code](https://github.com/inventree/InvenTree/blob/0.15.x/src/backend/InvenTree/report/templates/report/inventree_po_report_base.html) for the default purchase order report template.
|
||||
|
||||
@@ -23,4 +23,4 @@ In addition to the default report context variables, the following context varia
|
||||
|
||||
A default report template is provided out of the box, which can be used as a starting point for developing custom return order report templates.
|
||||
|
||||
View the [source code](https://github.com/inventree/InvenTree/blob/master/src/backend/InvenTree/report/templates/report/inventree_return_order_report_base.html) for the default return order report template.
|
||||
View the [source code](https://github.com/inventree/InvenTree/blob/0.15.x/src/backend/InvenTree/report/templates/report/inventree_return_order_report_base.html) for the default return order report template.
|
||||
|
||||
@@ -28,4 +28,4 @@ In addition to the default report context variables, the following variables are
|
||||
|
||||
A default *Sales Order Report* template is provided out of the box, which is useful for generating simple test reports. Furthermore, it may be used as a starting point for developing custom BOM reports:
|
||||
|
||||
View the [source code](https://github.com/inventree/InvenTree/blob/master/src/backend/InvenTree/report/templates/report/inventree_so_report_base.html) for the default sales order report template.
|
||||
View the [source code](https://github.com/inventree/InvenTree/blob/0.15.x/src/backend/InvenTree/report/templates/report/inventree_so_report_base.html) for the default sales order report template.
|
||||
|
||||
@@ -13,4 +13,4 @@ You can use all content variables from the [StockLocation](./context_variables.m
|
||||
|
||||
A default report template is provided out of the box, which can be used as a starting point for developing custom return order report templates.
|
||||
|
||||
View the [source code](https://github.com/inventree/InvenTree/blob/master/src/backend/InvenTree/report/templates/report/inventree_slr_report.html) for the default stock location report template.
|
||||
View the [source code](https://github.com/inventree/InvenTree/blob/0.15.x/src/backend/InvenTree/report/templates/report/inventree_slr_report.html) for the default stock location report template.
|
||||
|
||||
@@ -84,4 +84,4 @@ A default *Test Report* template is provided out of the box, which is useful for
|
||||
{% include "img.html" %}
|
||||
{% endwith %}
|
||||
|
||||
View the [source code](https://github.com/inventree/InvenTree/blob/master/src/backend/InvenTree/report/templates/report/inventree_test_report_base.html) for the default test report template.
|
||||
View the [source code](https://github.com/inventree/InvenTree/blob/0.15.x/src/backend/InvenTree/report/templates/report/inventree_test_report_base.html) for the default test report template.
|
||||
|
||||
@@ -22,7 +22,7 @@ The InvenTree server tries to locate the `config.yaml` configuration file on sta
|
||||
!!! tip "Config File Location"
|
||||
When the InvenTree server boots, it will report the location where it expects to find the configuration file
|
||||
|
||||
The configuration file *template* can be found on [GitHub](https://github.com/inventree/InvenTree/blob/master/src/backend/InvenTree/config_template.yaml)
|
||||
The configuration file *template* can be found on [GitHub](https://github.com/inventree/InvenTree/blob/0.15.x/src/backend/InvenTree/config_template.yaml)
|
||||
|
||||
!!! info "Template File"
|
||||
The default configuration file (as defined by the template linked above) will be copied to the specified configuration file location on first run, if a configuration file is not found in that location.
|
||||
|
||||
@@ -15,6 +15,14 @@ wget -qO install.sh https://get.inventree.org && bash install.sh
|
||||
|
||||
This script does all manual steps without any input. The installation might take up to 5-10 minutes to finish.
|
||||
|
||||
#### Permission Denied Error
|
||||
|
||||
The above command may need to be run with `sudo` permissions, depending on the system configuration. So, if the script fails with a permission error, try:
|
||||
|
||||
```bash
|
||||
sudo wget -qO install.sh https://get.inventree.org && sudo bash install.sh
|
||||
```
|
||||
|
||||
### File Locations
|
||||
|
||||
The installer creates the following directories:
|
||||
|
||||
@@ -1022,8 +1022,12 @@ if SITE_URL:
|
||||
logger.info('Using Site URL: %s', SITE_URL)
|
||||
|
||||
# Check that the site URL is valid
|
||||
validator = URLValidator()
|
||||
validator(SITE_URL)
|
||||
try:
|
||||
validator = URLValidator()
|
||||
validator(SITE_URL)
|
||||
except Exception:
|
||||
print(f"Invalid SITE_URL value: '{SITE_URL}'. InvenTree server cannot start.")
|
||||
sys.exit(-1)
|
||||
|
||||
# Enable or disable multi-site framework
|
||||
SITE_MULTI = get_boolean_setting('INVENTREE_SITE_MULTI', 'site_multi', False)
|
||||
|
||||
@@ -19,7 +19,7 @@ from dulwich.repo import NotGitRepository, Repo
|
||||
from .api_version import INVENTREE_API_TEXT, INVENTREE_API_VERSION
|
||||
|
||||
# InvenTree software version
|
||||
INVENTREE_SW_VERSION = '0.15.0 dev'
|
||||
INVENTREE_SW_VERSION = '0.15.3'
|
||||
|
||||
# Discover git
|
||||
try:
|
||||
|
||||
@@ -237,6 +237,16 @@ class BuildOutputCreateSerializer(serializers.Serializer):
|
||||
The Build object is provided to the serializer context.
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
"""Serializer metaclass."""
|
||||
fields = [
|
||||
'quantity',
|
||||
'batch_code',
|
||||
'serial_numbers',
|
||||
'location',
|
||||
'auto_allocate',
|
||||
]
|
||||
|
||||
quantity = serializers.DecimalField(
|
||||
max_digits=15,
|
||||
decimal_places=5,
|
||||
@@ -639,6 +649,14 @@ class OverallocationChoice():
|
||||
class BuildCompleteSerializer(serializers.Serializer):
|
||||
"""DRF serializer for marking a BuildOrder as complete."""
|
||||
|
||||
class Meta:
|
||||
"""Serializer metaclass"""
|
||||
fields = [
|
||||
'accept_overallocated',
|
||||
'accept_unallocated',
|
||||
'accept_incomplete',
|
||||
]
|
||||
|
||||
def get_context_data(self):
|
||||
"""Retrieve extra context data for this serializer.
|
||||
|
||||
@@ -732,6 +750,13 @@ class BuildUnallocationSerializer(serializers.Serializer):
|
||||
- bom_item: Filter against a particular BOM line item
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
"""Serializer metaclass"""
|
||||
fields = [
|
||||
'build_line',
|
||||
'output',
|
||||
]
|
||||
|
||||
build_line = serializers.PrimaryKeyRelatedField(
|
||||
queryset=BuildLine.objects.all(),
|
||||
many=False,
|
||||
|
||||
@@ -233,6 +233,7 @@
|
||||
|
||||
{% settings_value "TEST_STATION_DATA" as test_station_fields %}
|
||||
|
||||
{% if item.part.trackable %}
|
||||
loadStockTestResultsTable(
|
||||
$("#test-result-table"), {
|
||||
part: {{ item.part.id }},
|
||||
@@ -248,6 +249,7 @@
|
||||
url: '{% url "api-stockitem-testreport-list" %}',
|
||||
});
|
||||
});
|
||||
{% endif %}
|
||||
|
||||
{% if user.is_staff %}
|
||||
$("#delete-test-results").click(function() {
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
{% for line in lines %}
|
||||
<tr style="height: 2.5rem; border-bottom: 1px solid">
|
||||
<td style='padding-left: 1em;'>
|
||||
<a href='{{ line.link }}'>{{ line.part.full_name }}</a>{% if part.description %} - <em>{{ part.description }}</em>{% endif %}
|
||||
<a href='{{ line.link }}'>{{ line.part.full_name }}</a>{% if line.part.description %} - <em>{{ line.part.description }}</em>{% endif %}
|
||||
</td>
|
||||
<td style="text-align: center;">
|
||||
{% decimal line.required %} {% include "part/part_units.html" with part=line.part %}
|
||||
|
||||
@@ -3,11 +3,12 @@
|
||||
import datetime
|
||||
import logging
|
||||
|
||||
from django.contrib.auth import get_user, login
|
||||
from django.contrib.auth import get_user, login, logout
|
||||
from django.contrib.auth.models import Group, User
|
||||
from django.urls import include, path, re_path
|
||||
from django.views.generic.base import RedirectView
|
||||
|
||||
from allauth.account.adapter import get_adapter
|
||||
from dj_rest_auth.views import LoginView, LogoutView
|
||||
from drf_spectacular.utils import OpenApiResponse, extend_schema, extend_schema_view
|
||||
from rest_framework import exceptions, permissions
|
||||
@@ -17,6 +18,7 @@ from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
|
||||
import InvenTree.helpers
|
||||
from common.models import InvenTreeSetting
|
||||
from InvenTree.filters import SEARCH_ORDER_FILTER
|
||||
from InvenTree.mixins import (
|
||||
ListAPI,
|
||||
@@ -216,7 +218,22 @@ class GroupList(ListCreateAPI):
|
||||
class Login(LoginView):
|
||||
"""API view for logging in via API."""
|
||||
|
||||
...
|
||||
def process_login(self):
|
||||
"""Process the login request, ensure that MFA is enforced if required."""
|
||||
# Normal login process
|
||||
ret = super().process_login()
|
||||
|
||||
# Now check if MFA is enforced
|
||||
user = self.request.user
|
||||
adapter = get_adapter(self.request)
|
||||
|
||||
# User requires 2FA or MFA is enforced globally - no logins via API
|
||||
if adapter.has_2fa_enabled(user) or InvenTreeSetting.get_setting(
|
||||
'LOGIN_ENFORCE_MFA'
|
||||
):
|
||||
logout(self.request)
|
||||
raise exceptions.PermissionDenied('MFA required for this user')
|
||||
return ret
|
||||
|
||||
|
||||
@extend_schema_view(
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
# Generated by Django 4.2.12 on 2024-05-23 16:40
|
||||
|
||||
from importlib import import_module
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
def clear_sessions(apps, schema_editor):
|
||||
"""Clear all user sessions."""
|
||||
|
||||
try:
|
||||
engine = import_module(settings.SESSION_ENGINE)
|
||||
engine.SessionStore.clear_expired()
|
||||
print('Cleared all user sessions to deal with GHSA-2crp-q9pc-457j')
|
||||
except Exception:
|
||||
# Database may not be ready yet, so this does not matter anyhow
|
||||
pass
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
atomic = False
|
||||
|
||||
dependencies = [
|
||||
("users", "0010_alter_apitoken_key"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(
|
||||
clear_sessions, reverse_code=migrations.RunPython.noop,
|
||||
)
|
||||
]
|
||||
13
tasks.py
13
tasks.py
@@ -230,7 +230,12 @@ def plugins(c, uv=False):
|
||||
@task(help={'uv': 'Use UV package manager (experimental)'})
|
||||
def install(c, uv=False):
|
||||
"""Installs required python packages."""
|
||||
print("Installing required python packages from 'src/backend/requirements.txt'")
|
||||
INSTALL_FILE = 'src/backend/requirements.txt'
|
||||
|
||||
print(f"Installing required python packages from '{INSTALL_FILE}'")
|
||||
|
||||
if not Path(INSTALL_FILE).is_file():
|
||||
raise FileNotFoundError(f"Requirements file '{INSTALL_FILE}' not found")
|
||||
|
||||
# Install required Python packages with PIP
|
||||
if not uv:
|
||||
@@ -238,13 +243,13 @@ def install(c, uv=False):
|
||||
'pip3 install --no-cache-dir --disable-pip-version-check -U pip setuptools'
|
||||
)
|
||||
c.run(
|
||||
'pip3 install --no-cache-dir --disable-pip-version-check -U --require-hashes -r src/backend/requirements.txt'
|
||||
f'pip3 install --no-cache-dir --disable-pip-version-check -U --require-hashes -r {INSTALL_FILE}'
|
||||
)
|
||||
else:
|
||||
c.run(
|
||||
'pip3 install --no-cache-dir --disable-pip-version-check -U uv setuptools'
|
||||
)
|
||||
c.run('uv pip install -U --require-hashes -r src/backend/requirements.txt')
|
||||
c.run(f'uv pip install -U --require-hashes -r {INSTALL_FILE}')
|
||||
|
||||
# Run plugins install
|
||||
plugins(c, uv=uv)
|
||||
@@ -403,7 +408,7 @@ def restore(
|
||||
ignore_database=False,
|
||||
):
|
||||
"""Restore the database and media files."""
|
||||
base_cmd = '--no-input --uncompress -v 2'
|
||||
base_cmd = '--noinput --uncompress -v 2'
|
||||
|
||||
if path:
|
||||
base_cmd += f' -I {path}'
|
||||
|
||||
Reference in New Issue
Block a user