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

如何在Odoo服务器动作中创建发票后打印发票报表

Odoo服务器动作实现发票打印方案

问题描述

现有Odoo服务器动作代码用于处理交货单并创建发票,需要在执行invoice.write({'x_volgorde': volgorde})后实现发票打印功能。此前尝试with_context(print_mode=True).print_report(report_name='account.report_invoice_with_payments')未成功,需修正实现方式。

原代码

sale_ids = []
sale_ids_onkosten = []

for picking in records:
    if picking.sale_id:
        if picking.sale_id.invoice_status != 'to invoice':
            last_invoice = picking.sale_id.invoice_ids.sorted(key=lambda i: i.id, reverse=True)[0]
            last_chauffeurblad = picking.x_chauffeurblad.sorted(key=lambda r: r.id, reverse=True)[0]
            last_chauffeurblad.update({'x_invoice_id': last_invoice.id})
            picking.update({'x_invoice_id': last_invoice.id})
            error_message = 'FACTUUR REEDS GEMAAKT'
            picking.write({'x_error': error_message})
        else:
            if any(keyword in picking.x_ff.x_name.lower() for keyword in ['maand','lever', 'week', 'weke', 'post']):
                error_message = 'NIET GEFACTUREERD FACTURATIE TYPE: ' + picking.x_ff.x_name.upper()
                picking.write({'x_error': error_message})
            else:
                sale_id_list = sale_ids_onkosten if any("onkosten" in line.product_id.name.lower() for line in picking.move_ids_without_package) else sale_ids
                if picking.sale_id.id not in sale_id_list:
                    sale_id_list.append(picking.sale_id.id)

def process_invoices(sale_ids, onkosten=False):
    grouped_sale_orders = {}
    for sale_id in sale_ids:
        sale_order = env['sale.order'].browse(sale_id)
        key = (sale_order.partner_id.id, sale_order.partner_shipping_id.id)
        grouped_sale_orders.setdefault(key, []).append(sale_order)

    for order_group in grouped_sale_orders.values():
        sale_orders = env['sale.order'].concat(*order_group)
        invoices = sale_orders._create_invoices()

        for invoice in invoices:
            partner_email = invoice.partner_id.x_invoice_email or invoice.partner_id.email
            if invoice.amount_total <= 0:
                invoice.write({'x_message': 'Fout bij bedrag'})
            else:
                invoice.write({'x_message': '✓'})
                invoice.action_post()

            for picking in records:
                if picking.sale_id and picking.sale_id.name in invoice.invoice_origin:
                    error_message = 'FACTUUR'
                    if onkosten:
                        error_message += ' (onkosten)'
                    picking.write({'x_error': error_message})

                    last_chauffeurblad = picking.x_chauffeurblad.sorted(key=lambda r: r.id, reverse=True)[0]
                    volgorde = picking.x_volgorde
                    last_note_value = last_chauffeurblad.x_drivers_sheet_id.x_name if last_chauffeurblad.x_drivers_sheet_id else ''
                    if volgorde != 0.0:
                        invoice.write({'x_volgorde': volgorde})
                    
                    last_chauffeurblad.update({'x_invoice_id': invoice.id}) #update het chauffeursblad met link naar factuur
                    picking.update({'x_invoice_id': invoice.id}) #update de link naar de factuur in de leveringsbon
                    invoice.write({'x_chauffeur': last_note_value}) #update chauffeur op de factuur

if sale_ids:
    process_invoices(sale_ids)

if sale_ids_onkosten:
    process_invoices(sale_ids_onkosten, onkosten=True)

解决方案

服务器端无法直接触发前端打印弹窗,需通过报表动作对象调用标准方法实现。以下是两种可行实现方式:

1. 客户端触发打印预览/下载(适合手动执行的服务器动作)

在invoice.write({'x_volgorde': volgorde})之后添加如下代码,通过report_action触发报表动作,客户端执行时会弹出打印预览:

# 获取发票报表动作对象
report_action = env['ir.actions.report']._get_report_from_name('account.report_invoice_with_payments')
if report_action:
    # 触发报表动作,客户端将打开打印预览
    report_action.report_action(invoice, config=False)

2. 后台生成PDF内容(适合自动化流程)

如果需要后台生成PDF并保存为附件或发送邮件,可使用_render_qweb_pdf方法:

import base64

# 获取发票报表动作对象
report_action = env['ir.actions.report']._get_report_from_name('account.report_invoice_with_payments')
if report_action:
    # 生成PDF二进制内容
    pdf_content, pdf_format = report_action._render_qweb_pdf([invoice.id])
    # 将PDF保存为附件关联到发票
    attachment = env['ir.attachment'].create({
        'name': f"Invoice_{invoice.name}.pdf",
        'type': 'binary',
        'datas': base64.b64encode(pdf_content),
        'res_model': 'account.move',
        'res_id': invoice.id,
        'mimetype': 'application/pdf'
    })

修改后的核心代码片段

仅展示process_invoices函数中修改的关键部分:

def process_invoices(sale_ids, onkosten=False):
    grouped_sale_orders = {}
    for sale_id in sale_ids:
        sale_order = env['sale.order'].browse(sale_id)
        key = (sale_order.partner_id.id, sale_order.partner_shipping_id.id)
        grouped_sale_orders.setdefault(key, []).append(sale_order)

    for order_group in grouped_sale_orders.values():
        sale_orders = env['sale.order'].concat(*order_group)
        invoices = sale_orders._create_invoices()

        for invoice in invoices:
            partner_email = invoice.partner_id.x_invoice_email or invoice.partner_id.email
            if invoice.amount_total <= 0:
                invoice.write({'x_message': 'Fout bij bedrag'})
            else:
                invoice.write({'x_message': '✓'})
                invoice.action_post()

            for picking in records:
                if picking.sale_id and picking.sale_id.name in invoice.invoice_origin:
                    error_message = 'FACTUUR'
                    if onkosten:
                        error_message += ' (onkosten)'
                    picking.write({'x_error': error_message})

                    last_chauffeurblad = picking.x_chauffeurblad.sorted(key=lambda r: r.id, reverse=True)[0]
                    volgorde = picking.x_volgorde
                    last_note_value = last_chauffeurblad.x_drivers_sheet_id.x_name if last_chauffeurblad.x_drivers_sheet_id else ''
                    if volgorde != 0.0:
                        invoice.write({'x_volgorde': volgorde})
                        # --- 添加打印代码开始 ---
                        # 方案1:触发客户端打印预览
                        report_action = env['ir.actions.report']._get_report_from_name('account.report_invoice_with_payments')
                        if report_action:
                            report_action.report_action(invoice, config=False)
                        # --- 添加打印代码结束 ---
                    
                    last_chauffeurblad.update({'x_invoice_id': invoice.id}) #update het chauffeursblad met link naar factuur
                    picking.update({'x_invoice_id': invoice.id}) #update de link naar de factuur in de leveringsbon
                    invoice.write({'x_chauffeur': last_note_value}) #update chauffeur op de factuur

内容的提问来源于stack exchange,提问作者Pelingier

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 22:10:01