mcpField
O
odoo-report

odoo-report

github.com/ahmed-lakosha文档处理76133 次安装31 周前更新
代码仓库

关于 odoo-report

面向 Odoo 开发者的邮件模板与 QWeb 报告技能,覆盖 14–19 版本。支持创建、调试、验证、预览和按版本迁移,并提供渲染与 PDF 报告相关指导。

主要功能

  1. 01创建和分析邮件模板
  2. 02构建 QWeb PDF 报告
  3. 03调试渲染与模板错误
  4. 04验证并预览模板
  5. 05跨 Odoo 版本迁移模板
  6. 06提供按版本区分的渲染指导

适用场景

  1. 01创建报价单邮件模板
  2. 02构建采购订单 PDF 报告
  3. 03排查邮件被渲染为纯文本
  4. 04在不同 Odoo 版本间迁移模板

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/ahmed-lakosha/odoo-plugins --skill odoo-report

安装后在 Claude Code 中输入/odoo-report确认已加载。

详细介绍

Odoo 邮件模板与 QWeb 报表技能(v2.1)

用于跨 Odoo 14-19 版本创建、管理、调试和迁移 Odoo 邮件模板与 QWeb 报表的技能。

工作流

此技能可通过自然语言处理所有模板和报表工作流:

目标可以这样说
创建邮件模板“为 sale.order 报价单创建邮件模板”
创建 QWeb PDF 报表“为 purchase.order 创建 QWeb PDF 报表”
迁移模板“将此模板从 Odoo 14 迁移到 17”
分析模板“分析此模板是否存在问题”
调试渲染“调试我的邮件为何显示为纯文本”
修复模板“修复损坏的 QWeb 表达式”
部署前验证“在部署前验证此模板”
列出模板“列出 sale.order 的所有模板”
预览输出“预览此邮件模板”

配置

  • 支持的版本:Odoo 14、15、16、17、18、19
  • 核心模型:mail.template
  • 渲染引擎:用于标头的 inline_template(类似 Jinja2),用于 body_html 的 QWeb

用户覆盖设置:检查项目 .claude/ 目录中是否存在 odoo-report.local.md。如果存在,则将其 YAML frontmatter 设置(default_version、author、default_layout)用作默认值。


模板架构

mail.template
├── Inherits: mail.render.mixin (rendering engine)
├── Inherits: template.reset.mixin (reset - Odoo 16+)
│
├── Header Fields (inline_template engine):
│   subject, email_from, email_to, email_cc, reply_to, partner_to
│
├── Content Fields (QWeb engine):
│   body_html
│
├── Attachment Fields:
│   attachment_ids (static)
│   report_template (Odoo 14-16) / report_template_ids (Odoo 17+)
│   report_name (dynamic filename)
│
└── Configuration:
    email_layout_xmlid, auto_delete, mail_server_id,
    use_default_to, scheduled_date, template_category (16+)
渲染流程
mail.template.send_mail_batch(res_ids)
  ├─► _generate_template(res_ids, render_fields)
  │     ├─► _classify_per_lang()
  │     ├─► _render_field() per field (inline_template or qweb)
  │     ├─► _generate_template_recipients()
  │     ├─► _generate_template_attachments() (static + PDF report)
  │     └─► Return rendered values dict
  ├─► Create mail.mail records
  ├─► Apply email_layout_xmlid (if set)
  └─► Send via mail_server_id or default

两种渲染引擎

1. Inline 模板(类似 Jinja2)

用于:subject、email_from、email_to、email_cc、reply_to、partner_to、lang、scheduled_date

{{ object.name }}
{{ object.partner_id.name }}
{{ (object.user_id.email_formatted or user.email_formatted) }}
{{ object.state == 'draft' and 'Quotation' or 'Order' }}
{{ ctx.get('proforma') and 'Proforma' or '' }}
2. QWeb 引擎

用于:body_html


<t t-out="object.name"/>
<t t-out="format_amount(object.amount_total, object.currency_id)"/>


