GuideMarch 13, 2026

PLM in Odoo 19:
Engineering Change Orders & BoM Versioning

INTRODUCTION

Your Engineering Team Is Versioning BoMs in Spreadsheets. Production Is Building Last Month's Revision.

We audit dozens of Odoo manufacturing environments every year, and the pattern is always the same: engineering makes a material substitution, emails a PDF to the production manager, the production manager updates the BoM — sometimes. Three weeks later, a batch of 500 units ships with the old component because nobody archived the previous BoM revision. The root cause is never malice; it is the absence of a controlled change process.

Odoo 19's PLM module solves this by embedding Engineering Change Orders (ECOs) directly into the manufacturing workflow. An engineer proposes a change, it routes through an approval chain, and once approved the new BoM version activates automatically — no manual handoff, no spreadsheet versioning, no email chains. The old revision is archived with full traceability: who changed what, when, and why.

This guide walks you through the complete PLM setup in Odoo 19 — from installing the module and configuring ECO stages, to BoM versioning strategies, document management, and integration with manufacturing orders. Every configuration step is production-tested across discrete, process, and mixed-mode manufacturing clients.

01

How to Install and Configure the PLM Module in Odoo 19

The PLM module is an Enterprise-only add-on that extends Manufacturing with change control and versioning. It requires the Manufacturing app to be installed first.

Step 1: Install the PLM Module

Navigate to Apps, search for "PLM", and install the module. This adds the PLM menu under Manufacturing and introduces the ECO model (mrp.eco), ECO stages, and BoM versioning fields.

Shell — Install via CLI (alternative)
# Install PLM module from the command line
./odoo-bin -c /etc/odoo/odoo.conf \
  -d your_database \
  -i mrp_plm \
  --stop-after-init

# Verify installation
./odoo-bin shell -c /etc/odoo/odoo.conf -d your_database <<EOF
plm = env['ir.module.module'].search([
    ('name', '=', 'mrp_plm'),
    ('state', '=', 'installed')
])
print(f"PLM installed: {{bool(plm)}}")
EOF

Step 2: Configure ECO Types

ECO types categorize changes by their scope and approval requirements. Odoo 19 ships with a default "BoM Update" type, but real-world environments need more granularity:

ECO TypeUse CaseTypical ApproversAuto-Apply BoM
BoM ChangeMaterial substitution, quantity adjustmentEngineering Lead, Production ManagerYes
New Product IntroductionFirst BoM creation for a new SKUEngineering Lead, Quality ManagerYes
Quality Corrective ActionChange triggered by a quality alertQuality Manager, Engineering LeadAfter validation run
Cost OptimizationAlternative supplier or cheaper materialProcurement, Engineering Lead, FinanceYes
Python — Create ECO types programmatically
# Create custom ECO types via shell or migration script
EcoType = env['mrp.eco.type']

eco_types = [
    {
        'name': 'BoM Change',
        'sequence': 10,
    },
    {
        'name': 'New Product Introduction',
        'sequence': 20,
    },
    {
        'name': 'Quality Corrective Action',
        'sequence': 30,
    },
    {
        'name': 'Cost Optimization',
        'sequence': 40,
    },
]

for vals in eco_types:
    existing = EcoType.search([
        ('name', '=', vals['name'])
    ])
    if not existing:
        EcoType.create(vals)
        print(f"Created ECO type: {{vals['name']}}")
    else:
        print(f"ECO type exists: {{vals['name']}}")

Step 3: Define ECO Stages and Approval Gates

ECO stages define the workflow that every change request follows. Each stage can require one or more approvals before the ECO advances. Navigate to Manufacturing → Configuration → ECO Stages and configure:

Diagram — Recommended ECO stage pipeline
  [New]          [In Review]        [Validated]        [Applied]
    |                |                   |                  |
    v                v                   v                  v
 Engineer       Approval Gate:      Approval Gate:     BoM version
 drafts the     Engineering Lead    Production Mgr     auto-activates.
 change and     reviews technical   confirms shop      Old revision
 attaches       feasibility.        floor readiness.   is archived.
 documents.
                If rejected:        If rejected:
                back to [New]       back to [In Review]
                with comments.      with comments.
