My purpose
I have made a widget in JavaScript which has a button. I want to modify a
One2many field after clicking on this button. My widget is shown in
sale.order
form view and I want to modify the O2M order_line
field after the click.
In fact, I am trying to emulate part of the hr_timesheet_sheet module. This module adds a widget in hr_timesheet_sheet.sheet
form view and has a button too, each time the button is clicked the O2M timesheet_ids
changes.
Source code
So I was copying that part step by step, but I get a weird error in the
update_sheets
method. This is the source code:
update_sheets: function() {
if(this.querying) {
return;
}
this.updating = true;
var commands = [form_common.commands.delete_all()];
_.each(this.get("sheets"), function (_data) {
var data = _.clone(_data);
if(data.id) {
commands.push(form_common.commands.link_to(data.id));
commands.push(form_common.commands.update(data.id, data));
} else {
commands.push(form_common.commands.create(data));
}
});
var self = this;
this.field_manager.set_values({'timesheet_ids': commands}).done(function() {
self.updating = false;
});
},
My code: 1st attempt
And this is mine:
update_order_line_js: function() {
if(this.querying) {
return;
}
this.updating = true;
var commands = [form_common.commands.delete_all()];
_.each(this.get('order_line_js'), function (_data) {
var data = _.clone(_data);
if(data.id) {
commands.push(form_common.commands.link_to(data.id));
commands.push(form_common.commands.update(data.id, data));
} else {
commands.push(form_common.commands.create(data));
}
});
var self = this;
this.field_manager.set_values({'order_line': commands}).done(function() {
self.updating = false;
});
},
The error
As you can see, I have only changed the variable names, and order_line_js
contains sale.order.line
data such as sheets
contains account.analytic.line
data.
But when update_order_line_js
is called, the following line fails:
this.field_manager.set_values({'order_line': commands}).done(function() {
self.updating = false;
});
And throws me this error:
Unknown field qty_invoiced in domain ["|",["qty_invoiced",">",0],["procurement_ids","!=",[]]]
NOTE: If I remove the line commands.push(form_common.commands.create(data));
, which is in the else
statement, the error disappears.
Example
For example, I have a sale order with only a sale order line. The line has ID 28. When I add manually a new line to O2M order_line
, update_order_line_js
is called and the content of commands
just before the error is the following one:
[
[5, false, false],
[0, false, {
analytic_tag_ids: [],
customer_lead: 0,
discount: 0,
invoice_status: "no",
layout_category_id: false,
name: "[CONS_DEL03] Basic Computer Dvorak keyboard left-handed mouse",
price_unit: 23500,
procurement_ids: [],
product_id: 32,
product_uom: 1,
product_uom_qty: 1,
qty_delivered: 0,
qty_delivered_updateable: true,
sequence: 13,
state: "draft",
tax_id: []
}],
[4, 28, false],
[1, 28, {
analytic_tag_ids: [],
company_id: [1, "AnubĂa Soluciones en la Nube, S.L."],
create_date: "2018-10-30 09:03:34",
create_uid: [1, "Administrator"],
currency_id: [1, "EUR"],
customer_lead: 0,
discount: 0,
display_name: "Screen X555",
id: 28,
invoice_lines: [],
invoice_status: "to invoice",
layout_category_id: false,
layout_category_sequence: 0,
name: "Screen X555",
order_id: [11, "SO010"],
order_partner_id: [8, "Agrolait"],
price_reduce: 10,
price_reduce_taxexcl: 10,
price_reduce_taxinc: 12.1,
price_subtotal: 10,
price_tax: 2.1,
price_total: 12.1,
price_unit: 10,
procurement_ids: [],
product_id: [44, "Screen X555"],
product_uom: [1, "Unit(s)"],
product_uom_qty: 1,
qty_delivered: 0,
qty_delivered_updateable: true,
qty_invoiced: 0,
qty_to_invoice: 1,
salesman_id: [1, "Administrator"],
sequence: 12,
state: "sale",
tax_id: [1],
write_date: "2018-10-30 09:03:34",
write_uid: [1, "Administrator"]
}]
]
I guess the problem is because the field qty_invoiced
is inside the dictionary of the existing line, but why does it throw an error? I am stuck with this.
My code: 2nd attempt
I have also tried a way using Python, which is calling a Python method from the JS on_click
to update the current One2many of the sale order lines:
JS on_click content
var sale_order_id = self.field_manager.datarecord.id;
var SaleOrder = new Model('sale.order');
SaleOrder.call(
'test', [sale_order_id],
).then(function(result) {
console.log(result);
});
Python method called
@api.model
def test(self, id):
self = self.browse([id])
self.update({
'order_line': [(6, 0, [24, 27])],
})
return True
As you can see, I always replace the current lines with the existing ones (in my testing database) with the IDs 24 and 27, only to try the method. The problem is that the One2many field view is not automatically reloaded, so after clicking on my JS button, I still see the old records, but when I click on Save button, I see the records 24 and 27. Besides, if I click on Discard button, I get a domain error and the old records are overwritten by 24 and 27, ignoring the Discard button functionality. I guess that using update
out of an onchange method does the write
functionality actually (what I cannot understand is the domain error).
My code: 3rd attempt
And because of this, I have tried this too, to update O2M order_line
directly in JS:
self.field_manager.fields['order_line'].viewmanager.views.list.controller.do_delete(
self.field_manager.fields['order_line'].dataset.ids
);
That line works great, but now I need to add the old records with the new data I want. I was searching how to use do_add_record
or do_edit
, but I still do not know which arguments they need and I was wondering if I am making things more complex than they are.
Can anyone recommend me something to achieve what I need or does anyone know why I am getting the qty_invoiced
domain error?