<t t-if="object.state == 'draft'">Draft</t>
<t t-elif="object.state == 'sent'">Sent</t>
<t t-else="">Confirmed</t>


<t t-foreach="object.order_line" t-as="line">
    <tr><td t-out="line.name"/></tr>
</t>


<a t-att-href="object.get_portal_url()">View</a>

版本决策矩阵

功能141516171819
输出标签t-esct-outt-outt-outt-outt-out
report_template(M2O)YYY---
report_template_ids(M2M)---YYY
template_category--YYYY
公司品牌颜色-----Y
format_datetime()-YYYYY
is_html_empty()--YYYY
版本检测优先级
  1. 用户指定的 --version 标志
  2. 目录路径(odoo14、odoo17 等)
  3. __manifest__.py 版本字符串(例如 '17.0.1.0.0')
  4. 如果不明确,则询问用户

邮件布局模板

布局宽度用途
mail.mail_notification_layout900px带标头和页脚的完整通知
mail.mail_notification_light590px简单通知
mail.mail_notification_layout_with_responsible_signature900px使用记录的 user_id 签名(16+)

最佳实践

1. 始终使用回退值
<t t-out="object.partner_id.name or 'Valued Customer'"/>
2. 使用格式辅助函数
<t t-out="format_amount(object.amount_total, object.currency_id)"/>
<t t-out="format_date(object.date_order)"/>
3. 使用布局保持一致性
<field name="email_layout_xmlid">mail.mail_notification_layout</field>
4. 处理空 HTML(16+)
<t t-if="not is_html_empty(object.description)">
    <div t-out="object.description"/>
</t>
5. 使用适用于对应版本的输出方式
 <t t-out="value"/>
  <t t-esc="value"/>
6. 按版本设置报表附件

<field name="report_template" ref="module.report_action"/>

<field name="report_template_ids" eval="[(4, ref('module.report_action'))]"/>
7. 使用邮件表格以确保兼容性

<table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tr><td style="padding: 20px;">Content</td></tr>
</table>
8. 安全地生成动态文件名
<field name="report_name">{{ (object.name or 'Document').replace('/', '-') }}</field>

wkhtmltopdf(PDF 报表必需)

安装
# Windows
winget install wkhtmltopdf.wkhtmltox

# Ubuntu/Debian
sudo apt-get install wkhtmltopdf

# macOS
brew install wkhtmltopdf
Odoo 配置(必需)
[options]
bin_path = C:\Program Files\wkhtmltopdf\bin   # Windows
# bin_path = /usr/local/bin                    # Linux
关键限制:离线模式

wkhtmltopdf 运行时无法访问网络:

  • 无法加载 Google Fonts CDN
  • 无法渲染外部图片
  • 使用 web.external_layout 加载字体
  • 使用系统字体:'DejaVu Sans', 'Arial', sans-serif
常见错误
错误原因解决方案
Unable to find Wkhtmltopdf未配置 bin_path在 odoo.conf 中添加 bin_path
PDF 生成超时请求了外部资源移除 CDN URL
生成的 PDF 为空白CSS/SCSS 错误验证 SCSS 语法
以代码 1 退出HTML 语法错误验证 QWeb XML

阿拉伯语/RTL 支持

非拉丁文本必须使用的模板包装器
<template id="report_document">
    <t t-call="web.html_container">        
        <t t-foreach="docs" t-as="o">
            <t t-call="web.external_layout"> 
                <div class="page">
                    
                </div>
            </t>
        </t>
    </t>
</template>

如果不使用 web.html_container,阿拉伯语文本会显示为 ÙØ§ØªÙˆØ±Ø©(将 UTF-8 字节按 Latin-1 读取)。

双语标签
<th style="background: #1a5276; color: white; padding: 12px;">
    Date | التاريخ
</th>
RTL 对齐
<div style="direction: rtl; text-align: right;">
    يرجى إرسال حوالاتكم على الحساب المذكور أعلاه
</div>

报告 SCSS 样式

