OdooPLM is an open-source PLM/PDM extension for Odoo, developed and maintained by OmniaSolutions. It integrates Odoo with the most popular CAD editors and provides document management, BOM versioning, revision workflows, and a browser-based 3D/2D viewer.
This branch targets Odoo 19.0 and contains 36 modules, all built on the
core plm module.
📖 Wiki (install, CAD client, user guide, FAQ): https://github.com/OmniaGit/odooplm/wiki 🌐 Full documentation: https://odooplm.omniasolutions.website 🐛 Issues and support: https://github.com/OmniaGit/odooplm/issues 🚀 Live demo: https://v19.odooplm.cloud —
admin/admin, databaseodooplm
OdooPLM is published as a ready-to-run Docker image, on GitHub Container Registry and on Docker Hub. A single command gives you Odoo with the whole community PLM suite in the addons path, a PostgreSQL database and a working PLM server on the first boot — no database wizard, no dependency installation.
git clone --branch 19.0 https://github.com/OmniaGit/DockerOdooPLM.git odooplm-19
cd odooplm-19
docker compose upThen open http://localhost:8069.
| Variant | Size | Contains |
|---|---|---|
| full | ~4.4 GB | the CAD conversion stack, for batch STEP to 3MF, STL and PNG conversion |
| slim | ~2.5 GB | the same modules without the conversion stack |
Each variant also has a -demo tag that boots already populated — the sample
product of plm_demo over three BOM levels, its 3D models, ballooned assembly
drawings and the spare parts manual that prints from them. Log in with
admin / admin.
| Registry | Tags |
|---|---|
| GHCR | ghcr.io/omniagit/odooplm:19.0 · 19.0-slim · 19.0-demo · 19.0-slim-demo |
| Docker Hub | mboscolo/odooplm:19.0 · 19.0-slim · 19.0-demo · 19.0-slim-demo |
The images are rebuilt every week, against both the PLM sources and the official Odoo image, and every build is started and verified before it is published. Images, Compose stack and documentation: https://github.com/OmniaGit/DockerOdooPLM
The desktop CAD client (connector) is hosted on SourceForge:
https://sourceforge.net/projects/openerpplm/
It is a proprietary application distributed by OmniaSolutions; the server modules in this repository are open source.
The client supports the following CAD editors:
| CAD Editor | Notes |
|---|---|
| SolidWorks | Full integration (checkout, upload, BOM sync) |
| SolidEdge | Full integration |
| Autodesk Inventor | Full integration |
| AutoCAD / DraftSight | 2D drawings |
| ThinkDesign | Full integration |
| FreeCAD | Open-source integration |
The client communicates with Odoo via the REST API exposed by the plm module
(/plm_document_upload/login, /plm_document_upload/upload, etc.) and via
XML-RPC. Connection parameters:
| Live demo | Docker (local) | |
|---|---|---|
| Protocol | https |
http |
| Host | v19.odooplm.cloud |
localhost |
| Port | 443 |
8069 |
| Database | odooplm |
odooplm |
| User / password | admin / admin |
admin / admin |
Behind a TLS reverse proxy, point the client at 443 over
https, not at 80. Port 80 answers301to the HTTPS URL and the client's XML-RPC layer does not follow redirects, so the login fails.
| Module | Description |
|---|---|
plm |
Foundation module — versioned products, engineering documents, BOM lifecycle, checkout system, CAD client REST API |
plm_demo |
A populated PLM environment instead of an empty one: the LSU-100 sample product, 12 parts over three BOM levels, spare BOMs, 29 STEP/3MF/DXF/PDF documents with previews, ballooned assembly sheets, 3D markups, and the engineering workflow run over all of it — released revisions, a superseded part, one under modification, an open change order, a checked out sheet. Evaluation and training only |
| Module | Description |
|---|---|
plm_web_3d |
Browser-based 3D/2D viewer (Three.js). Supports 3MF, STEP, GLTF, STL, OBJ, DXF, SVG. Features: section plane with stencil cap, measurement tool (point/face snap), zoom window, part colour and transparency picker with persistence, markup system with chatter integration, model screenshot saved as attachment preview |
plm_web_3d_sale |
3D product previews on the eCommerce pages, from the engineering models already in the document management |
plm_automated_convertion |
Batch CAD format conversion (STEP→3MF, STEP→STL, STEP→PNG preview). Preserves assembly structure and component names |
plm_web_revision |
Trigger PLM revision workflows from the web interface |
plm_pack_and_go |
Download the full BOM file tree (all CAD documents of an assembly) as a ZIP |
| Module | Description |
|---|---|
plm_engineering |
Engineering BOMs — separate from manufacturing BOMs |
plm_spare |
Spare parts BOMs and spare parts manual generation |
plm_date_bom |
Date-effective BOMs — resolve the correct BOM for a given date |
plm_compare_bom |
Side-by-side BOM comparison between two revisions |
plm_bom_summarize |
Flatten/summarize a BOM uploaded from a CAD client |
plm_automate_normal_bom |
Automatically create/update standard manufacturing BOMs |
| Module | Description |
|---|---|
plm_automatic_weight |
Automatic weight calculation propagated through the BOM |
plm_breakages |
Breakage and consumable parts management |
plm_ent_breakages_helpdesk |
Breakages through the Odoo Helpdesk (Enterprise) |
plm_cutted_parts |
Cut parts and raw material management |
plm_auto_engcode |
Auto-generate engineering codes for new parts |
plm_auto_internalref |
Auto-generate internal references |
| Module | Description |
|---|---|
plm_mcp |
Model Context Protocol server: 14 tools that let an AI assistant ask the engineering database real questions — where a part is used, what changed between revisions, what is missing a drawing, what a change would affect. Bearer-token keys, calls running as the key's user |
plm_mcp_bot |
The same tools by typing /plm in a chat with OdooBot — no language model, no API key, no cost per question |
plm_mcp_ecr |
Two more MCP tools for engineering changes: what is open, and what is waiting on you (needs activity_validation) |
plm_mcp_odoo_ai |
Publishes the same tools to Odoo's own chat assistant, generated from the same registry (Enterprise) |
| Module | Description |
|---|---|
plm_pdf_workorder |
Attach PLM PDF documents to MRP work orders |
plm_pdf_workorder_enterprise |
Enterprise variant of the above |
plm_project |
Link Odoo Projects to PLM documents and components |
plm_consumption_plans |
Reference maintenance and consumption plans for products and BOM lines |
| Module | Description |
|---|---|
plm_purchase_share |
Share PLM documents with purchase orders |
plm_purchase_only_latest |
Restrict purchasing to latest-revision parts only |
plm_sale_only_latest |
Restrict sales to latest-revision parts only |
plm_product_only_latest |
Enforce latest-revision constraint on products |
| Module | Description |
|---|---|
plm_report_language_helper |
Multi-language report helpers |
plm_product_description_language_helper |
Product description per language |
plm_auto_translator |
Automatic translation of PLM descriptions |
| Module | Description |
|---|---|
plm_workflow_custom_action |
Custom server actions triggered by PLM state transitions |
plm_client_customprocedure |
Custom procedures executed by the CAD client |
plm_document_multi_site |
Multi-site document storage |
plm_suspended |
Mark components as suspended/obsolete |
plm_box |
Document management inside Odoo: nested folders, versions, check out and access rights, on standard Odoo attachments |
activity_validation |
Validation workflow using Odoo activities |
| Folder | Description |
|---|---|
mirror_document_server |
Standalone Flask service (flask, flask_httpauth) that mirrors PLM documents to a remote storage node. Used together with plm_document_multi_site |
documents |
Legacy design documents |
Every PLM object (product, document, BOM) inherits plm/models/plm_mixin.py.
It provides:
engineering_code+engineering_revision— unique pair, DB-enforcedengineering_state— lifecycle state machine:draft → confirmed → released ↔ undermodify → obsoleted- Write-protection in
confirmed,released,undermodify,obsoletedstates - Chatter (
mail.thread) and activity tracking
| Model | Role |
|---|---|
ir.attachment |
Engineering documents (drawings, CAD files, 3D models) |
product.template / product.product |
Parts with engineering fields |
mrp.bom |
BOMs with engineering state and where-used analysis |
plm.checkout |
Document checkout to prevent concurrent CAD editing |
plm.cad_open |
CAD editor session tracking |
ir.attachment.relation |
Document-to-document relationships (parent/child, 3D tree) |
The Docker images are the quickest way to a running server. To add OdooPLM to an Odoo instance you already run, follow this section.
The core plm module declares no external Python dependency — it installs on
a stock Odoo 19.0, and pulls in base, board, product, mrp and
stock_account. The extra packages belong to specific optional modules:
| Module | Python packages |
|---|---|
plm_automated_convertion |
ezdxf, matplotlib, cadquery, numpy-stl, to-3mf |
plm_pack_and_go |
base64io |
plm_mcp |
mcp-types |
plm_auto_translator |
googletrans, polib |
mirror_document_server |
flask, flask_httpauth |
aaa_requirements.txt collects the whole set, with the versions the conversion
stack needs pinned:
pip install -r aaa_requirements.txtThe whole suite is published as a single wheel, versioned after the plm
module:
pip install odooplm # the modules alone
pip install "odooplm[full]" # with every optional module's dependencyExtras follow the modules that declare them: cad (the conversion stack),
pack (plm_pack_and_go), translate (plm_auto_translator), full (all).
The addons land in odoo/addons, so they are on the addons path with no
further configuration.
cadqueryis installed from git inaaa_requirements.txt, because no PyPI release carries the OCP build the STEP reader needs. PyPI forbids a URL in a wheel's dependencies, sopip install "odooplm[cad]"takes the PyPI release instead. For server-side conversion, install fromaaa_requirements.txt.
plm_demois not in the PyPI package. It exists to be looked at, not to be installed on the production database a pip install is meant for, and it carries several MB of CAD payload. Get it from a git clone or from the Docker-demotags.
The 3D and DXF viewer libraries are git submodules, so clone recursively:
git clone --recurse-submodules -b 19.0 https://github.com/OmniaGit/odooplm.gitAdd the directory to addons_path in odoo.conf, restart Odoo and install from
the Apps menu, or from the command line:
# Core only
odoo -d <database> -i plm
# Core, web viewer and server-side conversion
odoo -d <database> -i plm,plm_web_3d,plm_automated_convertion
# A populated PLM to look at — evaluation and training only,
# and only from a git clone: the PyPI package leaves plm_demo out
odoo -d <database> -i plm_demo# Auto-reload XML (frontend development)
odoo --dev=xml
# Run all PLM tests
odoo --test-tags=odoo_plm
# Run specific module tests
odoo --test-tags=odoo_plm,odoo_plm_web_revision,plm_automatic_weightCommit message format: [TAG] | Description — tags: FIX, ADD, IMP, MOD.
Code quality: pre-commit run --all-files
The hooks are deliberately small: the checks that find real breakage without
rewriting a line — check-xml, check-yaml, merge and case conflicts, broken
symlinks, debug statements, docstring first — plus flake8 as a report only, and
a local hook that bumps the __manifest__.py patch version of every module with
staged changes. The formatters (black, isort, prettier) were dropped: they no
longer install on current Python, and bringing them back means reformatting the
repository in one go. See the comment at the top of .pre-commit-config.yaml.
See the Contributing wiki page before opening a pull request.
aaa_requirements.txt is generated — do not edit it. A module's python
packages are declared in the external_dependencies of its __manifest__.py,
their versions in scripts/requirements_pins.txt, and the file is written from
both:
python3 scripts/sync_requirements.py # regenerate
python3 scripts/sync_requirements.py --check # fail if it driftedThe pre-commit hook regenerates and stages it whenever a manifest changes, and
the same data feeds extras_require in setup.py, so the requirements file
and the wheel cannot disagree.
Tag the commit v19.0.<something> and .github/workflows/publish.yml builds
the sdist and wheel, verifies the requirements file matches the manifests, runs
twine check and publishes to PyPI through an OIDC trusted publisher. The
package version is the plm module's version, which a pre-commit hook bumps on
every commit so a tag is always publishable.
The suite is deliberately split in two.
The core module plm is LGPL-3: it can be integrated into other products,
including proprietary ones, without those products having to be published.
Every other module is AGPL-3: extending them, distributing the result or serving it over a network carries the obligation to publish the work under the same licence. The intent is simple — anyone is welcome to build on the core, and whoever builds a business on top of the extensions gives back what they add.
The licence of each module is declared in its __manifest__.py, which is the
authoritative source, and repeated in the header of its sources.
The desktop CAD client is a separate, proprietary product and is not covered by these licences.
LICENSING.md is the full reference: the module-by-module map,
what the split means for integrators, hosters and researchers, the licensing of
the aggregates (git, PyPI, Docker) and of the vendored third-party components.
The root LICENSE carries the AGPL-3.0 text, the strongest
obligation present in the aggregate; it does not relicense plm.
© OmniaSolutions — https://www.omniasolutions.website