Don't Over-Engineer the Stage Pipeline

We've seen clients create 8-stage ECO pipelines with approval gates at every step. The result? Engineers route around the system entirely because getting a simple material substitution approved takes two weeks and five signatures. Start with 4 stages (New, In Review, Validated, Applied) and add complexity only when you have evidence that the simpler pipeline is letting bad changes through.

02

Engineering Change Orders in Odoo 19: The Complete Approval Workflow

An ECO is the atomic unit of change in PLM. Every modification to a Bill of Materials — whether adding a component, changing a quantity, swapping a material, or updating a routing operation — flows through an ECO. Here's how to create and manage them.

Creating an ECO

Navigate to Manufacturing → PLM → Engineering Change Orders and click New. Fill in the required fields:

  • Description — A clear summary of what changes and why (e.g., "Replace capacitor C12 with higher-rated alternative due to field failure rate").
  • Type — Select the ECO type configured in Step 2.
  • Apply on — Choose "Bill of Materials" to modify an existing BoM, or "Product Only" for non-BoM changes like updating product specifications.
  • Product — The finished product affected by this change.
  • Bill of Materials — The specific BoM revision to modify. Odoo clones this BoM into a draft "new revision" that you edit without affecting the live production BoM.
Python — Create an ECO via RPC (integration use case)
import xmlrpc.client

url = 'https://your-odoo-instance.com'
db = 'production'
uid = 2  # Admin or engineering user
password = 'api_key_here'

models = xmlrpc.client.ServerProxy(
    f'{{url}}/xmlrpc/2/object'
)

# Find the product and its active BoM
product_id = models.execute_kw(
    db, uid, password,
    'product.product', 'search',
    [[('default_code', '=', 'PCB-MAIN-V3')]]
)[0]

bom_id = models.execute_kw(
    db, uid, password,
    'mrp.bom', 'search',
    [[('product_tmpl_id.product_variant_ids', 'in',
       [product_id]),
      ('active', '=', True)]],
    {'limit': 1}
)[0]

# Find the ECO type
eco_type_id = models.execute_kw(
    db, uid, password,
    'mrp.eco.type', 'search',
    [[('name', '=', 'BoM Change')]],
    {'limit': 1}
)[0]

# Create the ECO
eco_id = models.execute_kw(
    db, uid, password,
    'mrp.eco', 'create',
    [{
        'name': 'Replace capacitor C12 with C12-HR',
        'type_id': eco_type_id,
        'product_tmpl_id': models.execute_kw(
            db, uid, password,
            'product.product', 'read',
            [product_id],
            {'fields': ['product_tmpl_id']}
        )[0]['product_tmpl_id'][0],
        'bom_id': bom_id,
        'effectivity': 'asap',
    }]
)
print(f"ECO created: ID {{eco_id}}")

The Approval Gate Mechanism

When an ECO reaches a stage with approval requirements, Odoo blocks progression until all designated approvers have signed off. Approvers are notified via activity (the chatter bell icon) and optionally by email. Each approval is timestamped and logged in the ECO's chatter.

Odoo 19 introduced a key improvement: conditional approvals. You can configure approval rules based on the ECO type or the impact level. For example, a "BoM Change" ECO that modifies fewer than 3 components might only need the Engineering Lead, while one that changes more than 3 requires both the Engineering Lead and Quality Manager.

Python — Configure stage approvals
# Add approvers to the "In Review" stage
Stage = env['mrp.eco.stage']
review_stage = Stage.search([
    ('name', '=', 'In Review')
], limit=1)

# Find users for approval roles
eng_lead = env['res.users'].search([
    ('login', '=', 'eng.lead@company.com')
], limit=1)

