Odoo 17中_post方法soft参数缺失报错问题求助
问题描述
在Odoo 17中扩展AccountMove模型的_post方法,开发阶段测试正常,但部署到新数据库后,执行采购收货操作时触发报错。报错提示调用AccountMove._post()缺少必填参数soft,但自身代码调用该方法时已传递该参数,且未继承采购相关模块,无法理解报错原因。
报错信息
RPC_ERROR Odoo Server Error Traceback (most recent call last): File "D:\Documentos\odoo-17\odoo\odoo\http.py", line 1783, in _serve_db return service_model.retrying(self._serve_ir_http, self.env) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "D:\Documentos\odoo-17\odoo\odoo\service\model.py", line 133, in retrying result = func() ^^^^^^ File "D:\Documentos\odoo-17\odoo\odoo\http.py", line 1810, in _serve_ir_http response = self.dispatcher.dispatch(rule.endpoint, args) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "D:\Documentos\odoo-17\odoo\odoo\http.py", line 2014, in dispatch result = self.request.registry['ir.http']._dispatch(endpoint) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "D:\Documentos\odoo-17\odoo\odoo\addons\base\models\ir_http.py", line 222, in _dispatch result = endpoint(**request.params) ^^^^^^^^^^^^^^^^^^^^^^^^^^ File "D:\Documentos\odoo-17\odoo\odoo\http.py", line 759, in route_wrapper result = endpoint(self, *args, **params_ok) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "d:\documentos\odoo-17\odoo\addons\web\controllers\dataset.py", line 28, in call_button action = self._call_kw(model, method, args, kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "d:\documentos\odoo-17\odoo\addons\web\controllers\dataset.py", line 20, in _call_kw return call_kw(request.env[model], method, args, kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "D:\Documentos\odoo-17\odoo\odoo\api.py", line 468, in call_kw result = _call_kw_multi(method, model, args, kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "D:\Documentos\odoo-17\odoo\odoo\api.py", line 453, in _call_kw_multi result = method(recs, *args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "d:\documentos\odoo-17\odoo\addons\stock\models\stock_picking.py", line 1156, in button_validate pickings_to_backorder.with_context(cancel_backorder=False)._action_done() File "d:\documentos\odoo-17\odoo\addons\sale_stock\models\stock.py", line 109, in _action_done res = super()._action_done() ^^^^^^^^^^^^^^^^^^^^^^ File "d:\documentos\odoo-17\odoo\addons\stock\models\stock_picking.py", line 989, in _action_done todo_moves._action_done(cancel_backorder=self.env.context.get('cancel_backorder')) File "d:\documentos\odoo-17\odoo\addons\stock_account\models\stock_move.py", line 293, in _action_done stock_valuation_layers._validate_accounting_entries() File "d:\documentos\odoo-17\odoo\addons\stock_account\models\stock_valuation_layer.py", line 77, in _validate_accounting_entries account_moves._post() TypeError: AccountMove._post() missing 1 required positional argument: 'soft' The above server error caused the following client error: RPC_ERROR: Odoo Server Error RPC_ERROR at makeErrorFromResponse (http://localhost:8069/web/assets/e226aa6/web.assets_web.min.js:2888:163) at XMLHttpRequest.<anonymous> (http://localhost:8069/web/assets/e226aa6/web.assets_web.min.js:2892:13)
自定义实现代码
def _post(self, soft): facturas_especiales = self.filtered(lambda factura: factura.factura_especial) for factura_especial in facturas_especiales: if not factura_especial.journal_id.facturas_especiales: raise ValidationError("El diario no está configurado para trabajar con facturas especiales") move_types = ["fact", "fact_cambiaria", "fact_exportacion", "out_refund"] por_certificar = self.filtered( lambda factura: factura.journal_id.facturacion_activa and (factura.tipo_factura in move_types or factura.factura_especial or not factura.tipo_factura) and not factura.certificada ) for factura in por_certificar: if self.company_id.proveedor == "infile": infile.facturacion_electronica(self, factura) elif self.company_id.proveedor == "cofidi": cofidi.facturacion_electronica(self, factura) continuar_movimientos = self.filtered(lambda fact: not fact.certificacion_error) return super(AccountMove, continuar_movimientos)._post(soft)
问题分析与解决
核心原因
Odoo 17原生的AccountMove._post方法中,soft是可选参数,默认值为False,定义如下:
def _post(self, soft=False): # 原生逻辑
但你重写方法时,将soft设为了必填位置参数(没有默认值),而其他模块(如stock_account)调用_post()时未传递该参数,导致触发TypeError。
修复步骤
- 修改
_post方法参数定义,给soft加上默认值,与原生方法保持一致:
def _post(self, soft=False): # 添加默认值False facturas_especiales = self.filtered(lambda factura: factura.factura_especial) for factura_especial in facturas_especiales: if not factura_especial.journal_id.facturas_especiales: raise ValidationError("El diario no está configurado para trabajar con facturas especiales") move_types = ["fact", "fact_cambiaria", "fact_exportacion", "out_refund"] por_certificar = self.filtered( lambda factura: factura.journal_id.facturacion_activa and (factura.tipo_factura in move_types or factura.factura_especial or not factura.tipo_factura) and not factura.certificada ) for factura in por_certificar: # 优化:原代码用self.company_id存在多公司风险,改为factura.company_id if factura.company_id.proveedor == "infile": infile.facturacion_electronica(self, factura) elif factura.company_id.proveedor == "cofidi": cofidi.facturacion_electronica(self, factura) continuar_movimientos = self.filtered(lambda fact: not fact.certificacion_error) return super(AccountMove, continuar_movimientos)._post(soft)
- 额外优化点:原代码中
self.company_id存在风险,因为self是AccountMove的记录集,可能包含多个公司的凭证,改为factura.company_id可避免多公司场景下的逻辑错误。
验证
修改后重新升级模块,执行采购收货操作,报错即可解决。
内容的提问来源于stack exchange,提问作者damar
相关产品推荐
相关产品推荐

