如何在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
相关产品推荐
相关产品推荐

