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

如何确保RPC调用完成后再打印Odoo 12 POS收据?

Odoo 12 POS 收据延迟打印以等待RPC数据加载问题修复

问题背景

在Odoo 12 POS系统中,需要通过RPC调用获取数据并展示在POS收据上,但当前收据会在RPC调用完成前就打印,导致无法展示所需信息。尝试扩展PaymentScreenWidget强制等待RPC完成后再打印,但出现两处错误:

  • 调用this._super(force_validate)后报错
  • 执行self.pos.proxy('print_receipt')时提示“self.pos.proxy is not a function”

已完成的操作:

  • 保存原方法引用以避免_super调用报错
  • 扩展Order模型控制RPC状态
  • 在push_order中添加RPC调用

错误分析与修复方案

1. _super调用错误

原validate_order方法可能未返回Promise,直接使用.then()会导致报错。需要用Promise.resolve()包裹原方法调用,确保链式调用正常执行。

2. 打印方法错误

Odoo 12中POS的打印接口并非pos.proxy,而是pos.chrome.print_receipt,proxy方法属于chrome对象。

3. Order模型字段判断错误

export_for_printing中使用的this.rpc_completed未定义,应改为判断this.rpc_state === 'completed'。

修复后的完整代码

odoo.define('mymodule.sincronize_receitp', function (require) {
    "use strict";
    
    var models = require('point_of_sale.models');
    var screens = require('point_of_sale.screens');
    var rpc = require('web.rpc');
    var core = require('web.core');
    var _t = core._t;
    
    // 保存原方法引用
    var originalOrderInitialize = models.Order.prototype.initialize;
    var originalOrderExportForPrinting = models.Order.prototype.export_for_printing;
    var originalPushOrder = models.PosModel.prototype.push_order;

    // 扩展Order模型控制RPC状态
    models.Order = models.Order.extend({
        initialize: function() {
            if (originalOrderInitialize) {
                originalOrderInitialize.apply(this, arguments);
            }
            this.rpc_state = 'pending';
            this.rpc_data = {};
            this.print_callbacks = [];
        },
        
        add_print_callback: function(callback) {
            if (this.rpc_state === 'completed') {
                callback();
            } else {
                this.print_callbacks.push(callback);
            }
        },
        
        export_for_printing: function() {
            var receipt = originalOrderExportForPrinting ? 
                originalOrderExportForPrinting.apply(this, arguments) : 
                {};
                
            receipt.rpc_data = this.rpc_state === 'completed' ? this.rpc_data : { status: 'loading' };
            return receipt;
        }
    });

    // 在push_order中添加RPC调用
    models.PosModel = models.PosModel.extend({
        push_order: function(order) {
            var self = this;
            
            if (!order) {
                return Promise.resolve();
            }

            order.rpc_state = 'pending';
            order.rpc_data = { status: 'loading' };

            // 先执行原push_order方法,再执行RPC
            return (originalPushOrder ? originalPushOrder.apply(this, arguments) : Promise.resolve())
                .then(function() {
                    return rpc.query({
                        model: 'pos.order',
                        method: 'get_data_rpc',
                        args: [order.unique_id],
                    }).then(function(response) {
                        order.rpc_data = response || {};
                        order.rpc_state = 'completed';
                        
                        // 执行打印回调(如果有的话)
                        while (order.print_callbacks.length) {
                            order.print_callbacks.shift()();
                        }
                    }).catch(function(error) {
                        console.error('RPC Error:', error);
                        order.rpc_data = { 
                            error: error.message || 'Erro de comunicação',
                            details: error.data ? error.data.message : ''
                        };
                        order.rpc_state = 'failed';
                    });
                });
        }
    });

    // 扩展PaymentScreenWidget,确保RPC完成后再打印
    screens.PaymentScreenWidget.include({
        validate_order: function(force_validate) {
            var self = this;
            var order = this.pos.get_order();
            
            if (!order || order.is_empty()) {
                return this._super(force_validate);
            }
            
            // 用Promise.resolve包裹原方法调用,确保链式调用正常
            return Promise.resolve(this._super(force_validate)).then(function() {
                // 等待push_order中的RPC完成
                return self.pos.push_order(order).then(function() {
                    // 使用正确的打印方法
                    self.pos.chrome.print_receipt(order.export_for_printing());
                });
            }).catch(function(error) {
                console.error('Validation/Print Error:', error);
                // 添加错误提示给用户
                self.gui.show_popup('error', {
                    title: _t('Error'),
                    body: _t('Failed to process order and print receipt: ') + error.message,
                });
            });
        }
    });
});

关键修复点说明

  1. Order模型修正:将rpc_completed改为rpc_state === 'completed',确保状态判断正确;初始化时设置默认rpc_state为pending。
  2. push_order优化:添加错误处理的catch块,确保RPC失败时状态正确更新;同时执行打印回调队列,处理可能的延迟打印请求。
  3. validate_order修复:
    • 用Promise.resolve()包裹this._super(force_validate),避免原方法不返回Promise导致的链式调用错误。
    • 替换打印方法为self.pos.chrome.print_receipt,符合Odoo 12 POS的API规范。
    • 添加全局错误捕获,提升用户体验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 23:04:53