prod_mgr = env['res.users'].search([
    ('login', '=', 'prod.mgr@company.com')
], limit=1)

# Write approval configuration
review_stage.write({
    'approval_ids': [
        (0, 0, {
            'name': 'Engineering Review',
            'user_id': eng_lead.id,
            'approval_type': 'mandatory',
        }),
        (0, 0, {
            'name': 'Production Feasibility',
            'user_id': prod_mgr.id,
            'approval_type': 'mandatory',
        }),
    ]
})
Approval Delegation for Holidays

When an approver goes on leave, ECOs pile up and block the entire engineering pipeline. Configure approval delegation in the user's settings — a delegate can approve on behalf of the absent user. Without this, we've seen clients where a single person's two-week vacation delayed 15 ECOs and pushed a product launch by a month.

03

BoM Versioning in Odoo 19: How Revisions, Effectivity Dates, and Archives Work

BoM versioning is the core value proposition of PLM. Without it, you have one BoM per product and any change is destructive — the old version is gone. With PLM enabled, every ECO that modifies a BoM creates a new revision while preserving the previous one.

How Revisions Work Under the Hood

When you create an ECO and select a BoM, Odoo clones the current BoM into a draft revision linked to the ECO. You make your changes on this draft — the live BoM remains untouched. When the ECO reaches the "Applied" stage:

  • The draft revision becomes the new active BoM.
  • The previous BoM is archived (active = False) but not deleted.
  • The version number increments automatically (V1 → V2 → V3).
  • All future manufacturing orders use the new revision.
  • In-progress manufacturing orders continue with the BoM version they started with.
Python — Query BoM revision history for a product
# Retrieve all BoM revisions (active and archived)
product = env['product.template'].search([
    ('default_code', '=', 'PROD-ASSEMBLY-X1')
], limit=1)

# Include archived BoMs with context
all_boms = env['mrp.bom'].with_context(
    active_test=False
).search([
    ('product_tmpl_id', '=', product.id)
], order='version asc')

for bom in all_boms:
    status = "ACTIVE" if bom.active else "archived"
    eco_ref = bom.eco_ids[:1].name if bom.eco_ids else "N/A"
    print(
        f"V{{bom.version}} | "
        f"{{status}} | "
        f"Components: {{len(bom.bom_line_ids)}} | "
        f"ECO: {{eco_ref}} | "
        f"Date: {{bom.write_date.strftime('%Y-%m-%d')}}"
    )

# Example output:
# V1 | archived | Components: 12 | ECO: N/A            | Date: 2025-06-15
# V2 | archived | Components: 12 | ECO: ECO-00042      | Date: 2025-09-20
# V3 | ACTIVE   | Components: 13 | ECO: ECO-00067      | Date: 2026-01-10

Effectivity Dates vs. Immediate Application

Odoo 19 supports two effectivity modes for ECOs:

ModeBehaviorBest For
As Soon As PossibleNew BoM activates immediately when ECO is appliedUrgent fixes, safety corrections, quality escapes
At DateNew BoM activates on a scheduled date; old BoM remains active until thenPlanned revisions, new model year transitions, regulatory compliance deadlines
Python — Set effectivity date on an ECO
from datetime import date

eco = env['mrp.eco'].browse(eco_id)

# Schedule BoM activation for Q2 product refresh
eco.write({
    'effectivity': 'date',
    'effectivity_date': date(2026, 4, 1),
})

# When the date arrives, a scheduled action
# activates the new BoM and archives the old one.
# Manufacturing orders created after April 1
# automatically use the new revision.
Effectivity Date Trap

The scheduled action that activates date-based ECOs runs via ir.cron. If your cron workers are misconfigured or overloaded, the BoM switch can be delayed by hours. On the activation date, verify that the cron ran and the correct BoM version is active. We add a server action alert that notifies the engineering team when a date-based ECO activates (or fails to activate).

04

PLM Document Management: CAD Files, Datasheets, and Revision-Linked Attachments

