[FIX] sale,*: product_configurator: can drag&drop row

*sale_product_configurator

Since commit 50bf830, a crash occurred when a row containing a
many2one displayed with widget 'product_configurator' was dragged
and dropped.

For instance, open a quotation with at least two rows, and drag and
drop one of them.

Issue reported on task 2206228

closes odoo/odoo#48128

X-original-commit: d9c35b40b7df588f9e81142a2b272d9c7da06e04
Signed-off-by: Lucas Perais (lpe) <lpe@odoo.com>
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
This commit is contained in:
Aaron Bohy
2020-03-20 15:44:47 +00:00
parent fd113d48a2
commit 25aaf7afcf
5 changed files with 153 additions and 5 deletions
@@ -116,7 +116,7 @@ var ProductConfiguratorWidget = relationalFields.FieldMany2One.extend({
*/
reset: async function (record, ev) {
await this._super(...arguments);
if (ev.target === this) {
if (ev && ev.target === this) {
if (ev.data.changes && !ev.data.preventProductIdCheck && ev.data.changes.product_template_id) {
this._onTemplateChange(record.data.product_template_id.data.id, ev.data.dataPointID);
} else if (ev.data.changes && ev.data.changes.product_id) {
@@ -0,0 +1,100 @@
odoo.define('sale.product_configurator_tests', function (require) {
"use strict";
const FormView = require('web.FormView');
const testUtils = require('web.test_utils');
const createView = testUtils.createView;
QUnit.module('product_configurator', {
beforeEach: function () {
this.data = {
order: {
fields: {
line_ids: {
string: "Lines",
type: 'one2many',
relation: 'line',
relation_field: 'order_id'
},
},
records: [
{id: 1, line_ids: [1, 2]},
],
},
line: {
fields: {
product_id: {
string: "Product",
type: 'many2one',
relation: 'product',
},
order_id: {
string: "Order",
type: 'many2one',
relation: 'order'
},
sequence: {
string: "Sequence",
type: 'number',
},
},
records: [
{id: 1, sequence: 4, product_id: 3, order_id: 1},
{id: 2, sequence: 14, product_id: 4, order_id: 1},
]
},
product: {
fields: {
name: {
string: "Name",
type: 'char',
},
},
records: [
{id: 3, name: "Chair"},
{id: 4, name: "Table"},
],
},
};
},
}, function () {
QUnit.test('drag and drop rows containing product_configurator many2one', async function (assert) {
assert.expect(4);
const form = await createView({
View: FormView,
model: 'order',
data: this.data,
arch: `
<form>
<field name="line_ids"/>
</form>`,
archs: {
'line,false,list': `
<tree editable="bottom">
<field name="sequence" widget="handle"/>
<field name="product_id" widget="product_configurator"/>
</tree>`,
},
res_id: 1,
viewOptions: {
mode: 'edit',
},
});
assert.containsN(form, '.o_data_row', 2);
assert.strictEqual(form.$('.o_data_row').text(), 'ChairTable');
assert.containsN(form, '.o_data_row .o_row_handle', 2);
// move first row below second
const $firstHandle = form.$('.o_data_row:nth(0) .o_row_handle');
const $secondHandle = form.$('.o_data_row:nth(1) .o_row_handle');
await testUtils.dom.dragAndDrop($firstHandle, $secondHandle);
assert.strictEqual(form.$('.o_data_row').text(), 'TableChair');
form.destroy();
});
});
});
+1
View File
@@ -31,6 +31,7 @@
</template>
<template id="qunit_suite" name="sale_tests" inherit_id="web.qunit_suite">
<xpath expr="//t[@t-set='head']" position="inside">
<script type="text/javascript" src="/sale/static/tests/product_configurator_tests.js"></script>
<script type="text/javascript" src="/sale/static/tests/sales_team_dashboard_tests.js"></script>
</xpath>
</template>
@@ -34,7 +34,7 @@ ProductConfiguratorWidget.include({
* @private
*/
reset: function (record, ev) {
if (ev.target === this) {
if (ev && ev.target === this) {
this.restoreProductTemplateId = this.recordData.product_template_id;
this.optionalProducts = (ev.data && ev.data.optionalProducts) || this.optionalProducts;
}
@@ -82,7 +82,8 @@ QUnit.module('Product Configurator', {
type: 'one2many',
relation: 'product_custom_attribute_value'
},
product_uom_qty: {type: 'integer'}
product_uom_qty: {type: 'integer'},
sequence: {type: 'integer'},
}
},
product_custom_attribute_value: {
@@ -136,7 +137,7 @@ QUnit.module('Product Configurator', {
}
};
}
}, function (){
}, function () {
QUnit.test('Select a non configurable product template and verify that the product_id is correctly set', async function (assert) {
assert.expect(2);
@@ -225,7 +226,7 @@ QUnit.module('Product Configurator', {
form.destroy();
});
QUnit.test('Select a product in the list and check for template loading', async function (assert){
QUnit.test('Select a product in the list and check for template loading', async function (assert) {
assert.expect(1);
var product_configurator_form = await createView({
@@ -257,6 +258,52 @@ QUnit.module('Product Configurator', {
await testUtils.dom.click($("ul.ui-autocomplete li a:contains('Customizable Desk')").mouseenter());
product_configurator_form.destroy();
});
QUnit.test('drag and drop rows containing product_configurator many2one', async function (assert) {
assert.expect(4);
this.data.sale_order.records = [
{ id: 1, sale_order_line: [1, 2] }
];
this.data.sale_order_line.records = [
{ id: 1, sequence: 5, product_id: 1 },
{ id: 2, sequence: 15, product_id: 2 },
];
const form = await createView({
View: FormView,
model: 'sale_order',
data: this.data,
arch: `
<form>
<field name="sale_order_line"/>
</form>`,
archs: {
'sale_order_line,false,list': `
<tree editable="bottom">
<field name="sequence" widget="handle"/>
<field name="product_id" widget="product_configurator"/>
</tree>`,
},
res_id: 1,
viewOptions: {
mode: 'edit',
},
});
assert.containsN(form, '.o_data_row', 2);
assert.strictEqual(form.$('.o_data_row').text(), 'Customizable Desk (1)Customizable Desk (2)');
assert.containsN(form, '.o_data_row .o_row_handle', 2);
// move first row below second
const $firstHandle = form.$('.o_data_row:nth(0) .o_row_handle');
const $secondHandle = form.$('.o_data_row:nth(1) .o_row_handle');
await testUtils.dom.dragAndDrop($firstHandle, $secondHandle);
assert.strictEqual(form.$('.o_data_row').text(), 'Customizable Desk (2)Customizable Desk (1)');
form.destroy();
});
});
});