GuideOdoo DocumentsMarch 13, 2026

Odoo 19 Documents Module:
Digital Asset Management & Automated Workflows

INTRODUCTION

Why Most Companies Outgrow Shared Drives Before They Realize It

Every growing company eventually hits the same wall: vendor contracts live in someone's inbox, expense receipts sit in a Dropbox folder nobody remembers sharing, and the latest version of the employee handbook exists on three different Google Drives with three different names. The information is technically stored — but finding it, acting on it, and controlling who sees it becomes a full-time job.

The Documents module in Odoo 19 is not just a file storage system. It is a centralized digital asset management platform that connects directly to your accounting, HR, project management, and procurement workflows. Documents are tagged, indexed, searchable, and — most importantly — actionable. Upload a vendor bill and a workflow action can automatically create a draft journal entry, assign it to the AP team, and tag it for the correct expense category.

This guide walks through the entire module: workspace architecture, tag taxonomies, automated workflow actions, OCR digitization, spreadsheet integration, share links, access control, and deep integrations with Accounting, HR, and Project. Every configuration uses real Odoo 19 field names, menu paths, and Python model references.

01

Workspaces and Folders: Designing Your Document Architecture

Workspaces are the top-level organizational unit in the Documents module. Navigate to Documents → Configuration → Workspaces to manage them. Each workspace acts as an isolated container with its own tag structure, access rules, and default workflow actions. Think of workspaces as departments — Finance, Human Resources, Legal, Projects — while folders within workspaces mirror your internal filing structure.

The underlying model is documents.folder (renamed from documents.share in earlier versions). Key fields include name, parent_folder_id (for nesting), company_id, group_ids (access groups), read_group_ids, tag_ids (available tags), and action_ids (workflow actions available in this workspace). The description field supports HTML and appears as a helper tooltip when users browse the workspace.

A well-designed workspace hierarchy keeps documents discoverable without forcing users to remember exact file names. Here is a recommended structure for a mid-size company:

XML — Workspace seed data (data/documents_workspace.xml)
<odoo>
  <data noupdate="1">

    <!-- Top-level workspaces -->
    <record id="workspace_finance" model="documents.folder">
      <field name="name">Finance</field>
      <field name="company_id" ref="base.main_company"/>
      <field name="group_ids" eval="[(4, ref('account.group_account_user'))]"/>
      <field name="description"><![CDATA[
        Vendor bills, customer invoices, bank statements,
        and tax documents. OCR digitization is enabled.
      ]]></field>
    </record>

    <!-- Nested folder: Vendor Bills -->
    <record id="folder_vendor_bills" model="documents.folder">
      <field name="name">Vendor Bills</field>
      <field name="parent_folder_id" ref="workspace_finance"/>
      <field name="description">Scanned and emailed vendor invoices</field>
    </record>

    <!-- Nested folder: Bank Statements -->
    <record id="folder_bank_statements" model="documents.folder">
      <field name="name">Bank Statements</field>
      <field name="parent_folder_id" ref="workspace_finance"/>
    </record>

    <!-- HR workspace -->
    <record id="workspace_hr" model="documents.folder">
      <field name="name">Human Resources</field>
      <field name="company_id" ref="base.main_company"/>
      <field name="group_ids" eval="[(4, ref('hr.group_hr_user'))]"/>
    </record>

    <!-- Legal workspace -->
    <record id="workspace_legal" model="documents.folder">
      <field name="name">Legal &amp; Compliance</field>
      <field name="company_id" ref="base.main_company"/>
    </record>

  </data>
</odoo>
Workspace vs. Folder

Both use the same documents.folder model. A workspace is simply a folder with no parent (parent_folder_id = False). It appears in the left sidebar of the Documents app. A folder with a parent appears as a sub-item. Access rights cascade downward — a user who can access the Finance workspace automatically has access to Vendor Bills and Bank Statements unless explicitly restricted.

02

Tags and Facets: Building a Searchable Taxonomy for Every Document

Tags in Odoo Documents are organized into a two-level hierarchy: facets (categories) and tags (values within a facet). Navigate to Documents → Configuration → Tags to manage them. The model behind facets is documents.facet, and each tag is a documents.tag record linked to its facet via the facet_id field.