Engineering changes rarely involve only the BoM. A component substitution typically comes with updated CAD drawings, revised datasheets, new assembly instructions, and test reports. Odoo 19's PLM integrates with the Documents module to link files directly to ECOs and BoM revisions.

Linking Documents to ECOs

Every ECO has a Documents smart button. Attach files here — they are versioned alongside the ECO. When the ECO is applied, the documents carry over to the new BoM revision. Previous document versions remain accessible on the archived BoM.

Python — Attach a CAD file to an ECO programmatically
import base64

eco = env['mrp.eco'].browse(eco_id)

# Read the CAD file
with open('/path/to/assembly_v3.step', 'rb') as f:
    file_data = base64.b64encode(f.read())

# Create attachment linked to the ECO
attachment = env['ir.attachment'].create({
    'name': 'Assembly_V3.step',
    'type': 'binary',
    'datas': file_data,
    'res_model': 'mrp.eco',
    'res_id': eco.id,
    'mimetype': 'application/step',
})

print(
    f"Attached {{attachment.name}} "
    f"({{attachment.file_size // 1024}} KB) "
    f"to ECO {{eco.name}}"
)

Workspace Structure for Engineering Documents

If you have the Documents module installed, create a dedicated workspace for PLM with sub-folders per product line. This keeps engineering documents separate from sales quotes, HR files, and accounting records.

Directory layout — Recommended PLM workspace structure
Engineering Documents/
├── Product Line A/
│   ├── CAD/
│   │   ├── Assembly_V1.step
│   │   ├── Assembly_V2.step      (linked to ECO-00042)
│   │   └── Assembly_V3.step      (linked to ECO-00067)
│   ├── Datasheets/
│   │   ├── Component_C12.pdf
│   │   └── Component_C12-HR.pdf  (replacement spec)
│   └── Test Reports/
│       └── Validation_ECO-00067.pdf
├── Product Line B/
│   └── ...
└── Templates/
    ├── ECO_Request_Form.xlsx
    └── Validation_Checklist.pdf
CAD Integration Tip

Odoo does not natively render STEP, IGES, or SolidWorks files. Engineers still need their CAD software to view them. The value of attaching CAD files to ECOs is traceability, not viewing — production knows exactly which drawing revision corresponds to which BoM version. For teams that want in-browser 3D viewing, third-party connectors (e.g., Odoo-SolidWorks integrations) can push file references and thumbnails into the ECO.

05

Integrating PLM with Manufacturing Orders, Quality Checks, and Procurement

PLM does not exist in isolation — its value comes from how it connects to the rest of the manufacturing ecosystem. Here's how ECOs and BoM versioning interact with other Odoo modules.

Manufacturing Orders and BoM Version Locking

A critical behavior to understand: manufacturing orders lock to the BoM version that was active when they were created. If you apply an ECO that activates BoM V3 while 50 manufacturing orders are in progress on V2, those 50 orders continue using V2. Only new orders pick up V3. This is by design — you don't want to change the recipe mid-batch.

Python — Audit which MOs are running on outdated BoM versions
# Find manufacturing orders using non-current BoMs
MO = env['mrp.production']
BoM = env['mrp.bom']

# Get all active (current) BoM IDs
active_bom_ids = BoM.search([
    ('active', '=', True)
]).ids

# Find in-progress MOs on archived BoMs
outdated_mos = MO.search([
    ('state', 'in', ['confirmed', 'progress']),
    ('bom_id', 'not in', active_bom_ids),
    ('bom_id', '!=', False),
])

if outdated_mos:
    print(f"WARNING: {{len(outdated_mos)}} MOs on "
          f"outdated BoM versions:")
    for mo in outdated_mos:
        print(
            f"  {{mo.name}} | "
            f"Product: {{mo.product_id.display_name}} | "
            f"BoM V{{mo.bom_id.version}} | "
            f"State: {{mo.state}}"
        )
else:
    print("All in-progress MOs are on current BoMs.")

