You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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',
        }

问题原因

  1. _generate_efaktur_invoice是单记录逻辑方法(内部访问self.company_id这类单字段时,会自动触发ensure_one()检查),但当前_generate_efaktur直接用多记录集合调用它,导致报错。
  2. 最后一行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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 09:22:15