Odoo14/Flectra批量下载电子发票触发Expected Singleton Error
Odoo14/Flectra批量下载E-faktur触发Expected Singleton Error问题
错误详情
批量下载多条数据记录时触发如下错误:
File "c:\users\it uw\odoo14\mspcustomaddons\l10n_id_efaktur\models\account_move.py ", line 136, in download_efaktur self._generate_efaktur(',') File "c:\users\it uw\odoo14\mspcustomaddons\l10n_id_efaktur\models\account_move.py", line 296, in _generate_efaktur output_head = self._generate_efaktur_invoice(delimiter) File "c:\users\it uw\odoo14\mspcustomaddons\l10n_id_efaktur\models\account_move.py", line 144, in _generate_efaktur_invoice company_id = self.company_id File "C:\Users\IT UW\odoo14\flectra\flectra\fields.py", line 947, in __get__ record.ensure_one() File "C:\Users\IT UW\odoo14\flectra\flectra\models.py", line 4437, in ensure_one raise ValueError("Expected singleton: %s" % self) ValueError: <class 'ValueError'>: "Expected singleton: account.invoice(35590, 35589, 35588, 35587)" while evaluating 'action = records.download_effect()'
相关代码
@api.multi def download_efaktur(self): """Collect the data and execute function _generate_efaktur.""" for record in self: if record.state == 'draft': raise ValidationError(_('Could not download E-faktur in draft state')) if record.partner_id.l10n_id_pkp and not record.l10n_id_tax_number: raise ValidationError(_('Connect %(move_number)s with E-faktur to download this report', move_number=record.name)) self._generate_efaktur(',') return self.download_csv() @api.multi def _generate_efaktur(self, delimiter): if self.filtered(lambda x: not x.l10n_id_kode_transaksi): raise UserError(_('Some documents don\'t have a transaction code')) if self.filtered(lambda x: x.type != 'out_invoice'): raise UserError(_('Some documents are not Customer Invoices')) output_head = self._generate_efaktur_invoice(delimiter) my_utf8 = output_head.encode("utf-8") out = base64.b64encode(my_utf8) attachment = self.env['ir.attachment'].create({ 'datas': out, 'name': 'efaktur_%s.csv' % (fields.Datetime.to_string(fields.Datetime.now()) .replace(" ", "_")), 'type': 'binary', }) for record in self: record.message_post(attachment_ids=[attachment.id]) self.l10n_id_attachment_id = attachment.id return { 'type': 'ir.actions.client', 'tag': 'reload', }
问题原因
_generate_efaktur_invoice是单记录逻辑方法(内部访问self.company_id这类单字段时,会自动触发ensure_one()检查),但当前_generate_efaktur直接用多记录集合调用它,导致报错。- 最后一行
self.l10n_id_attachment_id = attachment.id试图给多记录集合直接赋值字段,同样会触发单记录检查。
解决方案
修改_generate_efaktur方法,循环处理每条记录并合并内容
将_generate_efaktur中的单记录方法调用改为循环处理,合并所有记录的E-faktur内容,同时修正字段赋值逻辑:
@api.multi def _generate_efaktur(self, delimiter): if self.filtered(lambda x: not x.l10n_id_kode_transaksi): raise UserError(_('Some documents don\'t have a transaction code')) if self.filtered(lambda x: x.type != 'out_invoice'): raise UserError(_('Some documents are not Customer Invoices')) # 循环处理每条记录,合并生成的E-faktur内容 output_content = [] for record in self: invoice_content = record._generate_efaktur_invoice(delimiter) output_content.append(invoice_content) # 合并所有内容(可根据实际E-faktur格式调整分隔/换行逻辑) output_head = '\n'.join(output_content) my_utf8 = output_head.encode("utf-8") out = base64.b64encode(my_utf8) attachment = self.env['ir.attachment'].create({ 'datas': out, 'name': 'efaktur_%s.csv' % (fields.Datetime.to_string(fields.Datetime.now()) .replace(" ", "_")), 'type': 'binary', }) for record in self: record.message_post(attachment_ids=[attachment.id]) # 循环给每条记录单独赋值附件ID,避免多记录集合直接赋值 record.l10n_id_attachment_id = attachment.id return { 'type': 'ir.actions.client', 'tag': 'reload', }
额外检查
确认_generate_efaktur_invoice方法的装饰器为@api.multi(单记录逻辑下该装饰器可正常处理单记录实例),确保它能正确接收单记录对象并生成对应内容。
内容的提问来源于stack exchange,提问作者it uw
相关产品推荐
相关产品推荐