Quality Integration: Triggering ECOs from Quality Alerts

When a quality check fails or a customer complaint arrives, the quality team can create an ECO directly from the quality alert. This closes the loop between defect detection and engineering correction:

  • Quality inspector creates an alert on a specific product lot.
  • The alert is linked to a root cause analysis.
  • From the alert, click "Create ECO" — Odoo pre-fills the product, BoM, and references the alert in the ECO description.
  • The ECO follows the normal approval workflow.
  • Once applied, the quality alert is marked as "corrective action implemented."

Procurement Impact of BoM Changes

When an ECO adds a new component or changes quantities, the impact on procurement is immediate once the BoM activates. The MRP scheduler picks up the new BoM and recalculates material requirements:

Python — Preview procurement impact before applying an ECO
# Compare components between current and new BoM
eco = env['mrp.eco'].browse(eco_id)
current_bom = eco.bom_id
new_bom = eco.new_bom_id

current_lines = {
    line.product_id.id: line.product_qty
    for line in current_bom.bom_line_ids
}
new_lines = {
    line.product_id.id: line.product_qty
    for line in new_bom.bom_line_ids
}

# Added components
for pid in set(new_lines) - set(current_lines):
    product = env['product.product'].browse(pid)
    print(f"  + ADDED: {{product.display_name}} "
          f"(qty: {{new_lines[pid]}})")

# Removed components
for pid in set(current_lines) - set(new_lines):
    product = env['product.product'].browse(pid)
    print(f"  - REMOVED: {{product.display_name}}")

# Changed quantities
for pid in set(current_lines) & set(new_lines):
    if current_lines[pid] != new_lines[pid]:
        product = env['product.product'].browse(pid)
        delta = new_lines[pid] - current_lines[pid]
        sign = "+" if delta > 0 else ""
        print(
            f"  ~ CHANGED: {{product.display_name}} "
            f"{{current_lines[pid]}} -> "
            f"{{new_lines[pid]}} "
            f"({{sign}}{{delta}})"
        )
Run MRP After Every ECO Application

After applying an ECO that changes component quantities or adds new materials, manually trigger the MRP scheduler (Manufacturing → Operations → Run Scheduler) or wait for the next cron run. The scheduler recalculates demand based on the new BoM. If you have open purchase orders for the old component, they won't be automatically cancelled — review your pending procurement manually after significant BoM changes.

06

5 PLM Gotchas That Break BoM Traceability and Stall Engineering Workflows

1

Editing the BoM Directly Instead of Using an ECO

PLM only tracks changes made through ECOs. If an engineer with BoM write access opens the BoM form and edits it directly, no version is created, no approval is required, and the change is invisible to the audit trail. The entire PLM process is bypassed. This is the #1 compliance failure we see in audits.

Our Fix

Remove write access on mrp.bom from the engineering group. Engineers should only be able to create/edit BoMs through ECOs. The PLM module grants the necessary permissions within the ECO workflow. Use record rules to enforce this — even administrators should go through ECOs for traceability.

2

Phantom BoMs Don't Version the Way You Expect

Phantom BoMs (kits) are exploded at order time — they don't produce a manufacturing order. When you version a phantom BoM through an ECO, the new version applies to future sales orders and delivery orders, not manufacturing orders. If your phantom BoM has sub-assemblies with their own BoMs, the ECO only versions the top-level phantom — the sub-assembly BoMs require their own ECOs.

Our Fix

When changing a multi-level BoM, create separate ECOs for each level and link them using the ECO's "Previous ECO" field. Apply them bottom-up: sub-assembly ECOs first, then the parent. This ensures each level is independently versioned and approved.

3

ECO Approvals Block the Entire Pipeline When One Approver Is Unavailable

If a mandatory approver is on vacation, sick, or simply not checking notifications, every ECO at that stage stops moving. We've seen engineering teams with 20+ ECOs stuck in "In Review" for weeks because a single approver was traveling. This is the #1 reason teams abandon PLM.

