如何为Odoo 15的UBL BIS3发票XML添加XML声明?
Odoo 15 UBL BIS3电子发票补XML声明的正确姿势
为啥直接改模板会报错?
你直接在bis3_templates.xml里加<?xml version="1.0" encoding="UTF-8"?>肯定炸,因为这个模板文件本身就是XML格式,模板内容是写在<template>标签的arch属性里的。XML解析器会把声明里的<当成属性值里的非法字符,直接给你抛“Unescaped '<' not allowed in attributes values”错误,根本走不通。
正确解法:从代码层面拼接XML声明
别碰核心模块的模板和代码,自己整个小模块继承处理就行,步骤如下:
1. 新建自定义模块
比如叫account_edi_ubl_bis3_xml_fix,模块结构简单就行:
__init__.py(空文件即可)__manifest__.py(配置依赖和基本信息)models/account_edi_ubl_bis3.py(核心逻辑)
2. 写模块配置文件__manifest__.py
{ 'name': 'UBL BIS3 XML声明补全', 'version': '1.0', 'depends': ['account_edi_ubl_bis3'], 'data': [], 'installable': True, 'auto_install': False, }
3. 写核心逻辑代码
在models/account_edi_ubl_bis3.py里继承原始的UBL生成类,在输出XML前补声明:
from odoo import models class AccountEdiXmlUblBis3(models.AbstractModel): _inherit = 'account.edi.xml.ubl_bis3' def _export_invoice(self, invoice): # 先调用父方法生成原本的XML内容 xml_content = super()._export_invoice(invoice) # 加XML声明,先检查有没有,避免重复添加 xml_decl = '<?xml version="1.0" encoding="UTF-8"?>\n' if not xml_content.strip().startswith('<?xml'): xml_content = xml_decl + xml_content return xml_content
4. 安装模块验证
把这个模块丢到Odoo的addons目录,刷新模块列表后安装。之后再生成UBL BIS3发票,XML开头就会自动带上声明,发Peppol ID就不会被拒收了。
为啥选这种方式?
一来不修改核心模块代码,升级Odoo的时候不会丢自定义内容;二来从代码层面拼接不会触发XML语法错误,比硬改模板靠谱多了。
内容的提问来源于stack exchange,提问作者geom
相关产品推荐
相关产品推荐