Facets answer a specific question about the document. For example, the facet Document Type answers "What kind of document is this?" with tag values like Invoice, Contract, Receipt, Policy. The facet Status answers "Where is this document in its lifecycle?" with values like Draft, Under Review, Approved, Archived.

Each facet can be scoped to specific workspaces via the folder_id field. This means the Finance workspace shows only finance-relevant tags (Invoice, Credit Note, Statement), while the HR workspace shows HR-relevant tags (Contract, Payslip, ID Copy). The sequence field on both documents.facet and documents.tag controls display order in the filter panel.

Facet (Category)Tags (Values)Workspace ScopeUse Case
Document TypeInvoice, Credit Note, Receipt, Statement, ContractFinanceFilter by document nature for accounting workflows
StatusDraft, Under Review, Approved, Expired, ArchivedAll workspacesTrack document lifecycle across departments
DepartmentSales, Operations, IT, Marketing, ExecutiveAll workspacesCross-reference documents by owning department
Employee DocumentID Copy, Work Permit, Diploma, Medical CertificateHuman ResourcesClassify employee-related documents for compliance
PriorityNormal, Urgent, CriticalLegalFlag legal documents requiring immediate review
XML — Tag and facet seed data (data/documents_tags.xml)
<odoo>
  <data noupdate="1">

    <!-- Facet: Document Type (Finance workspace) -->
    <record id="facet_doc_type" model="documents.facet">
      <field name="name">Document Type</field>
      <field name="folder_id" ref="workspace_finance"/>
      <field name="sequence">10</field>
    </record>

    <record id="tag_invoice" model="documents.tag">
      <field name="name">Invoice</field>
      <field name="facet_id" ref="facet_doc_type"/>
      <field name="sequence">1</field>
    </record>
    <record id="tag_credit_note" model="documents.tag">
      <field name="name">Credit Note</field>
      <field name="facet_id" ref="facet_doc_type"/>
      <field name="sequence">2</field>
    </record>
    <record id="tag_receipt" model="documents.tag">
      <field name="name">Receipt</field>
      <field name="facet_id" ref="facet_doc_type"/>
      <field name="sequence">3</field>
    </record>

    <!-- Facet: Status (all workspaces) -->
    <record id="facet_status" model="documents.facet">
      <field name="name">Status</field>
      <field name="sequence">20</field>
    </record>

    <record id="tag_draft" model="documents.tag">
      <field name="name">Draft</field>
      <field name="facet_id" ref="facet_status"/>
      <field name="sequence">1</field>
    </record>
    <record id="tag_approved" model="documents.tag">
      <field name="name">Approved</field>
      <field name="facet_id" ref="facet_status"/>
      <field name="sequence">2</field>
    </record>
    <record id="tag_archived" model="documents.tag">
      <field name="name">Archived</field>
      <field name="facet_id" ref="facet_status"/>
      <field name="sequence">3</field>
    </record>

  </data>
</odoo>

The real power of tags appears when combined with workflow actions. You can configure an action that triggers only when a document has a specific tag combination — for example, "when a document in the Finance workspace is tagged as Invoice + Approved, create a vendor bill in Accounting." This turns tagging from a passive filing exercise into an active trigger for business processes.

03

Workflow Actions: Turning Documents into Business Transactions

Workflow actions are the core feature that separates Odoo Documents from a generic file manager. Navigate to Documents → Configuration → Actions to create them. The underlying model is documents.workflow.action (linked to documents.workflow.rule for conditions). When a user selects a document and clicks an action button, Odoo executes a chain of operations: setting tags, moving to a folder, creating a linked business record, or running custom Python code.

Each action defines: a domain (which documents it appears on, based on tags, workspace, or MIME type), an action type (set tags, move folder, create record, run server action), and optional chained actions that execute sequentially. The domain field uses Odoo's standard domain syntax.

Python — Custom workflow action: auto-create vendor bill from document
from odoo import models, fields, api