资源包
'assets': {
    'web.report_assets_common': [
        'module/static/src/scss/report_styles.scss',
    ],
},
Google Fonts 注意事项
// BROKEN - Semicolons in URL break SCSS parsing
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap');

// FIXED - Use weight range syntax
@import url('https://fonts.googleapis.com/css2?family=Poppins:[email protected]&display=swap');

// BEST - Don't use Google Fonts (wkhtmltopdf is offline!)
推荐字体栈
$report-font-family: 'DejaVu Sans', 'Arial', 'Helvetica', sans-serif;

纸张格式配置

<record id="paperformat_custom" model="report.paperformat">
    <field name="name">Custom A4</field>
    <field name="format">A4</field>
    <field name="orientation">Portrait</field>
    <field name="margin_top">20</field>
    <field name="margin_bottom">20</field>
    <field name="margin_left">15</field>
    <field name="margin_right">15</field>
    <field name="header_line" eval="False"/>
    <field name="dpi">90</field>
</record>

报告链接:<field name="paperformat_id" ref="module.paperformat_custom"/>

格式尺寸用途
A4210 x 297 mm国际标准
Letter216 x 279 mm美国标准
Legal216 x 356 mm法律文档
横向任意 + Landscape宽表格、图表

调试工作流

诊断报告或模板问题时,请按以下顺序操作:

  1. 基础设施:是否已安装 wkhtmltopdf?odoo.conf 中的 bin_path 是否正确?服务器是否已重启?
  2. 模板结构:web.html_container → web.external_layout → div.page?
  3. 报告操作:report_name 是否与模板 ID 匹配?binding_model_id 是否正确?
  4. Shell 测试:env.ref('module.report_action')._render_qweb_pdf([record_id])
  5. 浏览器缓存:清除缓存(Ctrl+Shift+R)

参考文件

处理特定任务时,请从插件目录中阅读以下文件,以获取更深入的上下文:

创建模板
  • 按用途/模型选择模式:memories/template_patterns.md
  • 入门电子邮件 XML:templates/email/basic_notification.xml、templates/email/document_email.xml
  • 入门报告 XML:templates/qweb/basic_report.xml、templates/qweb/table_report.xml
  • 字段定义:data/template_fields.json
  • 按版本划分的上下文变量:data/context_variables.json
  • 布局选项:data/layouts.json
版本决策
  • 版本路由规则和迁移路径:memories/version_routing.md
  • 版本检测逻辑和功能映射:helpers/version_helper.md
验证
  • 预检验证清单:validators/template_validator.md
QWeb 质量
  • 安全性、性能、电子邮件/报告指南:memories/qweb_best_practices.md
模块专属模板
  • 按模块整理的已知 Odoo 模板 ID:data/module_templates.md

迁移参考

自动转换
从 → 到转换
14 → 15+t-esc → t-out,t-raw → t-out
14-16 → 17+report_template → report_template_ids,并添加 eval="[(4, ref(...))]"
Any → 16+添加 template_category 字段
Any → 19添加公司品牌设置:company.email_secondary_color、company.email_primary_color
迁移工作流
  1. 检测源版本(语法特征或目录名称)
  2. 创建备份:{file}.bak
  3. 按顺序应用转换
  4. 验证迁移后的 XML
  5. 显示差异摘要

完整迁移矩阵和规则请参阅 memories/version_routing.md。


常见错误

错误原因解决方案
AttributeError: 'NoneType' has no attribute 'name'访问空字段使用 object.field.name or ''
QWebException: t-esc is deprecated15+ 版本仍使用旧语法将 t-esc 替换为 t-out
KeyError: 'format_amount'缺少上下文辅助函数确保已继承 mail.render.mixin
ValidationError: Invalid XMLQWeb 格式错误检查标签是否闭合
阿拉伯语文本显示为 ÙØ§ØªÙˆØ±Ø©缺少 web.html_container添加 UTF-8 包装器
PDF 空白找不到 wkhtmltopdf 或 CSS 错误检查 bin_path,验证 SCSS

评论

支持 Markdown