Search code examples
javascriptpythonodoo-15

Print a report from a JavaScript call


I made a wizard that creates a report for some stock.move.line elements, and that is called from a list view. It works well.

Now, I would like to print that report from a button in the Barcode Interface. So, it would be printed from a JavaScript call. (when a click is made on a button present on each stock.move.line)

When I'm trying to call my report from the JavaScript, I can see that my python function that creates the report is called (I added some print() inside that I can see in the console) but the report is not actually printed. I tested the python function independently, and it worked.

My question : Why the printing of the report from the JavaScript doesn't work?

My JavaScript file that is calling my python function for the report printing :

odoo.define("colona_custo.print_product_label", function(require) {
"use strict";

var rpc = require("web.rpc");

function call_print_function(nb_printing, move_line_id)
{
    console.log(nb_printing);
    console.log(move_line_id);

    
    return rpc.query({
        model: 'print.product.label.wizard',
        method: 'print_product_label_from_js',
        args: [[], nb_printing, move_line_id]
    });



}

function print_product_label()
{
    var move_line_id = $(this).next().text();

    // Asking the user how many times he wants to print the label.
    $(document.body).append("<div id='warning_popup' style='background: rgba(255, 255, 255, 0.9); width: 50vw; height: 50vh; border-radius: 5px; padding: 10px; z-index: 1000; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);'><h2 style='position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);'>How many times do you want to print the product label?</h2><input id='user_entry' style='position:relative;top:50%;left:45%;'/><button id='action_print' style='position: absolute; bottom: 5px; left: 100px;' class='btn btn-primary'>Print</button><button id='close_popup_printing' style='position: absolute; bottom: 5px; left: 5px;' class='btn btn-primary'>Close</button></div>")
    $('#close_popup_printing').on('click', function() {
        $('#warning_popup').hide();
    });

    $('#action_print').on('click', function() {
        var nb_printing = $('#user_entry').val();
        if (nb_printing > 0) {
            call_print_function(nb_printing, move_line_id);
        }

    });
}

$(document).on('click', '.o_button_print_product_label', print_product_label)});

My python file where is located the function that prints the report (it is the _js one) :

from odoo import api, fields, models, api
from odoo.exceptions import UserError

class SmlPrintProductLabelWizard(models.TransientModel):

    _name = 'print.product.label.wizard'

    nb_printing = fields.Integer()

    def print_product_label(self):
        if (self.nb_printing >= 0):
            return self.env.ref('colona_custo.action_report_product_label').report_action([], data={'stock_move_line_id': self.env.context.get('active_id'), 'nb_printing': self.nb_printing})
        else:
            raise UserError("The number of printing is incorrect.")

    def print_product_label_from_js(self, nb_printing=1, move_line_id=34):
        print("===========================")
        print("Hello, function is launched.")
        return self.env.ref('colona_custo.action_report_product_label').report_action([], data={'stock_move_line_id': int(move_line_id), 'nb_printing': int(nb_printing)})

When I click on the concerned button in the interface, I can see the right values for nb_printing and stock_move_line that are printed into the navigator console. I can also see the "Function is launched" in the classic console.

Thank you for you help. Regards,


Solution

  • The print_product_label_from_js function calls the report_action and returns an action definition which is handled by the web client when using for example a button of type object (The web client will execute the action for you)

    In the case of rpc.query, Odoo will run the function and return a Promise object, it will return the action and not execute it. So you need one more step, handle the promise object to execute the action

    Example:

    call_print_function(nb_printing, move_line_id).then(function(action) {
        Component.env.services.report.do_action(action);
    });
    

    To use the Component, declare it like the following:

    var { Component } = owl;