class DocumentWorkflowCreateBill(models.Model):
    _inherit = 'documents.document'

    def action_create_vendor_bill(self):
        """Workflow action: create account.move from uploaded document."""
        self.ensure_one()
        AccountMove = self.env['account.move']

        bill_vals = {
            'move_type': 'in_invoice',
            'partner_id': self._guess_partner_from_content(),
            'invoice_date': fields.Date.today(),
            'ref': self.name,
        }
        bill = AccountMove.create(bill_vals)

        # Attach the document file to the new bill
        self.env['ir.attachment'].create({
            'name': self.name,
            'datas': self.datas,
            'res_model': 'account.move',
            'res_id': bill.id,
            'mimetype': self.mimetype,
        })

        # Update document metadata
        self.write({
            'res_model': 'account.move',
            'res_id': bill.id,
            'tag_ids': [(4, self.env.ref(
                'custom_documents.tag_invoice_processed'
            ).id)],
        })

        return {
            'type': 'ir.actions.act_window',
            'res_model': 'account.move',
            'res_id': bill.id,
            'views': [(False, 'form')],
        }

    def _guess_partner_from_content(self):
        """Attempt to match document name or OCR text to a vendor."""
        Partner = self.env['res.partner'].sudo()
        if self.partner_id:
            return self.partner_id.id
        # Fallback: search by document name tokens
        tokens = (self.name or '').replace('-', ' ').split()
        for token in tokens:
            if len(token) > 3:
                match = Partner.search(
                    [('name', 'ilike', token),
                     ('supplier_rank', '>', 0)],
                    limit=1,
                )
                if match:
                    return match.id
        return False

Built-in workflow action types available in Odoo 19 without custom code:

Action TypeWhat It DoesCommon Use Case
Set TagsAdds or removes tags from selected documentsMark a batch of invoices as "Approved" with one click
Move to FolderRelocates documents to a target workspace/folderMove processed bills from "Inbox" to "Archived"
Create Vendor BillGenerates account.move with type in_invoiceOne-click bill creation from scanned PDF
Create TaskGenerates project.task linked to the documentTurn a requirements doc into an actionable task
Request SignatureSends document to Sign module for e-signatureRoute contracts for approval without leaving Documents
Create SpreadsheetConverts CSV/XLSX to an Odoo Spreadsheet documentAnalyze uploaded data directly in the browser
Bulk Actions

Workflow actions work on multi-select. In the Documents Kanban view, select 50 scanned receipts with Shift+Click, then click "Create Vendor Bill" — Odoo will create 50 draft bills in one operation. Each bill links back to its source document via the res_model / res_id fields on documents.document. This bidirectional link means you can always trace a journal entry back to the original scan.

04

Spreadsheet Integration: Live Data Analysis Inside Your Document Workspace

Odoo 19 includes a full-featured spreadsheet engine accessible directly from the Documents module. Navigate to any workspace, click New → Spreadsheet, and you get a browser-based spreadsheet that supports formulas, pivot tables, charts, and — critically — live data from any Odoo model.

The spreadsheet is stored as a documents.document record with handler = 'spreadsheet' and the data persisted in the spreadsheet_data JSON field. The spreadsheet_snapshot field stores periodic snapshots for version history. Key menu path: Documents → [Workspace] → New → Spreadsheet.

The real power is the Insert Data feature. From within a spreadsheet, click Data → Insert Pivot or Data → Insert List to pull live data from any Odoo model. For example, insert a pivot of account.move.line grouped by account_id and date to build a real-time P&L report that updates every time the spreadsheet is opened. You can also insert individual cell references using the =ODOO.PIVOT() and =ODOO.LIST() functions.

Key spreadsheet functions available in Odoo 19:

FunctionSyntaxDescription
ODOO.PIVOT=ODOO.PIVOT(pivot_id, measure, ...)Returns a value from a pivot table defined in the spreadsheet
ODOO.PIVOT.HEADER=ODOO.PIVOT.HEADER(pivot_id, ...)Returns the header label for a pivot group
ODOO.LIST=ODOO.LIST(list_id, index, field)Returns a field value from a list data source at a given row index
ODOO.HYPERLINK=ODOO.HYPERLINK(url, label)Creates a clickable link to an Odoo record or external URL

Spreadsheets stored in the Documents module inherit the workspace's access controls. A financial model in the Finance workspace is automatically restricted to users with accounting access. You can share a read-only snapshot via a share link without granting access to the underlying Odoo data — the shared version contains static values, not live queries.

