OpenERP 7对接第三方XML文件方案咨询:无REST时创建account.invoice记录
解决方案:OpenERP 7接收XML发票数据并创建
account.invoice记录 嘿,针对你提到的OpenERP 7不支持REST、需要接收第三方XML发票数据并创建发票记录的需求,其实有几个靠谱的替代方案——毕竟REST支持确实是它的短板,下面给你详细拆解:
1. 用XML-RPC(官方原生支持,最推荐)
OpenERP 7本身就内置了XML-RPC支持,这是官方推荐的远程交互方式,完全能满足你的需求。第三方应用只需要通过XML-RPC调用OpenERP的模型方法,步骤大概是:
- 第三方先解析自身生成的XML发票数据,整理成符合OpenERP
account.invoice模型字段要求的字典格式(注意关联字段比如partner_id需要传对应记录的ID,发票行invoice_line要嵌套列表) - 通过XML-RPC连接到你的OpenERP实例,调用
account.invoice的create方法,或者自定义一个封装方法来处理XML解析+创建逻辑(更推荐后者,方便做错误处理和字段校验)
举个简单的Python客户端示例(第三方应用侧):
import xmlrpc.client import xml.etree.ElementTree as ET # 解析本地XML文件 tree = ET.parse('invoice_data.xml') root = tree.getroot() # 整理成OpenERP需要的字段格式 invoice_data = { 'partner_id': 123, # 替换成实际的合作伙伴ID 'name': root.find('invoice_number').text, 'amount_total': float(root.find('total_amount').text), 'journal_id': 5, # 替换成实际的日记账ID 'type': 'out_invoice', 'invoice_line': [ (0, 0, { 'name': root.find('line/product_name').text, 'quantity': float(root.find('line/quantity').text), 'price_unit': float(root.find('line/unit_price').text) }) ], } # 连接OpenERP XML-RPC服务 url = 'http://your-openerp-instance:8069' db = 'your_database' username = 'api_user' password = 'api_password' common = xmlrpc.client.ServerProxy(f'{url}/xmlrpc/2/common') uid = common.authenticate(db, username, password, {}) models = xmlrpc.client.ServerProxy(f'{url}/xmlrpc/2/object') # 调用create方法创建发票 invoice_id = models.execute_kw(db, uid, password, 'account.invoice', 'create', [invoice_data]) print(f"创建的发票ID: {invoice_id}")
2. 自定义HTTP控制器(灵活处理POST请求)
如果第三方应用更倾向于通过HTTP POST发送XML数据,你可以在OpenERP 7里开发一个自定义模块,添加一个HTTP控制器来接收请求。这种方式更灵活,还能自定义路由、权限验证逻辑。
示例控制器代码(OpenERP模块侧):
from openerp.addons.web.http import Controller, route, request import xml.etree.ElementTree as ET class InvoiceXMLController(Controller): @route('/invoice/xml/receive', type='http', auth='user', methods=['POST'], csrf=False) def receive_invoice_xml(self, **post): # 获取POST过来的XML原始数据 xml_data = request.httprequest.data root = ET.fromstring(xml_data) # 解析XML并整理发票数据 invoice_data = { 'partner_id': int(root.find('partner/id').text), 'name': root.find('invoice/number').text, 'amount_total': float(root.find('invoice/total').text), 'journal_id': 5, # 替换成实际的日记账ID 'type': 'out_invoice', 'invoice_line': [ (0, 0, { 'name': line.find('product/name').text, 'quantity': float(line.find('quantity').text), 'price_unit': float(line.find('unit_price').text) }) for line in root.findall('invoice/lines/line') ] } # 创建发票记录 invoice_obj = request.env['account.invoice'] invoice = invoice_obj.create(invoice_data) # 返回响应 return f"发票创建成功,ID: {invoice.id}"
注意:记得给访问该控制器的用户配置足够的权限,也可以添加API密钥验证等安全措施,避免非法请求。
3. 文件扫描+定时任务(适合非实时同步场景)
如果第三方应用可以把XML文件上传到OpenERP服务器的某个指定目录,你可以配置一个定时任务(ir.cron),定期扫描该目录,读取XML文件并创建发票。这种方式适合不需要实时同步的场景,比如每天批量处理一次。
步骤大概是:
- 在OpenERP里创建一个自定义模型,或者直接在
account.invoice里添加一个方法,用于扫描目录、解析XML、创建发票 - 配置
ir.cron定时任务,定期调用这个方法 - 第三方应用负责把XML文件上传到指定目录
一些关键注意点
- 字段映射:一定要确保XML里的数据和
account.invoice的字段完全匹配,特别是关联字段(比如合作伙伴、日记账、产品等)必须传对应的记录ID,或者添加逻辑通过名称查找ID - 错误处理:添加日志记录和异常捕获,比如XML格式错误、字段缺失、权限不足等情况,方便排查问题
- 权限控制:不管用哪种方式,都要给调用的用户分配
account.invoice的创建权限,避免权限错误
内容的提问来源于stack exchange,提问作者Jesse
相关产品推荐
相关产品推荐

