Compare commits
22 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
fa1a9da23a | ||
|
fe09437214 | ||
|
f1dfced89b | ||
|
d7c76aab9d | ||
|
dfdaddbc7e | ||
|
1f6e52138a | ||
|
e8c9ec076c | ||
|
d4d9aa9d1b | ||
|
54f2072e97 | ||
|
d1042cde0e | ||
|
5f4275679d | ||
|
1ba0bee1ea | ||
|
ea7aa93a28 | ||
|
9eccf69456 | ||
|
9cebfa85df | ||
|
af3cf62b8e | ||
|
f20a1245e7 | ||
|
92a4989a8d | ||
|
be3b22ce36 | ||
|
258b8e4ecc | ||
|
7df92aad03 | ||
|
2dac705779 |
@ -1,3 +1,5 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
db:
|
||||
image: postgres:13
|
||||
@ -11,12 +13,6 @@ services:
|
||||
POSTGRES_USER: inventree_user
|
||||
POSTGRES_PASSWORD: inventree_password
|
||||
|
||||
redis:
|
||||
image: redis:7.0
|
||||
restart: always
|
||||
expose:
|
||||
- 6379
|
||||
|
||||
inventree:
|
||||
build:
|
||||
context: ..
|
||||
@ -35,8 +31,6 @@ services:
|
||||
INVENTREE_DB_HOST: db
|
||||
INVENTREE_DB_USER: inventree_user
|
||||
INVENTREE_DB_PASSWORD: inventree_password
|
||||
INVENTREE_CACHE_HOST: redis
|
||||
INVENTREE_CACHE_PORT: 6379
|
||||
INVENTREE_PLUGINS_ENABLED: True
|
||||
INVENTREE_SITE_URL: http://localhost:8000
|
||||
INVENTREE_CORS_ORIGIN_ALLOW_ALL: True
|
||||
|
4
.github/FUNDING.yml
vendored
@ -1,3 +1,5 @@
|
||||
polar: inventree
|
||||
github: inventree
|
||||
ko_fi: inventree
|
||||
patreon: inventree
|
||||
polar: inventree
|
||||
custom: [paypal.me/inventree]
|
||||
|
1
.github/ISSUE_TEMPLATE/config.yml
vendored
@ -1 +0,0 @@
|
||||
blank_issues_enabled: false
|
4
.github/actions/migration/action.yaml
vendored
@ -13,5 +13,5 @@ runs:
|
||||
invoke export-records -f data.json
|
||||
python3 ./src/backend/InvenTree/manage.py flush --noinput
|
||||
invoke migrate
|
||||
invoke import-records -c -f data.json
|
||||
invoke import-records -c -f data.json
|
||||
invoke import-records -f data.json
|
||||
invoke import-records -f data.json
|
||||
|
9
.github/actions/setup/action.yaml
vendored
@ -44,11 +44,6 @@ runs:
|
||||
with:
|
||||
python-version: ${{ env.python_version }}
|
||||
cache: pip
|
||||
cache-dependency-path: |
|
||||
src/backend/requirements.txt
|
||||
src/backend/requirements-dev.txt
|
||||
contrib/container/requirements.txt
|
||||
contrib/dev_reqs/requirements.txt
|
||||
- name: Install Base Python Dependencies
|
||||
if: ${{ inputs.python == 'true' }}
|
||||
shell: bash
|
||||
@ -88,7 +83,7 @@ runs:
|
||||
|
||||
# Invoke commands
|
||||
- name: Install dev requirements
|
||||
if: ${{ inputs.dev-install == 'true' || inputs.install == 'true' }}
|
||||
if: ${{ inputs.dev-install == 'true' ||inputs.install == 'true' }}
|
||||
shell: bash
|
||||
run: uv pip install --require-hashes -r src/backend/requirements-dev.txt
|
||||
- name: Run invoke install
|
||||
@ -98,4 +93,4 @@ runs:
|
||||
- name: Run invoke update
|
||||
if: ${{ inputs.update == 'true' }}
|
||||
shell: bash
|
||||
run: invoke update --uv --skip-backup --skip-static
|
||||
run: invoke update --uv
|
||||
|
34
.github/dependabot.yml
vendored
@ -15,11 +15,22 @@ updates:
|
||||
interval: weekly
|
||||
|
||||
- package-ecosystem: pip
|
||||
directories:
|
||||
- /contrib/container
|
||||
- /docs
|
||||
- /contrib/dev_reqs
|
||||
- /src/backend
|
||||
directory: /contrib/container
|
||||
schedule:
|
||||
interval: weekly
|
||||
|
||||
- package-ecosystem: pip
|
||||
directory: /docs
|
||||
schedule:
|
||||
interval: weekly
|
||||
|
||||
- package-ecosystem: pip
|
||||
directory: /.github
|
||||
schedule:
|
||||
interval: weekly
|
||||
|
||||
- package-ecosystem: pip
|
||||
directory: /src/backend
|
||||
schedule:
|
||||
interval: weekly
|
||||
groups:
|
||||
@ -28,9 +39,16 @@ updates:
|
||||
- "*" # Include all dependencies
|
||||
|
||||
- package-ecosystem: npm
|
||||
directories:
|
||||
- /src/frontend
|
||||
- /src/backend
|
||||
directory: /src/backend
|
||||
schedule:
|
||||
interval: weekly
|
||||
groups:
|
||||
dependencies:
|
||||
patterns:
|
||||
- "*" # Include all dependencies
|
||||
|
||||
- package-ecosystem: npm
|
||||
directory: /src/frontend
|
||||
schedule:
|
||||
interval: weekly
|
||||
groups:
|
||||
|
4
.github/scripts/check_js_templates.py
vendored
@ -71,7 +71,7 @@ def check_prohibited_tags(data):
|
||||
for filename in pathlib.Path(js_i18n_dir).rglob('*.js'):
|
||||
print(f"Checking file 'translated/{os.path.basename(filename)}':")
|
||||
|
||||
with open(filename, encoding='utf-8') as js_file:
|
||||
with open(filename, 'r') as js_file:
|
||||
data = js_file.readlines()
|
||||
|
||||
errors += check_invalid_tag(data)
|
||||
@ -81,7 +81,7 @@ for filename in pathlib.Path(js_dynamic_dir).rglob('*.js'):
|
||||
print(f"Checking file 'dynamic/{os.path.basename(filename)}':")
|
||||
|
||||
# Check that the 'dynamic' files do not contains any translated strings
|
||||
with open(filename, encoding='utf-8') as js_file:
|
||||
with open(filename, 'r') as js_file:
|
||||
data = js_file.readlines()
|
||||
|
||||
invalid_tags = ['blocktrans', 'blocktranslate', 'trans', 'translate']
|
||||
|
4
.github/scripts/check_migration_files.py
vendored
@ -20,9 +20,9 @@ for line in str(out.decode()).split('\n'):
|
||||
if len(migrations) == 0:
|
||||
sys.exit(0)
|
||||
|
||||
print(f'There are {len(migrations)} unstaged migration files:')
|
||||
print('There are {n} unstaged migration files:'.format(n=len(migrations)))
|
||||
|
||||
for m in migrations:
|
||||
print(f' - {m}')
|
||||
print(' - {m}'.format(m=m))
|
||||
|
||||
sys.exit(len(migrations))
|
||||
|
42
.github/scripts/version_check.py
vendored
@ -10,7 +10,6 @@ tagged branch:
|
||||
|
||||
"""
|
||||
|
||||
import itertools
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
@ -19,11 +18,8 @@ from pathlib import Path
|
||||
|
||||
import requests
|
||||
|
||||
REPO = os.getenv('GITHUB_REPOSITORY', 'inventree/inventree')
|
||||
GITHUB_API_URL = os.getenv('GITHUB_API_URL', 'https://api.github.com')
|
||||
|
||||
|
||||
def get_existing_release_tags(include_prerelease=True):
|
||||
def get_existing_release_tags():
|
||||
"""Request information on existing releases via the GitHub API."""
|
||||
# Check for github token
|
||||
token = os.getenv('GITHUB_TOKEN', None)
|
||||
@ -32,7 +28,9 @@ def get_existing_release_tags(include_prerelease=True):
|
||||
if token:
|
||||
headers = {'Authorization': f'Bearer {token}'}
|
||||
|
||||
response = requests.get(f'{GITHUB_API_URL}/repos/{REPO}/releases', headers=headers)
|
||||
response = requests.get(
|
||||
'https://api.github.com/repos/inventree/inventree/releases', headers=headers
|
||||
)
|
||||
|
||||
if response.status_code != 200:
|
||||
raise ValueError(
|
||||
@ -52,9 +50,6 @@ def get_existing_release_tags(include_prerelease=True):
|
||||
print(f"Version '{tag}' did not match expected pattern")
|
||||
continue
|
||||
|
||||
if not include_prerelease and release['prerelease']:
|
||||
continue
|
||||
|
||||
tags.append([int(x) for x in match.groups()])
|
||||
|
||||
return tags
|
||||
@ -78,7 +73,7 @@ def check_version_number(version_string, allow_duplicate=False):
|
||||
version_tuple = [int(x) for x in match.groups()]
|
||||
|
||||
# Look through the existing releases
|
||||
existing = get_existing_release_tags(include_prerelease=False)
|
||||
existing = get_existing_release_tags()
|
||||
|
||||
# Assume that this is the highest release, unless told otherwise
|
||||
highest_release = True
|
||||
@ -89,17 +84,12 @@ def check_version_number(version_string, allow_duplicate=False):
|
||||
|
||||
if release > version_tuple:
|
||||
highest_release = False
|
||||
print(f'Found newer release: {release!s}')
|
||||
print(f'Found newer release: {str(release)}')
|
||||
|
||||
return highest_release
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Ensure that we are running in GH Actions
|
||||
if os.environ.get('GITHUB_ACTIONS', '') != 'true':
|
||||
print('This script is intended to be run within a GitHub Action!')
|
||||
sys.exit(1)
|
||||
|
||||
if 'only_version' in sys.argv:
|
||||
here = Path(__file__).parent.absolute()
|
||||
version_file = here.joinpath(
|
||||
@ -107,18 +97,16 @@ if __name__ == '__main__':
|
||||
)
|
||||
text = version_file.read_text()
|
||||
results = re.findall(r"""INVENTREE_API_VERSION = (.*)""", text)
|
||||
# If 2. args is true lower the version number by 1
|
||||
if len(sys.argv) > 2 and sys.argv[2] == 'true':
|
||||
results[0] = str(int(results[0]) - 1)
|
||||
print(results[0])
|
||||
exit(0)
|
||||
|
||||
# GITHUB_REF_TYPE may be either 'branch' or 'tag'
|
||||
GITHUB_REF_TYPE = os.environ['GITHUB_REF_TYPE']
|
||||
|
||||
# GITHUB_REF may be either 'refs/heads/<branch>' or 'refs/heads/<tag>'
|
||||
GITHUB_REF = os.environ['GITHUB_REF']
|
||||
|
||||
GITHUB_REF_NAME = os.environ['GITHUB_REF_NAME']
|
||||
|
||||
GITHUB_BASE_REF = os.environ['GITHUB_BASE_REF']
|
||||
|
||||
# Print out version information, makes debugging actions *much* easier!
|
||||
@ -134,7 +122,7 @@ if __name__ == '__main__':
|
||||
|
||||
version = None
|
||||
|
||||
with open(version_file, encoding='utf-8') as f:
|
||||
with open(version_file, 'r') as f:
|
||||
text = f.read()
|
||||
|
||||
# Extract the InvenTree software version
|
||||
@ -175,7 +163,10 @@ if __name__ == '__main__':
|
||||
print(f"Version number '{version}' does not match tag '{version_tag}'")
|
||||
sys.exit
|
||||
|
||||
docker_tags = [version_tag, 'stable'] if highest_release else [version_tag]
|
||||
if highest_release:
|
||||
docker_tags = [version_tag, 'stable']
|
||||
else:
|
||||
docker_tags = [version_tag]
|
||||
|
||||
elif GITHUB_REF_TYPE == 'branch':
|
||||
# Otherwise we know we are targeting the 'master' branch
|
||||
@ -196,13 +187,10 @@ if __name__ == '__main__':
|
||||
print(f"Version check passed for '{version}'!")
|
||||
print(f"Docker tags: '{docker_tags}'")
|
||||
|
||||
target_repos = [REPO.lower(), f'ghcr.io/{REPO.lower()}']
|
||||
|
||||
# Ref: https://getridbug.com/python/how-to-set-environment-variables-in-github-actions-using-python/
|
||||
with open(os.getenv('GITHUB_ENV'), 'a', encoding='utf-8') as env_file:
|
||||
with open(os.getenv('GITHUB_ENV'), 'a') as env_file:
|
||||
# Construct tag string
|
||||
tag_list = [[f'{r}:{t}' for t in docker_tags] for r in target_repos]
|
||||
tags = ','.join(itertools.chain(*tag_list))
|
||||
tags = ','.join([f'inventree/inventree:{tag}' for tag in docker_tags])
|
||||
|
||||
env_file.write(f'docker_tags={tags}\n')
|
||||
|
||||
|
2
.github/workflows/check_translations.yaml
vendored
@ -30,7 +30,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # pin@v4.1.7
|
||||
uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # pin@v4.1.5
|
||||
- name: Environment Setup
|
||||
uses: ./.github/actions/setup
|
||||
with:
|
||||
|
29
.github/workflows/docker.yaml
vendored
@ -39,7 +39,7 @@ jobs:
|
||||
docker: ${{ steps.filter.outputs.docker }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # pin@v4.1.7
|
||||
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # pin@v4.1.5
|
||||
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # pin@v3.0.2
|
||||
id: filter
|
||||
with:
|
||||
@ -66,9 +66,9 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Check out repo
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # pin@v4.1.7
|
||||
uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # pin@v4.1.5
|
||||
- name: Set Up Python ${{ env.python_version }}
|
||||
uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # pin@v5.1.1
|
||||
uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # pin@v5.1.0
|
||||
with:
|
||||
python-version: ${{ env.python_version }}
|
||||
- name: Version Check
|
||||
@ -115,40 +115,39 @@ jobs:
|
||||
- name: Run Unit Tests
|
||||
run: |
|
||||
echo "GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}" >> contrib/container/docker.dev.env
|
||||
docker compose --project-directory . -f contrib/container/dev-docker-compose.yml run --rm inventree-dev-server invoke test --disable-pty
|
||||
- name: Run Migration Tests
|
||||
run: |
|
||||
docker compose --project-directory . -f contrib/container/dev-docker-compose.yml run --rm inventree-dev-server invoke test --migrations
|
||||
docker compose --project-directory . -f contrib/container/dev-docker-compose.yml run inventree-dev-server invoke test --disable-pty
|
||||
docker compose --project-directory . -f contrib/container/dev-docker-compose.yml run inventree-dev-server invoke test --migrations --disable-pty
|
||||
docker compose --project-directory . -f contrib/container/dev-docker-compose.yml down
|
||||
- name: Clean up test folder
|
||||
run: |
|
||||
rm -rf InvenTree/_testfolder
|
||||
- name: Set up QEMU
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # pin@v3.2.0
|
||||
uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # pin@v3.0.0
|
||||
- name: Set up Docker Buildx
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/setup-buildx-action@988b5a0280414f521da01fcc63a27aeeb4b104db # pin@v3.6.1
|
||||
uses: docker/setup-buildx-action@d70bba72b1f3fd22344832f00baa16ece964efeb # pin@v3.3.0
|
||||
- name: Set up cosign
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: sigstore/cosign-installer@4959ce089c160fddf62f7b42464195ba1a56d382 # pin@v3.6.0
|
||||
uses: sigstore/cosign-installer@59acb6260d9c0ba8f4a2f9d9b48431a222b68e20 # pin@v3.5.0
|
||||
- name: Check if Dockerhub login is required
|
||||
id: docker_login
|
||||
run: |
|
||||
if [ -z "${{ secrets.DOCKER_USERNAME }}" ]; then
|
||||
echo "skip_dockerhub_login=true" >> $GITHUB_OUTPUT
|
||||
echo "skip_dockerhub_login=true" >> $GITHUB_ENV
|
||||
else
|
||||
echo "skip_dockerhub_login=false" >> $GITHUB_OUTPUT
|
||||
echo "skip_dockerhub_login=false" >> $GITHUB_ENV
|
||||
fi
|
||||
- name: Login to Dockerhub
|
||||
if: github.event_name != 'pull_request' && steps.docker_login.outputs.skip_dockerhub_login != 'true'
|
||||
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # pin@v3.3.0
|
||||
uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # pin@v3.1.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Log into registry ghcr.io
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # pin@v3.3.0
|
||||
uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # pin@v3.1.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
@ -166,7 +165,7 @@ jobs:
|
||||
- name: Push Docker Images
|
||||
id: push-docker
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/build-push-action@5cd11c3a4ced054e52742c5fd54dca954e0edd85 # pin@v6.7.0
|
||||
uses: docker/build-push-action@2cdde995de11925a030ce8070c3d77a52ffcf1c0 # pin@v5.3.0
|
||||
with:
|
||||
context: .
|
||||
file: ./contrib/container/Dockerfile
|
||||
|
77
.github/workflows/qc_checks.yaml
vendored
@ -10,9 +10,11 @@ on:
|
||||
|
||||
env:
|
||||
python_version: 3.9
|
||||
node_version: 20
|
||||
node_version: 18
|
||||
# The OS version must be set per job
|
||||
server_start_sleep: 60
|
||||
requests_version: 2.31.0
|
||||
pyyaml_version: 6.0.1
|
||||
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
INVENTREE_DB_ENGINE: sqlite3
|
||||
@ -38,7 +40,7 @@ jobs:
|
||||
force: ${{ steps.force.outputs.force }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # pin@v4.1.7
|
||||
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # pin@v4.1.5
|
||||
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # pin@v3.0.2
|
||||
id: filter
|
||||
with:
|
||||
@ -70,7 +72,7 @@ jobs:
|
||||
needs: ["pre-commit"]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # pin@v4.1.7
|
||||
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # pin@v4.1.5
|
||||
- name: Environment Setup
|
||||
uses: ./.github/actions/setup
|
||||
with:
|
||||
@ -92,9 +94,9 @@ jobs:
|
||||
if: needs.paths-filter.outputs.server == 'true' || needs.paths-filter.outputs.frontend == 'true' || needs.paths-filter.outputs.force == 'true'
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # pin@v4.1.7
|
||||
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # pin@v4.1.5
|
||||
- name: Set up Python ${{ env.python_version }}
|
||||
uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # pin@v5.1.1
|
||||
uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # pin@v5.1.0
|
||||
with:
|
||||
python-version: ${{ env.python_version }}
|
||||
cache: "pip"
|
||||
@ -113,9 +115,9 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # pin@v4.1.7
|
||||
uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # pin@v4.1.5
|
||||
- name: Set up Python ${{ env.python_version }}
|
||||
uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # pin@v5.1.1
|
||||
uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # pin@v5.1.0
|
||||
with:
|
||||
python-version: ${{ env.python_version }}
|
||||
- name: Check Config
|
||||
@ -149,7 +151,7 @@ jobs:
|
||||
version: ${{ steps.version.outputs.version }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # pin@v4.1.7
|
||||
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # pin@v4.1.5
|
||||
- name: Environment Setup
|
||||
uses: ./.github/actions/setup
|
||||
with:
|
||||
@ -159,32 +161,20 @@ jobs:
|
||||
- name: Export API Documentation
|
||||
run: invoke schema --ignore-warnings --filename src/backend/InvenTree/schema.yml
|
||||
- name: Upload schema
|
||||
uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # pin@v4.3.6
|
||||
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # pin@v4.3.3
|
||||
with:
|
||||
name: schema.yml
|
||||
path: src/backend/InvenTree/schema.yml
|
||||
- name: Download public schema
|
||||
if: needs.paths-filter.outputs.api == 'false'
|
||||
run: |
|
||||
pip install --require-hashes -r contrib/dev_reqs/requirements.txt >/dev/null 2>&1
|
||||
version="$(python3 .github/scripts/version_check.py only_version ${{ needs.paths-filter.outputs.api }} 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"
|
||||
echo "URL: $url"
|
||||
code=$(curl -s -o api.yaml $url --write-out '%{http_code}' --silent)
|
||||
if [ "$code" != "200" ]; then
|
||||
exit 1
|
||||
fi
|
||||
curl -s -o api.yaml $url
|
||||
echo "Downloaded api.yaml"
|
||||
- name: Running OpenAPI Spec diff action
|
||||
id: breaking_changes
|
||||
uses: oasdiff/oasdiff-action/diff@a2ff6682b27d175162a74c09ace8771bd3d512f8 # pin@main
|
||||
with:
|
||||
base: 'api.yaml'
|
||||
revision: 'src/backend/InvenTree/schema.yml'
|
||||
format: 'html'
|
||||
- name: Echoing diff to step
|
||||
run: echo "${{ steps.breaking_changes.outputs.diff }}" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
- name: Check for differences in API Schema
|
||||
if: needs.paths-filter.outputs.api == 'false'
|
||||
run: |
|
||||
@ -211,13 +201,12 @@ jobs:
|
||||
version: ${{ needs.schema.outputs.version }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
name: Checkout Code
|
||||
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
|
||||
with:
|
||||
repository: inventree/schema
|
||||
token: ${{ secrets.SCHEMA_PAT }}
|
||||
- name: Download schema artifact
|
||||
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
|
||||
uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7
|
||||
with:
|
||||
name: schema.yml
|
||||
- name: Move schema to correct location
|
||||
@ -226,9 +215,8 @@ jobs:
|
||||
mkdir export/${version}
|
||||
mv schema.yml export/${version}/api.yaml
|
||||
- uses: stefanzweifel/git-auto-commit-action@8621497c8c39c72f3e2a999a26b4ca1b5058a842 # v5.0.1
|
||||
name: Commit schema changes
|
||||
with:
|
||||
commit_message: "Update API schema for ${{ env.version }} / ${{ github.sha }}"
|
||||
commit_message: "Update API schema for ${version}"
|
||||
|
||||
python:
|
||||
name: Tests - inventree-python
|
||||
@ -250,7 +238,7 @@ jobs:
|
||||
INVENTREE_SITE_URL: http://127.0.0.1:12345
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # pin@v4.1.7
|
||||
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # pin@v4.1.5
|
||||
- name: Environment Setup
|
||||
uses: ./.github/actions/setup
|
||||
with:
|
||||
@ -281,8 +269,7 @@ jobs:
|
||||
continue-on-error: true # continue if a step fails so that coverage gets pushed
|
||||
strategy:
|
||||
matrix:
|
||||
python_version: [3.9]
|
||||
# python_version: [3.9, 3.12] # Disabled due to requirement issues
|
||||
python_version: [3.9, 3.12]
|
||||
|
||||
env:
|
||||
INVENTREE_DB_NAME: ./inventree.sqlite
|
||||
@ -292,7 +279,7 @@ jobs:
|
||||
python_version: ${{ matrix.python_version }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # pin@v4.1.7
|
||||
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # pin@v4.1.5
|
||||
- name: Environment Setup
|
||||
uses: ./.github/actions/setup
|
||||
with:
|
||||
@ -308,7 +295,7 @@ jobs:
|
||||
- name: Coverage Tests
|
||||
run: invoke test --coverage
|
||||
- name: Upload coverage reports to Codecov
|
||||
uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673 # pin@v4.5.0
|
||||
uses: codecov/codecov-action@5ecb98a3c6b747ed38dc09f787459979aebb39be # pin@v4.3.1
|
||||
if: always()
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
@ -346,7 +333,7 @@ jobs:
|
||||
- 6379:6379
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # pin@v4.1.7
|
||||
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # pin@v4.1.5
|
||||
- name: Environment Setup
|
||||
uses: ./.github/actions/setup
|
||||
with:
|
||||
@ -390,7 +377,7 @@ jobs:
|
||||
- 3306:3306
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # pin@v4.1.7
|
||||
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # pin@v4.1.5
|
||||
- name: Environment Setup
|
||||
uses: ./.github/actions/setup
|
||||
with:
|
||||
@ -429,7 +416,7 @@ jobs:
|
||||
- 5432:5432
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # pin@v4.1.7
|
||||
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # pin@v4.1.5
|
||||
- name: Environment Setup
|
||||
uses: ./.github/actions/setup
|
||||
with:
|
||||
@ -440,7 +427,7 @@ jobs:
|
||||
- name: Run Tests
|
||||
run: invoke test --migrations --report --coverage
|
||||
- name: Upload coverage reports to Codecov
|
||||
uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673 # pin@v4.5.0
|
||||
uses: codecov/codecov-action@5ecb98a3c6b747ed38dc09f787459979aebb39be # pin@v4.3.1
|
||||
if: always()
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
@ -460,7 +447,7 @@ jobs:
|
||||
INVENTREE_PLUGINS_ENABLED: false
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # pin@v4.1.7
|
||||
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # pin@v4.1.5
|
||||
name: Checkout Code
|
||||
- name: Environment Setup
|
||||
uses: ./.github/actions/setup
|
||||
@ -517,7 +504,7 @@ jobs:
|
||||
VITE_COVERAGE: true
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # pin@v4.1.7
|
||||
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # pin@v4.1.5
|
||||
- name: Environment Setup
|
||||
uses: ./.github/actions/setup
|
||||
with:
|
||||
@ -535,7 +522,7 @@ jobs:
|
||||
- name: Run Playwright tests
|
||||
id: tests
|
||||
run: cd src/frontend && npx nyc playwright test
|
||||
- uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # pin@v4
|
||||
- uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # pin@v4
|
||||
if: ${{ !cancelled() && steps.tests.outcome == 'failure' }}
|
||||
with:
|
||||
name: playwright-report
|
||||
@ -545,7 +532,7 @@ jobs:
|
||||
if: always()
|
||||
run: cd src/frontend && npx nyc report --report-dir ./coverage --temp-dir .nyc_output --reporter=lcov --exclude-after-remap false
|
||||
- name: Upload coverage reports to Codecov
|
||||
uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673 # pin@v4.5.0
|
||||
uses: codecov/codecov-action@5ecb98a3c6b747ed38dc09f787459979aebb39be # pin@v4.3.1
|
||||
if: always()
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
@ -558,7 +545,7 @@ jobs:
|
||||
timeout-minutes: 60
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # pin@v4.1.7
|
||||
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # pin@v4.1.5
|
||||
- name: Environment Setup
|
||||
uses: ./.github/actions/setup
|
||||
with:
|
||||
@ -567,13 +554,11 @@ jobs:
|
||||
run: cd src/frontend && yarn install
|
||||
- name: Build frontend
|
||||
run: cd src/frontend && yarn run compile && yarn run build
|
||||
- name: Write version file - SHA
|
||||
run: cd src/backend/InvenTree/web/static/web/.vite && echo "$GITHUB_SHA" > sha.txt
|
||||
- name: Zip frontend
|
||||
run: |
|
||||
cd src/backend/InvenTree/web/static
|
||||
zip -r frontend-build.zip web/ web/.vite
|
||||
- uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # pin@v4.3.6
|
||||
- uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # pin@v4.3.3
|
||||
with:
|
||||
name: frontend-build
|
||||
path: src/backend/InvenTree/web/static/web
|
||||
|
43
.github/workflows/release.yaml
vendored
@ -1,16 +1,13 @@
|
||||
# Runs on releases
|
||||
|
||||
name: Publish release
|
||||
name: Publish release notes
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
stable:
|
||||
runs-on: ubuntu-latest
|
||||
name: Write release to stable branch
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
@ -18,7 +15,7 @@ jobs:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # pin@v4.1.7
|
||||
uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # pin@v4.1.5
|
||||
- name: Version Check
|
||||
run: |
|
||||
pip install --require-hashes -r contrib/dev_reqs/requirements.txt
|
||||
@ -31,15 +28,13 @@ jobs:
|
||||
branch: stable
|
||||
force: true
|
||||
|
||||
build:
|
||||
publish-build:
|
||||
runs-on: ubuntu-latest
|
||||
name: Build and attest frontend
|
||||
permissions:
|
||||
id-token: write
|
||||
contents: write
|
||||
attestations: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # pin@v4.1.7
|
||||
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # pin@v4.1.5
|
||||
- name: Environment Setup
|
||||
uses: ./.github/actions/setup
|
||||
with:
|
||||
@ -48,38 +43,14 @@ jobs:
|
||||
run: cd src/frontend && yarn install
|
||||
- name: Build frontend
|
||||
run: cd src/frontend && npm run compile && npm run build
|
||||
- name: Create SBOM for frontend
|
||||
uses: anchore/sbom-action@61119d458adab75f756bc0b9e4bde25725f86a7a # pin@v0
|
||||
with:
|
||||
artifact-name: frontend-build.spdx
|
||||
path: src/frontend
|
||||
- name: Write version file - SHA
|
||||
run: cd src/backend/InvenTree/web/static/web/.vite && echo "$GITHUB_SHA" > sha.txt
|
||||
- name: Write version file - TAG
|
||||
run: cd src/backend/InvenTree/web/static/web/.vite && echo "${{ github.ref_name }}" > tag.txt
|
||||
- name: Zip frontend
|
||||
run: |
|
||||
cd src/backend/InvenTree/web/static/web
|
||||
zip -r ../frontend-build.zip * .vite
|
||||
- name: Attest Build Provenance
|
||||
id: attest
|
||||
uses: actions/attest-build-provenance@6149ea5740be74af77f260b9db67e633f6b0a9a1 # pin@v1
|
||||
with:
|
||||
subject-path: "${{ github.workspace }}/src/backend/InvenTree/web/static/frontend-build.zip"
|
||||
|
||||
- name: Upload frontend
|
||||
uses: svenstaro/upload-release-action@04733e069f2d7f7f0b4aebc4fbdbce8613b03ccd # pin@2.9.0
|
||||
zip -r ../frontend-build.zip *
|
||||
- uses: svenstaro/upload-release-action@04733e069f2d7f7f0b4aebc4fbdbce8613b03ccd # pin@2.9.0
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: src/backend/InvenTree/web/static/frontend-build.zip
|
||||
asset_name: frontend-build.zip
|
||||
tag: ${{ github.ref }}
|
||||
overwrite: true
|
||||
- name: Upload Attestation
|
||||
uses: svenstaro/upload-release-action@04733e069f2d7f7f0b4aebc4fbdbce8613b03ccd # pin@2.9.0
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
asset_name: frontend-build.intoto.jsonl
|
||||
file: ${{ steps.attest.outputs.bundle-path}}
|
||||
tag: ${{ github.ref }}
|
||||
overwrite: true
|
||||
|
8
.github/workflows/scorecard.yaml
vendored
@ -32,12 +32,12 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: "Checkout code"
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: "Run analysis"
|
||||
uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0
|
||||
uses: ossf/scorecard-action@dc50aa9510b46c811795eb24b2f1ba02a914e534 # v2.3.3
|
||||
with:
|
||||
results_file: results.sarif
|
||||
results_format: sarif
|
||||
@ -59,7 +59,7 @@ jobs:
|
||||
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
|
||||
# format to the repository Actions tab.
|
||||
- name: "Upload artifact"
|
||||
uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6
|
||||
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
|
||||
with:
|
||||
name: SARIF file
|
||||
path: results.sarif
|
||||
@ -67,6 +67,6 @@ jobs:
|
||||
|
||||
# Upload the results to GitHub's code scanning dashboard.
|
||||
- name: "Upload to code-scanning"
|
||||
uses: github/codeql-action/upload-sarif@2c779ab0d087cd7fe7b826087247c2c81f27bfa6 # v3.26.5
|
||||
uses: github/codeql-action/upload-sarif@b7cec7526559c32f1616476ff32d17ba4c59b2d6 # v3.25.5
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
38
.github/workflows/translations.yaml
vendored
@ -7,17 +7,16 @@ on:
|
||||
|
||||
env:
|
||||
python_version: 3.9
|
||||
node_version: 20
|
||||
node_version: 18
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
synchronize-with-crowdin:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@ -31,7 +30,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # pin@v4.1.7
|
||||
uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # pin@v4.1.5
|
||||
- name: Environment Setup
|
||||
uses: ./.github/actions/setup
|
||||
with:
|
||||
@ -40,29 +39,16 @@ jobs:
|
||||
apt-dependency: gettext
|
||||
- name: Make Translations
|
||||
run: invoke translate
|
||||
- name: Remove compiled static files
|
||||
run: rm -rf src/backend/InvenTree/static
|
||||
- name: Remove all local changes that are not *.po files
|
||||
- name: Commit files
|
||||
run: |
|
||||
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
git config --local user.name "github-actions[bot]"
|
||||
git add src/backend/InvenTree/locale/en/LC_MESSAGES/django.po src/frontend/src/locales/en/messages.po
|
||||
git commit -m "add translations"
|
||||
git reset --hard
|
||||
git reset HEAD~
|
||||
- name: crowdin action
|
||||
uses: crowdin/github-action@6ed209d411599a981ccb978df3be9dc9b8a81699 # pin@v2
|
||||
git checkout -b l10_local
|
||||
git add "*.po"
|
||||
git commit -m "updated translation base"
|
||||
- name: Push changes
|
||||
uses: ad-m/github-push-action@d91a481090679876dfc4178fef17f286781251df # pin@v0.8.0
|
||||
with:
|
||||
upload_sources: true
|
||||
upload_translations: false
|
||||
download_translations: true
|
||||
localization_branch_name: l10_crowdin
|
||||
create_pull_request: true
|
||||
pull_request_title: 'New Crowdin updates'
|
||||
pull_request_body: 'New Crowdin translations by [Crowdin GH Action](https://github.com/crowdin/github-action)'
|
||||
pull_request_base_branch_name: 'master'
|
||||
pull_request_labels: 'translations'
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}
|
||||
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
branch: l10
|
||||
force: true
|
||||
|
3
.gitignore
vendored
@ -31,7 +31,6 @@ var/
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
*.sqlite
|
||||
*.sqlite3
|
||||
*.sqlite3-journal
|
||||
*.backup
|
||||
@ -109,7 +108,5 @@ src/backend/InvenTree/web/static
|
||||
InvenTree/web/static
|
||||
|
||||
# Generated docs files
|
||||
docs/schema.yml
|
||||
docs/docs/api/*.yml
|
||||
docs/docs/api/schema/*.yml
|
||||
inventree_settings.json
|
||||
|
@ -14,10 +14,7 @@ env:
|
||||
- INVENTREE_BACKUP_DIR=/opt/inventree/backup
|
||||
- INVENTREE_PLUGIN_FILE=/opt/inventree/plugins.txt
|
||||
- INVENTREE_CONFIG_FILE=/opt/inventree/config.yaml
|
||||
- APP_REPO=inventree/InvenTree
|
||||
before_install: contrib/packager.io/preinstall.sh
|
||||
after_install: contrib/packager.io/postinstall.sh
|
||||
before_remove: contrib/packager.io/preinstall.sh
|
||||
before:
|
||||
- contrib/packager.io/before.sh
|
||||
dependencies:
|
||||
@ -35,7 +32,7 @@ dependencies:
|
||||
- gettext
|
||||
- nginx
|
||||
- jq
|
||||
- "libffi7 | libffi8"
|
||||
- libffi7
|
||||
targets:
|
||||
ubuntu-20.04: true
|
||||
debian-11: true
|
||||
|
@ -17,57 +17,52 @@ repos:
|
||||
- id: check-yaml
|
||||
- id: mixed-line-ending
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: v0.6.1
|
||||
rev: v0.4.1
|
||||
hooks:
|
||||
- id: ruff-format
|
||||
args: [--preview]
|
||||
- id: ruff
|
||||
args: [
|
||||
--fix,
|
||||
# --unsafe-fixes,
|
||||
--preview
|
||||
]
|
||||
- repo: https://github.com/astral-sh/uv-pre-commit
|
||||
rev: 0.2.37
|
||||
rev: 0.1.35
|
||||
hooks:
|
||||
- id: pip-compile
|
||||
name: pip-compile requirements-dev.in
|
||||
args: [src/backend/requirements-dev.in, -o, src/backend/requirements-dev.txt, --no-strip-extras, --generate-hashes]
|
||||
args: [src/backend/requirements-dev.in, -o, src/backend/requirements-dev.txt, --python-version=3.9, --no-strip-extras, --generate-hashes]
|
||||
files: src/backend/requirements-dev\.(in|txt)$
|
||||
- id: pip-compile
|
||||
name: pip-compile requirements.txt
|
||||
args: [src/backend/requirements.in, -o, src/backend/requirements.txt, --no-strip-extras, --generate-hashes]
|
||||
args: [src/backend/requirements.in, -o, src/backend/requirements.txt,--python-version=3.9, --no-strip-extras,--generate-hashes]
|
||||
files: src/backend/requirements\.(in|txt)$
|
||||
- id: pip-compile
|
||||
name: pip-compile requirements.txt
|
||||
args: [contrib/dev_reqs/requirements.in, -o, contrib/dev_reqs/requirements.txt, --no-strip-extras, --generate-hashes]
|
||||
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, --no-strip-extras, --generate-hashes]
|
||||
args: [docs/requirements.in, -o, docs/requirements.txt,--python-version=3.9, --no-strip-extras, --generate-hashes]
|
||||
files: docs/requirements\.(in|txt)$
|
||||
- id: pip-compile
|
||||
name: pip-compile requirements.txt
|
||||
args: [contrib/container/requirements.in, -o, contrib/container/requirements.txt, --python-version=3.11, --no-strip-extras, --generate-hashes]
|
||||
args: [contrib/container/requirements.in, -o, contrib/container/requirements.txt,--python-version=3.11, --no-strip-extras, --generate-hashes]
|
||||
files: contrib/container/requirements\.(in|txt)$
|
||||
- repo: https://github.com/Riverside-Healthcare/djLint
|
||||
rev: v1.34.1
|
||||
hooks:
|
||||
- id: djlint-django
|
||||
- repo: https://github.com/codespell-project/codespell
|
||||
rev: v2.3.0
|
||||
rev: v2.2.6
|
||||
hooks:
|
||||
- id: codespell
|
||||
additional_dependencies:
|
||||
- tomli
|
||||
exclude: >
|
||||
(?x)^(
|
||||
docs/docs/stylesheets/.*|
|
||||
docs/docs/javascripts/.*|
|
||||
docs/docs/webfonts/.* |
|
||||
src/frontend/src/locales/.* |
|
||||
pyproject.toml |
|
||||
src/frontend/vite.config.ts |
|
||||
)$
|
||||
- repo: https://github.com/pre-commit/mirrors-prettier
|
||||
rev: "v4.0.0-alpha.8"
|
||||
@ -78,7 +73,7 @@ repos:
|
||||
- "prettier@^2.4.1"
|
||||
- "@trivago/prettier-plugin-sort-imports"
|
||||
- repo: https://github.com/pre-commit/mirrors-eslint
|
||||
rev: "v9.9.0"
|
||||
rev: "v9.1.0"
|
||||
hooks:
|
||||
- id: eslint
|
||||
additional_dependencies:
|
||||
@ -90,7 +85,7 @@ repos:
|
||||
- "@typescript-eslint/parser"
|
||||
files: ^src/frontend/.*\.(js|jsx|ts|tsx)$
|
||||
- repo: https://github.com/gitleaks/gitleaks
|
||||
rev: v8.18.4
|
||||
rev: v8.18.2
|
||||
hooks:
|
||||
- id: gitleaks
|
||||
#- repo: https://github.com/jumanjihouse/pre-commit-hooks
|
||||
|
26
.vscode/launch.json
vendored
@ -6,37 +6,19 @@
|
||||
"configurations": [
|
||||
{
|
||||
"name": "InvenTree Server",
|
||||
"type": "debugpy",
|
||||
"type": "python",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/src/backend/InvenTree/manage.py",
|
||||
"args": [
|
||||
"runserver",
|
||||
// "0.0.0.0:8000", // expose server in network (useful for testing with mobile app)
|
||||
// "--noreload" // disable auto-reload
|
||||
],
|
||||
"django": true,
|
||||
"justMyCode": true
|
||||
},
|
||||
{
|
||||
"name": "InvenTree Server - Tests",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/src/backend/InvenTree/manage.py",
|
||||
"args": [
|
||||
"test",
|
||||
// "part.test_api.PartCategoryAPITest", // run only a specific test
|
||||
],
|
||||
"args": ["runserver"],
|
||||
"django": true,
|
||||
"justMyCode": true
|
||||
},
|
||||
{
|
||||
"name": "InvenTree Server - 3rd party",
|
||||
"type": "debugpy",
|
||||
"type": "python",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/src/backend/InvenTree/manage.py",
|
||||
"args": [
|
||||
"runserver"
|
||||
],
|
||||
"args": ["runserver"],
|
||||
"django": true,
|
||||
"justMyCode": false
|
||||
},
|
||||
|
@ -39,7 +39,7 @@ InvenTree/
|
||||
│ │ ├─ tsconfig.json # Settings for frontend compilation
|
||||
├─ .pkgr.yml # Build definition for Debian/Ubuntu packages
|
||||
├─ .pre-commit-config.yaml # Code formatter/linter configuration
|
||||
├─ CONTRIBUTING.md # Contribution guidelines and overview
|
||||
├─ CONTRIBUTING.md # Contirbution guidelines and overview
|
||||
├─ Procfile # Process definition for Debian/Ubuntu packages
|
||||
├─ README.md # General project information and overview
|
||||
├─ runtime.txt # Python runtime settings for Debian/Ubuntu packages build
|
||||
|
@ -66,7 +66,7 @@ InvenTree is designed to be **extensible**, and provides multiple options for **
|
||||
<li><a href="https://www.djangoproject.com/">Django</a></li>
|
||||
<li><a href="https://www.django-rest-framework.org/">DRF</a></li>
|
||||
<li><a href="https://django-q.readthedocs.io/">Django Q</a></li>
|
||||
<li><a href="https://docs.allauth.org/">Django-Allauth</a></li>
|
||||
<li><a href="https://django-allauth.readthedocs.io/">Django-Allauth</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
|
||||
|
@ -3,7 +3,6 @@ coverage:
|
||||
project:
|
||||
default:
|
||||
target: 82%
|
||||
patch: off
|
||||
|
||||
github_checks:
|
||||
annotations: true
|
||||
|
@ -28,7 +28,6 @@ INVENTREE_DB_PASSWORD=pgpassword
|
||||
# Un-comment the following lines to enable Redis cache
|
||||
# Note that you will also have to run docker-compose with the --profile redis command
|
||||
# Refer to settings.py for other cache options
|
||||
#INVENTREE_CACHE_ENABLED=True
|
||||
#INVENTREE_CACHE_HOST=inventree-cache
|
||||
#INVENTREE_CACHE_PORT=6379
|
||||
|
||||
|
@ -11,7 +11,6 @@
|
||||
|
||||
ARG base_image=python:3.11-alpine3.18
|
||||
FROM ${base_image} AS inventree_base
|
||||
ARG base_image
|
||||
|
||||
# Build arguments for this image
|
||||
ARG commit_tag=""
|
||||
@ -49,18 +48,13 @@ ENV INVENTREE_BACKGROUND_WORKERS="4"
|
||||
ENV INVENTREE_WEB_ADDR=0.0.0.0
|
||||
ENV INVENTREE_WEB_PORT=8000
|
||||
|
||||
LABEL org.opencontainers.image.created=${DATE} \
|
||||
org.opencontainers.image.vendor="inventree" \
|
||||
org.opencontainers.image.title="InvenTree backend server" \
|
||||
org.opencontainers.image.description="InvenTree is the open-source inventory management system" \
|
||||
org.opencontainers.image.url="https://inventree.org" \
|
||||
org.opencontainers.image.documentation="https://docs.inventree.org" \
|
||||
org.opencontainers.image.source="https://github.com/inventree/InvenTree" \
|
||||
org.opencontainers.image.revision=${commit_hash} \
|
||||
org.opencontainers.image.licenses="MIT" \
|
||||
org.opencontainers.image.base.name="docker.io/library/${base_image}" \
|
||||
org.opencontainers.image.version=${commit_tag}
|
||||
|
||||
LABEL org.label-schema.schema-version="1.0" \
|
||||
org.label-schema.build-date=${DATE} \
|
||||
org.label-schema.vendor="inventree" \
|
||||
org.label-schema.name="inventree/inventree" \
|
||||
org.label-schema.url="https://hub.docker.com/r/inventree/inventree" \
|
||||
org.label-schema.vcs-url="https://github.com/inventree/InvenTree.git" \
|
||||
org.label-schema.vcs-ref=${commit_tag}
|
||||
|
||||
# Install required system level packages
|
||||
RUN apk add --no-cache \
|
||||
@ -74,9 +68,8 @@ RUN apk add --no-cache \
|
||||
# MySQL / MariaDB client
|
||||
mariadb-client mariadb-connector-c \
|
||||
&& \
|
||||
# font support
|
||||
apk --update --upgrade --no-cache add fontconfig ttf-freefont font-terminus font-noto font-noto-cjk font-noto-extra \
|
||||
&& fc-cache -f
|
||||
# fonts
|
||||
apk --update --upgrade --no-cache add fontconfig ttf-freefont font-noto terminus-font && fc-cache -f
|
||||
|
||||
EXPOSE 8000
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
version: "3.8"
|
||||
|
||||
# Docker compose recipe for InvenTree development server
|
||||
# - Runs PostgreSQL as the database backend
|
||||
# - Uses built-in django webserver
|
||||
|
@ -1,3 +1,5 @@
|
||||
version: "3.8"
|
||||
|
||||
# Docker compose recipe for a production-ready InvenTree setup, with the following containers:
|
||||
# - PostgreSQL as the database backend
|
||||
# - gunicorn as the InvenTree web server
|
||||
@ -51,9 +53,14 @@ services:
|
||||
restart: unless-stopped
|
||||
|
||||
# redis acts as database cache manager
|
||||
# only runs under the "redis" profile : https://docs.docker.com/compose/profiles/
|
||||
inventree-cache:
|
||||
image: redis:7.0
|
||||
container_name: inventree-cache
|
||||
depends_on:
|
||||
- inventree-db
|
||||
profiles:
|
||||
- redis
|
||||
env_file:
|
||||
- .env
|
||||
expose:
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!/bin/ash
|
||||
|
||||
# Install system packages required for building InvenTree python libraries
|
||||
# Note that for postgreslql, we use the version 13, which matches the version used in the InvenTree docker image
|
||||
# Note that for postgreslql, we use the 13 version, which matches the version used in the InvenTree docker image
|
||||
|
||||
apk add gcc g++ musl-dev openssl-dev libffi-dev cargo python3-dev openldap-dev \
|
||||
libstdc++ build-base linux-headers py3-grpcio \
|
||||
|
@ -17,7 +17,6 @@ gunicorn>=22.0.0
|
||||
# LDAP required packages
|
||||
django-auth-ldap # Django integration for ldap auth
|
||||
python-ldap # LDAP auth support
|
||||
django<5.0 # Force lower to match main project
|
||||
|
||||
# Upgraded python package installer
|
||||
uv
|
||||
|
@ -4,24 +4,19 @@ asgiref==3.8.1 \
|
||||
--hash=sha256:3e1e3ecc849832fe52ccf2cb6686b7a55f82bb1d6aee72a58826471390335e47 \
|
||||
--hash=sha256:c343bd80a0bec947a9860adb4c432ffa7db769836c64238fc34bdc3fec84d590
|
||||
# via django
|
||||
django==4.2.15 \
|
||||
--hash=sha256:61ee4a130efb8c451ef3467c67ca99fdce400fedd768634efc86a68c18d80d30 \
|
||||
--hash=sha256:c77f926b81129493961e19c0e02188f8d07c112a1162df69bfab178ae447f94a
|
||||
# via
|
||||
# -r contrib/container/requirements.in
|
||||
# django-auth-ldap
|
||||
django==4.2.11 \
|
||||
--hash=sha256:6e6ff3db2d8dd0c986b4eec8554c8e4f919b5c1ff62a5b4390c17aff2ed6e5c4 \
|
||||
--hash=sha256:ddc24a0a8280a0430baa37aff11f28574720af05888c62b7cfe71d219f4599d3
|
||||
# via django-auth-ldap
|
||||
django-auth-ldap==4.8.0 \
|
||||
--hash=sha256:4b4b944f3c28bce362f33fb6e8db68429ed8fd8f12f0c0c4b1a4344a7ef225ce \
|
||||
--hash=sha256:604250938ddc9fda619f247c7a59b0b2f06e53a7d3f46a156f28aa30dd71a738
|
||||
# via -r contrib/container/requirements.in
|
||||
gunicorn==23.0.0 \
|
||||
--hash=sha256:ec400d38950de4dfd418cff8328b2c8faed0edb0d517d3394e457c317908ca4d \
|
||||
--hash=sha256:f014447a0101dc57e294f6c18ca6b40227a4c90e9bdb586042628030cba004ec
|
||||
# via -r contrib/container/requirements.in
|
||||
gunicorn==22.0.0 \
|
||||
--hash=sha256:350679f91b24062c86e386e198a15438d53a7a8207235a78ba1b53df4c4378d9 \
|
||||
--hash=sha256:4a0b436239ff76fb33f11c07a16482c521a7e09c1ce3cc293c2330afe01bec63
|
||||
invoke==2.2.0 \
|
||||
--hash=sha256:6ea924cc53d4f78e3d98bc436b08069a03077e6f85ad1ddaa8a116d7dad15820 \
|
||||
--hash=sha256:ee6cbb101af1a859c7fe84f2a264c059020b0cb7fe3535f9424300ab568f6bd5
|
||||
# via -r contrib/container/requirements.in
|
||||
mariadb==1.1.10 \
|
||||
--hash=sha256:03d6284ef713d1cad40146576a4cc2d6cbc1662060f2a0e59b174e1694521698 \
|
||||
--hash=sha256:1ce87971c02375236ff8933e6c593c748e7b2f2950b86eabfab4289fd250ea63 \
|
||||
@ -34,7 +29,6 @@ mariadb==1.1.10 \
|
||||
--hash=sha256:a332893e3ef7ceb7970ab4bd7c844bcb4bd68a051ca51313566f9808d7411f2d \
|
||||
--hash=sha256:d7b09ec4abd02ed235257feb769f90cd4066e8f536b55b92f5166103d5b66a63 \
|
||||
--hash=sha256:dff8b28ce4044574870d7bdd2d9f9f5da8e5f95a7ff6d226185db733060d1a93
|
||||
# via -r contrib/container/requirements.in
|
||||
mysqlclient==2.2.4 \
|
||||
--hash=sha256:329e4eec086a2336fe3541f1ce095d87a6f169d1cc8ba7b04ac68bcb234c9711 \
|
||||
--hash=sha256:33bc9fb3464e7d7c10b1eaf7336c5ff8f2a3d3b88bab432116ad2490beb3bf41 \
|
||||
@ -45,75 +39,85 @@ mysqlclient==2.2.4 \
|
||||
--hash=sha256:ac44777eab0a66c14cb0d38965572f762e193ec2e5c0723bcd11319cc5b693c5 \
|
||||
--hash=sha256:d43987bb9626096a302ca6ddcdd81feaeca65ced1d5fe892a6a66b808326aa54 \
|
||||
--hash=sha256:e1ebe3f41d152d7cb7c265349fdb7f1eca86ccb0ca24a90036cde48e00ceb2ab
|
||||
# via -r contrib/container/requirements.in
|
||||
packaging==24.1 \
|
||||
--hash=sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002 \
|
||||
--hash=sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124
|
||||
packaging==24.0 \
|
||||
--hash=sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5 \
|
||||
--hash=sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9
|
||||
# via
|
||||
# gunicorn
|
||||
# mariadb
|
||||
psycopg[binary, pool]==3.2.1 \
|
||||
--hash=sha256:dc8da6dc8729dacacda3cc2f17d2c9397a70a66cf0d2b69c91065d60d5f00cb7 \
|
||||
--hash=sha256:ece385fb413a37db332f97c49208b36cf030ff02b199d7635ed2fbd378724175
|
||||
# via -r contrib/container/requirements.in
|
||||
psycopg-binary==3.2.1 \
|
||||
--hash=sha256:059cbd4e6da2337e17707178fe49464ed01de867dc86c677b30751755ec1dc51 \
|
||||
--hash=sha256:06a7aae34edfe179ddc04da005e083ff6c6b0020000399a2cbf0a7121a8a22ea \
|
||||
--hash=sha256:0879b5d76b7d48678d31278242aaf951bc2d69ca4e4d7cef117e4bbf7bfefda9 \
|
||||
--hash=sha256:0ab58213cc976a1666f66bc1cb2e602315cd753b7981a8e17237ac2a185bd4a1 \
|
||||
--hash=sha256:0b018631e5c80ce9bc210b71ea885932f9cca6db131e4df505653d7e3873a938 \
|
||||
--hash=sha256:101472468d59c74bb8565fab603e032803fd533d16be4b2d13da1bab8deb32a3 \
|
||||
--hash=sha256:1d353e028b8f848b9784450fc2abf149d53a738d451eab3ee4c85703438128b9 \
|
||||
--hash=sha256:1d6833f607f3fc7b22226a9e121235d3b84c0eda1d3caab174673ef698f63788 \
|
||||
--hash=sha256:21927f41c4d722ae8eb30d62a6ce732c398eac230509af5ba1749a337f8a63e2 \
|
||||
--hash=sha256:28ada5f610468c57d8a4a055a8ea915d0085a43d794266c4f3b9d02f4288f4db \
|
||||
--hash=sha256:2e8213bf50af073b1aa8dc3cff123bfeedac86332a16c1b7274910bc88a847c7 \
|
||||
--hash=sha256:302b86f92c0d76e99fe1b5c22c492ae519ce8b98b88d37ef74fda4c9e24c6b46 \
|
||||
--hash=sha256:334046a937bb086c36e2c6889fe327f9f29bfc085d678f70fac0b0618949f674 \
|
||||
--hash=sha256:33e6669091d09f8ba36e10ce678a6d9916e110446236a9b92346464a3565635e \
|
||||
--hash=sha256:3c838806eeb99af39f934b7999e35f947a8e577997cc892c12b5053a97a9057f \
|
||||
--hash=sha256:40bb515d042f6a345714ec0403df68ccf13f73b05e567837d80c886c7c9d3805 \
|
||||
--hash=sha256:413977d18412ff83486eeb5875eb00b185a9391c57febac45b8993bf9c0ff489 \
|
||||
--hash=sha256:415c3b72ea32119163255c6504085f374e47ae7345f14bc3f0ef1f6e0976a879 \
|
||||
--hash=sha256:42781ba94e8842ee98bca5a7d0c44cc9d067500fedca2d6a90fa3609b6d16b42 \
|
||||
--hash=sha256:463d55345f73ff391df8177a185ad57b552915ad33f5cc2b31b930500c068b22 \
|
||||
--hash=sha256:4a42b8f9ab39affcd5249b45cac763ac3cf12df962b67e23fd15a2ee2932afe5 \
|
||||
--hash=sha256:4c84fcac8a3a3479ac14673095cc4e1fdba2935499f72c436785ac679bec0d1a \
|
||||
--hash=sha256:592b27d6c46a40f9eeaaeea7c1fef6f3c60b02c634365eb649b2d880669f149f \
|
||||
--hash=sha256:62b1b7b07e00ee490afb39c0a47d8282a9c2822c7cfed9553a04b0058adf7e7f \
|
||||
--hash=sha256:6418712ba63cebb0c88c050b3997185b0ef54173b36568522d5634ac06153040 \
|
||||
--hash=sha256:6f9e13600647087df5928875559f0eb8f496f53e6278b7da9511b4b3d0aff960 \
|
||||
--hash=sha256:7066d3dca196ed0dc6172f9777b2d62e4f138705886be656cccff2d555234d60 \
|
||||
--hash=sha256:73f9c9b984be9c322b5ec1515b12df1ee5896029f5e72d46160eb6517438659c \
|
||||
--hash=sha256:74d623261655a169bc84a9669890975c229f2fa6e19a7f2d10a77675dcf1a707 \
|
||||
--hash=sha256:788ffc43d7517c13e624c83e0e553b7b8823c9655e18296566d36a829bfb373f \
|
||||
--hash=sha256:78c2007caf3c90f08685c5378e3ceb142bafd5636be7495f7d86ec8a977eaeef \
|
||||
--hash=sha256:7a84b5eb194a258116154b2a4ff2962ea60ea52de089508db23a51d3d6b1c7d1 \
|
||||
--hash=sha256:7ce965caf618061817f66c0906f0452aef966c293ae0933d4fa5a16ea6eaf5bb \
|
||||
--hash=sha256:84837e99353d16c6980603b362d0f03302d4b06c71672a6651f38df8a482923d \
|
||||
--hash=sha256:8f28ff0cb9f1defdc4a6f8c958bf6787274247e7dfeca811f6e2f56602695fb1 \
|
||||
--hash=sha256:921f0c7f39590763d64a619de84d1b142587acc70fd11cbb5ba8fa39786f3073 \
|
||||
--hash=sha256:950fd666ec9e9fe6a8eeb2b5a8f17301790e518953730ad44d715b59ffdbc67f \
|
||||
--hash=sha256:9a997efbaadb5e1a294fb5760e2f5643d7b8e4e3fe6cb6f09e6d605fd28e0291 \
|
||||
--hash=sha256:aa3931f308ab4a479d0ee22dc04bea867a6365cac0172e5ddcba359da043854b \
|
||||
--hash=sha256:af0469c00f24c4bec18c3d2ede124bf62688d88d1b8a5f3c3edc2f61046fe0d7 \
|
||||
--hash=sha256:b0104a72a17aa84b3b7dcab6c84826c595355bf54bb6ea6d284dcb06d99c6801 \
|
||||
--hash=sha256:b09e8a576a2ac69d695032ee76f31e03b30781828b5dd6d18c6a009e5a3d1c35 \
|
||||
--hash=sha256:b140182830c76c74d17eba27df3755a46442ce8d4fb299e7f1cf2f74a87c877b \
|
||||
--hash=sha256:b1f087bd84bdcac78bf9f024ebdbfacd07fc0a23ec8191448a50679e2ac4a19e \
|
||||
--hash=sha256:c1d2b6438fb83376f43ebb798bf0ad5e57bc56c03c9c29c85bc15405c8c0ac5a \
|
||||
--hash=sha256:cad2de17804c4cfee8640ae2b279d616bb9e4734ac3c17c13db5e40982bd710d \
|
||||
--hash=sha256:cc304a46be1e291031148d9d95c12451ffe783ff0cc72f18e2cc7ec43cdb8c68 \
|
||||
--hash=sha256:dc314a47d44fe1a8069b075a64abffad347a3a1d8652fed1bab5d3baea37acb2 \
|
||||
--hash=sha256:f092114f10f81fb6bae544a0ec027eb720e2d9c74a4fcdaa9dd3899873136935 \
|
||||
--hash=sha256:f34e369891f77d0738e5d25727c307d06d5344948771e5379ea29c76c6d84555 \
|
||||
--hash=sha256:f8a509aeaac364fa965454e80cd110fe6d48ba2c80f56c9b8563423f0b5c3cfd \
|
||||
--hash=sha256:f8afb07114ea9b924a4a0305ceb15354ccf0ef3c0e14d54b8dbeb03e50182dd7 \
|
||||
--hash=sha256:f99e59f8a5f4dcd9cbdec445f3d8ac950a492fc0e211032384d6992ed3c17eb7
|
||||
psycopg[binary, pool]==3.1.18 \
|
||||
--hash=sha256:31144d3fb4c17d78094d9e579826f047d4af1da6a10427d91dfcfb6ecdf6f12b \
|
||||
--hash=sha256:4d5a0a5a8590906daa58ebd5f3cfc34091377354a1acced269dd10faf55da60e
|
||||
psycopg-binary==3.1.18 \
|
||||
--hash=sha256:02bd4da45d5ee9941432e2e9bf36fa71a3ac21c6536fe7366d1bd3dd70d6b1e7 \
|
||||
--hash=sha256:0f68ac2364a50d4cf9bb803b4341e83678668f1881a253e1224574921c69868c \
|
||||
--hash=sha256:13bcd3742112446037d15e360b27a03af4b5afcf767f5ee374ef8f5dd7571b31 \
|
||||
--hash=sha256:1729d0e3dfe2546d823841eb7a3d003144189d6f5e138ee63e5227f8b75276a5 \
|
||||
--hash=sha256:1859aeb2133f5ecdd9cbcee155f5e38699afc06a365f903b1512c765fd8d457e \
|
||||
--hash=sha256:1c9b6bd7fb5c6638cb32469674707649b526acfe786ba6d5a78ca4293d87bae4 \
|
||||
--hash=sha256:247474af262bdd5559ee6e669926c4f23e9cf53dae2d34c4d991723c72196404 \
|
||||
--hash=sha256:258d2f0cb45e4574f8b2fe7c6d0a0e2eb58903a4fd1fbaf60954fba82d595ab7 \
|
||||
--hash=sha256:2e2484ae835dedc80cdc7f1b1a939377dc967fed862262cfd097aa9f50cade46 \
|
||||
--hash=sha256:320047e3d3554b857e16c2b6b615a85e0db6a02426f4d203a4594a2f125dfe57 \
|
||||
--hash=sha256:39242546383f6b97032de7af30edb483d237a0616f6050512eee7b218a2aa8ee \
|
||||
--hash=sha256:3c2b039ae0c45eee4cd85300ef802c0f97d0afc78350946a5d0ec77dd2d7e834 \
|
||||
--hash=sha256:3c7afcd6f1d55992f26d9ff7b0bd4ee6b475eb43aa3f054d67d32e09f18b0065 \
|
||||
--hash=sha256:3e4b0bb91da6f2238dbd4fbb4afc40dfb4f045bb611b92fce4d381b26413c686 \
|
||||
--hash=sha256:3e7ce4d988112ca6c75765c7f24c83bdc476a6a5ce00878df6c140ca32c3e16d \
|
||||
--hash=sha256:4085f56a8d4fc8b455e8f44380705c7795be5317419aa5f8214f315e4205d804 \
|
||||
--hash=sha256:4575da95fc441244a0e2ebaf33a2b2f74164603341d2046b5cde0a9aa86aa7e2 \
|
||||
--hash=sha256:489aa4fe5a0b653b68341e9e44af247dedbbc655326854aa34c163ef1bcb3143 \
|
||||
--hash=sha256:4e4de16a637ec190cbee82e0c2dc4860fed17a23a35f7a1e6dc479a5c6876722 \
|
||||
--hash=sha256:531381f6647fc267383dca88dbe8a70d0feff433a8e3d0c4939201fea7ae1b82 \
|
||||
--hash=sha256:55ff0948457bfa8c0d35c46e3a75193906d1c275538877ba65907fd67aa059ad \
|
||||
--hash=sha256:59701118c7d8842e451f1e562d08e8708b3f5d14974eefbce9374badd723c4ae \
|
||||
--hash=sha256:5c323103dfa663b88204cf5f028e83c77d7a715f9b6f51d2bbc8184b99ddd90a \
|
||||
--hash=sha256:5d6e860edf877d4413e4a807e837d55e3a7c7df701e9d6943c06e460fa6c058f \
|
||||
--hash=sha256:639dd78ac09b144b0119076783cb64e1128cc8612243e9701d1503c816750b2e \
|
||||
--hash=sha256:6432047b8b24ef97e3fbee1d1593a0faaa9544c7a41a2c67d1f10e7621374c83 \
|
||||
--hash=sha256:67284e2e450dc7a9e4d76e78c0bd357dc946334a3d410defaeb2635607f632cd \
|
||||
--hash=sha256:6ebecbf2406cd6875bdd2453e31067d1bd8efe96705a9489ef37e93b50dc6f09 \
|
||||
--hash=sha256:7121acc783c4e86d2d320a7fb803460fab158a7f0a04c5e8c5d49065118c1e73 \
|
||||
--hash=sha256:74e498586b72fb819ca8ea82107747d0cb6e00ae685ea6d1ab3f929318a8ce2d \
|
||||
--hash=sha256:780a90bcb69bf27a8b08bc35b958e974cb6ea7a04cdec69e737f66378a344d68 \
|
||||
--hash=sha256:7ac1785d67241d5074f8086705fa68e046becea27964267ab3abd392481d7773 \
|
||||
--hash=sha256:812726266ab96de681f2c7dbd6b734d327f493a78357fcc16b2ac86ff4f4e080 \
|
||||
--hash=sha256:824a1bfd0db96cc6bef2d1e52d9e0963f5bf653dd5bc3ab519a38f5e6f21c299 \
|
||||
--hash=sha256:87dd9154b757a5fbf6d590f6f6ea75f4ad7b764a813ae04b1d91a70713f414a1 \
|
||||
--hash=sha256:887f8d856c91510148be942c7acd702ccf761a05f59f8abc123c22ab77b5a16c \
|
||||
--hash=sha256:888a72c2aca4316ca6d4a619291b805677bae99bba2f6e31a3c18424a48c7e4d \
|
||||
--hash=sha256:8f54978c4b646dec77fefd8485fa82ec1a87807f334004372af1aaa6de9539a5 \
|
||||
--hash=sha256:91074f78a9f890af5f2c786691575b6b93a4967ad6b8c5a90101f7b8c1a91d9c \
|
||||
--hash=sha256:9d684227ef8212e27da5f2aff9d4d303cc30b27ac1702d4f6881935549486dd5 \
|
||||
--hash=sha256:9e24e7b6a68a51cc3b162d0339ae4e1263b253e887987d5c759652f5692b5efe \
|
||||
--hash=sha256:9ffcbbd389e486d3fd83d30107bbf8b27845a295051ccabde240f235d04ed921 \
|
||||
--hash=sha256:a87e9eeb80ce8ec8c2783f29bce9a50bbcd2e2342a340f159c3326bf4697afa1 \
|
||||
--hash=sha256:ad35ac7fd989184bf4d38a87decfb5a262b419e8ba8dcaeec97848817412c64a \
|
||||
--hash=sha256:b15e3653c82384b043d820fc637199b5c6a36b37fa4a4943e0652785bb2bad5d \
|
||||
--hash=sha256:b293e01057e63c3ac0002aa132a1071ce0fdb13b9ee2b6b45d3abdb3525c597d \
|
||||
--hash=sha256:b2f7f95746efd1be2dc240248cc157f4315db3fd09fef2adfcc2a76e24aa5741 \
|
||||
--hash=sha256:bd27f713f2e5ef3fd6796e66c1a5203a27a30ecb847be27a78e1df8a9a5ae68c \
|
||||
--hash=sha256:c38a4796abf7380f83b1653c2711cb2449dd0b2e5aca1caa75447d6fa5179c69 \
|
||||
--hash=sha256:c76659ae29a84f2c14f56aad305dd00eb685bd88f8c0a3281a9a4bc6bd7d2aa7 \
|
||||
--hash=sha256:c84a0174109f329eeda169004c7b7ca2e884a6305acab4a39600be67f915ed38 \
|
||||
--hash=sha256:cd2a9f7f0d4dacc5b9ce7f0e767ae6cc64153264151f50698898c42cabffec0c \
|
||||
--hash=sha256:d322ba72cde4ca2eefc2196dad9ad7e52451acd2f04e3688d590290625d0c970 \
|
||||
--hash=sha256:d4422af5232699f14b7266a754da49dc9bcd45eba244cf3812307934cd5d6679 \
|
||||
--hash=sha256:d46ae44d66bf6058a812467f6ae84e4e157dee281bfb1cfaeca07dee07452e85 \
|
||||
--hash=sha256:da917f6df8c6b2002043193cb0d74cc173b3af7eb5800ad69c4e1fbac2a71c30 \
|
||||
--hash=sha256:dea4a59da7850192fdead9da888e6b96166e90608cf39e17b503f45826b16f84 \
|
||||
--hash=sha256:e05f6825f8db4428782135e6986fec79b139210398f3710ed4aa6ef41473c008 \
|
||||
--hash=sha256:e1cf59e0bb12e031a48bb628aae32df3d0c98fd6c759cb89f464b1047f0ca9c8 \
|
||||
--hash=sha256:e252d66276c992319ed6cd69a3ffa17538943954075051e992143ccbf6dc3d3e \
|
||||
--hash=sha256:e262398e5d51563093edf30612cd1e20fedd932ad0994697d7781ca4880cdc3d \
|
||||
--hash=sha256:e28ff8f3de7b56588c2a398dc135fd9f157d12c612bd3daa7e6ba9872337f6f5 \
|
||||
--hash=sha256:eea5f14933177ffe5c40b200f04f814258cc14b14a71024ad109f308e8bad414 \
|
||||
--hash=sha256:f876ebbf92db70125f6375f91ab4bc6b27648aa68f90d661b1fc5affb4c9731c \
|
||||
--hash=sha256:f8ff3bc08b43f36fdc24fedb86d42749298a458c4724fb588c4d76823ac39f54
|
||||
# via psycopg
|
||||
psycopg-pool==3.2.2 \
|
||||
--hash=sha256:273081d0fbfaced4f35e69200c89cb8fbddfe277c38cc86c235b90a2ec2c8153 \
|
||||
--hash=sha256:9e22c370045f6d7f2666a5ad1b0caf345f9f1912195b0b25d0d3bcc4f3a7389c
|
||||
psycopg-pool==3.2.1 \
|
||||
--hash=sha256:060b551d1b97a8d358c668be58b637780b884de14d861f4f5ecc48b7563aafb7 \
|
||||
--hash=sha256:6509a75c073590952915eddbba7ce8b8332a440a31e77bba69561483492829ad
|
||||
# via psycopg
|
||||
pyasn1==0.6.0 \
|
||||
--hash=sha256:3a35ab2c4b5ef98e17dfdec8ab074046fbda76e281c5a706ccd82328cfc8f64c \
|
||||
@ -127,99 +131,90 @@ pyasn1-modules==0.4.0 \
|
||||
# via python-ldap
|
||||
python-ldap==3.4.4 \
|
||||
--hash=sha256:7edb0accec4e037797705f3a05cbf36a9fde50d08c8f67f2aef99a2628fab828
|
||||
# via
|
||||
# -r contrib/container/requirements.in
|
||||
# django-auth-ldap
|
||||
pyyaml==6.0.2 \
|
||||
--hash=sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff \
|
||||
--hash=sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48 \
|
||||
--hash=sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086 \
|
||||
--hash=sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e \
|
||||
--hash=sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133 \
|
||||
--hash=sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5 \
|
||||
--hash=sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484 \
|
||||
--hash=sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee \
|
||||
--hash=sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5 \
|
||||
--hash=sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68 \
|
||||
--hash=sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a \
|
||||
--hash=sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf \
|
||||
--hash=sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99 \
|
||||
--hash=sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8 \
|
||||
--hash=sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85 \
|
||||
--hash=sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19 \
|
||||
--hash=sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc \
|
||||
--hash=sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a \
|
||||
--hash=sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1 \
|
||||
--hash=sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317 \
|
||||
--hash=sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c \
|
||||
--hash=sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631 \
|
||||
--hash=sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d \
|
||||
--hash=sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652 \
|
||||
--hash=sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5 \
|
||||
--hash=sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e \
|
||||
--hash=sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b \
|
||||
--hash=sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8 \
|
||||
--hash=sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476 \
|
||||
--hash=sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706 \
|
||||
--hash=sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563 \
|
||||
--hash=sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237 \
|
||||
--hash=sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b \
|
||||
--hash=sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083 \
|
||||
--hash=sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180 \
|
||||
--hash=sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425 \
|
||||
--hash=sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e \
|
||||
--hash=sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f \
|
||||
--hash=sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725 \
|
||||
--hash=sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183 \
|
||||
--hash=sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab \
|
||||
--hash=sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774 \
|
||||
--hash=sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725 \
|
||||
--hash=sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e \
|
||||
--hash=sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5 \
|
||||
--hash=sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d \
|
||||
--hash=sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290 \
|
||||
--hash=sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44 \
|
||||
--hash=sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed \
|
||||
--hash=sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4 \
|
||||
--hash=sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba \
|
||||
--hash=sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12 \
|
||||
--hash=sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4
|
||||
# via -r contrib/container/requirements.in
|
||||
setuptools==73.0.1 \
|
||||
--hash=sha256:b208925fcb9f7af924ed2dc04708ea89791e24bde0d3020b27df0e116088b34e \
|
||||
--hash=sha256:d59a3e788ab7e012ab2c4baed1b376da6366883ee20d7a5fc426816e3d7b1193
|
||||
# via -r contrib/container/requirements.in
|
||||
sqlparse==0.5.1 \
|
||||
--hash=sha256:773dcbf9a5ab44a090f3441e2180efe2560220203dc2f8c0b0fa141e18b505e4 \
|
||||
--hash=sha256:bb6b4df465655ef332548e24f08e205afc81b9ab86cb1c45657a7ff173a3a00e
|
||||
# via django-auth-ldap
|
||||
pyyaml==6.0.1 \
|
||||
--hash=sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5 \
|
||||
--hash=sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc \
|
||||
--hash=sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df \
|
||||
--hash=sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741 \
|
||||
--hash=sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206 \
|
||||
--hash=sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27 \
|
||||
--hash=sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595 \
|
||||
--hash=sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62 \
|
||||
--hash=sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98 \
|
||||
--hash=sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696 \
|
||||
--hash=sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290 \
|
||||
--hash=sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9 \
|
||||
--hash=sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d \
|
||||
--hash=sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6 \
|
||||
--hash=sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867 \
|
||||
--hash=sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47 \
|
||||
--hash=sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486 \
|
||||
--hash=sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6 \
|
||||
--hash=sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3 \
|
||||
--hash=sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007 \
|
||||
--hash=sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938 \
|
||||
--hash=sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0 \
|
||||
--hash=sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c \
|
||||
--hash=sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735 \
|
||||
--hash=sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d \
|
||||
--hash=sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28 \
|
||||
--hash=sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4 \
|
||||
--hash=sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba \
|
||||
--hash=sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8 \
|
||||
--hash=sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef \
|
||||
--hash=sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5 \
|
||||
--hash=sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd \
|
||||
--hash=sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3 \
|
||||
--hash=sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0 \
|
||||
--hash=sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515 \
|
||||
--hash=sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c \
|
||||
--hash=sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c \
|
||||
--hash=sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924 \
|
||||
--hash=sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34 \
|
||||
--hash=sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43 \
|
||||
--hash=sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859 \
|
||||
--hash=sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673 \
|
||||
--hash=sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54 \
|
||||
--hash=sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a \
|
||||
--hash=sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b \
|
||||
--hash=sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab \
|
||||
--hash=sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa \
|
||||
--hash=sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c \
|
||||
--hash=sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585 \
|
||||
--hash=sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d \
|
||||
--hash=sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f
|
||||
setuptools==69.5.1 \
|
||||
--hash=sha256:6c1fccdac05a97e598fb0ae3bbed5904ccb317337a51139dcd51453611bbb987 \
|
||||
--hash=sha256:c636ac361bc47580504644275c9ad802c50415c7522212252c033bd15f301f32
|
||||
sqlparse==0.5.0 \
|
||||
--hash=sha256:714d0a4932c059d16189f58ef5411ec2287a4360f17cdd0edd2d09d4c5087c93 \
|
||||
--hash=sha256:c204494cd97479d0e39f28c93d46c0b2d5959c7b9ab904762ea6c7af211c8663
|
||||
# via django
|
||||
typing-extensions==4.12.2 \
|
||||
--hash=sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d \
|
||||
--hash=sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8
|
||||
typing-extensions==4.11.0 \
|
||||
--hash=sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0 \
|
||||
--hash=sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a
|
||||
# via
|
||||
# psycopg
|
||||
# psycopg-pool
|
||||
uv==0.3.0 \
|
||||
--hash=sha256:084551ee0743339aa5d0d4c76a94c9f9df16c33030b850f0cd98f316db7b42cc \
|
||||
--hash=sha256:0da4f060d583325846cde0727a8cc0cb4e8c63b30ac9373dae213a7315056d90 \
|
||||
--hash=sha256:160a1f3b01298942d6cfe21f95a9b7daa3eb73231ba1fc4689157eb9f23b3438 \
|
||||
--hash=sha256:21ebc6ca30df7ff57a8e17e3abeeba8a9d1d4ac79c1adf842fa42d48a5c7f372 \
|
||||
--hash=sha256:24a1388f5e285058f97576b7dfee79bb5007a712a9e368f3fcdcfeb2dfd9ce92 \
|
||||
--hash=sha256:2f937ebdf9976ec1ffe7228fd608ef3e6ce2a61ed68cf7b157ae6900a9c80f41 \
|
||||
--hash=sha256:39a4276afe0808ca6c033e0cd6cb73249f934b4a0c9d7b18a944f3f8ea635e27 \
|
||||
--hash=sha256:3b62e44f61a154303fc9f4aa87ae54891957d49769d21dcf2be9c22e640c3e92 \
|
||||
--hash=sha256:4303364d717b1def58e82b11271259d2ee3bb03da0ca6111819ee254f65b38f4 \
|
||||
--hash=sha256:503fc619238550be222b41422b415677c9b8045c92a9815f80ff5d7477671fe6 \
|
||||
--hash=sha256:52b3a6110705ff27462ddc68657fedf8a296ed545619a90fa73354f130ad632e \
|
||||
--hash=sha256:5c826d9daace67d67790503b0c1152093b3cecd35a91de10f5bb9e26afea9de9 \
|
||||
--hash=sha256:6d1025349cbaeba9a974d413795d0ce8d37de5ad7fb7654c0519968b2c083ba1 \
|
||||
--hash=sha256:a15b2321444f3668bc95863d2b13ce44ea54053189427ea48d112ecd8b3d2f89 \
|
||||
--hash=sha256:a71b7080ee6d7658b22f93aa750cbfd19111cd6c8ac643a73d6778598dd06559 \
|
||||
--hash=sha256:b44ebf501de5eef33e4f3cf4b6ea9a458d1f1b3cf26737c25ac507ab7914076a \
|
||||
--hash=sha256:d3da56b87ec5aa4f2ae572127c754655bad3820dd41a4d37ed4d5e2f67035990 \
|
||||
--hash=sha256:d87ff76da5128036c05db0291db7510a85cb8efb86538e8f49adc8074bb292f0
|
||||
# via -r contrib/container/requirements.in
|
||||
wheel==0.44.0 \
|
||||
--hash=sha256:2376a90c98cc337d18623527a97c31797bd02bad0033d41547043a1cbfbe448f \
|
||||
--hash=sha256:a29c3f2817e95ab89aa4660681ad547c0e9547f20e75b0562fe7723c9a2a9d49
|
||||
# via -r contrib/container/requirements.in
|
||||
uv==0.1.38 \
|
||||
--hash=sha256:03242a734a572733f2b9a5dbb94517e918fe26fc01114b7c51d12296dfbb8f8b \
|
||||
--hash=sha256:067af2d986329db4fa3c7373017d49f0e16ddff23e483b7e5bc3a5a18ce08ea6 \
|
||||
--hash=sha256:0937ad16ae0e0b6bb6dd3c386f8fb33141ad08d1762eaacffb4d2b27fb466a17 \
|
||||
--hash=sha256:0e1d64ac437b0a14fbcec55b1c3f162fa24860711e0d855fcd9c672b149a122a \
|
||||
--hash=sha256:1be7aa46936c0351ccb1400ea95e5381b3f05fef772fa3b9f23af728cc175dea \
|
||||
--hash=sha256:309e73a3ec3a5a536a3efaf434270fc94b483069f1425765165c1c9d786c27fd \
|
||||
--hash=sha256:4251f9771d392d7badc1e5fb934b397b12ca00fef9d955207ade169cc1f7e872 \
|
||||
--hash=sha256:43772e7589f70e954b1ae29230e575ef9e4d8d769138a94dfa5ae7eaf1e26ac5 \
|
||||
--hash=sha256:4a6024256d38b77151e32876be9fcb99cf75df7a86b26e0161cc202bed558adf \
|
||||
--hash=sha256:5a98d6aacd4b57b7e00daf154919e7c9206fefdf40bd28cfb13efe0e0324d491 \
|
||||
--hash=sha256:8de6dbd8f348ee90af044f4cc7b6650521d25ba2d20a813c1e157a3f90069dd9 \
|
||||
--hash=sha256:9133e24db9bdd4f412eab69586d03294419825432a9a27ee1b510a4c01eb7b0b \
|
||||
--hash=sha256:92f65b6e4e5c8126501785af3629dc537d7c82caa56ac9336a86929c73d0e138 \
|
||||
--hash=sha256:afd85029923e712b6b2c45ddc1680c785392220876c766521e45778db3f71f8e \
|
||||
--hash=sha256:b0b15e51a0f8240969bc412ed0dd60cfe3f664b30173139ef263d71c596d631f \
|
||||
--hash=sha256:ea44c07605d1359a7d82bf42706dd86d341f15f4ca2e1f36e51626a7111c2ad5 \
|
||||
--hash=sha256:f87c9711493c53d32012a96b49c4d53aabdf7ed666cbf2c3fb55dd402a6b31a8
|
||||
wheel==0.43.0 \
|
||||
--hash=sha256:465ef92c69fa5c5da2d1cf8ac40559a8c940886afcef87dcf14b9470862f1d85 \
|
||||
--hash=sha256:55c570405f142630c6b9f72fe09d9b67cf1477fcf543ae5b8dcb1f5b7377da81
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Packages needed for CI/packages
|
||||
requests==2.32.3
|
||||
pyyaml==6.0.2
|
||||
jc==1.25.3
|
||||
requests==2.31.0
|
||||
pyyaml==6.0.1
|
||||
jc==1.25.2
|
||||
|
@ -1,8 +1,8 @@
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# uv pip compile contrib/dev_reqs/requirements.in -o contrib/dev_reqs/requirements.txt --no-strip-extras --generate-hashes
|
||||
certifi==2024.7.4 \
|
||||
--hash=sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b \
|
||||
--hash=sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90
|
||||
# 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
|
||||
# via requests
|
||||
charset-normalizer==3.3.2 \
|
||||
--hash=sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027 \
|
||||
@ -100,73 +100,68 @@ idna==3.7 \
|
||||
--hash=sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc \
|
||||
--hash=sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0
|
||||
# via requests
|
||||
jc==1.25.3 \
|
||||
--hash=sha256:ea17a8578497f2da92f73924d9d403f4563ba59422fbceff7bb4a16cdf84a54f \
|
||||
--hash=sha256:fa3140ceda6cba1210d1362f363cd79a0514741e8a1dd6167db2b2e2d5f24f7b
|
||||
# via -r contrib/dev_reqs/requirements.in
|
||||
pygments==2.18.0 \
|
||||
--hash=sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199 \
|
||||
--hash=sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a
|
||||
jc==1.25.2 \
|
||||
--hash=sha256:26e412a65a478f9da3097653db6277f915cfae5c0f0a3f42026b405936abd358 \
|
||||
--hash=sha256:97ada193495f79550f06fe0cbfb119ff470bcca57c1cc593a5cdb0008720e0b3
|
||||
pygments==2.17.2 \
|
||||
--hash=sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c \
|
||||
--hash=sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367
|
||||
# via jc
|
||||
pyyaml==6.0.2 \
|
||||
--hash=sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff \
|
||||
--hash=sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48 \
|
||||
--hash=sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086 \
|
||||
--hash=sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e \
|
||||
--hash=sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133 \
|
||||
--hash=sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5 \
|
||||
--hash=sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484 \
|
||||
--hash=sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee \
|
||||
--hash=sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5 \
|
||||
--hash=sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68 \
|
||||
--hash=sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a \
|
||||
--hash=sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf \
|
||||
--hash=sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99 \
|
||||
--hash=sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8 \
|
||||
--hash=sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85 \
|
||||
--hash=sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19 \
|
||||
--hash=sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc \
|
||||
--hash=sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a \
|
||||
--hash=sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1 \
|
||||
--hash=sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317 \
|
||||
--hash=sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c \
|
||||
--hash=sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631 \
|
||||
--hash=sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d \
|
||||
--hash=sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652 \
|
||||
--hash=sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5 \
|
||||
--hash=sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e \
|
||||
--hash=sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b \
|
||||
--hash=sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8 \
|
||||
--hash=sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476 \
|
||||
--hash=sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706 \
|
||||
--hash=sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563 \
|
||||
--hash=sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237 \
|
||||
--hash=sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b \
|
||||
--hash=sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083 \
|
||||
--hash=sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180 \
|
||||
--hash=sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425 \
|
||||
--hash=sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e \
|
||||
--hash=sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f \
|
||||
--hash=sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725 \
|
||||
--hash=sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183 \
|
||||
--hash=sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab \
|
||||
--hash=sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774 \
|
||||
--hash=sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725 \
|
||||
--hash=sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e \
|
||||
--hash=sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5 \
|
||||
--hash=sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d \
|
||||
--hash=sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290 \
|
||||
--hash=sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44 \
|
||||
--hash=sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed \
|
||||
--hash=sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4 \
|
||||
--hash=sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba \
|
||||
--hash=sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12 \
|
||||
--hash=sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4
|
||||
# via -r contrib/dev_reqs/requirements.in
|
||||
requests==2.32.3 \
|
||||
--hash=sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760 \
|
||||
--hash=sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6
|
||||
# via -r contrib/dev_reqs/requirements.in
|
||||
pyyaml==6.0.1 \
|
||||
--hash=sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5 \
|
||||
--hash=sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc \
|
||||
--hash=sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df \
|
||||
--hash=sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741 \
|
||||
--hash=sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206 \
|
||||
--hash=sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27 \
|
||||
--hash=sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595 \
|
||||
--hash=sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62 \
|
||||
--hash=sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98 \
|
||||
--hash=sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696 \
|
||||
--hash=sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290 \
|
||||
--hash=sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9 \
|
||||
--hash=sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d \
|
||||
--hash=sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6 \
|
||||
--hash=sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867 \
|
||||
--hash=sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47 \
|
||||
--hash=sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486 \
|
||||
--hash=sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6 \
|
||||
--hash=sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3 \
|
||||
--hash=sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007 \
|
||||
--hash=sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938 \
|
||||
--hash=sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0 \
|
||||
--hash=sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c \
|
||||
--hash=sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735 \
|
||||
--hash=sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d \
|
||||
--hash=sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28 \
|
||||
--hash=sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4 \
|
||||
--hash=sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba \
|
||||
--hash=sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8 \
|
||||
--hash=sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef \
|
||||
--hash=sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5 \
|
||||
--hash=sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd \
|
||||
--hash=sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3 \
|
||||
--hash=sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0 \
|
||||
--hash=sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515 \
|
||||
--hash=sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c \
|
||||
--hash=sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c \
|
||||
--hash=sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924 \
|
||||
--hash=sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34 \
|
||||
--hash=sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43 \
|
||||
--hash=sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859 \
|
||||
--hash=sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673 \
|
||||
--hash=sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54 \
|
||||
--hash=sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a \
|
||||
--hash=sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b \
|
||||
--hash=sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab \
|
||||
--hash=sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa \
|
||||
--hash=sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c \
|
||||
--hash=sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585 \
|
||||
--hash=sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d \
|
||||
--hash=sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f
|
||||
requests==2.31.0 \
|
||||
--hash=sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f \
|
||||
--hash=sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1
|
||||
ruamel-yaml==0.18.6 \
|
||||
--hash=sha256:57b53ba33def16c4f3d807c0ccbc00f8a6081827e81ba2491691b76882d0c636 \
|
||||
--hash=sha256:8b27e6a217e786c6fbe5634d8f3f11bc63e0f80f6a5890f28863d9c45aac311b
|
||||
@ -223,9 +218,9 @@ ruamel-yaml-clib==0.2.8 \
|
||||
--hash=sha256:f481f16baec5290e45aebdc2a5168ebc6d35189ae6fea7a58787613a25f6e875 \
|
||||
--hash=sha256:fff3573c2db359f091e1589c3d7c5fc2f86f5bdb6f24252c2d8e539d4e45f412
|
||||
# via ruamel-yaml
|
||||
urllib3==2.2.2 \
|
||||
--hash=sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472 \
|
||||
--hash=sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168
|
||||
urllib3==2.2.1 \
|
||||
--hash=sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d \
|
||||
--hash=sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19
|
||||
# via requests
|
||||
xmltodict==0.13.0 \
|
||||
--hash=sha256:341595a488e3e01a85a9d8911d8912fd922ede5fecc4dce437eb4b6c8d037e56 \
|
||||
|
@ -75,7 +75,6 @@ root_command() {
|
||||
;;
|
||||
"Debian GNU/Linux" | "debian gnu/linux" | Raspbian)
|
||||
if [[ $VER == "12" ]]; then
|
||||
DIST_VER="11"
|
||||
SUPPORTED=true
|
||||
elif [[ $VER == "11" ]]; then
|
||||
SUPPORTED=true
|
||||
|
@ -5,40 +5,33 @@
|
||||
|
||||
set -eu
|
||||
|
||||
# The sha is the second element in APP_PKG_ITERATION
|
||||
VERSION="$APP_PKG_VERSION-$APP_PKG_ITERATION"
|
||||
echo "Setting VERSION information to $VERSION"
|
||||
echo "$VERSION" > VERSION
|
||||
|
||||
# The sha is the second element in APP_PKG_ITERATION
|
||||
SHA=$(echo $APP_PKG_ITERATION | cut -d'.' -f2)
|
||||
|
||||
# Download info
|
||||
echo "INFO collection | Getting info from github for commit $SHA"
|
||||
curl -L -s -f \
|
||||
echo "Getting info from github for commit $SHA"
|
||||
curl -L \
|
||||
-H "Accept: application/vnd.github+json" \
|
||||
-H "X-GitHub-Api-Version: 2022-11-28" \
|
||||
https://api.github.com/repos/$APP_REPO/commits/$SHA > commit.json
|
||||
echo "INFO collection | Got commit.json with size $(wc -c commit.json)"
|
||||
curl -L -s -f \
|
||||
https://api.github.com/repos/InvenTree/InvenTree/commits/$SHA > commit.json
|
||||
curl -L \
|
||||
-H "Accept: application/vnd.github+json" \
|
||||
-H "X-GitHub-Api-Version: 2022-11-28" \
|
||||
https://api.github.com/repos/$APP_REPO/commits/$SHA/branches-where-head > branches.json
|
||||
echo "INFO collection | Got branches.json with size $(wc -c branches.json)"
|
||||
curl -L -s -f \
|
||||
-H "Accept: application/vnd.github+json" \
|
||||
-H "X-GitHub-Api-Version: 2022-11-28" \
|
||||
https://api.github.com/repos/$APP_REPO/commits/$APP_PKG_VERSION > tag.json
|
||||
echo "INFO collection | Got tag.json with size $(wc -c tag.json)"
|
||||
https://api.github.com/repos/InvenTree/InvenTree/commits/$SHA/branches-where-head > branches.json
|
||||
|
||||
# Extract info
|
||||
echo "INFO extract | Extracting info from github"
|
||||
echo "Extracting info from github"
|
||||
DATE=$(jq -r '.commit.committer.date' commit.json)
|
||||
BRANCH=$(jq -r '.[].name' branches.json)
|
||||
NODE_ID=$(jq -r '.node_id' commit.json)
|
||||
SIGNATURE=$(jq -r '.commit.verification.signature' commit.json)
|
||||
FULL_SHA=$(jq -r '.sha' commit.json)
|
||||
|
||||
echo "INFO write | Write VERSION information"
|
||||
echo "$VERSION" > VERSION
|
||||
echo "Write VERSION information"
|
||||
echo "INVENTREE_COMMIT_HASH='$SHA'" >> VERSION
|
||||
echo "INVENTREE_COMMIT_SHA='$FULL_SHA'" >> VERSION
|
||||
echo "INVENTREE_COMMIT_DATE='$DATE'" >> VERSION
|
||||
echo "INVENTREE_PKG_INSTALLER='PKG'" >> VERSION
|
||||
echo "INVENTREE_PKG_BRANCH='$BRANCH'" >> VERSION
|
||||
@ -46,22 +39,5 @@ echo "INVENTREE_PKG_TARGET='$TARGET'" >> VERSION
|
||||
echo "NODE_ID='$NODE_ID'" >> VERSION
|
||||
echo "SIGNATURE='$SIGNATURE'" >> VERSION
|
||||
|
||||
echo "INFO write | Written VERSION information"
|
||||
echo "### VERSION ###"
|
||||
echo "Written VERSION information"
|
||||
cat VERSION
|
||||
echo "### VERSION ###"
|
||||
|
||||
# Try to get frontend
|
||||
echo "INFO frontend | Trying to get frontend"
|
||||
# Check if tag sha is the same as the commit sha
|
||||
TAG_SHA=$(jq -r '.sha' tag.json)
|
||||
if [ "$TAG_SHA" != "$FULL_SHA" ]; then
|
||||
echo "INFO frontend | Tag sha '$TAG_SHA' is not the same as commit sha $FULL_SHA, can not download frontend"
|
||||
else
|
||||
echo "INFO frontend | Getting frontend from github via tag"
|
||||
curl https://github.com/$APP_REPO/releases/download/$APP_PKG_VERSION/frontend-build.zip -L -O -f
|
||||
mkdir -p src/backend/InvenTree/web/static
|
||||
echo "INFO frontend | Unzipping frontend"
|
||||
unzip -qq frontend-build.zip -d src/backend/InvenTree/web/static/web
|
||||
echo "INFO frontend | Unzipped frontend"
|
||||
fi
|
||||
|
@ -4,8 +4,6 @@
|
||||
#
|
||||
Color_Off='\033[0m'
|
||||
On_Red='\033[41m'
|
||||
PYTHON_FROM=9
|
||||
PYTHON_TO=12
|
||||
|
||||
function detect_docker() {
|
||||
if [ -n "$(grep docker </proc/1/cgroup)" ]; then
|
||||
@ -59,19 +57,6 @@ function detect_python() {
|
||||
echo "# No python environment found - using environment variable: ${SETUP_PYTHON}"
|
||||
fi
|
||||
|
||||
# Try to detect a python between 3.9 and 3.12 in reverse order
|
||||
if [ -z "$(which ${SETUP_PYTHON})" ]; then
|
||||
echo "# Trying to detecting python3.${PYTHON_FROM} to python3.${PYTHON_TO} - using newest version"
|
||||
for i in $(seq $PYTHON_TO -1 $PYTHON_FROM); do
|
||||
echo "# Checking for python3.${i}"
|
||||
if [ -n "$(which python3.${i})" ]; then
|
||||
SETUP_PYTHON="python3.${i}"
|
||||
echo "# Found python3.${i} installed - using for setup ${SETUP_PYTHON}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# Ensure python can be executed - abort if not
|
||||
if [ -z "$(which ${SETUP_PYTHON})" ]; then
|
||||
echo "${On_Red}"
|
||||
@ -132,22 +117,22 @@ function detect_envs() {
|
||||
pip install --require-hashes -r ${APP_HOME}/contrib/dev_reqs/requirements.txt -q
|
||||
|
||||
# Load config
|
||||
export INVENTREE_CONF_DATA=$(cat ${INVENTREE_CONFIG_FILE} | jc --yaml)
|
||||
local CONF=$(cat ${INVENTREE_CONFIG_FILE} | jc --yaml)
|
||||
|
||||
# Parse the config file
|
||||
export INVENTREE_MEDIA_ROOT=$(jq -r '.[].media_root' <<< ${INVENTREE_CONF_DATA})
|
||||
export INVENTREE_STATIC_ROOT=$(jq -r '.[].static_root' <<< ${INVENTREE_CONF_DATA})
|
||||
export INVENTREE_BACKUP_DIR=$(jq -r '.[].backup_dir' <<< ${INVENTREE_CONF_DATA})
|
||||
export INVENTREE_PLUGINS_ENABLED=$(jq -r '.[].plugins_enabled' <<< ${INVENTREE_CONF_DATA})
|
||||
export INVENTREE_PLUGIN_FILE=$(jq -r '.[].plugin_file' <<< ${INVENTREE_CONF_DATA})
|
||||
export INVENTREE_SECRET_KEY_FILE=$(jq -r '.[].secret_key_file' <<< ${INVENTREE_CONF_DATA})
|
||||
export INVENTREE_MEDIA_ROOT=$(jq -r '.[].media_root' <<< ${CONF})
|
||||
export INVENTREE_STATIC_ROOT=$(jq -r '.[].static_root' <<< ${CONF})
|
||||
export INVENTREE_BACKUP_DIR=$(jq -r '.[].backup_dir' <<< ${CONF})
|
||||
export INVENTREE_PLUGINS_ENABLED=$(jq -r '.[].plugins_enabled' <<< ${CONF})
|
||||
export INVENTREE_PLUGIN_FILE=$(jq -r '.[].plugin_file' <<< ${CONF})
|
||||
export INVENTREE_SECRET_KEY_FILE=$(jq -r '.[].secret_key_file' <<< ${CONF})
|
||||
|
||||
export INVENTREE_DB_ENGINE=$(jq -r '.[].database.ENGINE' <<< ${INVENTREE_CONF_DATA})
|
||||
export INVENTREE_DB_NAME=$(jq -r '.[].database.NAME' <<< ${INVENTREE_CONF_DATA})
|
||||
export INVENTREE_DB_USER=$(jq -r '.[].database.USER' <<< ${INVENTREE_CONF_DATA})
|
||||
export INVENTREE_DB_PASSWORD=$(jq -r '.[].database.PASSWORD' <<< ${INVENTREE_CONF_DATA})
|
||||
export INVENTREE_DB_HOST=$(jq -r '.[].database.HOST' <<< ${INVENTREE_CONF_DATA})
|
||||
export INVENTREE_DB_PORT=$(jq -r '.[].database.PORT' <<< ${INVENTREE_CONF_DATA})
|
||||
export INVENTREE_DB_ENGINE=$(jq -r '.[].database.ENGINE' <<< ${CONF})
|
||||
export INVENTREE_DB_NAME=$(jq -r '.[].database.NAME' <<< ${CONF})
|
||||
export INVENTREE_DB_USER=$(jq -r '.[].database.USER' <<< ${CONF})
|
||||
export INVENTREE_DB_PASSWORD=$(jq -r '.[].database.PASSWORD' <<< ${CONF})
|
||||
export INVENTREE_DB_HOST=$(jq -r '.[].database.HOST' <<< ${CONF})
|
||||
export INVENTREE_DB_PORT=$(jq -r '.[].database.PORT' <<< ${CONF})
|
||||
else
|
||||
echo "# No config file found: ${INVENTREE_CONFIG_FILE}, using envs or defaults"
|
||||
|
||||
@ -246,11 +231,7 @@ function create_initscripts() {
|
||||
}
|
||||
|
||||
function create_admin() {
|
||||
# Create data for admin users - stop with setting SETUP_ADMIN_NOCREATION to true
|
||||
if [ "${SETUP_ADMIN_NOCREATION}" == "true" ]; then
|
||||
echo "# Admin creation is disabled - skipping"
|
||||
return
|
||||
fi
|
||||
# Create data for admin user
|
||||
|
||||
if test -f "${SETUP_ADMIN_PASSWORD_FILE}"; then
|
||||
echo "# Admin data already exists - skipping"
|
||||
@ -318,17 +299,17 @@ function set_env() {
|
||||
sed -i s=debug:\ True=debug:\ False=g ${INVENTREE_CONFIG_FILE}
|
||||
|
||||
# Database engine
|
||||
sed -i s=#\ ENGINE:\ Database\ engine.\ Selection\ from:=ENGINE:\ ${INVENTREE_DB_ENGINE}=g ${INVENTREE_CONFIG_FILE}
|
||||
sed -i s=#ENGINE:\ sampleengine=ENGINE:\ ${INVENTREE_DB_ENGINE}=g ${INVENTREE_CONFIG_FILE}
|
||||
# Database name
|
||||
sed -i s=#\ NAME:\ Database\ name=NAME:\ \'${INVENTREE_DB_NAME}\'=g ${INVENTREE_CONFIG_FILE}
|
||||
sed -i s=#NAME:\ \'/path/to/database\'=NAME:\ \'${INVENTREE_DB_NAME}\'=g ${INVENTREE_CONFIG_FILE}
|
||||
# Database user
|
||||
sed -i s=#\ USER:\ Database\ username\ \(if\ required\)=USER:\ ${INVENTREE_DB_USER}=g ${INVENTREE_CONFIG_FILE}
|
||||
sed -i s=#USER:\ sampleuser=USER:\ ${INVENTREE_DB_USER}=g ${INVENTREE_CONFIG_FILE}
|
||||
# Database password
|
||||
sed -i s=#\ PASSWORD:\ Database\ password\ \(if\ required\)=PASSWORD:\ ${INVENTREE_DB_PASSWORD}=g ${INVENTREE_CONFIG_FILE}
|
||||
sed -i s=#PASSWORD:\ samplepassword=PASSWORD:\ ${INVENTREE_DB_PASSWORD}=g ${INVENTREE_CONFIG_FILE}
|
||||
# Database host
|
||||
sed -i s=#\ HOST:\ Database\ host\ address\ \(if\ required\)=HOST:\ ${INVENTREE_DB_HOST}=g ${INVENTREE_CONFIG_FILE}
|
||||
sed -i s=#HOST:\ samplehost=HOST:\ ${INVENTREE_DB_HOST}=g ${INVENTREE_CONFIG_FILE}
|
||||
# Database port
|
||||
sed -i s=#\ PORT:\ Database\ host\ port\ \(if\ required\)=PORT:\ ${INVENTREE_DB_PORT}=g ${INVENTREE_CONFIG_FILE}
|
||||
sed -i s=#PORT:\ 123456=PORT:\ ${INVENTREE_DB_PORT}=g ${INVENTREE_CONFIG_FILE}
|
||||
|
||||
# Fixing the permissions
|
||||
chown ${APP_USER}:${APP_GROUP} ${DATA_DIR} ${INVENTREE_CONFIG_FILE}
|
||||
@ -359,44 +340,3 @@ function final_message() {
|
||||
echo -e " Password: ${INVENTREE_ADMIN_PASSWORD}"
|
||||
echo -e "####################################################################################"
|
||||
}
|
||||
|
||||
|
||||
function update_checks() {
|
||||
echo "# Running upgrade"
|
||||
local old_version=$1
|
||||
local old_version_rev=$(echo ${old_version} | cut -d'-' -f1 | cut -d'.' -f2)
|
||||
echo "# Old version is: ${old_version} - release: ${old_version_rev}"
|
||||
|
||||
local ABORT=false
|
||||
function check_config_value() {
|
||||
local env_key=$1
|
||||
local config_key=$2
|
||||
local name=$3
|
||||
|
||||
local value=$(inventree config:get ${env_key})
|
||||
if [ -z "${value}" ] || [ "$value" == "null" ]; then
|
||||
value=$(jq -r ".[].${config_key}" <<< ${INVENTREE_CONF_DATA})
|
||||
fi
|
||||
if [ -z "${value}" ] || [ "$value" == "null" ]; then
|
||||
echo "# No setting for ${name} found - please set it manually either in ${INVENTREE_CONFIG_FILE} under '${config_key}' or with 'inventree config:set ${env_key}=value'"
|
||||
ABORT=true
|
||||
else
|
||||
echo "# Found setting for ${name} - ${value}"
|
||||
fi
|
||||
}
|
||||
|
||||
# Custom checks if old version is below 0.8.0
|
||||
if [ "${old_version_rev}" -lt "9" ]; then
|
||||
echo "# Old version is below 0.9.0 - You might be missing some configs"
|
||||
|
||||
# Check for BACKUP_DIR and SITE_URL in INVENTREE_CONF_DATA and config
|
||||
check_config_value "INVENTREE_SITE_URL" "site_url" "site URL"
|
||||
check_config_value "INVENTREE_BACKUP_DIR" "backup_dir" "backup dir"
|
||||
|
||||
if [ "${ABORT}" = true ]; then
|
||||
echo "# Aborting - please set the missing values and run the update again"
|
||||
exit 1
|
||||
fi
|
||||
echo "# All checks passed - continuing with the update"
|
||||
fi
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ PATH=${APP_HOME}/env/bin:${APP_HOME}/:/sbin:/bin:/usr/sbin:/usr/bin:
|
||||
. ${APP_HOME}/contrib/packager.io/functions.sh
|
||||
|
||||
# Envs that should be passed to setup commands
|
||||
export SETUP_ENVS=PATH,APP_HOME,INVENTREE_MEDIA_ROOT,INVENTREE_STATIC_ROOT,INVENTREE_BACKUP_DIR,INVENTREE_SITE_URL,INVENTREE_PLUGINS_ENABLED,INVENTREE_PLUGIN_FILE,INVENTREE_CONFIG_FILE,INVENTREE_SECRET_KEY_FILE,INVENTREE_DB_ENGINE,INVENTREE_DB_NAME,INVENTREE_DB_USER,INVENTREE_DB_PASSWORD,INVENTREE_DB_HOST,INVENTREE_DB_PORT,INVENTREE_ADMIN_USER,INVENTREE_ADMIN_EMAIL,INVENTREE_ADMIN_PASSWORD,SETUP_NGINX_FILE,SETUP_ADMIN_PASSWORD_FILE,SETUP_NO_CALLS,SETUP_DEBUG,SETUP_EXTRA_PIP,SETUP_PYTHON,SETUP_ADMIN_NOCREATION
|
||||
export SETUP_ENVS=PATH,APP_HOME,INVENTREE_MEDIA_ROOT,INVENTREE_STATIC_ROOT,INVENTREE_BACKUP_DIR,INVENTREE_PLUGINS_ENABLED,INVENTREE_PLUGIN_FILE,INVENTREE_CONFIG_FILE,INVENTREE_SECRET_KEY_FILE,INVENTREE_DB_ENGINE,INVENTREE_DB_NAME,INVENTREE_DB_USER,INVENTREE_DB_PASSWORD,INVENTREE_DB_HOST,INVENTREE_DB_PORT,INVENTREE_ADMIN_USER,INVENTREE_ADMIN_EMAIL,INVENTREE_ADMIN_PASSWORD,SETUP_NGINX_FILE,SETUP_ADMIN_PASSWORD_FILE,SETUP_NO_CALLS,SETUP_DEBUG,SETUP_EXTRA_PIP,SETUP_PYTHON
|
||||
|
||||
# Get the envs
|
||||
detect_local_env
|
||||
@ -24,7 +24,6 @@ export SETUP_NGINX_FILE=${SETUP_NGINX_FILE:-/etc/nginx/sites-enabled/inventree.c
|
||||
export SETUP_ADMIN_PASSWORD_FILE=${CONF_DIR}/admin_password.txt
|
||||
export SETUP_NO_CALLS=${SETUP_NO_CALLS:-false}
|
||||
export SETUP_PYTHON=${SETUP_PYTHON:-python3.9}
|
||||
export SETUP_ADMIN_NOCREATION=${SETUP_ADMIN_NOCREATION:-false}
|
||||
# SETUP_DEBUG can be set to get debug info
|
||||
# SETUP_EXTRA_PIP can be set to install extra pip packages
|
||||
# SETUP_PYTHON can be set to use a different python version
|
||||
@ -36,14 +35,6 @@ detect_initcmd
|
||||
detect_ip
|
||||
detect_python
|
||||
|
||||
# Check if we are updating and need to alert
|
||||
echo "# Checking if update checks are needed"
|
||||
if [ -z "$2" ]; then
|
||||
echo "# Normal install - no need for checks"
|
||||
else
|
||||
update_checks $2
|
||||
fi
|
||||
|
||||
# create processes
|
||||
create_initscripts
|
||||
create_admin
|
||||
|
@ -1,20 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# packager.io preinstall/preremove script
|
||||
#
|
||||
PATH=${APP_HOME}/env/bin:${APP_HOME}/:/sbin:/bin:/usr/sbin:/usr/bin:
|
||||
|
||||
# Envs that should be passed to setup commands
|
||||
export SETUP_ENVS=PATH,APP_HOME,INVENTREE_MEDIA_ROOT,INVENTREE_STATIC_ROOT,INVENTREE_BACKUP_DIR,INVENTREE_PLUGINS_ENABLED,INVENTREE_PLUGIN_FILE,INVENTREE_CONFIG_FILE,INVENTREE_SECRET_KEY_FILE,INVENTREE_DB_ENGINE,INVENTREE_DB_NAME,INVENTREE_DB_USER,INVENTREE_DB_PASSWORD,INVENTREE_DB_HOST,INVENTREE_DB_PORT,INVENTREE_ADMIN_USER,INVENTREE_ADMIN_EMAIL,INVENTREE_ADMIN_PASSWORD,SETUP_NGINX_FILE,SETUP_ADMIN_PASSWORD_FILE,SETUP_NO_CALLS,SETUP_DEBUG,SETUP_EXTRA_PIP,SETUP_PYTHON
|
||||
|
||||
if test -f "${APP_HOME}/env/bin/pip"; then
|
||||
# Check if clear-generated is available
|
||||
if sudo -u ${APP_USER} --preserve-env=$SETUP_ENVS bash -c "cd ${APP_HOME} && invoke clear-generated --help" > /dev/null 2>&1; then
|
||||
echo "# Clearing precompiled files"
|
||||
sudo -u ${APP_USER} --preserve-env=$SETUP_ENVS bash -c "cd ${APP_HOME} && invoke clear-generated"
|
||||
else
|
||||
echo "# Clearing precompiled files - skipping"
|
||||
fi
|
||||
else
|
||||
echo "# No python environment found - skipping"
|
||||
fi
|
@ -1,14 +1,8 @@
|
||||
# Configuration file for Crowdin project integration
|
||||
# See: https://crowdin.com/project/inventree
|
||||
|
||||
"commit_message": "Fix: New translations %original_file_name% from Crowdin"
|
||||
"append_commit_message": false
|
||||
"preserve_hierarchy": true
|
||||
|
||||
files:
|
||||
- source: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po
|
||||
dest: /%original_path%/%original_file_name%
|
||||
translation: /src/backend/InvenTree/locale/%two_letters_code%/LC_MESSAGES/%original_file_name%
|
||||
- source: /src/frontend/src/locales/en/messages.po
|
||||
dest: /%original_path%/%original_file_name%
|
||||
translation: /src/frontend/src/locales/%two_letters_code%/%original_file_name%
|
||||
|
4
docs/.gitignore
vendored
@ -13,10 +13,6 @@ site/
|
||||
# Generated API schema files
|
||||
docs/api/schema/*.yml
|
||||
|
||||
# Temporary cache files
|
||||
url_cache.txt
|
||||
invoke-commands.txt
|
||||
|
||||
# Temp files
|
||||
releases.json
|
||||
versions.json
|
||||
|
@ -10,7 +10,7 @@ tld = os.path.abspath(os.path.join(here, '..'))
|
||||
|
||||
config_file = os.path.join(tld, 'mkdocs.yml')
|
||||
|
||||
with open(config_file, encoding='utf-8') as f:
|
||||
with open(config_file, 'r') as f:
|
||||
data = yaml.load(f, yaml.BaseLoader)
|
||||
|
||||
assert data['strict'] == 'true'
|
||||
|
Before Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 45 KiB |
Before Width: | Height: | Size: 54 KiB |
Before Width: | Height: | Size: 58 KiB |
Before Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 5.4 KiB |
BIN
docs/docs/assets/images/report/add_report_template.png
Normal file
After Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 42 KiB |
BIN
docs/docs/assets/images/settings/user_notifications.png
Normal file
After Width: | Height: | Size: 56 KiB |
BIN
docs/docs/assets/images/settings/user_reporting.png
Normal file
After Width: | Height: | Size: 84 KiB |
@ -4,11 +4,7 @@ title: Internal Barcodes
|
||||
|
||||
## Internal Barcodes
|
||||
|
||||
InvenTree ships with two integrated internal formats for generating barcodes for various items which are available through the built-in InvenTree Barcode plugin. The used format can be selected through the plugin settings of the InvenTree Barcode plugin.
|
||||
|
||||
### 1. JSON-based QR Codes
|
||||
|
||||
This format uses a simple JSON-style string to uniquely identify an item in the database.
|
||||
InvenTree defines an internal format for generating barcodes for various items. This format uses a simple JSON-style string to uniquely identify an item in the database.
|
||||
|
||||
Some simple examples of this format are shown below:
|
||||
|
||||
@ -16,49 +12,10 @@ Some simple examples of this format are shown below:
|
||||
| --- | --- |
|
||||
| Part | `{% raw %}{"part": 10}{% endraw %}` |
|
||||
| Stock Item | `{% raw %}{"stockitem": 123}{% endraw %}` |
|
||||
| Stock Location | `{% raw %}{"stocklocation": 1}{% endraw %}` |
|
||||
| Supplier Part | `{% raw %}{"supplierpart": 99}{% endraw %}` |
|
||||
|
||||
The numerical ID value used is the *Primary Key* (PK) of the particular object in the database.
|
||||
|
||||
#### Downsides
|
||||
|
||||
1. The JSON format includes binary only characters (`{% raw %}{{% endraw %}` and `{% raw %}"{% endraw %}`) which requires unnecessary use of the binary QR code encoding which means fewer amount of chars can be encoded with the same version of QR code.
|
||||
2. The model name key has not a fixed length. Some model names are longer than others. E.g. a part QR code with the shortest possible id requires 11 chars, while a stock location QR code with the same id would already require 20 chars, which already requires QR code version 2 and quickly version 3.
|
||||
|
||||
!!! info "QR code versions"
|
||||
There are 40 different qr code versions from 1-40. They all can encode more data than the previous version, but require more "squares". E.g. a V1 QR codes has 21x21 "squares" while a V2 already has 25x25. For more information see [QR code comparison](https://www.qrcode.com/en/about/version.html).
|
||||
|
||||
For a more detailed size analysis of the JSON-based QR codes refer to [this issue](https://github.com/inventree/InvenTree/issues/6612).
|
||||
|
||||
### 2. Short alphanumeric QR Codes
|
||||
|
||||
While JSON-based QR Codes encode all necessary information, they come with the described downsides. This new, short, alphanumeric only format is build to improve those downsides. The basic format uses an alphanumeric string: `INV-??x`
|
||||
|
||||
- `INV-` is a constant prefix. This is configurable in the InvenTree Barcode plugins settings per instance to support environments that use multiple instances.
|
||||
- `??` is a two character alphanumeric (`0-9A-Z $%*+-./:` (45 chars)) code, individual to each model.
|
||||
- `x` the actual pk of the model.
|
||||
|
||||
Now with an overhead of 6 chars for every model, this format supports the following amount of model instances using the described QR code modes:
|
||||
|
||||
| QR code mode | Alphanumeric mode | Mixed mode |
|
||||
| --- | --- | --- |
|
||||
| v1 M ECL (15%) | `10**14` items (~3.170 items per sec for 1000 years) | `10**20` items (~3.170.979.198 items per sec for 1000 years) |
|
||||
| v1 Q ECL (25%) | `10**10` items (~0.317 items per sec for 1000 years) | `10**13` items (~317 items per sec for 1000 years) |
|
||||
| v1 H ECL (30%) | `10**4` items (~100 items per day for 100 days) | `10**3` items (~100 items per day for 10 days (*even worse*)) |
|
||||
|
||||
!!! info "QR code mixed mode"
|
||||
Normally the QR code data is encoded only in one format (binary, alphanumeric, numeric). But the data can also be split into multiple chunks using different formats. This is especially useful with long model ids, because the first 6 chars can be encoded using the alphanumeric mode and the id using the more efficient numeric mode. Mixed mode is used by default, because the `qrcode` template tag uses a default value for optimize of 1.
|
||||
|
||||
Some simple examples of this format are shown below:
|
||||
|
||||
| Model Type | Example Barcode |
|
||||
| --- | --- |
|
||||
| Part | `INV-PA10` |
|
||||
| Stock Item | `INV-SI123` |
|
||||
| Stock Location | `INV-SL1` |
|
||||
| Supplier Part | `INV-SP99` |
|
||||
|
||||
## Report Integration
|
||||
|
||||
This barcode format can be used to generate 1D or 2D barcodes (e.g. for [labels and reports](../report/barcodes.md))
|
||||
|
116
docs/docs/build/build.md
vendored
@ -26,6 +26,14 @@ To navigate to the Build Order display, select *Build* from the main navigation
|
||||
{% include "img.html" %}
|
||||
{% endwith %}
|
||||
|
||||
#### Tree View
|
||||
|
||||
*Tree View* also provides a tabulated view of Build Orders. Orders are displayed in a hierarchical manner, showing any parent / child relationships between different build orders.
|
||||
|
||||
{% with id="build_tree", url="build/build_tree.png", description="Build Tree" %}
|
||||
{% include "img.html" %}
|
||||
{% endwith %}
|
||||
|
||||
#### Calendar View
|
||||
|
||||
*Calendar View* shows a calendar display with upcoming build orders, based on the various dates specified for each build.
|
||||
@ -66,23 +74,10 @@ Each *Build Order* has an associated *Status* flag, which indicates the state of
|
||||
|
||||
| Status | Description |
|
||||
| ----------- | ----------- |
|
||||
| `Pending` | Build order has been created, but is not yet in production |
|
||||
| `Production` | Build order is currently in production |
|
||||
| `On Hold` | Build order has been placed on hold, but is still active |
|
||||
| `Cancelled` | Build order has been cancelled |
|
||||
| `Completed` | Build order has been completed |
|
||||
|
||||
**Source Code**
|
||||
|
||||
Refer to the source code for the Build Order status codes:
|
||||
|
||||
::: build.status_codes.BuildStatus
|
||||
options:
|
||||
show_bases: False
|
||||
show_root_heading: False
|
||||
show_root_toc_entry: False
|
||||
show_source: True
|
||||
members: []
|
||||
| `Pending` | Build has been created and build is ready for subpart allocation |
|
||||
| `Production` | One or more build outputs have been created for this build |
|
||||
| `Cancelled` | Build has been cancelled |
|
||||
| `Completed` | Build has been completed |
|
||||
|
||||
### Stock Allocations
|
||||
|
||||
@ -104,29 +99,41 @@ For further information, refer to the [stock allocation documentation](./allocat
|
||||
|
||||
## Build Order Display
|
||||
|
||||
The detail view for a single build order provides multiple display panels, as follows:
|
||||
The detail view for a single build order provides multiple display tabs, as follows:
|
||||
|
||||
### Build Details
|
||||
|
||||
The *Build Details* panel provides an overview of the Build Order:
|
||||
The *Build Details* tab provides an overview of the Build Order:
|
||||
|
||||
{% with id="build_details", url="build/build_panel_details.png", description="Build details panel" %}
|
||||
{% with id="build_details", url="build/build_details.png", description="Details tab" %}
|
||||
{% include "img.html" %}
|
||||
{% endwith %}
|
||||
|
||||
### Line Items
|
||||
### Allocate Stock
|
||||
|
||||
The *Line Items* panel displays all the line items (as defined by the [bill of materials](./bom.md)) required to complete the build order.
|
||||
The *Allocate Stock* tab provides an interface to allocate required stock (as specified by the BOM) to the build:
|
||||
|
||||
{% with id="build_allocate", url="build/build_panel_line_items.png", description="Build line items panel" %}
|
||||
{% with id="build_allocate", url="build/build_allocate.png", description="Allocation tab" %}
|
||||
{% include "img.html" %}
|
||||
{% endwith %}
|
||||
|
||||
The allocation table (as shown above) provides an interface to allocate required stock, and also shows the stock allocation progress for each line item in the build.
|
||||
The allocation table (as shown above) shows the stock allocation progress for this build. In the example above, there are two BOM lines, which have been partially allocated.
|
||||
|
||||
### Incomplete Outputs
|
||||
!!! info "Completed Builds"
|
||||
The *Allocate Stock* tab is not available if the build has been completed!
|
||||
|
||||
The *Incomplete Outputs* panel shows the list of in-progress [build outputs](./output.md) (created stock items) associated with this build.
|
||||
### Consumed Stock
|
||||
|
||||
The *Consumed Stock* tab displays all stock items which have been *consumed* by this build order. These stock items remain in the database after the build order has been completed, but are no longer available for use.
|
||||
|
||||
- [Tracked stock items](./allocate.md#tracked-stock) are consumed by specific build outputs
|
||||
- [Untracked stock items](./allocate.md#untracked-stock) are consumed by the build order
|
||||
|
||||
### Build Outputs
|
||||
|
||||
The *Build Outputs* tab shows the [build outputs](./output.md) (created stock items) associated with this build.
|
||||
|
||||
As shown below, there are separate panels for *incomplete* and *completed* build outputs.
|
||||
|
||||
{% with id="build_outputs", url="build/build_outputs.png", description="Outputs tab" %}
|
||||
{% include "img.html" %}
|
||||
@ -139,48 +146,11 @@ The *Incomplete Outputs* panel shows the list of in-progress [build outputs](./o
|
||||
- Outputs which are "in progress" can be completed or cancelled
|
||||
- Completed outputs (which are simply *stock items*) can be viewed in the stock table at the bottom of the screen
|
||||
|
||||
### Completed Outputs
|
||||
|
||||
This panel displays all the completed build outputs (stock items) which have been created by this build order:
|
||||
|
||||
### Allocated Stock
|
||||
|
||||
The *Allocated Stock* tab displays all stock items which have been *allocated* to this build order. These stock items are reserved for this build, and will be consumed when the build is completed:
|
||||
|
||||
{% with id="allocated_stock_table", url="build/allocated_stock_table.png", description="Allocated Stock Table" %}
|
||||
{% include "img.html" %}
|
||||
{% endwith %}
|
||||
|
||||
### Consumed Stock
|
||||
|
||||
The *Consumed Stock* tab displays all stock items which have been *consumed* by this build order. These stock items remain in the database after the build order has been completed, but are no longer available for use.
|
||||
|
||||
- [Tracked stock items](./allocate.md#tracked-stock) are consumed by specific build outputs
|
||||
- [Untracked stock items](./allocate.md#untracked-stock) are consumed by the build order
|
||||
|
||||
### Child Builds
|
||||
|
||||
If there exist any build orders which are *children* of the selected build order, they are displayed in the *Child Builds* tab:
|
||||
|
||||
{% with id="build_childs", url="build/build_childs.png", description="Child builds panel" %}
|
||||
{% include "img.html" %}
|
||||
{% endwith %}
|
||||
|
||||
### Test Results
|
||||
|
||||
For *trackable* parts, test results can be recorded against each build output. These results are displayed in the *Test Results* panel:
|
||||
|
||||
{% with id="build_test_results", url="build/build_panel_test_results.png", description="Test Results panel" %}
|
||||
{% include "img.html" %}
|
||||
{% endwith %}
|
||||
|
||||
This table provides a summary of the test results for each build output, and allows test results to be quickly added for each build output.
|
||||
|
||||
### Test Statistics
|
||||
|
||||
For *trackable* parts, this panel displays a summary of the test results for all build outputs:
|
||||
|
||||
{% with id="build_test_stats", url="build/build_panel_test_statistics.png", description="Test Statistics panel" %}
|
||||
{% with id="build_childs", url="build/build_childs.png", description="Child builds tab" %}
|
||||
{% include "img.html" %}
|
||||
{% endwith %}
|
||||
|
||||
@ -221,10 +191,6 @@ To create a build order for your part, you have two options:
|
||||
|
||||
Fill-out the form as required, then click the "Submit" button to create the build.
|
||||
|
||||
### Create Child Builds
|
||||
|
||||
When creating a new build order, you have the option to automatically generate build orders for any subassembly parts. This can be useful to create a complete tree of build orders for a complex assembly. *However*, it must be noted that any build orders created for subassemblies will use the default BOM quantity for that part. Any child build orders created in this manner must be manually reviewed, to ensure that the correct quantity is being built as per your production requirements.
|
||||
|
||||
## Complete Build Order
|
||||
|
||||
To complete a build, click on <span class='fas fa-tools'></span> icon on the build detail page, the `Complete Build` form will be displayed.
|
||||
@ -268,17 +234,3 @@ Build orders may (optionally) have a target complete date specified. If this dat
|
||||
|
||||
- Builds can be filtered by overdue status in the build list
|
||||
- Overdue builds will be displayed on the home page
|
||||
|
||||
## Build Order Settings
|
||||
|
||||
The following [global settings](../settings/global.md) are available for adjusting the behavior of build orders:
|
||||
|
||||
| Name | Description | Default | Units |
|
||||
| ---- | ----------- | ------- | ----- |
|
||||
{{ globalsetting("BUILDORDER_REFERENCE_PATTERN") }}
|
||||
{{ globalsetting("BUILDORDER_REQUIRE_RESPONSIBLE") }}
|
||||
{{ globalsetting("BUILDORDER_REQUIRE_ACTIVE_PART") }}
|
||||
{{ globalsetting("BUILDORDER_REQUIRE_LOCKED_PART") }}
|
||||
{{ globalsetting("BUILDORDER_REQUIRE_VALID_BOM") }}
|
||||
{{ globalsetting("BUILDORDER_REQUIRE_CLOSED_CHILDS") }}
|
||||
{{ globalsetting("PREVENT_BUILD_COMPLETION_HAVING_INCOMPLETED_TESTS") }}
|
||||
|
@ -1,15 +0,0 @@
|
||||
---
|
||||
title: Custom States
|
||||
---
|
||||
|
||||
## Custom States
|
||||
|
||||
Several models within InvenTree support the use of custom states. The custom states are display only - the business logic is not affected by the state.
|
||||
|
||||
States can be added in the Admin Center under the "Custom States" section. Each state has a name, label and a color that are used to display the state in the user interface. Changes to these settings will only be reflected in the user interface after a full reload of the interface.
|
||||
|
||||
States need to be assigned to a model, state (for example status on a StockItem) and a logical key - that will be used for business logic. These 3 values combined need to be unique throughout the system.
|
||||
|
||||
Custom states can be used in the following models:
|
||||
- StockItem
|
||||
- Orders (PurchaseOrder, SalesOrder, ReturnOrder, ReturnOrderLine)
|
@ -4,22 +4,4 @@ title: InvenTree Demo
|
||||
|
||||
## InvenTree Demo
|
||||
|
||||
If you are interested in trying out InvenTree, you can access the InvenTree demo instance at [https://demo.inventree.org](https://demo.inventree.org).
|
||||
|
||||
This page is populated with a sample dataset, which is reset every 24 hours.
|
||||
|
||||
You can read more about the InvenTree demo here: [https://inventree.org/demo.html](https://inventree.org/demo.html)
|
||||
|
||||
### User Accounts
|
||||
|
||||
The demo instance has a number of user accounts which you can use to explore the system:
|
||||
|
||||
| Username | Password | Staff Access | Enabled | Description |
|
||||
| -------- | -------- | ------------ | ------- | ----------- |
|
||||
| allaccess | nolimits | No | Yes | View / create / edit all pages and items |
|
||||
| reader | readonly | No | Yes | Can view all pages but cannot create, edit or delete database records |
|
||||
| engineer | partsonly | No | Yes | Can manage parts, view stock, but no access to purchase orders or sales orders |
|
||||
| steven | wizardstaff | Yes | Yes | Staff account, can access some admin sections |
|
||||
| ian | inactive | No | No | Inactive account, cannot log in |
|
||||
| susan | inactive | No | No | Inactive account, cannot log in |
|
||||
| admin | inventree | Yes | Yes | Superuser account, can access all parts of the system |
|
||||
This page has moved to [https://inventree.org/demo.html](https://inventree.org/demo.html)
|
||||
|
@ -22,9 +22,9 @@ To setup a development environment using [docker](../start/docker.md), run the f
|
||||
|
||||
```bash
|
||||
git clone https://github.com/inventree/InvenTree.git && cd InvenTree
|
||||
docker compose --project-directory . -f contrib/container/dev-docker-compose.yml run --rm inventree-dev-server invoke install
|
||||
docker compose --project-directory . -f contrib/container/dev-docker-compose.yml run --rm inventree-dev-server invoke setup-test --dev
|
||||
docker compose --project-directory . -f contrib/container/dev-docker-compose.yml up -d
|
||||
docker compose run inventree-dev-server invoke install
|
||||
docker compose run inventree-dev-server invoke setup-test --dev
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
### Bare Metal
|
||||
@ -54,23 +54,13 @@ invoke setup-dev
|
||||
|
||||
InvenTree roughly follow the [GitLab flow](https://docs.gitlab.com/ee/topics/gitlab_flow.html) branching style, to allow simple management of multiple tagged releases, short-lived branches, and development on the main branch.
|
||||
|
||||
There are nominally 5 active branches:
|
||||
- `master` - The main development branch
|
||||
- `stable` - The latest stable release
|
||||
- `l10n` - Translation branch: Source to Crowdin
|
||||
- `l10_crowdin` - Translation branch: Source from Crowdin
|
||||
- `y.y.x` - Release branch for the currently supported version (e.g. `0.5.x`)
|
||||
|
||||
All other branches are removed periodically by maintainers or core team members. This includes old release branches.
|
||||
Do not use them as base for feature development or forks as patches from them might not be accepted without rebasing.
|
||||
|
||||
### Version Numbering
|
||||
|
||||
InvenTree version numbering follows the [semantic versioning](https://semver.org/) specification.
|
||||
|
||||
### Main Development Branch
|
||||
### Master Branch
|
||||
|
||||
The HEAD of the "master" branch of InvenTree represents the current "latest" state of code development.
|
||||
The HEAD of the "main" or "master" branch of InvenTree represents the current "latest" state of code development.
|
||||
|
||||
- All feature branches are merged into master
|
||||
- All bug fixes are merged into master
|
||||
@ -83,6 +73,7 @@ Feature branches should be branched *from* the *master* branch.
|
||||
|
||||
- One major feature per branch / pull request
|
||||
- Feature pull requests are merged back *into* the master branch
|
||||
- Features *may* also be merged into a release candidate branch
|
||||
|
||||
### Stable Branch
|
||||
|
||||
@ -91,28 +82,21 @@ The HEAD of the "stable" branch represents the latest stable release code.
|
||||
- Versioned releases are merged into the "stable" branch
|
||||
- Bug fix branches are made *from* the "stable" branch
|
||||
|
||||
#### Release Candidate Branches
|
||||
|
||||
### Bugfix Branches
|
||||
- Release candidate branches are made from master, and merged into stable.
|
||||
- RC branches are targeted at a major/minor version e.g. "0.5"
|
||||
- When a release candidate branch is merged into *stable*, the release is tagged
|
||||
|
||||
#### Bugfix Branches
|
||||
|
||||
- If a bug is discovered in a tagged release version of InvenTree, a "bugfix" or "hotfix" branch should be made *from* that tagged release
|
||||
- When approved, the branch is merged back *into* stable, with an incremented PATCH number (e.g. 0.4.1 -> 0.4.2)
|
||||
- The bugfix *must* also be cherry picked into the *master* branch.
|
||||
- A bugfix *might* also be backported from *master* to the *stable* branch automatically if marked with the `backport` label.
|
||||
|
||||
### Translation Branches
|
||||
|
||||
Crowdin is used for web-based translation management. The handling of files is fully automated, the `l10n` and `l10_crowdin` branches are used to manage the translation process and are not meant to be touched manually by anyone.
|
||||
|
||||
The translation process is as follows:
|
||||
1. Commits to `master` trigger CI by GitHub Actions
|
||||
2. Translation source files are created and automatically pushed to the `l10n` branch - this is the source branch for Crowdin
|
||||
3. Crowdin picks up on the new source files and makes them available for translation
|
||||
4. Translations made in Crowdin are automatically pushed back to the `l10_crowdin` branch by Crowdin once they are approved
|
||||
5. The `l10_crowdin` branch is merged back into `master` by a maintainer periodically
|
||||
|
||||
## API versioning
|
||||
|
||||
The [API version]({{ sourcefile("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
|
||||
|
||||
@ -125,7 +109,7 @@ The core software modules are targeting the following versions:
|
||||
| Python | {{ config.extra.min_python_version }} | Minimum required version |
|
||||
| Invoke | {{ config.extra.min_invoke_version }} | Minimum required version |
|
||||
| Django | {{ config.extra.django_version }} | Pinned version |
|
||||
| Node | 20 | Only needed for frontend development |
|
||||
| Node | 18 | Only needed for frontend development |
|
||||
|
||||
Any other software dependencies are handled by the project package config.
|
||||
|
||||
|
@ -18,13 +18,12 @@ You need to make sure that you have the following tools installed before continu
|
||||
|
||||
#### Docker Containers
|
||||
|
||||
The InvenTree devcontainer setup will install the following docker containers:
|
||||
The InvenTree devcontainer setup will install two docker containers:
|
||||
|
||||
| Container | Description |
|
||||
| --- | --- |
|
||||
| inventree | InvenTree host server |
|
||||
| db | InvenTree database (postgresql) |
|
||||
| redis | Redis server for caching |
|
||||
| inventree | InvenTree server |
|
||||
|
||||
#### Setup/Installation
|
||||
|
||||
@ -67,7 +66,7 @@ If you need to process your queue with background workers, run the `worker` task
|
||||
You can either only run InvenTree or use the integrated debugger for debugging. Goto the `Run and debug` side panel make sure `InvenTree Server` is selected. Click on the play button on the left.
|
||||
|
||||
!!! tip "Debug with 3rd party"
|
||||
Sometimes you need to debug also some 3rd party packages. Just select `InvenTree Server - 3rd party`
|
||||
Sometimes you need to debug also some 3rd party packages. Just select `InvenTree Servre - 3rd party`
|
||||
|
||||
You can now set breakpoints and vscode will automatically pause execution if that point is hit. You can see all variables available in that context and evaluate some code with the debugger console at the bottom. Use the play or step buttons to continue execution.
|
||||
|
||||
@ -120,9 +119,3 @@ If you are running a devcontainer in Windows, you may experience some performanc
|
||||
For a significant improvement in performance, the source code should be installed into the **WSL 2** filesystem (not on your "Windows" filesystem). This will greatly improve file access performance, and also make the devcontainer much more responsive to file system changes.
|
||||
|
||||
You can also refer to the [Improve disk performance guide](https://code.visualstudio.com/remote/advancedcontainers/improve-performance) for more information.
|
||||
|
||||
### Redis Caching
|
||||
|
||||
The devcontainer setup provides a [redis](https://redis.io/) container which can be used for managing global cache. By default this is disabled, but it can be easily enabled for testing or developing with the [redis cache](../start/config.md#caching) enabled.
|
||||
|
||||
To enable the cache, locate the InvenTree configuration file (`./dev/config.yaml`) and set the `cache.enabled` setting to `True`.
|
||||
|
@ -149,7 +149,7 @@ class SampleActionPlugin(ActionMixin, InvenTreePlugin):
|
||||
# metadata
|
||||
AUTHOR = "Sample Author"
|
||||
DESCRIPTION = "A very basic plugin with one mixin"
|
||||
PUBLISH_DATE = "2222-02-22"
|
||||
PUBLISH_DATE = "22.02.2222"
|
||||
VERSION = "1.2.3" # We recommend semver and increase the major version with each new major release of InvenTree
|
||||
WEBSITE = "https://example.com/"
|
||||
LICENSE = "MIT" # use what you want - OSI approved is ♥
|
||||
|
@ -6,9 +6,6 @@ title: Machines
|
||||
|
||||
InvenTree has a builtin machine registry. There are different machine types available where each type can have different drivers. Drivers and even custom machine types can be provided by plugins.
|
||||
|
||||
!!! info "Requires Redis"
|
||||
If the machines features is used in production setup using workers, a shared [redis cache](../../start/docker.md#redis-cache) is required to function properly.
|
||||
|
||||
### Registry
|
||||
|
||||
The machine registry is the main component which gets initialized on server start and manages all configured machines.
|
||||
@ -24,13 +21,6 @@ The machine registry initialization process can be divided into three stages:
|
||||
2. The driver.init_driver function is called for each used driver
|
||||
3. The machine.initialize function is called for each machine, which calls the driver.init_machine function for each machine, then the machine.initialized state is set to true
|
||||
|
||||
#### Production setup (with a worker)
|
||||
|
||||
If a worker is connected, there exist multiple instances of the machine registry (one in each worker thread and one in the main thread) due to the nature of how python handles state in different processes. Therefore the machine instances and drivers are instantiated multiple times (The `__init__` method is called multiple times). But the init functions and update hooks (e.g. `init_machine`) are only called once from the main process.
|
||||
|
||||
The registry, driver and machine state (e.g. machine status codes, errors, ...) is stored in the cache. Therefore a shared redis cache is needed. (The local in-memory cache which is used by default is not capable to cache across multiple processes)
|
||||
|
||||
|
||||
### Machine types
|
||||
|
||||
Each machine type can provide a different type of connection functionality between inventree and a physical machine. These machine types are already built into InvenTree.
|
||||
@ -47,8 +37,6 @@ If you want to create your own machine type, please also take a look at the alre
|
||||
|
||||
```py
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from generic.states import ColorEnum
|
||||
from plugin.machine import BaseDriver, BaseMachineType, MachineStatus
|
||||
|
||||
class ABCBaseDriver(BaseDriver):
|
||||
@ -74,9 +62,9 @@ class ABCMachine(BaseMachineType):
|
||||
base_driver = ABCBaseDriver
|
||||
|
||||
class ABCStatus(MachineStatus):
|
||||
CONNECTED = 100, _('Connected'), ColorEnum.success
|
||||
STANDBY = 101, _('Standby'), ColorEnum.success
|
||||
PRINTING = 110, _('Printing'), ColorEnum.primary
|
||||
CONNECTED = 100, _('Connected'), 'success'
|
||||
STANDBY = 101, _('Standby'), 'success'
|
||||
PRINTING = 110, _('Printing'), 'primary'
|
||||
|
||||
MACHINE_STATUS = ABCStatus
|
||||
default_machine_status = ABCStatus.DISCONNECTED
|
||||
@ -98,7 +86,6 @@ The machine type class gets instantiated for each machine on server startup and
|
||||
- update
|
||||
- restart
|
||||
- handle_error
|
||||
- clear_errors
|
||||
- get_setting
|
||||
- set_setting
|
||||
- check_setting
|
||||
|
@ -9,14 +9,14 @@ The InvenTree server code supports an extensible plugin architecture, allowing c
|
||||
Plugins can be added from multiple sources:
|
||||
|
||||
- Plugins can be installed in InvenTrees venv via PIP (python package manager)
|
||||
- Custom plugins should be placed in the directory `./data/plugins`.
|
||||
- Custom plugins should be placed in the directory `./src/backend/InvenTree/plugins`.
|
||||
- InvenTree built-in plugins are located in the directory `./src/backend/InvenTree/plugin/builtin`.
|
||||
|
||||
For further information, read more about [installing plugins](./plugins/install.md).
|
||||
|
||||
### Plugin Base Class
|
||||
|
||||
Custom plugins must inherit from the [InvenTreePlugin class]({{ sourcefile("src/backend/InvenTree/plugin/plugin.py") }}). Any plugins installed via the methods outlined above will be "discovered" when the InvenTree server launches.
|
||||
Custom plugins must inherit from the [InvenTreePlugin class](https://github.com/inventree/InvenTree/blob/2d1776a151721d65d0ae007049d358085b2fcfd5/InvenTree/plugin/plugin.py#L204). Any plugins installed via the methods outlined above will be "discovered" when the InvenTree server launches.
|
||||
|
||||
!!! warning "Namechange"
|
||||
The name of the base class was changed with `0.7.0` from `IntegrationPluginBase` to `InvenTreePlugin`. While the old name is still available till `0.8.0` we strongly suggest upgrading your plugins. Deprecation warnings are raised if the old name is used.
|
||||
@ -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]({{ sourcefile("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 [can be found here]({{ sourcefile("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
|
||||
|
||||
@ -72,7 +72,7 @@ MIN_VERSION = None # Lowest InvenTree version number that is supported by the p
|
||||
MAX_VERSION = None # Highest InvenTree version number that is supported by the plugin
|
||||
```
|
||||
|
||||
Refer to the [sample plugins]({{ sourcedir("src/backend/InvenTree/plugin/samples") }}) for further examples.
|
||||
Refer to the [sample plugins](https://github.com/inventree/InvenTree/tree/master/src/backend/InvenTree/plugin/samples) for further examples.
|
||||
|
||||
### Plugin Config
|
||||
|
||||
|
@ -15,14 +15,4 @@ POST {
|
||||
}
|
||||
```
|
||||
|
||||
### Sample Plugin
|
||||
|
||||
A sample action plugin is provided in the `InvenTree` source code, which can be used as a template for creating custom action plugins:
|
||||
|
||||
::: plugin.samples.integration.simpleactionplugin.SimpleActionPlugin
|
||||
options:
|
||||
show_bases: False
|
||||
show_root_heading: False
|
||||
show_root_toc_entry: False
|
||||
show_source: True
|
||||
members: []
|
||||
For an example of a very simple action plugin, refer to `/src/backend/InvenTree/plugin/samples/integratoni/simpleactionplugin.py`
|
||||
|
@ -5,15 +5,3 @@ title: Schedule Mixin
|
||||
## APICallMixin
|
||||
|
||||
The APICallMixin class provides basic functionality for integration with an external API.
|
||||
|
||||
### Sample Plugin
|
||||
|
||||
The following example demonstrates how to use the `APICallMixin` class to make a simple API call:
|
||||
|
||||
::: plugin.samples.integration.api_caller.SampleApiCallerPlugin
|
||||
options:
|
||||
show_bases: False
|
||||
show_root_heading: False
|
||||
show_root_toc_entry: False
|
||||
show_source: True
|
||||
members: []
|
||||
|
@ -2,11 +2,11 @@
|
||||
title: Barcode Mixin
|
||||
---
|
||||
|
||||
## Barcode Plugins
|
||||
### Barcode Plugins
|
||||
|
||||
InvenTree supports decoding of arbitrary barcode data and generation of internal barcode formats via a **Barcode Plugin** interface. Barcode data POSTed to the `/api/barcode/` endpoint will be supplied to all loaded barcode plugins, and the first plugin to successfully interpret the barcode data will return a response to the client.
|
||||
InvenTree supports decoding of arbitrary barcode data via a **Barcode Plugin** interface. Barcode data POSTed to the `/api/barcode/` endpoint will be supplied to all loaded barcode plugins, and the first plugin to successfully interpret the barcode data will return a response to the client.
|
||||
|
||||
InvenTree can generate native QR codes to represent database objects (e.g. a single StockItem). This barcode can then be used to perform quick lookup of a stock item or location in the database. A client application (for example the InvenTree mobile app) scans a barcode, and sends the barcode data to the InvenTree server. The server then uses the **InvenTreeBarcodePlugin** (found at `src/backend/InvenTree/plugin/builtin/barcodes/inventree_barcode.py`) to decode the supplied barcode data.
|
||||
InvenTree can generate native QR codes to represent database objects (e.g. a single StockItem). This barcode can then be used to perform quick lookup of a stock item or location in the database. A client application (for example the InvenTree mobile app) scans a barcode, and sends the barcode data to the InvenTree server. The server then uses the **InvenTreeBarcodePlugin** (found at `/src/backend/InvenTree/plugins/barcode/inventree.py`) to decode the supplied barcode data.
|
||||
|
||||
Any third-party barcodes can be decoded by writing a matching plugin to decode the barcode data. These plugins could then perform a server-side action or render a JSON response back to the client for further action.
|
||||
|
||||
@ -24,27 +24,15 @@ POST {
|
||||
}
|
||||
```
|
||||
|
||||
### Builtin Plugin
|
||||
|
||||
The InvenTree server includes a builtin barcode plugin which can generate and decode the QR codes. This plugin is enabled by default.
|
||||
|
||||
::: plugin.builtin.barcodes.inventree_barcode.InvenTreeInternalBarcodePlugin
|
||||
options:
|
||||
show_bases: False
|
||||
show_root_heading: False
|
||||
show_root_toc_entry: False
|
||||
show_source: True
|
||||
members: []
|
||||
|
||||
|
||||
### Example Plugin
|
||||
|
||||
Please find below a very simple example that is used to return a part if the barcode starts with `PART-`
|
||||
### Example
|
||||
Please find below a very simple example that is executed each time a barcode is scanned.
|
||||
|
||||
```python
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from InvenTree.models import InvenTreeBarcodeMixin
|
||||
from plugin import InvenTreePlugin
|
||||
from plugin.mixins import BarcodeMixin
|
||||
from part.models import Part
|
||||
|
||||
class InvenTreeBarcodePlugin(BarcodeMixin, InvenTreePlugin):
|
||||
|
||||
@ -54,39 +42,16 @@ class InvenTreeBarcodePlugin(BarcodeMixin, InvenTreePlugin):
|
||||
VERSION = "0.0.1"
|
||||
AUTHOR = "Michael"
|
||||
|
||||
def scan(self, barcode_data):
|
||||
if barcode_data.startswith("PART-"):
|
||||
try:
|
||||
pk = int(barcode_data.split("PART-")[1])
|
||||
instance = Part.objects.get(pk=pk)
|
||||
label = Part.barcode_model_type()
|
||||
status = 0
|
||||
|
||||
def scan(self, barcode_data):
|
||||
|
||||
self.status = self.status+1
|
||||
print('Started barcode plugin', self.status)
|
||||
print(barcode_data)
|
||||
response = {}
|
||||
return response
|
||||
|
||||
return {label: instance.format_matched_response()}
|
||||
except Part.DoesNotExist:
|
||||
pass
|
||||
```
|
||||
|
||||
To try it just copy the file to src/InvenTree/plugins and restart the server. Open the scan barcode window and start to scan codes or type in text manually. Each time the timeout is hit the plugin will execute and printout the result. The timeout can be changed in `Settings->Barcode Support->Barcode Input Delay`.
|
||||
|
||||
### Custom Internal Format
|
||||
|
||||
To implement a custom internal barcode format, the `generate(...)` method from the Barcode Mixin needs to be overridden. Then the plugin can be selected at `System Settings > Barcodes > Barcode Generation Plugin`.
|
||||
|
||||
```python
|
||||
from InvenTree.models import InvenTreeBarcodeMixin
|
||||
from plugin import InvenTreePlugin
|
||||
from plugin.mixins import BarcodeMixin
|
||||
|
||||
class InvenTreeBarcodePlugin(BarcodeMixin, InvenTreePlugin):
|
||||
NAME = "MyInternalBarcode"
|
||||
TITLE = "My Internal Barcodes"
|
||||
DESCRIPTION = "support for custom internal barcodes"
|
||||
VERSION = "0.0.1"
|
||||
AUTHOR = "InvenTree contributors"
|
||||
|
||||
def generate(self, model_instance: InvenTreeBarcodeMixin):
|
||||
return f'{model_instance.barcode_model_type()}: {model_instance.pk}'
|
||||
```
|
||||
|
||||
!!! info "Scanning implementation required"
|
||||
The parsing of the custom format needs to be implemented too, so that the scanning of the generated QR codes resolves to the correct part.
|
||||
|
@ -6,24 +6,7 @@ title: Currency Exchange Mixin
|
||||
|
||||
The `CurrencyExchangeMixin` class enabled plugins to provide custom backends for updating currency exchange rate information.
|
||||
|
||||
Any implementing classes must provide the `update_exchange_rates` method.
|
||||
|
||||
### Builtin Plugin
|
||||
|
||||
The default builtin plugin for handling currency exchange rates is the `InvenTreeCurrencyExchangePlugin` class.
|
||||
|
||||
::: plugin.builtin.integration.currency_exchange.InvenTreeCurrencyExchange
|
||||
options:
|
||||
show_bases: False
|
||||
show_root_heading: False
|
||||
show_root_toc_entry: False
|
||||
show_source: True
|
||||
members: []
|
||||
|
||||
|
||||
### Sample Plugin
|
||||
|
||||
A simple example is shown below (with fake data).
|
||||
Any implementing classes must provide the `update_exchange_rates` method. A simple example is shown below (with fake data).
|
||||
|
||||
```python
|
||||
|
||||
|
@ -15,34 +15,56 @@ When a certain (server-side) event occurs, the background worker passes the even
|
||||
{% include 'img.html' %}
|
||||
{% endwith %}
|
||||
|
||||
### Sample Plugin - All events
|
||||
### Example (all events)
|
||||
|
||||
Implementing classes must at least provide a `process_event` function:
|
||||
|
||||
::: plugin.samples.event.event_sample.EventPluginSample
|
||||
options:
|
||||
show_bases: False
|
||||
show_root_heading: False
|
||||
show_root_toc_entry: False
|
||||
show_source: True
|
||||
members: []
|
||||
```python
|
||||
class EventPlugin(EventMixin, InvenTreePlugin):
|
||||
"""
|
||||
A simple example plugin which responds to events on the InvenTree server.
|
||||
|
||||
### Sample Plugin - Specific Events
|
||||
This example simply prints out the event information.
|
||||
A more complex plugin could respond to specific events however it wanted.
|
||||
"""
|
||||
|
||||
NAME = "EventPlugin"
|
||||
SLUG = "event"
|
||||
TITLE = "Triggered Events"
|
||||
|
||||
def process_event(self, event, *args, **kwargs):
|
||||
print(f"Processing triggered event: '{event}'")
|
||||
```
|
||||
|
||||
### Example (specific events)
|
||||
|
||||
If you want to process just some specific events, you can also implement the `wants_process_event` function to decide if you want to process this event or not. This function will be executed synchronously, so be aware that it should contain simple logic.
|
||||
|
||||
Overall this function can reduce the workload on the background workers significantly since less events are queued to be processed.
|
||||
|
||||
::: plugin.samples.event.filtered_event_sample.FilteredEventPluginSample
|
||||
options:
|
||||
show_bases: False
|
||||
show_root_heading: False
|
||||
show_root_toc_entry: False
|
||||
show_source: True
|
||||
members: []
|
||||
```python
|
||||
class EventPlugin(EventMixin, InvenTreePlugin):
|
||||
"""
|
||||
A simple example plugin which responds to 'salesordershipment.completed' event on the InvenTree server.
|
||||
|
||||
This example simply prints out the event information.
|
||||
A more complex plugin can run enhanced logic on this event.
|
||||
"""
|
||||
|
||||
## Events
|
||||
NAME = "EventPlugin"
|
||||
SLUG = "event"
|
||||
TITLE = "Triggered Events"
|
||||
|
||||
def wants_process_event(self, event):
|
||||
"""Here you can decide if this event should be send to `process_event` or not."""
|
||||
return event == "salesordershipment.completed"
|
||||
|
||||
def process_event(self, event, *args, **kwargs):
|
||||
"""Here you can run you'r specific logic."""
|
||||
print(f"Sales order was completely shipped: '{args}' '{kwargs}'")
|
||||
```
|
||||
|
||||
### Events
|
||||
|
||||
Events are passed through using a string identifier, e.g. `build.completed`
|
||||
|
||||
|
@ -1,19 +0,0 @@
|
||||
---
|
||||
title: Icon Pack Mixin
|
||||
---
|
||||
|
||||
## IconPackMixin
|
||||
|
||||
The IconPackMixin class provides basic functionality for letting plugins expose custom icon packs that are available in the InvenTree UI. This is especially useful to provide a custom crafted icon pack with icons for different location types, e.g. different sizes and styles of drawers, bags, ESD bags, ... which are not available in the standard tabler icons library.
|
||||
|
||||
### Sample Plugin
|
||||
|
||||
The following example demonstrates how to use the `IconPackMixin` class to add a custom icon pack:
|
||||
|
||||
::: plugin.samples.icons.icon_sample.SampleIconPlugin
|
||||
options:
|
||||
show_bases: False
|
||||
show_root_heading: False
|
||||
show_root_toc_entry: False
|
||||
show_source: True
|
||||
members: []
|
@ -74,10 +74,10 @@ Admin users can install plugins directly from the web interface, via the "Plugin
|
||||
|
||||
#### Local Directory
|
||||
|
||||
Custom plugins can be placed in the `data/plugins/` directory, where they will be automatically discovered. This can be useful for developing and testing plugins, but can prove more difficult in production (e.g. when using Docker).
|
||||
Custom plugins can be placed in the `src/InvenTree/plugins/` directory, where they will be automatically discovered. This can be useful for developing and testing plugins, but can prove more difficult in production (e.g. when using Docker).
|
||||
|
||||
!!! info "Git Tracking"
|
||||
The `data/plugins/` directory is excluded from Git version tracking - any plugin files here will be hidden from Git
|
||||
The `src/backend/InvenTree/plugins/` directory is excluded from Git version tracking - any plugin files here will be hidden from Git
|
||||
|
||||
!!! warning "Not Recommended For Production"
|
||||
Loading plugins via the local *plugins* directory is not recommended for production. If you cannot use PIP installation (above), specify a custom plugin directory (below) or use a [VCS](https://pip.pypa.io/en/stable/topics/vcs-support/) as a plugin install source.
|
||||
|
@ -172,14 +172,6 @@ InvenTree supplies the `InvenTreeLabelPlugin` out of the box, which generates a
|
||||
|
||||
The default plugin also features a *DEBUG* mode which generates a raw HTML output, rather than PDF. This can be handy for tracking down any template rendering errors in your labels.
|
||||
|
||||
::: plugin.builtin.labels.inventree_label.InvenTreeLabelPlugin
|
||||
options:
|
||||
show_bases: False
|
||||
show_root_heading: False
|
||||
show_root_toc_entry: False
|
||||
show_source: True
|
||||
members: []
|
||||
|
||||
### Available Data
|
||||
|
||||
The *label* data are supplied to the plugin in both `PDF` and `PNG` formats. This provides compatibility with a great range of label printers "out of the box". Conversion to other formats, if required, is left as an exercise for the plugin developer.
|
||||
|
@ -28,16 +28,4 @@ If a locate plugin is installed and activated, the [InvenTree mobile app](../../
|
||||
|
||||
### Implementation
|
||||
|
||||
Refer to the [InvenTree source code]({{ sourcefile("src/backend/InvenTree/plugin/samples/locate/locate_sample.py") }}) for a simple implementation example.
|
||||
|
||||
### Sample Plugin
|
||||
|
||||
A simple example is provided in the InvenTree code base:
|
||||
|
||||
::: plugin.samples.locate.locate_sample.SampleLocatePlugin
|
||||
options:
|
||||
show_bases: False
|
||||
show_root_heading: False
|
||||
show_root_toc_entry: False
|
||||
show_source: True
|
||||
members: []
|
||||
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.
|
||||
|
@ -52,18 +52,6 @@ Or to add a template file that will be rendered as javascript code, from the plu
|
||||
|
||||
Note : see convention for template directory above.
|
||||
|
||||
## Sample Plugin
|
||||
|
||||
A sample plugin is provided in the InvenTree code base:
|
||||
|
||||
::: plugin.samples.integration.custom_panel_sample.CustomPanelSample
|
||||
options:
|
||||
show_bases: False
|
||||
show_root_heading: False
|
||||
show_root_toc_entry: False
|
||||
show_source: True
|
||||
members: []
|
||||
|
||||
## Example Implementations
|
||||
|
||||
Refer to the `CustomPanelSample` example class in the `./plugin/samples/integration/` directory, for a fully worked example of how custom UI panels can be implemented.
|
||||
|
@ -14,14 +14,48 @@ A plugin which implements the ReportMixin mixin can define the `add_report_conte
|
||||
|
||||
Additionally the `add_label_context` method, allowing custom context data to be added to a label template at time of printing.
|
||||
|
||||
### Sample Plugin
|
||||
### Example
|
||||
|
||||
A sample plugin which provides additional context data to the report templates is available:
|
||||
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):
|
||||
|
||||
::: plugin.samples.integration.report_plugin_sample.SampleReportPlugin
|
||||
options:
|
||||
show_bases: False
|
||||
show_root_heading: False
|
||||
show_root_toc_entry: False
|
||||
show_source: True
|
||||
members: []
|
||||
```python
|
||||
"""Sample plugin for extending reporting functionality"""
|
||||
|
||||
import random
|
||||
|
||||
from plugin import InvenTreePlugin
|
||||
from plugin.mixins import ReportMixin
|
||||
from report.models import PurchaseOrderReport
|
||||
|
||||
|
||||
class SampleReportPlugin(ReportMixin, InvenTreePlugin):
|
||||
"""Sample plugin which provides extra context data to a report"""
|
||||
|
||||
NAME = "Sample Report Plugin"
|
||||
SLUG = "reportexample"
|
||||
TITLE = "Sample Report Plugin"
|
||||
DESCRIPTION = "A sample plugin which provides extra context data to a report"
|
||||
VERSION = "1.0"
|
||||
|
||||
def some_custom_function(self):
|
||||
"""Some custom function which is not required for the plugin to function"""
|
||||
return random.randint(0, 100)
|
||||
|
||||
def add_report_context(self, report_instance, model_instance, request, context):
|
||||
|
||||
"""Add example content to the report instance"""
|
||||
|
||||
# We can add any extra context data we want to the report
|
||||
|
||||
# Generate a random string of data
|
||||
context['random_text'] = ''.join(random.choices('abcdefghijklmnopqrstuvwxyz', k=20))
|
||||
|
||||
# Call a custom method
|
||||
context['random_int'] = self.some_custom_function()
|
||||
|
||||
# We can also add extra data to the context which is specific to the report type
|
||||
context['is_purchase_order'] = isinstance(report_instance, PurchaseOrderReport)
|
||||
|
||||
# We can also use the 'request' object to add extra context data
|
||||
context['request_method'] = request.method
|
||||
```
|
||||
|
@ -18,14 +18,45 @@ The ScheduleMixin class provides a plugin with the ability to call functions at
|
||||
{% include 'img.html' %}
|
||||
{% endwith %}
|
||||
|
||||
### SamplePlugin
|
||||
### Example
|
||||
|
||||
An example of a plugin which supports scheduled tasks:
|
||||
|
||||
::: plugin.samples.integration.scheduled_task.ScheduledTaskPlugin
|
||||
options:
|
||||
show_bases: False
|
||||
show_root_heading: False
|
||||
show_root_toc_entry: False
|
||||
show_source: True
|
||||
members: []
|
||||
```python
|
||||
class ScheduledTaskPlugin(ScheduleMixin, SettingsMixin, InvenTreePlugin):
|
||||
"""
|
||||
Sample plugin which runs a scheduled task, and provides user configuration.
|
||||
"""
|
||||
|
||||
NAME = "Scheduled Tasks"
|
||||
SLUG = 'schedule'
|
||||
|
||||
SCHEDULED_TASKS = {
|
||||
'global': {
|
||||
'func': 'some_module.function',
|
||||
'schedule': 'H', # Run every hour
|
||||
},
|
||||
'member': {
|
||||
'func': 'foo',
|
||||
'schedule': 'I', # Minutes
|
||||
'minutes': 15,
|
||||
},
|
||||
}
|
||||
|
||||
SETTINGS = {
|
||||
'SECRET': {
|
||||
'name': 'A secret',
|
||||
'description': 'User configurable value',
|
||||
},
|
||||
}
|
||||
|
||||
def foo(self):
|
||||
"""
|
||||
This function runs every 15 minutes
|
||||
"""
|
||||
secret_value = self.get_setting('SECRET')
|
||||
print(f"foo - SECRET = {secret_value})
|
||||
```
|
||||
|
||||
!!! 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/0.15.x/src/backend/InvenTree/plugin/samples/integration/scheduled_task.py).
|
||||
|
@ -15,7 +15,7 @@ The dict must be formatted similar to the following sample that shows how to use
|
||||
|
||||
Take a look at the settings defined in `InvenTree.common.models.InvenTreeSetting` for all possible parameters.
|
||||
|
||||
### Example Plugin
|
||||
### Example
|
||||
|
||||
Below is a simple example of how a plugin can implement settings:
|
||||
|
||||
|
@ -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]({{ sourcefile("src/backend/InvenTree/templates/page_base.html") }}). Look through this file to determine overridable blocks. The [stock app]({{ sourcedir("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,40 +9,34 @@ 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]({{ sourcefile("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.
|
||||
|
||||
## Model Deletion
|
||||
|
||||
Any model which inherits the `PluginValidationMixin` class is exposed to the plugin system for custom deletion validation. Before the model is deleted from the database, it is first passed to the plugin ecosystem to check if it really should be deleted.
|
||||
|
||||
A custom plugin may implement the `validate_model_deletion` method to perform custom validation on the model instance before it is deleted.
|
||||
|
||||
::: plugin.base.integration.ValidationMixin.ValidationMixin.validate_model_deletion
|
||||
options:
|
||||
show_bases: False
|
||||
show_root_heading: False
|
||||
show_root_toc_entry: False
|
||||
show_sources: True
|
||||
summary: False
|
||||
members: []
|
||||
|
||||
## Model Validation
|
||||
|
||||
Any model which inherits the `PluginValidationMixin` mixin class is exposed to the plugin system for custom validation. Before the model is saved to the database (either when created, or updated), it is first passed to the plugin ecosystem for validation.
|
||||
|
||||
Any plugin which inherits the `ValidationMixin` can implement the `validate_model_instance` method, and run a custom validation routine.
|
||||
|
||||
::: plugin.base.integration.ValidationMixin.ValidationMixin.validate_model_instance
|
||||
options:
|
||||
show_bases: False
|
||||
show_root_heading: False
|
||||
show_root_toc_entry: False
|
||||
show_sources: True
|
||||
summary: False
|
||||
members: []
|
||||
The `validate_model_instance` method is passed the following arguments:
|
||||
|
||||
| Argument | Description |
|
||||
| --- | --- |
|
||||
| `instance` | The model instance to be validated |
|
||||
| `deltas` | A dict of field deltas (if the instance is being updated) |
|
||||
|
||||
```python
|
||||
def validate_model_instance(self, instance, deltas=None):
|
||||
"""Validate the supplied model instance.
|
||||
|
||||
Arguments:
|
||||
instance: The model instance to be validated
|
||||
deltas: A dict of field deltas (if the instance is being updated)
|
||||
"""
|
||||
...
|
||||
```
|
||||
|
||||
### Error Messages
|
||||
|
||||
@ -58,7 +52,7 @@ To indicate a *field* validation error (i.e. the validation error applies only t
|
||||
|
||||
Note that an error can be which corresponds to multiple model instance fields.
|
||||
|
||||
### Example Plugin
|
||||
### Example
|
||||
|
||||
Presented below is a simple working example for a plugin which implements the `validate_model_instance` method:
|
||||
|
||||
@ -108,70 +102,21 @@ By default, part names are not subject to any particular naming conventions or r
|
||||
|
||||
If the custom method determines that the part name is *objectionable*, it should throw a `ValidationError` which will be handled upstream by parent calling methods.
|
||||
|
||||
::: plugin.base.integration.ValidationMixin.ValidationMixin.validate_part_name
|
||||
options:
|
||||
show_bases: False
|
||||
show_root_heading: False
|
||||
show_root_toc_entry: False
|
||||
show_sources: True
|
||||
summary: False
|
||||
members: []
|
||||
|
||||
### Part IPN
|
||||
|
||||
Validation of the Part IPN (Internal Part Number) field is exposed to custom plugins via the `validate_part_ipn` method. Any plugins which extend the `ValidationMixin` class can implement this method, and raise a `ValidationError` if the IPN value does not match a required convention.
|
||||
|
||||
::: plugin.base.integration.ValidationMixin.ValidationMixin.validate_part_ipn
|
||||
options:
|
||||
show_bases: False
|
||||
show_root_heading: False
|
||||
show_root_toc_entry: False
|
||||
show_sources: True
|
||||
summary: False
|
||||
members: []
|
||||
Validation of the Part IPN (Internal Part Number) field is exposed to custom plugins via the `validate_part_IPN` method. Any plugins which extend the `ValidationMixin` class can implement this method, and raise a `ValidationError` if the IPN value does not match a required convention.
|
||||
|
||||
### Part Parameter Values
|
||||
|
||||
[Part parameters](../../part/parameter.md) can also have custom validation rules applied, by implementing the `validate_part_parameter` method. A plugin which implements this method should raise a `ValidationError` with an appropriate message if the part parameter value does not match a required convention.
|
||||
|
||||
::: plugin.base.integration.ValidationMixin.ValidationMixin.validate_part_parameter
|
||||
options:
|
||||
show_bases: False
|
||||
show_root_heading: False
|
||||
show_root_toc_entry: False
|
||||
show_sources: True
|
||||
summary: False
|
||||
members: []
|
||||
|
||||
### Batch Codes
|
||||
|
||||
[Batch codes](../../stock/tracking.md#batch-codes) can be generated and/or validated by custom plugins.
|
||||
|
||||
#### Validate Batch Code
|
||||
|
||||
The `validate_batch_code` method allows plugins to raise an error if a batch code input by the user does not meet a particular pattern.
|
||||
|
||||
::: plugin.base.integration.ValidationMixin.ValidationMixin.validate_batch_code
|
||||
options:
|
||||
show_bases: False
|
||||
show_root_heading: False
|
||||
show_root_toc_entry: False
|
||||
show_sources: True
|
||||
summary: False
|
||||
members: []
|
||||
|
||||
#### Generate Batch Code
|
||||
|
||||
The `generate_batch_code` method can be implemented to generate a new batch code, based on a set of provided information.
|
||||
|
||||
::: plugin.base.integration.ValidationMixin.ValidationMixin.generate_batch_code
|
||||
options:
|
||||
show_bases: False
|
||||
show_root_heading: False
|
||||
show_root_toc_entry: False
|
||||
show_sources: True
|
||||
summary: False
|
||||
members: []
|
||||
The `generate_batch_code` method can be implemented to generate a new batch code.
|
||||
|
||||
### Serial Numbers
|
||||
|
||||
@ -183,30 +128,17 @@ The default InvenTree [serial numbering system](../../stock/tracking.md#serial-n
|
||||
|
||||
Custom serial number validation can be implemented using the `validate_serial_number` method. A *proposed* serial number is passed to this method, which then has the opportunity to raise a `ValidationError` to indicate that the serial number is not valid.
|
||||
|
||||
::: plugin.base.integration.ValidationMixin.ValidationMixin.validate_serial_number
|
||||
options:
|
||||
show_bases: False
|
||||
show_root_heading: False
|
||||
show_root_toc_entry: False
|
||||
show_sources: True
|
||||
summary: False
|
||||
members: []
|
||||
|
||||
!!! info "Stock Item"
|
||||
If the `stock_item` argument is provided, then this stock item has already been assigned with the provided serial number. This stock item should be excluded from any subsequent checks for *uniqueness*. The `stock_item` parameter is optional, and may be `None` if the serial number is being validated in a context where no stock item is available.
|
||||
|
||||
##### Example
|
||||
|
||||
A plugin which requires all serial numbers to be valid hexadecimal values may implement this method as follows:
|
||||
|
||||
```python
|
||||
def validate_serial_number(self, serial: str, part: Part, stock_item: StockItem = None):
|
||||
def validate_serial_number(self, serial: str, part: Part):
|
||||
"""Validate the supplied serial number
|
||||
|
||||
Arguments:
|
||||
serial: The proposed serial number (string)
|
||||
part: The Part instance for which this serial number is being validated
|
||||
stock_item: The StockItem instance for which this serial number is being validated
|
||||
"""
|
||||
|
||||
try:
|
||||
@ -222,15 +154,6 @@ While InvenTree supports arbitrary text values in the serial number fields, behi
|
||||
|
||||
A custom plugin can implement the `convert_serial_to_int` method to determine how a particular serial number is converted to an integer representation.
|
||||
|
||||
::: plugin.base.integration.ValidationMixin.ValidationMixin.convert_serial_to_int
|
||||
options:
|
||||
show_bases: False
|
||||
show_root_heading: False
|
||||
show_root_toc_entry: False
|
||||
show_sources: True
|
||||
summary: False
|
||||
members: []
|
||||
|
||||
!!! info "Not Required"
|
||||
If this method is not implemented, or the serial number cannot be converted to an integer, then the sorting algorithm falls back to the text (string) value
|
||||
|
||||
@ -240,15 +163,6 @@ A core component of the InvenTree serial number system is the ability to *increm
|
||||
|
||||
For custom serial number schemes, it is important to provide a method to generate the *next* serial number given a current value. The `increment_serial_number` method can be implemented by a plugin to achieve this.
|
||||
|
||||
::: plugin.base.integration.ValidationMixin.ValidationMixin.increment_serial_number
|
||||
options:
|
||||
show_bases: False
|
||||
show_root_heading: False
|
||||
show_root_toc_entry: False
|
||||
show_sources: True
|
||||
summary: False
|
||||
members: []
|
||||
|
||||
!!! info "Invalid Increment"
|
||||
If the provided number cannot be incremented (or an error occurs) the method should return `None`
|
||||
|
||||
@ -268,15 +182,3 @@ def increment_serial_number(self, serial: str):
|
||||
|
||||
return val
|
||||
```
|
||||
|
||||
## Sample Plugin
|
||||
|
||||
A sample plugin which implements custom validation routines is provided in the InvenTree source code:
|
||||
|
||||
::: plugin.samples.integration.validation_sample.SampleValidatorPlugin
|
||||
options:
|
||||
show_bases: False
|
||||
show_root_heading: False
|
||||
show_root_toc_entry: False
|
||||
show_source: True
|
||||
members: []
|
||||
|
@ -14,7 +14,7 @@ Navigate to the "Settings" page and click on the "Display" tab, you should see t
|
||||
{% include 'img.html' %}
|
||||
{% endwith %}
|
||||
|
||||
The drop-down list let's you select any other color theme found in your static folder (see next section to find out how to [add color themes](#add-color-theme)). Once selected, click on the "Apply Theme" button for the new color theme to be activated.
|
||||
The drop-down list let's you select any other color theme found in your static folder (see next section to find out how to [add color themes](#add-color-themes)). Once selected, click on the "Apply Theme" button for the new color theme to be activated.
|
||||
|
||||
!!! info "Per-user Setting"
|
||||
Color themes are "user specific" which means that changing the color theme in your own settings won't affect other users.
|
||||
|
@ -57,7 +57,7 @@ def fetch_rtd_versions():
|
||||
versions = sorted(versions, key=lambda x: StrictVersion(x['version']), reverse=True)
|
||||
|
||||
# Add "latest" version first
|
||||
if not any(x['title'] == 'latest' for x in versions):
|
||||
if not any((x['title'] == 'latest' for x in versions)):
|
||||
versions.insert(
|
||||
0,
|
||||
{
|
||||
@ -70,7 +70,7 @@ def fetch_rtd_versions():
|
||||
# Ensure we have the 'latest' version
|
||||
current_version = os.environ.get('READTHEDOCS_VERSION', None)
|
||||
|
||||
if current_version and not any(x['title'] == current_version for x in versions):
|
||||
if current_version and not any((x['title'] == current_version for x in versions)):
|
||||
versions.append({
|
||||
'version': current_version,
|
||||
'title': current_version,
|
||||
@ -82,7 +82,7 @@ def fetch_rtd_versions():
|
||||
print('Discovered the following versions:')
|
||||
print(versions)
|
||||
|
||||
with open(output_filename, 'w', encoding='utf-8') as file:
|
||||
with open(output_filename, 'w') as file:
|
||||
json.dump(versions, file, indent=2)
|
||||
|
||||
|
||||
@ -100,7 +100,7 @@ def get_release_data():
|
||||
# Release information has been cached to file
|
||||
|
||||
print("Loading release information from 'releases.json'")
|
||||
with open(json_file, encoding='utf-8') as f:
|
||||
with open(json_file) as f:
|
||||
return json.loads(f.read())
|
||||
|
||||
# Download release information via the GitHub API
|
||||
@ -127,7 +127,7 @@ def get_release_data():
|
||||
page += 1
|
||||
|
||||
# Cache these results to file
|
||||
with open(json_file, 'w', encoding='utf-8') as f:
|
||||
with open(json_file, 'w') as f:
|
||||
print("Saving release information to 'releases.json'")
|
||||
f.write(json.dumps(releases))
|
||||
|
||||
@ -173,7 +173,7 @@ def on_config(config, *args, **kwargs):
|
||||
# Add *all* readthedocs related keys
|
||||
readthedocs = {}
|
||||
|
||||
for key in os.environ:
|
||||
for key in os.environ.keys():
|
||||
if key.startswith('READTHEDOCS_'):
|
||||
k = key.replace('READTHEDOCS_', '').lower()
|
||||
readthedocs[k] = os.environ[key]
|
||||
|
@ -20,25 +20,8 @@ Each Purchase Order has a specific status code which indicates the current state
|
||||
| --- | --- |
|
||||
| Pending | The purchase order has been created, but has not been submitted to the supplier |
|
||||
| In Progress | The purchase order has been issued to the supplier, and is in progress |
|
||||
| On Hold | The purchase order has been placed on hold, but is still active |
|
||||
| Complete | The purchase order has been completed, and is now closed |
|
||||
| Cancelled | The purchase order was cancelled, and is now closed |
|
||||
| Lost | The purchase order was lost, and is now closed |
|
||||
| Returned | The purchase order was returned, and is now closed |
|
||||
|
||||
**Source Code**
|
||||
|
||||
Refer to the source code for the Purchase Order status codes:
|
||||
|
||||
::: order.status_codes.PurchaseOrderStatus
|
||||
options:
|
||||
show_bases: False
|
||||
show_root_heading: False
|
||||
show_root_toc_entry: False
|
||||
show_source: True
|
||||
members: []
|
||||
|
||||
Purchase Order Status supports [custom states](../concepts/custom_states.md).
|
||||
|
||||
### Purchase Order Currency
|
||||
|
||||
@ -141,14 +124,3 @@ This view can be accessed externally as an ICS calendar using a URL like the fol
|
||||
`http://inventree.example.org/api/order/calendar/purchase-order/calendar.ics`
|
||||
|
||||
by default, completed orders are not exported. These can be included by appending `?include_completed=True` to the URL.
|
||||
|
||||
## Purchase Order Settings
|
||||
|
||||
The following [global settings](../settings/global.md) are available for purchase orders:
|
||||
|
||||
| Name | Description | Default | Units |
|
||||
| ---- | ----------- | ------- | ----- |
|
||||
{{ globalsetting("PURCHASEORDER_REFERENCE_PATTERN") }}
|
||||
{{ globalsetting("PURCHASEORDER_REQUIRE_RESPONSIBLE") }}
|
||||
{{ globalsetting("PURCHASEORDER_EDIT_COMPLETED_ORDERS") }}
|
||||
{{ globalsetting("PURCHASEORDER_AUTO_COMPLETE") }}
|
||||
|
@ -45,24 +45,9 @@ Each Return Order has a specific status code, as follows:
|
||||
| --- | --- |
|
||||
| Pending | The return order has been created, but not sent to the customer |
|
||||
| In Progress | The return order has been issued to the customer |
|
||||
| On Hold | The return order has been placed on hold, but is still active |
|
||||
| Complete | The return order was marked as complete, and is now closed |
|
||||
| Cancelled | The return order was cancelled, and is now closed |
|
||||
|
||||
**Source Code**
|
||||
|
||||
Refer to the source code for the Return Order status codes:
|
||||
|
||||
::: order.status_codes.ReturnOrderStatus
|
||||
options:
|
||||
show_bases: False
|
||||
show_root_heading: False
|
||||
show_root_toc_entry: False
|
||||
show_source: True
|
||||
members: []
|
||||
|
||||
Return Order Status supports [custom states](../concepts/custom_states.md).
|
||||
|
||||
## Create a Return Order
|
||||
|
||||
From the Return Order index, click on <span class='badge inventree add'><span class='fas fa-plus-circle'></span> New Return Order</span> which opens the "Create Return Order" form.
|
||||
@ -113,7 +98,7 @@ While [line items](#line-items) must reference a particular stock item, extra li
|
||||
|
||||
## Return Order Reports
|
||||
|
||||
Custom [reports](../report/templates.md) can be generated against each Return Order.
|
||||
Custom [reports](../report/return_order.md) can be generated against each Return Order.
|
||||
|
||||
### Calendar view
|
||||
|
||||
@ -123,14 +108,3 @@ This view can be accessed externally as an ICS calendar using a URL like the fol
|
||||
`http://inventree.example.org/api/order/calendar/return-order/calendar.ics`
|
||||
|
||||
by default, completed orders are not exported. These can be included by appending `?include_completed=True` to the URL.
|
||||
|
||||
## Return Order Settings
|
||||
|
||||
The following [global settings](../settings/global.md) are available for return orders:
|
||||
|
||||
| Name | Description | Default | Units |
|
||||
| ---- | ----------- | ------- | ----- |
|
||||
{{ globalsetting("RETURNORDER_ENABLED") }}
|
||||
{{ globalsetting("RETURNORDER_REFERENCE_PATTERN") }}
|
||||
{{ globalsetting("RETURNORDER_REQUIRE_RESPONSIBLE") }}
|
||||
{{ globalsetting("RETURNORDER_EDIT_COMPLETED_ORDERS") }}
|
||||
|
@ -20,26 +20,8 @@ Each Sales Order has a specific status code, which represents the state of the o
|
||||
| --- | --- |
|
||||
| Pending | The sales order has been created, but has not been finalized or submitted |
|
||||
| In Progress | The sales order has been issued, and is in progress |
|
||||
| On Hold | The sales order has been placed on hold, but is still active |
|
||||
| Shipped | The sales order has been shipped, but is not yet complete |
|
||||
| Complete | The sales order is fully completed, and is now closed |
|
||||
| Shipped | The sales order has been completed, and is now closed |
|
||||
| Cancelled | The sales order was cancelled, and is now closed |
|
||||
| Lost | The sales order was lost, and is now closed |
|
||||
| Returned | The sales order was returned, and is now closed |
|
||||
|
||||
**Source Code**
|
||||
|
||||
Refer to the source code for the Sales Order status codes:
|
||||
|
||||
::: order.status_codes.SalesOrderStatus
|
||||
options:
|
||||
show_bases: False
|
||||
show_root_heading: False
|
||||
show_root_toc_entry: False
|
||||
show_source: True
|
||||
members: []
|
||||
|
||||
Sales Order Status supports [custom states](../concepts/custom_states.md).
|
||||
|
||||
### Sales Order Currency
|
||||
|
||||
@ -101,7 +83,7 @@ To view all the completed shipment, click on the <span class="badge inventree na
|
||||
|
||||
### Complete Order
|
||||
|
||||
Once all items in the sales order have been shipped, click on <span class="badge inventree add"><span class='fas fa-check-circle'></span> Complete Order</span> to mark the sales order as shipped. Confirm then click on <span class="badge inventree confirm">Submit</span> to complete the order.
|
||||
Once all items in the sales order have been shipped, click on <span class="badge inventree add"><span class='fas fa-check-circle'></span> Complete Order</span> to mark the sales order as complete.
|
||||
|
||||
### Cancel Order
|
||||
|
||||
@ -185,15 +167,3 @@ All these fields can be edited by the user:
|
||||
{% with id="edit-shipment", url="order/edit_shipment.png", description="Edit shipment" %}
|
||||
{% include "img.html" %}
|
||||
{% endwith %}
|
||||
|
||||
## Sales Order Settings
|
||||
|
||||
The following [global settings](../settings/global.md) are available for sales orders:
|
||||
|
||||
| Name | Description | Default | Units |
|
||||
| ---- | ----------- | ------- | ----- |
|
||||
{{ globalsetting("SALESORDER_REFERENCE_PATTERN") }}
|
||||
{{ globalsetting("SALESORDER_REQUIRE_RESPONSIBLE") }}
|
||||
{{ globalsetting("SALESORDER_DEFAULT_SHIPMENT") }}
|
||||
{{ globalsetting("SALESORDER_EDIT_COMPLETED_ORDERS") }}
|
||||
{{ globalsetting("SALESORDER_SHIP_COMPLETE") }}
|
||||
|
@ -47,10 +47,6 @@ If a part is designated as an *Assembly* it can be created (or built) from other
|
||||
|
||||
If a part is designated as a *Component* it can be used as a sub-component of an *Assembly*. [Read further information about BOM management here](../build/bom.md)
|
||||
|
||||
### Testable
|
||||
|
||||
Testable parts can have test templates defined against the part, allowing test results to be recorded against any stock items for that part. For more information on testing, refer to the [testing documentation](./test.md).
|
||||
|
||||
### Trackable
|
||||
|
||||
Trackable parts can be assigned batch numbers or serial numbers which uniquely identify a particular stock item. Trackable parts also provide other features (and restrictions) in the InvenTree ecosystem.
|
||||
@ -77,15 +73,7 @@ A [Purchase Order](../order/purchase_order.md) allows parts to be ordered from a
|
||||
|
||||
If a part is designated as *Salable* it can be sold to external customers. Setting this flag allows parts to be added to sales orders.
|
||||
|
||||
## Locked Parts
|
||||
|
||||
Parts can be locked to prevent them from being modified. This is useful for parts which are in production and should not be changed. The following restrictions apply to parts which are locked:
|
||||
|
||||
- Locked parts cannot be deleted
|
||||
- BOM items cannot be created, edited, or deleted when they are part of a locked assembly
|
||||
- Part parameters linked to a locked part cannot be created, edited or deleted
|
||||
|
||||
## Active Parts
|
||||
### Active
|
||||
|
||||
By default, all parts are *Active*. Marking a part as inactive means it is not available for many actions, but the part remains in the database. If a part becomes obsolete, it is recommended that it is marked as inactive, rather than deleting it from the database.
|
||||
|
||||
|
@ -46,7 +46,7 @@ Additionally, the following information is stored for each part, in relation to
|
||||
|
||||
InvenTree supports pricing data in multiple currencies, allowing integration with suppliers and customers using different currency systems.
|
||||
|
||||
Supported currencies can be configured in the [InvenTree settings](../settings/currency.md).
|
||||
Supported currencies must be configured as part of [the InvenTree setup process](../start/config.md#supported-currencies).
|
||||
|
||||
!!! info "Currency Support"
|
||||
InvenTree provides multi-currency pricing support via the [django-money](https://django-money.readthedocs.io/en/latest/) library.
|
||||
|
@ -1,78 +0,0 @@
|
||||
---
|
||||
title: Part Revisions
|
||||
---
|
||||
|
||||
## Part Revisions
|
||||
|
||||
When creating a complex part (such as an assembly comprised of other parts), it is often necessary to track changes to the part over time. For example, throughout the lifetime of an assembly, it may be necessary to adjust the bill of materials, or update the design of the part.
|
||||
|
||||
Rather than overwrite the existing part data, InvenTree allows you to create a new *revision* of the part. This allows you to track changes to the part over time, and maintain a history of the part design.
|
||||
|
||||
Crucially, creating a new *revision* ensures that any related data entries which refer to the original part (such as stock items, build orders, purchase orders, etc) are not affected by the change.
|
||||
|
||||
### Revisions are Parts
|
||||
|
||||
A *revision* of a part is itself a part. This means that each revision of a part has its own part number, stock items, parameters, bill of materials, etc. The only thing that differentiates a *revision* from any other part is that the *revision* is linked to the original part.
|
||||
|
||||
### Revision Fields
|
||||
|
||||
Each part has two fields which are used to track the revision of the part:
|
||||
|
||||
* **Revision**: The revision number of the part. This is a user-defined field, and can be any string value.
|
||||
* **Revision Of**: A reference to the part of which *this* part is a revision. This field is used to keep track of the available revisions for any particular part.
|
||||
|
||||
### Revision Restrictions
|
||||
|
||||
When creating a new revision of a part, there are some restrictions which must be adhered to:
|
||||
|
||||
* **Circular References**: A part cannot be a revision of itself. This would create a circular reference which is not allowed.
|
||||
* **Unique Revisions**: A part cannot have two revisions with the same revision number. Each revision (of a given part) must have a unique revision code.
|
||||
* **Revisions of Revisions**: A single part can have multiple revisions, but a revision cannot have its own revision. This restriction is in place to prevent overly complex part relationships.
|
||||
* **Template Revisions**: A part which is a [template part](./template.md) cannot have revisions. This is because the template part is used to create variants, and allowing revisions of templates would create disallowed relationship states in the database. However, variant parts are allowed to have revisions.
|
||||
* **Template References**: A part which is a revision of a variant part must point to the same template as the original part. This is to ensure that the revision is correctly linked to the original part.
|
||||
|
||||
## Revision Settings
|
||||
|
||||
The following options are available to control the behavior of part revisions.
|
||||
|
||||
Note that these options can be changed in the InvenTree settings:
|
||||
|
||||
{% with id="part_revision_settings", url="part/part_revision_settings.png", description="Part revision settings" %}
|
||||
{% include 'img.html' %}
|
||||
{% endwith %}
|
||||
|
||||
* **Enable Revisions**: If this setting is enabled, parts can have revisions. If this setting is disabled, parts cannot have revisions.
|
||||
* **Assembly Revisions Only**: If this setting is enabled, only assembly parts can have revisions. This is useful if you only want to track revisions of assemblies, and not individual parts.
|
||||
|
||||
## Create a Revision
|
||||
|
||||
To create a new revision for a given part, navigate to the part detail page, and click on the "Revisions" tab.
|
||||
|
||||
Select the "Duplicate Part" action, to create a new copy of the selected part. This will open the "Duplicate Part" form:
|
||||
|
||||
{% with id="part_create_revision", url="part/part_create_revision.png", description="Create part revision" %}
|
||||
{% include 'img.html' %}
|
||||
{% endwith %}
|
||||
|
||||
In this form, make the following updates:
|
||||
|
||||
1. Set the *Revision Of* field to the original part (the one that you are duplicating)
|
||||
2. Set the *Revision* field to a unique revision number for the new part revision
|
||||
|
||||
Once these changes (and any other required changes) are made, press *Submit* to create the new part.
|
||||
|
||||
Once the form is submitted (without any errors), you will be redirected to the new part revision. Here you can see that it is linked to the original part:
|
||||
|
||||
{% with id="part_revision_b", url="part/part_revision_b.png", description="Revision B" %}
|
||||
{% include 'img.html' %}
|
||||
{% endwith %}
|
||||
|
||||
## Revision Navigation
|
||||
|
||||
When multiple revisions exist for a particular part, you can navigate between revisions using the *Select Part Revision* drop-down which renders at the top of the part page:
|
||||
|
||||
{% with id="part_revision_select", url="part/part_revision_select.png", description="Select part revision" %}
|
||||
{% include 'img.html' %}
|
||||
{% endwith %}
|
||||
|
||||
Note that this revision selector is only visible when multiple revisions exist for the part.
|
@ -5,7 +5,7 @@ title: Part Scheduling
|
||||
## Part Scheduling
|
||||
|
||||
|
||||
The *Scheduling* tab provides an overview of the *predicted* future available quantity of a particular part.
|
||||
The *Scheduling* tab provides an overview of the *predicted* future availabile quantity of a particular part.
|
||||
|
||||
The *Scheduling* tab displays a chart of estimated future part stock levels. It begins at the current date, with the current stock level. It then projects into the "future", taking information from:
|
||||
|
||||
|
@ -4,7 +4,7 @@ title: Part Test Templates
|
||||
|
||||
## Part Test Templates
|
||||
|
||||
Parts which are designated as [testable](./part.md#testable) can define templates for tests which are to be performed against individual stock items corresponding to the part.
|
||||
Parts which are designated as *trackable* (meaning they can be uniquely serialized) can define templates for tests which are to be performed against individual stock items corresponding to the part.
|
||||
|
||||
A test template defines the parameters of the test; the individual stock items can then have associated test results which correspond to a test template.
|
||||
|
||||
|
@ -28,6 +28,7 @@ Details provides information about the particular part. Parts details can be dis
|
||||
{% with id="part_overview", url="part/part_overview.png", description="Part details" %}
|
||||
{% include 'img.html' %}
|
||||
{% endwith %}
|
||||
<p></p>
|
||||
|
||||
A Part is defined in the system by the following parameters:
|
||||
|
||||
@ -37,7 +38,7 @@ A Part is defined in the system by the following parameters:
|
||||
|
||||
**Description** - Longer form text field describing the Part
|
||||
|
||||
**Revision** - An optional revision code denoting the particular version for the part. Used when there are multiple revisions of the same master part object. Read [more about part revisions here](./revision.md).
|
||||
**Revision** - An optional revision code denoting the particular version for the part. Used when there are multiple revisions of the same master part object.
|
||||
|
||||
**Keywords** - Optional few words to describe the part and make the part search more efficient.
|
||||
|
||||
@ -61,7 +62,7 @@ Parts can have multiple defined parameters.
|
||||
|
||||
If a part is a *Template Part* then the *Variants* tab will be visible.
|
||||
|
||||
[Read about Part templates and variants](./template.md)
|
||||
[Read about Part templates](./template.md)
|
||||
|
||||
### Stock
|
||||
|
||||
@ -131,9 +132,9 @@ The *Scheduling* tab provides an overview of the *predicted* future availability
|
||||
|
||||
The *Stocktake* tab provide historical stock level information, based on user-provided stocktake data. Refer to the [stocktake documentation](./stocktake.md) for further information.
|
||||
|
||||
### Test Templates
|
||||
### Tests
|
||||
|
||||
If a part is marked as *testable*, the user can define tests which must be performed on any stock items which are instances of this part. [Read more about testing](./test.md).
|
||||
If a part is marked as *trackable*, the user can define tests which must be performed on any stock items which are instances of this part. [Read more about testing](./test.md).
|
||||
|
||||
### Related Parts
|
||||
|
||||
|
@ -61,7 +61,7 @@ Also, dedicated settings sections were added for:
|
||||
|
||||
For Category section, read [Category Parameter Templates](#category-parameter-templates)
|
||||
|
||||
Other section allows to set the prefix of build, purchase and sales orders.
|
||||
Other section allows to set the prefix of build, puchase and sales orders.
|
||||
|
||||
### Category Parameter Templates
|
||||
|
||||
|
@ -24,7 +24,7 @@ Refer to the [report documentation](../report/report.md) for further information
|
||||
!!! warning "LaTeX Support"
|
||||
LaTeX report templates are no longer supported for a number of technical and ideological reasons
|
||||
|
||||
[#1292](https://github.com/inventree/InvenTree/pull/1292) adds support for build order / work order reports. Refer to the [report documentation](../report/templates.md) for further information.
|
||||
[#1292](https://github.com/inventree/InvenTree/pull/1292) adds support for build order / work order reports. Refer to the [build report documentation](../report/build.md) for further information.
|
||||
|
||||
### Inherited BOM Items
|
||||
|
||||
|
@ -32,7 +32,7 @@ Details on how to create and manage manufacturer parts were added
|
||||
|
||||
[#1462](https://github.com/inventree/InvenTree/pull/1417) adds the ability to
|
||||
create a QR code containing the URL of a StockItem, which can be opened directly
|
||||
on a portable device using the camera or a QR code scanner. More details [here](../report/labels.md).
|
||||
on a portable device using the camera or a QR code scanner. More details [here](../report/labels.md#url-style-qr-code).
|
||||
|
||||
## Major Bug Fixes
|
||||
|
||||
|
@ -29,5 +29,5 @@ title: Release 0.4.0
|
||||
| Pull Request | Description |
|
||||
| --- | --- |
|
||||
| [#1823](https://github.com/inventree/InvenTree/pull/1823) | Fixes link formatting issues for ManufacturerParts |
|
||||
| [#1824](https://github.com/inventree/InvenTree/pull/1824) | Selects correct currency code when creating a new PurchaseOrderLineItem |
|
||||
| [#1824](https://github.com/inventree/InvenTree/pull/1824) | Selects correct curreny code when creating a new PurchaseOrderLineItem |
|
||||
| [#1867](https://github.com/inventree/InvenTree/pull/1867) | Fixes long-running bug when deleting sequential items via the API |
|
||||
|
@ -53,7 +53,7 @@ This release also provides a marked improvement in unit testing and code coverag
|
||||
[#2372](https://github.com/inventree/InvenTree/pull/2372) provides an overhaul of notifications, allowing users to view their notifications directly in the InvenTree interface.
|
||||
|
||||
### Why are you hiding my name?
|
||||
[#2861](https://github.com/inventree/InvenTree/pull/2861) adds several changes to enable admins to remove more of InvenTrees branding. Change logo, hide the about-modal for all but superusers and add custom messages to login and main navbar. Check out [the docs](../start/config.md#customization-options)
|
||||
[#2861](https://github.com/inventree/InvenTree/pull/2861) adds several changes to enable admins to remove more of InvenTrees branding. Change logo, hide the about-modal for all but superusers and add custom messages to login and main navbar. Check out [the docs](../start/config.md#customisation-options).
|
||||
|
||||
### Label Printing Plugin
|
||||
|
||||
|
186
docs/docs/report/bom.md
Normal file
@ -0,0 +1,186 @@
|
||||
---
|
||||
title: BOM Generation
|
||||
---
|
||||
|
||||
## BOM Generation
|
||||
|
||||
The bill of materials is an essential part of the documentation that needs to be sent to the factory. A simple csv export is OK to be important into SMT machines. But for human readable documentation it might not be sufficient. Additional information is needed. The Inventree report system allows to generate BOM well formatted BOM reports.
|
||||
|
||||
### Context variables
|
||||
| Variable | Description |
|
||||
| --- | --- |
|
||||
| bom_items | Query set that contains all BOM items |
|
||||
| bom_items...sub_part | One component of the BOM |
|
||||
| bom_items...quantity | Number of parts |
|
||||
| bom_items...reference | Reference designators of the part |
|
||||
| bom_items...substitutes | Query set that contains substitutes of the part if any exist in the BOM |
|
||||
|
||||
### Examples
|
||||
|
||||
#### BOM
|
||||
|
||||
The following picture shows a simple example for a PCB with just three components from two different parts.
|
||||
|
||||
{% with id="report-options", url="report/bom_example.png", description="BOM example" %} {% include 'img.html' %} {% endwith %}
|
||||
|
||||
This example has been created using the following html template:
|
||||
|
||||
```html
|
||||
{% raw %}
|
||||
{% extends "report/inventree_report_base.html" %}
|
||||
|
||||
{% load i18n %}
|
||||
{% load report %}
|
||||
{% load inventree_extras %}
|
||||
|
||||
{% block page_margin %}
|
||||
margin-left: 2cm;
|
||||
margin-right: 1cm;
|
||||
margin-top: 4cm;
|
||||
{% endblock %}
|
||||
|
||||
{% block bottom_left %}
|
||||
content: "v{{report_revision}} - {% format_date date %}";
|
||||
{% endblock %}
|
||||
|
||||
{% block bottom_center %}
|
||||
content: "InvenTree v{% inventree_version %}";
|
||||
{% endblock %}
|
||||
|
||||
{% block style %}
|
||||
.header-left {
|
||||
text-align: left;
|
||||
float: left;
|
||||
}
|
||||
table {
|
||||
border: 1px solid #eee;
|
||||
border-radius: 3px;
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
font-size: 80%;
|
||||
}
|
||||
table td {
|
||||
border: 1px solid #eee;
|
||||
}
|
||||
{% endblock %}
|
||||
|
||||
{% block header_content %}
|
||||
<div class='header-left'>
|
||||
<h3>{% trans "Bill of Materials" %}</h3>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block page_content %}
|
||||
<table>
|
||||
<tr> <td>Board</td><td>{{ part.IPN }}</td> </tr>
|
||||
<tr> <td>Description</td><td>{{ part.description }}</td> </tr>
|
||||
<tr> <td>User</td><td>{{ user }}</td> </tr>
|
||||
<tr> <td>Date</td><td>{{ date }}</td> </tr>
|
||||
<tr> <td>Number of different components (codes)</td><td>{{ bom_items.count }}</td> </tr>
|
||||
</table>
|
||||
<br>
|
||||
<table class='table table-striped table-condensed'>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "IPN" %}</th>
|
||||
<th>{% trans "MPN" %}</th>
|
||||
<th>{% trans "Manufacturer" %}</th>
|
||||
<th>{% trans "Quantity" %}</th>
|
||||
<th>{% trans "Reference" %}</th>
|
||||
<th>{% trans "Substitute" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for line in bom_items.all %}
|
||||
<tr>
|
||||
<td>{{ line.sub_part.IPN }}</td>
|
||||
<td>{{ line.sub_part.name }}</td>
|
||||
<td>
|
||||
{% for manf in line.sub_part.manufacturer_parts.all %}
|
||||
{{ manf.manufacturer.name }}
|
||||
{% endfor %}
|
||||
</td>
|
||||
<td>{% decimal line.quantity %}</td>
|
||||
<td>{{ line.reference }}</td>
|
||||
<td>
|
||||
{% for sub in line.substitutes.all %}
|
||||
{{ sub.part.IPN }}<br>
|
||||
{% endfor %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
{% endblock %}
|
||||
{% endraw %}
|
||||
```
|
||||
|
||||
#### Pick List
|
||||
|
||||
When all material has been allocated someone has to pick all things from the warehouse.
|
||||
In case you need a printed pick list you can use the following template. This it just the
|
||||
table. All other info and CSS has been left out for simplicity. Please have a look at the
|
||||
BOM report for details.
|
||||
|
||||
{% raw %}
|
||||
```html
|
||||
<table class='changes-table'>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Original IPN</th>
|
||||
<th>Allocated Part</th>
|
||||
<th>Location</th>
|
||||
<th>PCS</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for line in build.allocated_stock.all %}
|
||||
<tr>
|
||||
<td> {{ line.bom_item.sub_part.IPN }} </td>
|
||||
{% if line.stock_item.part.IPN != line.bom_item.sub_part.IPN %}
|
||||
<td class='chg'> {{ line.stock_item.part.IPN }} </td>
|
||||
{% else %}
|
||||
<td> {{ line.stock_item.part.IPN }} </td>
|
||||
{% endif %}
|
||||
<td> {{ line.stock_item.location.pathstring }} </td>
|
||||
<td> {{ line.quantity }} </td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
Here we have a loop that runs through all allocated parts for the build. For each part
|
||||
we list the original IPN from the BOM and the IPN of the allocated part. These can differ
|
||||
in case you have substitutes or template/variants in the BOM. In case the parts differ
|
||||
we use a different format for the table cell e.g. print bold font or red color.
|
||||
For the picker we list the full path names of the stock locations and the quantity
|
||||
that is needed for the build. This will result in the following printout:
|
||||
|
||||
{% with id="picklist", url="report/picklist.png", description="Picklist Example" %} {% include "img.html" %} {% endwith %}
|
||||
|
||||
For those of you who would like to replace the "/" by something else because it is hard
|
||||
to read in some fonts use the following trick:
|
||||
|
||||
{% raw %}
|
||||
```html
|
||||
<td> {% for loc in line.stock_item.location.path %}{{ loc.name }}{% if not forloop.last %}-{% endif %}{% endfor %} </td>
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
Here we use location.path which is a query set that contains the location path up to the
|
||||
topmost parent. We use a loop to cycle through that and print the .name of the entry followed
|
||||
by a "-". The foorloop.last is a Django trick that allows us to not print the "-" after
|
||||
the last entry. The result looks like here:
|
||||
|
||||
{% with id="picklist_with_path", url="report/picklist_with_path.png", description="Picklist Example" %} {% include "img.html" %} {% endwith %}
|
||||
|
||||
Finally added a `{% raw %}|floatformat:0{% endraw %}` to the quantity that removes the trailing zeros.
|
||||
|
||||
### Default Report Template
|
||||
|
||||
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/0.15.x/src/backend/InvenTree/report/templates/report/inventree_bill_of_materials_report.html) for the default test report template.
|
324
docs/docs/report/build.md
Normal file
@ -0,0 +1,324 @@
|
||||
---
|
||||
title: Build Order Report
|
||||
---
|
||||
|
||||
## Build Order Report
|
||||
|
||||
Custom build order reports may be generated against any given [Build Order](../build/build.md). For example, build order reports can be used to generate work orders.
|
||||
|
||||
### Build Filters
|
||||
|
||||
A build order report template may define a set of filters against which [Build Order](../build/build.md) items are sorted.
|
||||
|
||||
### Context Variables
|
||||
|
||||
In addition to the default report context variables, the following context variables are made available to the build order report template for rendering:
|
||||
|
||||
| Variable | Description |
|
||||
| --- | --- |
|
||||
| build | The build object the report is being generated against |
|
||||
| part | The [Part](./context_variables.md#part) object that the build references |
|
||||
| line_items | A shortcut for [build.line_items](#build) |
|
||||
| bom_items | A shortcut for [build.bom_items](#build) |
|
||||
| build_outputs | A shortcut for [build.build_outputs](#build) |
|
||||
| reference | The build order reference string |
|
||||
| quantity | Build order quantity (number of assemblies being built) |
|
||||
|
||||
#### build
|
||||
|
||||
The following variables are accessed by build.variable
|
||||
|
||||
| Variable | Description |
|
||||
| --- | --- |
|
||||
| active | Boolean that tells if the build is active |
|
||||
| batch | Batch code transferred to build parts (optional) |
|
||||
| line_items | A query set with all the build line items associated with the build |
|
||||
| bom_items | A query set with all BOM items for the part being assembled |
|
||||
| build_outputs | A queryset containing all build output ([Stock Item](../stock/stock.md)) objects associated with this build |
|
||||
| can_complete | Boolean that tells if the build can be completed. Means: All material allocated and all parts have been build. |
|
||||
| are_untracked_parts_allocated | Boolean that tells if all bom_items have allocated stock_items. |
|
||||
| creation_date | Date where the build has been created |
|
||||
| completion_date | Date the build was completed (or, if incomplete, the expected date of completion) |
|
||||
| completed_by | The [User](./context_variables.md#user) that completed the build |
|
||||
| is_overdue | Boolean that tells if the build is overdue |
|
||||
| is_complete | Boolean that tells if the build is complete |
|
||||
| issued_by | The [User](./context_variables.md#user) who created the build |
|
||||
| link | External URL for extra information |
|
||||
| notes | Text notes |
|
||||
| parent | Reference to a parent build object if this is a sub build |
|
||||
| part | The [Part](./context_variables.md#part) to be built (from component BOM items) |
|
||||
| quantity | Build order quantity (total number of assembly outputs) |
|
||||
| completed | The number out outputs which have been completed |
|
||||
| reference | Build order reference (required, must be unique) |
|
||||
| required_parts | A query set with all parts that are required for the build |
|
||||
| responsible | Owner responsible for completing the build. This can be a user or a group. Depending on that further context variables differ |
|
||||
| sales_order | References to a [Sales Order](./context_variables.md#salesorder) object for which this build is required (e.g. the output of this build will be used to fulfil a sales order) |
|
||||
| status | The status of the build. 20 means 'Production' |
|
||||
| sub_build_count | Number of sub builds |
|
||||
| sub_builds | Query set with all sub builds |
|
||||
| target_date | Date the build will be overdue |
|
||||
| take_from | [StockLocation](./context_variables.md#stocklocation) to take stock from to make this build (if blank, can take from anywhere) |
|
||||
| title | The full name of the build |
|
||||
| description | The description of the build |
|
||||
| allocated_stock.all | A query set with all allocated stock items for the build |
|
||||
|
||||
As usual items in a query sets can be selected by adding a .n to the set e.g. build.required_parts.0
|
||||
will result in the first part of the list. Each query set has again its own context variables.
|
||||
|
||||
#### line_items
|
||||
|
||||
The `line_items` variable is a list of all build line items associated with the selected build. The following attributes are available for each individual line_item instance:
|
||||
|
||||
| Attribute | Description |
|
||||
| --- | --- |
|
||||
| .build | A reference back to the parent build order |
|
||||
| .bom_item | A reference to the BOMItem which defines this line item |
|
||||
| .quantity | The required quantity which is to be allocated against this line item |
|
||||
| .part | A shortcut for .bom_item.sub_part |
|
||||
| .allocations | A list of BuildItem objects which allocate stock items against this line item |
|
||||
| .allocated_quantity | The total stock quantity which has been allocated against this line |
|
||||
| .unallocated_quantity | The remaining quantity to allocate |
|
||||
| .is_fully_allocated | Boolean value, returns True if the line item has sufficient stock allocated against it |
|
||||
| .is_overallocated | Boolean value, returns True if the line item has more allocated stock than is required |
|
||||
|
||||
#### bom_items
|
||||
|
||||
| Attribute | Description |
|
||||
| --- | --- |
|
||||
| .reference | The reference designators of the components |
|
||||
| .quantity | The number of components required to build |
|
||||
| .overage | The extra amount required to assembly |
|
||||
| .consumable | Boolean field, True if this is a "consumable" part which is not tracked through builds |
|
||||
| .sub_part | The part at this position |
|
||||
| .substitutes.all | A query set with all allowed substitutes for that part |
|
||||
| .note | Extra text field which can contain additional information |
|
||||
|
||||
|
||||
#### allocated_stock.all
|
||||
|
||||
| Attribute | Description |
|
||||
| --- | --- |
|
||||
| .bom_item | The bom item where this part belongs to |
|
||||
| .stock_item | The allocated [StockItem](./context_variables.md#stockitem) |
|
||||
| .quantity | The number of components needed for the build (components in BOM x parts to build) |
|
||||
|
||||
### Example
|
||||
|
||||
The following example will create a report with header and BOM. In the BOM table substitutes will be listed.
|
||||
|
||||
{% raw %}
|
||||
```html
|
||||
{% extends "report/inventree_report_base.html" %}
|
||||
|
||||
{% load i18n %}
|
||||
{% load report %}
|
||||
{% load barcode %}
|
||||
{% load inventree_extras %}
|
||||
{% load markdownify %}
|
||||
|
||||
{% block page_margin %}
|
||||
margin: 2cm;
|
||||
margin-top: 4cm;
|
||||
{% endblock %}
|
||||
|
||||
{% block style %}
|
||||
|
||||
.header-right {
|
||||
text-align: right;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.logo {
|
||||
height: 20mm;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.details {
|
||||
width: 100%;
|
||||
border: 1px solid;
|
||||
border-radius: 3px;
|
||||
padding: 5px;
|
||||
min-height: 42mm;
|
||||
}
|
||||
|
||||
.details table {
|
||||
overflow-wrap: break-word;
|
||||
word-wrap: break-word;
|
||||
width: 65%;
|
||||
table-layout: fixed;
|
||||
font-size: 75%;
|
||||
}
|
||||
.changes table {
|
||||
overflow-wrap: break-word;
|
||||
word-wrap: break-word;
|
||||
width: 100%;
|
||||
table-layout: fixed;
|
||||
font-size: 75%;
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
.changes-table th {
|
||||
font-size: 100%;
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
.changes-table td {
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
.details table td:not(:last-child){
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.details table td:last-child{
|
||||
width: 50%;
|
||||
padding-left: 1cm;
|
||||
padding-right: 1cm;
|
||||
}
|
||||
|
||||
.details-table td {
|
||||
padding-left: 10px;
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
border-bottom: 1px solid #555;
|
||||
}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block bottom_left %}
|
||||
content: "v{{report_revision}} - {% format_date date %}";
|
||||
{% endblock %}
|
||||
|
||||
{% block header_content %}
|
||||
<!-- TODO - Make the company logo asset generic -->
|
||||
<img class='logo' src="{% asset 'company_logo.png' %}" alt="logo" width="150">
|
||||
|
||||
<div class='header-right'>
|
||||
<h3>
|
||||
Build Order {{ build }}
|
||||
</h3>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
{% endblock %}
|
||||
|
||||
{% block page_content %}
|
||||
|
||||
<div class='details'>
|
||||
|
||||
<table class='details-table'>
|
||||
<tr>
|
||||
<th>{% trans "Build Order" %}</th>
|
||||
<td>{% internal_link build.get_absolute_url build %}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{% trans "Order" %}</th>
|
||||
<td>{{ reference }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{% trans "Part" %}</th>
|
||||
<td>{% internal_link part.get_absolute_url part.IPN %}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{% trans "Quantity" %}</th>
|
||||
<td>{{ build.quantity }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{% trans "Description" %}</th>
|
||||
<td>{{ build.title }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{% trans "Issued" %}</th>
|
||||
<td>{% format_date build.creation_date %}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{% trans "Target Date" %}</th>
|
||||
<td>
|
||||
{% if build.target_date %}
|
||||
{% format_date build.target_date %}
|
||||
{% else %}
|
||||
<em>Not specified</em>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% if build.parent %}
|
||||
<tr>
|
||||
<th>{% trans "Required For" %}</th>
|
||||
<td>{% internal_link build.parent.get_absolute_url build.parent %}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if build.issued_by %}
|
||||
<tr>
|
||||
<th>{% trans "Issued By" %}</th>
|
||||
<td>{{ build.issued_by }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if build.responsible %}
|
||||
<tr>
|
||||
<th>{% trans "Responsible" %}</th>
|
||||
<td>{{ build.responsible }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
<tr>
|
||||
<th>{% trans "Sub builds count" %}</th>
|
||||
<td>{{ build.sub_build_count }}</td>
|
||||
</tr>
|
||||
{% if build.sub_build_count > 0 %}
|
||||
<tr>
|
||||
<th>{% trans "Sub Builds" %}</th>
|
||||
<td>{{ build.sub_builds }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
<tr>
|
||||
<th>{% trans "Overdue" %}</th>
|
||||
<td>{{ build.is_overdue }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{% trans "Can complete" %}</th>
|
||||
<td>{{ build.can_complete }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<h3>{% trans "Notes" %}</h3>
|
||||
{% if build.notes %}
|
||||
{{ build.notes|markdownify }}
|
||||
{% endif %}
|
||||
|
||||
<h3>{% trans "Parts" %}</h3>
|
||||
|
||||
<div class='changes'>
|
||||
<table class='changes-table'>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Original IPN</th>
|
||||
<th>Reference</th>
|
||||
<th>Replace width IPN</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for line in build.bom_items %}
|
||||
<tr>
|
||||
<td> {{ line.sub_part.IPN }} </td>
|
||||
<td> {{ line.reference }} </td>
|
||||
<td> {{ line.substitutes.all.0.part.IPN }} </td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% endblock %}
|
||||
```
|
||||
|
||||
{% endraw %}
|
||||
|
||||
This will result a report page like this:
|
||||
|
||||
{% with id="report-options", url="build/report-61.png", description="Report Example Builds" %} {% include "img.html" %} {% endwith %}
|
||||
|
||||
### Default Report Template
|
||||
|
||||
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/0.15.x/src/backend/InvenTree/report/templates/report/inventree_build_order_base.html) for the default build report template.
|
@ -2,244 +2,64 @@
|
||||
title: Context Variables
|
||||
---
|
||||
|
||||
|
||||
## Context Variables
|
||||
|
||||
Context variables are provided to each template when it is rendered. The available context variables depend on the model type for which the template is being rendered.
|
||||
### Report
|
||||
|
||||
### Global Context
|
||||
!!! info "Specific Report Context"
|
||||
Specific report types may have additional context variables, see below.
|
||||
|
||||
In addition to the model-specific context variables, the following global context variables are available to all templates:
|
||||
Each report has access to a number of context variables by default. The following context variables are provided to every report template:
|
||||
|
||||
| Variable | Description |
|
||||
| --- | --- |
|
||||
| base_url | The base URL for the InvenTree instance |
|
||||
| date | Current date, represented as a Python datetime.date object |
|
||||
| datetime | Current datetime, represented as a Python datetime object |
|
||||
| template | The report template instance which is being rendered against |
|
||||
| template_description | Description of the report template |
|
||||
| template_name | Name of the report template |
|
||||
| template_revision | Revision of the report template |
|
||||
| page_size | The specified page size for this report, e.g. `A4` or `Letter landscape` |
|
||||
| report_template | The report template model instance |
|
||||
| report_name | Name of the report template |
|
||||
| report_description | Description of the report template |
|
||||
| report_revision | Revision of the report template |
|
||||
| request | Django request object |
|
||||
| user | User who made the request to render the template |
|
||||
|
||||
::: report.models.ReportTemplateBase.base_context
|
||||
options:
|
||||
show_source: True
|
||||
#### Label
|
||||
|
||||
### Report Context
|
||||
Certain types of labels have different context variables then other labels.
|
||||
|
||||
In addition to the [global context](#global-context), all *report* templates have access to the following context variables:
|
||||
##### Stock Item Label
|
||||
|
||||
The following variables are made available to the StockItem label template:
|
||||
|
||||
| Variable | Description |
|
||||
| --- | --- |
|
||||
| page_size | The page size of the report |
|
||||
| landscape | Boolean value, True if the report is in landscape mode |
|
||||
|
||||
Note that custom plugins may also add additional context variables to the report context.
|
||||
|
||||
::: report.models.ReportTemplate.get_context
|
||||
options:
|
||||
show_source: True
|
||||
|
||||
### Label Context
|
||||
|
||||
In addition to the [global context](#global-context), all *label* templates have access to the following context variables:
|
||||
|
||||
| Variable | Description |
|
||||
| --- | --- |
|
||||
| width | The width of the label (in mm) |
|
||||
| height | The height of the label (in mm) |
|
||||
|
||||
Note that custom plugins may also add additional context variables to the label context.
|
||||
|
||||
::: report.models.LabelTemplate.get_context
|
||||
options:
|
||||
show_source: True
|
||||
|
||||
|
||||
## Template Types
|
||||
|
||||
Templates (whether for generating [reports](./report.md) or [labels](./labels.md)) are rendered against a particular "model" type. The following model types are supported, and can have templates renderer against them:
|
||||
|
||||
| Model Type | Description |
|
||||
| --- | --- |
|
||||
| [build](#build-order) | A [Build Order](../build/build.md) instance |
|
||||
| [buildline](#build-line) | A [Build Order Line Item](../build/build.md) instance |
|
||||
| [salesorder](#sales-order) | A [Sales Order](../order/sales_order.md) instance |
|
||||
| [returnorder](#return-order) | A [Return Order](../order/return_order.md) instance |
|
||||
| [purchaseorder](#purchase-order) | A [Purchase Order](../order/purchase_order.md) instance |
|
||||
| [stockitem](#stock-item) | A [StockItem](../stock/stock.md#stock-item) instance |
|
||||
| [stocklocation](#stock-location) | A [StockLocation](../stock/stock.md#stock-location) instance |
|
||||
| [part](#part) | A [Part](../part/part.md) instance |
|
||||
|
||||
### Build Order
|
||||
|
||||
When printing a report or label against a [Build Order](../build/build.md) object, the following context variables are available:
|
||||
|
||||
| Variable | Description |
|
||||
| --- | --- |
|
||||
| bom_items | Query set of all BuildItem objects associated with the BuildOrder |
|
||||
| build | The BuildOrder instance itself |
|
||||
| build_outputs | Query set of all BuildItem objects associated with the BuildOrder |
|
||||
| line_items | Query set of all build line items associated with the BuildOrder |
|
||||
| part | The Part object which is being assembled in the build order |
|
||||
| quantity | The total quantity of the part being assembled |
|
||||
| reference | The reference field of the BuildOrder |
|
||||
| title | The title field of the BuildOrder |
|
||||
|
||||
::: build.models.Build.report_context
|
||||
options:
|
||||
show_source: True
|
||||
|
||||
### Build Line
|
||||
|
||||
When printing a report or label against a [BuildOrderLineItem](../build/build.md) object, the following context variables are available:
|
||||
|
||||
| Variable | Description |
|
||||
| --- | --- |
|
||||
| allocated_quantity | The quantity of the part which has been allocated to this build |
|
||||
| allocations | A query set of all StockItem objects which have been allocated to this build line |
|
||||
| bom_item | The BomItem associated with this line item |
|
||||
| build | The BuildOrder instance associated with this line item |
|
||||
| build_line | The build line instance itself |
|
||||
| part | The sub-part (component) associated with the linked BomItem instance |
|
||||
| quantity | The quantity required for this line item |
|
||||
|
||||
::: build.models.BuildLine.report_context
|
||||
options:
|
||||
show_source: True
|
||||
|
||||
|
||||
### Sales Order
|
||||
|
||||
When printing a report or label against a [SalesOrder](../order/sales_order.md) object, the following context variables are available:
|
||||
|
||||
| Variable | Description |
|
||||
| --- | --- |
|
||||
| customer | The customer object associated with the SalesOrder |
|
||||
| description | The description field of the SalesOrder |
|
||||
| extra_lines | Query set of all extra lines associated with the SalesOrder |
|
||||
| lines | Query set of all line items associated with the SalesOrder |
|
||||
| order | The SalesOrder instance itself |
|
||||
| reference | The reference field of the SalesOrder |
|
||||
| title | The title (string representation) of the SalesOrder |
|
||||
|
||||
::: order.models.Order.report_context
|
||||
options:
|
||||
show_source: True
|
||||
|
||||
### Return Order
|
||||
|
||||
When printing a report or label against a [ReturnOrder](../order/return_order.md) object, the following context variables are available:
|
||||
|
||||
| Variable | Description |
|
||||
| --- | --- |
|
||||
| customer | The customer object associated with the ReturnOrder |
|
||||
| description | The description field of the ReturnOrder |
|
||||
| extra_lines | Query set of all extra lines associated with the ReturnOrder |
|
||||
| lines | Query set of all line items associated with the ReturnOrder |
|
||||
| order | The ReturnOrder instance itself |
|
||||
| reference | The reference field of the ReturnOrder |
|
||||
| title | The title (string representation) of the ReturnOrder |
|
||||
|
||||
### Purchase Order
|
||||
|
||||
When printing a report or label against a [PurchaseOrder](../order/purchase_order.md) object, the following context variables are available:
|
||||
|
||||
| Variable | Description |
|
||||
| --- | --- |
|
||||
| description | The description field of the PurchaseOrder |
|
||||
| extra_lines | Query set of all extra lines associated with the PurchaseOrder |
|
||||
| lines | Query set of all line items associated with the PurchaseOrder |
|
||||
| order | The PurchaseOrder instance itself |
|
||||
| reference | The reference field of the PurchaseOrder |
|
||||
| supplier | The supplier object associated with the PurchaseOrder |
|
||||
| title | The title (string representation) of the PurchaseOrder |
|
||||
|
||||
### Stock Item
|
||||
|
||||
When printing a report or label against a [StockItem](../stock/stock.md#stock-item) object, the following context variables are available:
|
||||
|
||||
| Variable | Description |
|
||||
| --- | --- |
|
||||
| barcode_data | Generated barcode data for the StockItem |
|
||||
| barcode_hash | Hash of the barcode data |
|
||||
| batch | The batch code for the StockItem |
|
||||
| child_items | Query set of all StockItem objects which are children of this StockItem |
|
||||
| ipn | The IPN (internal part number) of the associated Part |
|
||||
| installed_items | Query set of all StockItem objects which are installed in this StockItem |
|
||||
| item | The StockItem object itself |
|
||||
| name | The name of the associated Part |
|
||||
| part | The Part object which is associated with the StockItem |
|
||||
| qr_data | Generated QR code data for the StockItem |
|
||||
| qr_url | Generated URL for embedding in a QR code |
|
||||
| -------- | ----------- |
|
||||
| item | The [StockItem](./context_variables.md#stockitem) object itself |
|
||||
| part | The [Part](./context_variables.md#part) object which is referenced by the [StockItem](./context_variables.md#stockitem) object |
|
||||
| name | The `name` field of the associated Part object |
|
||||
| ipn | The `IPN` field of the associated Part object |
|
||||
| revision | The `revision` field of the associated Part object |
|
||||
| quantity | The `quantity` field of the StockItem object |
|
||||
| serial | The `serial` field of the StockItem object |
|
||||
| uid | The `uid` field of the StockItem object |
|
||||
| tests | Dict object of TestResult data associated with the StockItem |
|
||||
| parameters | Dict object containing the parameters associated with the base Part |
|
||||
| quantity | The quantity of the StockItem |
|
||||
| result_list | FLattened list of TestResult data associated with the stock item |
|
||||
| results | Dict object of TestResult data associated with the StockItem |
|
||||
| serial | The serial number of the StockItem |
|
||||
| stock_item | The StockItem object itself (shadow of 'item') |
|
||||
| tests | Dict object of TestResult data associated with the StockItem (shadow of 'results') |
|
||||
| test_keys | List of test keys associated with the StockItem |
|
||||
| test_template_list | List of test templates associated with the StockItem |
|
||||
| test_templates | Dict object of test templates associated with the StockItem |
|
||||
|
||||
::: stock.models.StockItem.report_context
|
||||
options:
|
||||
show_source: True
|
||||
|
||||
|
||||
### Stock Location
|
||||
##### Stock Location Label
|
||||
|
||||
When printing a report or label against a [StockLocation](../stock/stock.md#stock-location) object, the following context variables are available:
|
||||
The following variables are made available to the StockLocation label template:
|
||||
|
||||
| Variable | Description |
|
||||
| --- | --- |
|
||||
| location | The StockLocation object itself |
|
||||
| qr_data | Formatted QR code data for the StockLocation |
|
||||
| parent | The parent StockLocation object |
|
||||
| stock_location | The StockLocation object itself (shadow of 'location') |
|
||||
| stock_items | Query set of all StockItem objects which are located in the StockLocation |
|
||||
|
||||
::: stock.models.StockLocation.report_context
|
||||
options:
|
||||
show_source: True
|
||||
|
||||
|
||||
### Part
|
||||
|
||||
When printing a report or label against a [Part](../part/part.md) object, the following context variables are available:
|
||||
|
||||
| Variable | Description |
|
||||
| --- | --- |
|
||||
| bom_items | Query set of all BomItem objects associated with the Part |
|
||||
| category | The PartCategory object associated with the Part |
|
||||
| description | The description field of the Part |
|
||||
| IPN | The IPN (internal part number) of the Part |
|
||||
| name | The name of the Part |
|
||||
| parameters | Dict object containing the parameters associated with the Part |
|
||||
| part | The Part object itself |
|
||||
| qr_data | Formatted QR code data for the Part |
|
||||
| qr_url | Generated URL for embedding in a QR code |
|
||||
| revision | The revision of the Part |
|
||||
| test_template_list | List of test templates associated with the Part |
|
||||
| test_templates | Dict object of test templates associated with the Part |
|
||||
|
||||
::: part.models.Part.report_context
|
||||
options:
|
||||
show_source: True
|
||||
|
||||
## Model Variables
|
||||
|
||||
Additional to the context variables provided directly to each template, each model type has a number of attributes and methods which can be accessedd via the template.
|
||||
|
||||
For each model type, a subset of the most commonly used attributes are listed below. For a full list of attributes and methods, refer to the source code for the particular model type.
|
||||
| -------- | ----------- |
|
||||
| location | The [StockLocation](./context_variables.md#stocklocation) object itself |
|
||||
|
||||
### Parts
|
||||
|
||||
#### Part
|
||||
!!! incomplete "TODO"
|
||||
This section requires further work
|
||||
|
||||
Each part object has access to a lot of context variables about the part. The following context variables are provided when accessing a `Part` object from within the template.
|
||||
#### Part
|
||||
Each part object has access to a lot of context variables about the part. The following context variables are provided when accessing a `Part` object:
|
||||
|
||||
| Variable | Description |
|
||||
|----------|-------------|
|
||||
@ -286,7 +106,6 @@ Each part object has access to a lot of context variables about the part. The fo
|
||||
|
||||
#### Part Category
|
||||
|
||||
|
||||
| Variable | Description |
|
||||
|----------|-------------|
|
||||
| name | Name of this category |
|
||||
@ -298,7 +117,6 @@ Each part object has access to a lot of context variables about the part. The fo
|
||||
|
||||
#### StockItem
|
||||
|
||||
|
||||
| Variable | Description |
|
||||
|----------|-------------|
|
||||
| parent | Link to another [StockItem](./context_variables.md#stockitem) from which this StockItem was created |
|
||||
@ -321,7 +139,7 @@ Each part object has access to a lot of context variables about the part. The fo
|
||||
| notes | Extra notes field |
|
||||
| build | Link to a Build (if this stock item was created from a build) |
|
||||
| is_building | Boolean field indicating if this stock item is currently being built (or is "in production") |
|
||||
| purchase_order | Link to a [PurchaseOrder](./context_variables.md#purchase-order) (if this stock item was created from a PurchaseOrder) |
|
||||
| purchase_order | Link to a [PurchaseOrder](./context_variables.md#purchaseorder) (if this stock item was created from a PurchaseOrder) |
|
||||
| infinite | If True this [StockItem](./context_variables.md#stockitem) can never be exhausted |
|
||||
| sales_order | Link to a [SalesOrder](./context_variables.md#salesorder) object (if the StockItem has been assigned to a SalesOrder) |
|
||||
| purchase_price | The unit purchase price for this [StockItem](./context_variables.md#stockitem) - this is the unit price at time of purchase (if this item was purchased from an external supplier) |
|
||||
@ -346,7 +164,6 @@ Each part object has access to a lot of context variables about the part. The fo
|
||||
|
||||
#### Company
|
||||
|
||||
|
||||
| Variable | Description |
|
||||
|----------|-------------|
|
||||
| name | Name of the company |
|
||||
@ -367,7 +184,6 @@ Each part object has access to a lot of context variables about the part. The fo
|
||||
|
||||
#### Address
|
||||
|
||||
|
||||
| Variable | Description |
|
||||
|----------|-------------|
|
||||
| line1 | First line of the postal address |
|
||||
@ -378,6 +194,9 @@ Each part object has access to a lot of context variables about the part. The fo
|
||||
|
||||
#### Contact
|
||||
|
||||
Contacts are added to companies. Actually the company has no link to the contacts.
|
||||
You can search the company object of the contact.
|
||||
|
||||
| Variable | Description |
|
||||
|----------|-------------|
|
||||
| company | Company object where the contact belongs to |
|
||||
@ -388,7 +207,6 @@ Each part object has access to a lot of context variables about the part. The fo
|
||||
|
||||
#### SupplierPart
|
||||
|
||||
|
||||
| Variable | Description |
|
||||
|----------|-------------|
|
||||
| part | Link to the master Part (Obsolete) |
|
||||
@ -408,13 +226,24 @@ Each part object has access to a lot of context variables about the part. The fo
|
||||
| has_price_breaks | Whether this [SupplierPart](./context_variables.md#supplierpart) has price breaks |
|
||||
| manufacturer_string | Format a MPN string for this [SupplierPart](./context_variables.md#supplierpart). Concatenates manufacture name and part number. |
|
||||
|
||||
### Manufacturers
|
||||
|
||||
!!! incomplete "TODO"
|
||||
This section requires further work
|
||||
|
||||
#### Manufacturer
|
||||
|
||||
| Variable | Description |
|
||||
|----------|-------------|
|
||||
|
||||
#### ManufacturerPart
|
||||
|
||||
| Variable | Description |
|
||||
|----------|-------------|
|
||||
|
||||
### Orders
|
||||
|
||||
#### Purchase Order
|
||||
|
||||
!!! note "TODO"
|
||||
This section is incomplete
|
||||
The [Purchase Order](../order/purchase_order.md) context variables are described in the [Purchase Order](./purchase_order.md) section.
|
||||
|
||||
#### SalesOrder
|
||||
|
||||
|
@ -12,13 +12,13 @@ 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]({{ sourcefile("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
|
||||
|
||||
When making use of helper functions within a template, it can be useful to store the result of the function to a variable, rather than immediately rendering the output.
|
||||
|
||||
For example, using the [render_currency](#currency-formatting) helper function, we can store the output to a variable which can be used at a later point in the template:
|
||||
For example, using the [render_currency](#rendering-currency) helper function, we can store the output to a variable which can be used at a later point in the template:
|
||||
|
||||
```html
|
||||
{% raw %}
|
||||
@ -130,8 +130,8 @@ The following keyword arguments are available to the `render_currency` function:
|
||||
| --- | --- |
|
||||
| currency | Specify the currency code to render in (will attempt conversion if different to provided currency) |
|
||||
| decimal_places | Specify the number of decimal places to render |
|
||||
| min_decimal_places | Specify the minimum number of decimal places to render |
|
||||
| max_decimal_places | Specify the maximum number of decimal places to render |
|
||||
| min_decimal_places | Specify the minimum number of decimal places to render (ignored if *decimal_places* is specified) |
|
||||
| max_decimal_places | Specify the maximum number of decimal places to render (ignored if *decimal_places* is specified) |
|
||||
| include_symbol | Include currency symbol in rendered value (default = True) |
|
||||
|
||||
## Maths Operations
|
||||
@ -259,31 +259,6 @@ A shortcut function is provided for rendering an image associated with a Company
|
||||
|
||||
*Preview* and *thumbnail* image variations can be rendered for the `company_image` tag, in a similar manner to [part image variations](#image-variations)
|
||||
|
||||
## Icons
|
||||
|
||||
Some models (e.g. part categories and locations) allow to specify a custom icon. To render these icons in a report, there is a `{% raw %}{% icon location.icon %}{% endraw %}` template tag from the report template library available.
|
||||
|
||||
This tag renders the required html for the icon.
|
||||
|
||||
!!! info "Loading fonts"
|
||||
Additionally the icon fonts need to be loaded into the template. This can be done using the `{% raw %}{% include_icon_fonts %}{% endraw %}` template tag inside of a style block
|
||||
|
||||
!!! tip "Custom classes for styling the icon further"
|
||||
The icon template tag accepts an optional `class` argument which can be used to apply a custom class to the rendered icon used to style the icon further e.g. positioning it, changing it's size, ... `{% raw %}{% icon location.icon class="my-class" %}{% endraw %}`.
|
||||
|
||||
```html
|
||||
{% raw %}
|
||||
{% load report %}
|
||||
|
||||
{% block style %}
|
||||
{% include_icon_fonts %}
|
||||
{% endblock style %}
|
||||
|
||||
{% icon location.icon %}
|
||||
|
||||
{% endraw %}
|
||||
```
|
||||
|
||||
## InvenTree Logo
|
||||
|
||||
A template tag is provided to load the InvenTree logo image into a report. You can render the logo using the `{% raw %}{% logo_image %}{% endraw %}` tag:
|
||||
@ -297,7 +272,7 @@ A template tag is provided to load the InvenTree logo image into a report. You c
|
||||
|
||||
### Custom Logo
|
||||
|
||||
If the system administrator has enabled a [custom logo](../start/config.md#customization-options) then this logo will be used instead of the base InvenTree logo.
|
||||
If the system administrator has enabled a [custom logo](../start/config.md#customisation-options), then this logo will be used instead of the base InvenTree logo.
|
||||
|
||||
This is a useful way to get a custom company logo into your reports.
|
||||
|
||||
@ -312,7 +287,7 @@ If you have a custom logo, but explicitly wish to load the InvenTree logo itself
|
||||
|
||||
## Report Assets
|
||||
|
||||
[Report Assets](./templates.md#report-assets) are files specifically uploaded by the user for inclusion in generated reports and labels.
|
||||
[Report Assets](./report.md#report-assets) are files specifically uploaded by the user for inclusion in generated reports and labels.
|
||||
|
||||
You can add asset images to the reports and labels by using the `{% raw %}{% asset ... %}{% endraw %}` template tag:
|
||||
|
||||
|
@ -11,6 +11,17 @@ Custom labels can be generated using simple HTML templates, with support for QR-
|
||||
|
||||
Simple (generic) label templates are supplied 'out of the box' with InvenTree - however support is provided for generation of extremely specific custom labels, to meet any particular requirement.
|
||||
|
||||
## Label Types
|
||||
|
||||
The following types of labels are available
|
||||
|
||||
| Label Type | Description |
|
||||
| --- | --- |
|
||||
| [Part Labels](./labels/part_labels.md) | Print labels for individual parts |
|
||||
| [Stock Labels](./labels/stock_labels.md) | Print labels for individual stock items |
|
||||
| [Location Labels](./labels/location_labels.md) | Print labels for individual stock locations
|
||||
| [Build Labels](./labels/build_labels.md) | Print labels for individual build order line items |
|
||||
|
||||
## Label Templates
|
||||
|
||||
Label templates are written using a mixture of [HTML](https://www.w3schools.com/html/) and [CSS](https://www.w3schools.com/css). [Weasyprint](https://weasyprint.org/) templates support a *subset* of HTML and CSS features. In addition to supporting HTML and CSS formatting, the label templates support the Django templating engine, allowing conditional formatting of the label data.
|
||||
|
118
docs/docs/report/labels/build_labels.md
Normal file
@ -0,0 +1,118 @@
|
||||
---
|
||||
title: Build Labels
|
||||
---
|
||||
|
||||
## Build Line Labels
|
||||
|
||||
Build label templates are used to generate labels for individual build order line items.
|
||||
|
||||
### Creating Build Line Label Templates
|
||||
|
||||
Build label templates are added (and edited) via the [admin interface](../../settings/admin.md).
|
||||
|
||||
### Printing Build Line Labels
|
||||
|
||||
Build line labels are printed from the Build Order page, under the *Allocate Stock* tab. Multiple line items can be selected for printing:
|
||||
|
||||
{% with id='print_build_labels', url='report/label_build_print.png', description='Print build line labels' %}
|
||||
{% include 'img.html' %}
|
||||
{% endwith %}
|
||||
|
||||
### Context Data
|
||||
|
||||
The following context variables are made available to the Build Line label template:
|
||||
|
||||
| Variable | Description |
|
||||
| --- | --- |
|
||||
| build_line | The build_line instance |
|
||||
| build | The build order to which the build_line is linked |
|
||||
| bom_item | The bom_item to which the build_line is linked |
|
||||
| part | The required part for this build_line instance. References bom_item.sub_part |
|
||||
| quantity | The total quantity required for the build line |
|
||||
| allocated_quantity | The total quantity which has been allocated against the build line |
|
||||
| allocations | A queryset containing the allocations made against the build_line |
|
||||
|
||||
## Example
|
||||
|
||||
A simple example template is shown below:
|
||||
|
||||
```html
|
||||
{% raw %}
|
||||
{% extends "label/label_base.html" %}
|
||||
{% load barcode report %}
|
||||
{% load inventree_extras %}
|
||||
|
||||
{% block style %}
|
||||
|
||||
{{ block.super }}
|
||||
|
||||
.label {
|
||||
margin: 1mm;
|
||||
}
|
||||
|
||||
.qr {
|
||||
height: 28mm;
|
||||
width: 28mm;
|
||||
position: relative;
|
||||
top: 0mm;
|
||||
right: 0mm;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.label-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
border: 1pt solid black;
|
||||
}
|
||||
|
||||
.label-table tr {
|
||||
width: 100%;
|
||||
border-bottom: 1pt solid black;
|
||||
padding: 2.5mm;
|
||||
}
|
||||
|
||||
.label-table td {
|
||||
padding: 3mm;
|
||||
}
|
||||
|
||||
{% endblock style %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class='label'>
|
||||
<table class='label-table'>
|
||||
<tr>
|
||||
<td>
|
||||
<b>Build Order:</b> {{ build.reference }}<br>
|
||||
<b>Build Qty:</b> {% decimal build.quantity %}<br>
|
||||
</td>
|
||||
<td>
|
||||
<img class='qr' alt='build qr' src='{% qrcode build.barcode %}'>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<b>Part:</b> {{ part.name }}<br>
|
||||
{% if part.IPN %}
|
||||
<b>IPN:</b> {{ part.IPN }}<br>
|
||||
{% endif %}
|
||||
<b>Qty / Unit:</b> {% decimal bom_item.quantity %} {% if part.units %}[{{ part.units }}]{% endif %}<br>
|
||||
<b>Qty Total:</b> {% decimal quantity %} {% if part.units %}[{{ part.units }}]{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
<img class='qr' alt='part qr' src='{% qrcode part.barcode %}'>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{% endblock content %}
|
||||
|
||||
{% endraw %}
|
||||
```
|
||||
|
||||
Which results in a label like:
|
||||
|
||||
{% with id='build_label_example', url='report/label_build_example.png', description='Example build line labels' %}
|
||||
{% include 'img.html' %}
|
||||
{% endwith %}
|
24
docs/docs/report/labels/location_labels.md
Normal file
@ -0,0 +1,24 @@
|
||||
---
|
||||
title: Location Labels
|
||||
---
|
||||
|
||||
|
||||
## Stock Location Labels
|
||||
|
||||
Stock Location label templates are used to generate labels for individual Stock Locations.
|
||||
|
||||
### Creating Stock Location Label Templates
|
||||
|
||||
Stock Location label templates are added (and edited) via the admin interface.
|
||||
|
||||
### Printing Stock Location Labels
|
||||
|
||||
To print a single label from the Stock Location detail view, select the *Print Label* option.
|
||||
|
||||
### Context Data
|
||||
|
||||
The following variables are made available to the StockLocation label template:
|
||||
|
||||
| Variable | Description |
|
||||
| -------- | ----------- |
|
||||
| location | The [StockLocation](../context_variables.md#stocklocation) object itself |
|