A practical example: the CFO creates a spreadsheet in the Finance workspace with a pivot of account.move.line grouped by account_id.code (rows) and date:month (columns), measuring balance. This produces a real-time trial balance that updates on every page refresh. Add a chart on top of the pivot, and you have a live financial dashboard — no BI tool required, no data export, no stale CSV. The spreadsheet can be bookmarked, shared with the board via a time-limited link, and versioned automatically through the Documents module's snapshot system.

05

Digitization and OCR: Extracting Structured Data from Scanned Documents

The digitization feature (powered by Odoo's IAP OCR service) automatically extracts structured data from uploaded documents. When you upload a PDF or image to a workspace with digitization enabled, Odoo sends it to the OCR endpoint and populates fields like partner_id, invoice_date, total_amount, and individual line items — without any manual data entry.

Enable digitization at Documents → Configuration → Settings → Digitization. The setting documents.digitization_mode controls behavior: manual (user clicks "Digitize"), auto_send (uploaded files are sent immediately), or disabled. OCR credits are consumed from your Odoo IAP account — each document costs approximately one credit.

Supported document types for OCR extraction:

Document TypeExtracted FieldsTarget Model
Vendor BillsVendor name, invoice number, date, due date, line items, taxes, totalaccount.move
Expense ReceiptsMerchant, date, amount, currency, payment methodhr.expense
ID DocumentsFull name, document number, expiry date, nationalityhr.employee
Python — Server action: auto-digitize on upload to Finance workspace
from odoo import models, api


class DocumentAutoDigitize(models.Model):
    _inherit = 'documents.document'

    @api.model_create_multi
    def create(self, vals_list):
        records = super().create(vals_list)
        finance_folder = self.env.ref(
            'custom_documents.workspace_finance',
            raise_if_not_found=False,
        )
        for doc in records:
            if (
                doc.folder_id == finance_folder
                and doc.mimetype in ('application/pdf', 'image/jpeg', 'image/png')
                and not doc.res_model  # not already linked to a record
            ):
                doc.action_send_for_digitization()
        return records
OCR Accuracy Tip

OCR accuracy improves dramatically with consistent vendors. After the first invoice from a vendor is manually verified, Odoo's AI learns the layout. Subsequent invoices from the same vendor are extracted with significantly higher accuracy. For best results, correct OCR mistakes in the first 5-10 invoices per vendor — the system adapts its extraction template over time.

06

Share Links, Document Requests, and Access Control

Odoo Documents provides three mechanisms for external sharing: share links (send a URL to download specific documents), document requests (send a URL where external users can upload files), and access tokens (time-limited, password-protected access). All three are managed through the documents.share model.

Share Links

Select one or more documents, click Share, and Odoo generates a unique URL. Configuration options on the share wizard include: date_deadline (link expiry), type (ids for specific documents, domain for dynamic sets), action (download or downloadupload), and owner_id (the user whose access rights are used to serve the files). External recipients do not need an Odoo account.

Document Requests

Document requests reverse the flow — you send a link and the recipient uploads documents into your workspace. Navigate to Documents → [Workspace] → Request. The request creates a placeholder documents.document record with type = 'empty'. Once the recipient uploads, the record is updated with the file data. Fields include request_activity_id (triggers a scheduled activity when fulfilled), partner_id (expected sender), and folder_id (destination workspace).

Common use case: during employee onboarding, HR sends a document request link for ID copy, tax form, and bank details. The new hire uploads directly into the HR workspace without needing Odoo access. Each upload triggers an activity notification to the HR officer.

Access Control Model

Document access is controlled at three levels:

LevelFieldBehavior
Workspacegroup_ids on documents.folderOnly users in these groups see the workspace in the sidebar
Workspace (Read)read_group_ids on documents.folderUsers can view but not edit, upload, or delete in this workspace
Documentowner_id on documents.documentDocument owner always has full access regardless of workspace rules
Sharedate_deadline + access_tokenExternal access via unique token, optionally time-limited
07

Deep Integrations: Accounting, HR, Project, and Custom Models

The Documents module connects bidirectionally with other Odoo apps via bridge modules. When installed, these bridges automatically centralize documents from their respective apps into the Documents workspace. Each bridge is a separate module that can be independently installed.

Bridge ModuleTechnical NameWhat It Does
Accountingdocuments_accountVendor bills and attachments sync to Finance workspace. Workflow actions create account.move records.
HRdocuments_hrEmployee documents (contracts, payslips, ID copies) centralized in HR workspace with per-employee filtering.
Projectdocuments_projectProject attachments appear in a dedicated workspace. Create tasks directly from documents.
Signdocuments_signSend documents for e-signature directly from the Documents UI. Signed copies auto-return to workspace.
Spreadsheetdocuments_spreadsheetBrowser-based spreadsheets stored as documents with live Odoo data connections.
XML — Enabling document bridges in module manifest (__manifest__.py)
{
    'name': 'Custom Documents Configuration',
    'version': '19.0.1.0.0',
    'category': 'Document Management',
    'depends': [
        'documents',
        'documents_account',    # Accounting bridge
        'documents_hr',         # HR bridge
        'documents_project',    # Project bridge
        'documents_sign',       # E-signature bridge
        'documents_spreadsheet',# Spreadsheet engine
    ],
    'data': [
        'data/documents_workspace.xml',
        'data/documents_tags.xml',
        'data/documents_workflow_actions.xml',
    ],
    'installable': True,
    'auto_install': False,
    'license': 'OEEL-1',
}

When documents_account is installed, every attachment uploaded to a vendor bill or customer invoice is automatically copied to the configured Finance workspace. The sync is controlled by settings at Accounting → Configuration → Settings → Documents, where you set the target folder_id and default tags. The same pattern applies to documents_hr (payslips sync to HR workspace) and documents_project (task attachments sync to Project workspace).

Storage Management

Document storage in Odoo 19 can be configured at Settings → Technical → Database Structure → Attachments (developer mode). The ir.attachment model supports three storage backends: db (PostgreSQL large objects — default), file (local filesystem at --data-dir), and s3 (Amazon S3 or compatible object storage via the attachment_s3 community module). For production deployments with more than 10,000 documents, we recommend filesystem or S3 storage to keep the database size manageable and backups fast.

Monitor storage usage at Documents → Configuration → Storage. This dashboard shows total storage consumed per workspace, file type distribution, and storage growth trends. Set up a scheduled action (ir.cron) to archive documents older than a retention period:

XML — Scheduled action: auto-archive old documents (data/documents_cron.xml)
<odoo>
  <data noupdate="1">
    <record id="cron_archive_old_documents" model="ir.cron">
      <field name="name">Documents: Archive Old Files</field>
      <field name="model_id" ref="documents.model_documents_document"/>
      <field name="state">code</field>
      <field name="code">
from dateutil.relativedelta import relativedelta
cutoff = datetime.date.today() - relativedelta(years=2)
old_docs = env['documents.document'].search([
    ('create_date', '&lt;=', str(cutoff)),
    ('active', '=', True),
    ('tag_ids.name', '=', 'Archived'),
])
archive_folder = env.ref(
    'custom_documents.folder_cold_storage',
    raise_if_not_found=False,
)
if archive_folder and old_docs:
    old_docs.write({
        'folder_id': archive_folder.id,
        'active': False,
    })
      </field>
      <field name="interval_number">1</field>
      <field name="interval_type">weeks</field>
      <field name="numbercall">-1</field>
      <field name="active">True</field>
    </record>
  </data>
</odoo>

This scheduled action runs weekly, finds all documents tagged "Archived" that are older than two years, and moves them to a cold storage folder while deactivating them. Deactivated documents (active = False) are excluded from normal searches but remain accessible through the "Archived" filter in the Documents interface. This keeps the active document list fast and focused while preserving compliance records indefinitely.

08

3 Documents Module Mistakes That Lead to Lost Files and Broken Workflows

1

Flat Workspace Structure Creates Tag Soup

Companies that dump everything into a single "General" workspace and rely exclusively on tags for organization hit a wall around 5,000 documents. The tag filter panel becomes unusable with 40+ tags, search results return hundreds of irrelevant matches, and users revert to asking colleagues "where is that file?" — the exact problem the module was supposed to solve.

Our Fix

Design workspaces around business functions (Finance, HR, Legal, Projects) and folders around document flows (Inbox, Under Review, Approved, Archived). Use tags for cross-cutting concerns (priority, fiscal year, department). This three-dimensional organization — workspace, folder, tags — scales to hundreds of thousands of documents.

2

OCR Credits Burn Through Silently on Auto-Send Mode

Setting digitization_mode = auto_send means every uploaded file — including screenshots, internal memos, and duplicate scans — consumes an OCR credit. We have seen clients burn through 500 credits in a week because employees were uploading photos of whiteboards and casual screenshots into the Finance workspace. At approximately EUR 0.04 per credit, this adds up fast on high-volume workspaces.

Our Fix

Use auto_send only on workspaces where the vast majority of uploads are actual invoices or receipts (e.g., the Vendor Bills folder). Set all other workspaces to manual mode. Add a domain filter on the auto-digitize logic to check mimetype = 'application/pdf' before sending — this skips images and Office documents that are rarely vendor bills.

3

Bridge Module Sync Creates Duplicate Attachments

When documents_account is installed, attachments on account.move records are copied to the Finance workspace — not moved. This means the file exists in two places: as an ir.attachment on the invoice and as a documents.document in the workspace. Both reference the same binary data (no actual storage duplication), but users see "two copies" and get confused about which one to update. Worse, deleting the document from the workspace does not delete the attachment from the invoice, and vice versa.

Our Fix

Educate users that the Documents workspace is the single source of truth. The attachment on the invoice is a convenience copy for context. Set up a naming convention (e.g., "INV-2026-0042_scan.pdf") so both copies are identifiable. If storage size is a concern, note that Odoo deduplicates binary data via checksum — two records pointing to identical file content share the same physical storage.

BUSINESS ROI

The Business Impact of Centralized Document Management in Odoo 19

Companies that migrate from shared drives and email attachments to Odoo Documents see measurable improvements within the first quarter:

75%Faster Document Retrieval

Faceted search with workspace scoping replaces manual folder browsing. Users find documents in seconds instead of minutes, eliminating the "where is that file?" conversations that interrupt teams daily.

12 minSaved per Vendor Bill

OCR extraction + one-click bill creation eliminates manual data entry. For a company processing 200 bills/month, that is 40 hours of accounting time reclaimed — nearly a full week of work every month.

100%Audit Trail Coverage

Every document action is logged: who uploaded, tagged, moved, shared, and linked each file. This complete chain of custody satisfies SOC 2 and ISO 27001 evidence requirements without additional tooling.

Beyond efficiency: having documents live inside the ERP means they participate in the same permission model, backup schedule, and retention policy as your business data. No more "the contract was in the marketing manager's personal Dropbox and they left the company."

SEO NOTES

Optimization Metadata

Meta Desc

Complete guide to the Odoo 19 Documents module. Configure workspaces, tags, OCR digitization, workflow actions, spreadsheet integration, share links, and deep accounting/HR bridges.

H2 Keywords

1. "Workspaces and Folders: Designing Your Document Architecture"
2. "Workflow Actions: Turning Documents into Business Transactions"
3. "Digitization and OCR: Extracting Structured Data from Scanned Documents"
4. "3 Documents Module Mistakes That Lead to Lost Files and Broken Workflows"

Your Documents Should Work as Hard as Your Team Does

A document management system that just stores files is a glorified hard drive. Odoo 19's Documents module earns its place in your stack by making files actionable — upload a scan and it becomes a vendor bill, tag a contract and it routes for signature, request a document and it lands in the right workspace with the right permissions.

The key to a successful implementation is architecture: design your workspaces around business functions, your folders around document flows, and your tags around the questions people actually ask when searching. Get the taxonomy right, configure the workflow actions, and enable OCR where it matters — the module does the rest.

Need help designing your document architecture or building custom workflow actions? We configure Odoo Documents for companies ranging from 20 to 2,000 employees. The initial workspace design and workflow setup typically takes 2-3 days and pays for itself within the first month of reduced manual filing.

Book a Free Documents Module Consultation