Release/2.0.0 - #1
Merged
Merged
Conversation
Rebuild the plugin on the official plugin creator template (creator 1.20.0),
targeting InvenTree 1.0+ (developed against 1.5.2). The plugin slug and the
distribution name are unchanged, so stored settings survive and installing the
new distribution is an upgrade rather than a new package.
Fix three bugs that made the 1.x settings silently inert:
- The generate_batch_code hook read kwargs['stock_item'], but InvenTree passes
the stock item as 'item' (see stock/generators.py and the caller kwargs in
GenerateBatchCodeSerializer). Part and location were therefore always None,
so PER_PART, PER_LOCATION and USE_LOCATION_PREFIX never had any effect.
- get_setting()'s second positional parameter is 'cache', not a default value,
so every call of the form get_setting('KEY', default) passed the default as
the cache flag.
- MIN_DIGITS was only applied on the format-error fallback path, never to
normal output.
Replace the derived counter with a persistent one. models.BatchCounter holds
one row per scope, advanced atomically under select_for_update(), so the
sequence no longer depends on the code format being sortable as a string and
survives concurrent stock creation. SEED_FROM_EXISTING raises the counter past
numbers already present in existing batch codes, so upgrading from 1.x does not
reissue codes which are already in use. This requires AppMixin, so the plugin
is now a Django app: it needs a server restart to load, and a migration.
Other changes:
- DAILY_RESET now resets the counter itself, rather than filtering existing
codes for today's date, so it no longer requires {date} in CODE_FORMAT.
- TRIGGER_MODE=on_receive now means "a purchase order is part of the request",
which is what the hook context actually exposes.
- Remove TARGET_FIELD: the hook returns a string and InvenTree decides where it
goes, which is always StockItem.batch.
- Add preview/ and generate/ REST endpoints via UrlsMixin. The 1.x urls.py was
never mounted (no UrlsMixin, no setup_urls) and called a method that did not
exist, so nothing depended on it.
- Add a React panel for the stock item page and a live format preview on the
plugin settings page, with a complete Italian catalog.
- Manage the Python environment with uv; format and lint with ruff; run CI on
GitHub Actions.
- Version is now declared once, in batchcode_plugin/__init__.py.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Cover the parts of the plugin that decide what a batch code looks like: format rendering and padding, counter scoping, the generate_batch_code hook context, trigger modes, prefix resolution, role gating, the panel context and serializer construction. 76 tests, no InvenTree checkout required. tests/conftest.py configures Django minimally, stubs the InvenTree modules and loads the plugin modules by path, then subclasses BatchCodePlugin with a dict-backed get_setting. Only persistence is faked: build_key is delegated to the real BatchCounter, so the scope key under test is the production one. Fix a bug the suite found immediately: the serializers declared PrimaryKeyRelatedField(queryset=None) and filled the queryset in from Serializer.__init__, but DRF validates queryset inside the *field* constructor, which runs when the class body is evaluated. serializers.py therefore raised AssertionError on import, which would have taken down the plugin's whole URL set via setup_urls -> views -> serializers. Replaced with LazyModelField subclasses that override get_queryset(), deferring the model import and suppressing DRF's constructor check. Drop .github/workflows/pypi.yaml: the plugin is not published to PyPI, and the workflow referenced a PYPI_API_TOKEN secret that does not exist, so the first published release would have failed. README documents how to restore it. The install instructions now point at this repository rather than PyPI, and note that a git install omits the uncommitted frontend bundles. Pin the development interpreter with .python-version, and mark the Django and DRF dev dependencies for python_version >= 3.10: the distribution still declares requires-python >=3.9, matching what InvenTree itself claims, while Django 5.2 needs 3.10+. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
InvenTree's plugin installer (plugin/installer.py) only accepts VCS URLs,
composed as {packagename}@{url}; a plain https:// URL is handed to pip as a
package *index* (-i), not as a package to install, so a link to a release file
does not work from that form. A VCS install builds from source, which means a
plugin installed through Settings -> Plugins had no user interface at all,
because batchcode_plugin/static/ was gitignored.
Commit the bundles, and guard them against going stale: the CI frontend job
rebuilds both the bundles and the message catalogs and fails if the result
differs from what is committed. It stages before diffing, since bundle
filenames carry a content hash and a plain `git diff` would not see the new
files. Switch CI to `npm ci` - several dependencies are declared as "latest",
so only the lockfile makes the output reproducible enough to compare. Fold the
translation check into the same job and drop translations.yaml, which was
repeating the same npm install and build for one diff.
Add .gitattributes pinning line endings to LF. This is load-bearing rather
than cosmetic: a sourcemap embeds its sources verbatim in "sourcesContent",
line endings included, so a CRLF checkout of frontend/src builds different
.js.map files and would fail the artifact check on Windows with no real
change. Generated artifacts are marked -text so they stay byte-identical.
Document the install procedure properly, which the previous version got wrong
in two ways:
- Three global settings gate the mixins this plugin uses, and all three
default to False: ENABLE_PLUGINS_APP (AppMixin), ENABLE_PLUGINS_URL
(UrlsMixin) and ENABLE_PLUGINS_INTERFACE (UserInterfaceMixin). They live in
common/setting/system.py as database settings, not in config.yaml, so
searching the config template for them finds nothing. CLAUDE.md previously
claimed no such flag existed.
- Neither the installer nor the container entrypoint runs migrations, so
installation cannot be completed from the web interface alone: an admin must
run `invoke update` (or `invoke migrate`) once. The README now says so up
front and walks through the four steps in order.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.