Our Fix

Configure group-based approvals instead of individual approvals. Set the approval to require "any member of the Engineering Leads group" rather than a specific person. Additionally, set up an escalation server action: if an ECO has been in "In Review" for more than 3 business days, auto-assign it to the department manager.

4

Effectivity Date ECOs Silently Fail When Cron Workers Are Overloaded

Date-based ECOs rely on a scheduled action to activate on the specified date. If your cron workers are backed up processing emails, scheduled reports, or MRP calculations, the BoM switch can be delayed by hours. Production starts the day shift building on the old revision while the new one was supposed to activate at midnight.

Our Fix

Add a monitoring check for ECOs with effectivity dates. Create a server action that runs every 15 minutes and checks: "Are there any ECOs with an effectivity date in the past that haven't been applied?" If yes, send an urgent notification to the PLM manager. Better yet, apply critical ECOs manually on the effective date instead of relying on cron.

5

No Rollback Mechanism for Applied ECOs

Once an ECO is applied and the new BoM version is active, there is no "undo" button. If the new revision causes problems on the shop floor, you can't revert to the previous version through the PLM interface. The old BoM is archived, and manually reactivating it doesn't update the ECO history correctly.

Our Fix

Create a new ECO to revert. Don't manually archive/unarchive BoMs — that breaks the audit trail. The "revert ECO" references the original ECO, explains why the change is being rolled back, and goes through the same approval process. This way the audit trail shows: V1 → V2 (ECO-042) → V3 (ECO-055, reverts ECO-042). Full traceability preserved.

BUSINESS ROI

What PLM Saves Your Manufacturing Operation

PLM is not a developer tool — it is an operational control system. Here's what changes when you stop versioning BoMs in spreadsheets and approving changes over email:

90%Fewer Wrong-Revision Builds

Automated BoM activation eliminates the gap between "engineering approved it" and "production is using it." No more email-based handoffs that get lost in inboxes.

3 daysAverage ECO Cycle Time (was 3 weeks)

Structured approval workflows with notifications replace the "did you see my email?" follow-up cycle. Approvers act faster when the system tracks their response time.

100%Change Audit Trail

Every BoM revision links to an ECO with approvals, timestamps, and documents. ISO 9001 and AS9100 auditors can trace any component on any product back to the engineering decision that put it there.

60%Less Scrap from Obsolete Materials

When BoM changes trigger procurement recalculation, you stop ordering components that are about to be replaced. The MRP scheduler sees the new BoM and adjusts purchase requisitions automatically.

The hidden ROI is regulatory compliance. For manufacturers in medical devices, aerospace, automotive, or food production, the ability to produce a complete change history for any product at any point in time is not optional — it is a certification requirement. PLM turns an audit from a two-week document scramble into a five-minute report.

SEO NOTES

Optimization Metadata

Meta Desc

Complete guide to PLM in Odoo 19. Configure Engineering Change Orders, BoM versioning, approval workflows, document management, and MRP integration for manufacturing.

H2 Keywords

1. "How to Install and Configure the PLM Module in Odoo 19"
2. "Engineering Change Orders in Odoo 19: The Complete Approval Workflow"
3. "BoM Versioning in Odoo 19: How Revisions, Effectivity Dates, and Archives Work"
4. "5 PLM Gotchas That Break BoM Traceability and Stall Engineering Workflows"

Stop Versioning BoMs in Spreadsheets

Every BoM change communicated via email is a change that might not reach the shop floor. Every revision tracked in a spreadsheet is a revision that an auditor will question. Every approval given over chat is an approval with no timestamp and no accountability.

If you're running Odoo 19 Manufacturing and managing engineering changes outside the system, we can help. We implement PLM workflows, configure ECO approval pipelines, migrate legacy BoM revision history into Odoo, and integrate document management with your existing CAD tools. The result is a change control process that your engineering team will actually use — because it's faster than the email chain it replaces.

Book a Free PLM Assessment