Skip to content

fix: import DOCX/XLSX/PPTX documents as templates - #1

Closed
Rad0van wants to merge 127 commits into
feature/19.0from
feature/templates-office-import
Closed

Rad0van wants to merge 127 commits into
feature/19.0from
feature/templates-office-import

Conversation

@Rad0van

@Rad0van Rad0van commented Jun 29, 2026 •

Copy link
Copy Markdown
Member

Problem

Uploading an Office document (DOCX/XLSX/PPTX) as a template always failed. Three things blocked it:

  1. UI — the upload widget's file picker was locked to .pdf, so a DOCX couldn't even be selected.
  2. Storage — uploaded bytes were always stored as application/pdf named .pdf, regardless of the real content.
  3. Conversion — _convert_to_form() hardcoded "filetype": "pdf", so the document server was asked to build a PDF form out of DOCX bytes and the conversion errored (pdf_utils even carried a # TODO: add convert docx to pdf).

Fix

  • pdf_utils — new get_source_format() detects the real type from magic bytes (%PDF vs the PK\x03\x04 OOXML zip header, peeking inside for word/document.xml etc.). The upload field carries no filename, so detection has to come from the bytes.
  • model — create() and _onchange_file() now store the source file with its correct name/mimetype while converting, pass the real filetype to the converter, then overwrite the attachment with the resulting PDF form on success (rollback preserved on failure). _convert_to_form() takes a filetype argument.
  • controller — the download endpoint (what the document server fetches mid-conversion) serves the attachment's real mimetype/extension instead of always application/pdf.
  • view — the upload field accepts .pdf,.docx,.xlsx,.pptx and the helper text reflects it.

outputtype: "pdf" + pdf.form: True are unchanged, so the end result is still a fillable PDF form.

Testing

Verified end-to-end against a local ONLYOFFICE Document Server (Odoo 17 deployment): upload a .docx → it converts to a fillable PDF on save → opens in the editor. ruff check passes on the changed files.

ZEROM22 and others added 30 commits March 13, 2026 12:47
Summary
JWT timestamps generated by onlyoffice_odoo are incorrect on non-UTC systems.
Root cause
The module uses datetime.utcnow() and then converts that naive datetime with timestamp(). In Python, timestamp() interprets naive datetimes as local time. That means a naive UTC value is converted incorrectly on hosts whose local timezone is not UTC.
Impact
On systems running in timezones such as America/Argentina/Buenos_Aires (UTC-3), the generated iat claim is shifted into the future. PyJWT then rejects the token with "The token is not yet valid (iat)". This breaks ONLYOFFICE file access and editor callbacks.
Resolution
Replace naive UTC datetimes with timezone-aware UTC datetimes:

    datetime.datetime.now(datetime.timezone.utc)

This produces correct iat/exp claims regardless of the server timezone.
When doc_server_odoo_url or doc_server_inner_url fields are empty
(False in Odoo), settings_validation() crashes with:
  AttributeError: 'bool' object has no attribute 'startswith'

This happens because check_mixed_content() calls .startswith() on
the raw field value without checking for False/None first.

The fix:
- Falls back to web.base.url when doc_server_odoo_url is falsy
- Guards check_mixed_content and check_doc_serv_convert_service
  against missing base_url
- Uses str() cast in check_mixed_content for defensive safety
This avoids Python 3.12 SyntaxWarning caused by invalid escape sequences (e.g. \/, \w, \d) in normal strings, and simplifies the pattern by removing redundant escaping of /.
This avoids Python 3.12 SyntaxWarning caused by invalid escape sequences (e.g. \/, \w, \d) in normal strings, and simplifies the pattern by removing redundant escaping of /.
This avoids Python 3.12 SyntaxWarning caused by invalid escape sequences (e.g. \/, \w, \d) in normal strings, and simplifies the pattern by removing redundant escaping of /.
Updating to type="jsonrpc" ensures compatibility with current and future Odoo versions and removes deprecation warnings.
Summary
JWT timestamps generated by onlyoffice_odoo are incorrect on non-UTC systems.
Root cause
The module uses datetime.utcnow() and then converts that naive datetime with timestamp(). In Python, timestamp() interprets naive datetimes as local time. That means a naive UTC value is converted incorrectly on hosts whose local timezone is not UTC.
Impact
On systems running in timezones such as America/Argentina/Buenos_Aires (UTC-3), the generated iat claim is shifted into the future. PyJWT then rejects the token with "The token is not yet valid (iat)". This breaks ONLYOFFICE file access and editor callbacks.
Resolution
Replace naive UTC datetimes with timezone-aware UTC datetimes:

    datetime.datetime.now(datetime.timezone.utc)

This produces correct iat/exp claims regardless of the server timezone.
…e/19.0

# Conflicts:
#	onlyoffice_odoo/utils/validation_utils.py
This avoids Python 3.12 SyntaxWarning caused by invalid escape sequences (e.g. \/, \w, \d) in normal strings, and simplifies the pattern by removing redundant escaping of /.
# Conflicts:
#	onlyoffice_odoo/utils/validation_utils.py
# Conflicts:
#	onlyoffice_odoo/utils/validation_utils.py
… at import time

_() at class definition time triggers "no translation language detected" warnings
in Odoo 19.0 because no language context exists during module loading. _lt() defers
translation to render time.
…doo 19.0

Since Odoo 19.0, type='json' is a deprecated alias for type='jsonrpc'.
Updated all three modules: onlyoffice_odoo, onlyoffice_odoo_documents,
and onlyoffice_odoo_templates.
…tion-fields' into feature/19.0

# Conflicts:
#	onlyoffice_odoo_documents/models/onlyoffice_documents_access.py
#	onlyoffice_odoo_documents/models/onlyoffice_documents_access_user.py
ZEROM22 and others added 27 commits May 25, 2026 17:40
Uploading an Office document as a template always failed: the upload widget
only accepted .pdf, the uploaded bytes were stored as application/pdf
regardless of content, and _convert_to_form hardcoded "filetype": "pdf", so
the document server was asked to build a PDF form out of DOCX bytes and the
conversion errored.

- pdf_utils: detect the real source format from magic bytes (PDF vs OOXML zip)
- model: store the source file with its correct name/mimetype while converting,
  pass the real filetype to the converter, then overwrite the attachment with
  the resulting PDF form (both create and _onchange_file paths)
- controller: serve the attachment's real mimetype/extension on download so the
  document server receives the source in the format it was told to expect
- view: accept .pdf,.docx,.xlsx,.pptx and update the helper text

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Rad0van

Rad0van commented Jun 29, 2026

Copy link
Copy Markdown
Member Author

Superseded — reopening against ONLYOFFICE upstream (feature/19.0) instead of the fork.

@Rad0van
Rad0van force-pushed the feature/templates-office-import branch from 8b19ba1 to d0d204c Compare June 29, 2026 08:42
@Rad0van Rad0van closed this Jun 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants