[IMP] web: always use record data for signature widget 'full_name'

For signature field widget, we can set 'full_name' node option, which can be
used to auto fill the sign. However, current implementation for getting data
for field provided in 'full_name' (mainly, a string) has some flaws.

For example :
-In case of m2o fields, the string is not properly fetched due to different
structure than regular 'input' fields
- In case of x2m views inside a form view, field with same name can exist in
both parent record and child records. This is already the case with form view
of res.partner, where 'phone' field is there in both parent's form as well as
children's kanban view (for field 'child_ids').  With current implementation,
if we add signature on the form view, and  set 'phone' as 'full_name' node
option, instead of form view, we will get phone number from 'child_ids'.

This commit improves the behavior by getting data from the 'recordData' instead
of searching them from the DOM. To have recordData in it's latest state, we've
set 'resetOnAnyFieldChange' flag to true.

task-1948364

closes odoo/odoo#33105

Signed-off-by: Martin Geubelle (mge) <mge@openerp.com>
This commit is contained in:
Dharmraj Jhala
2019-05-16 09:15:13 +00:00
committed by Martin Geubelle
parent 7317f174c7
commit 35b778590a
3 changed files with 121 additions and 12 deletions
+8 -12
View File
@@ -116,6 +116,7 @@ var FieldBinarySignature = AbstractFieldBinary.extend({
fieldDependencies: _.extend({}, AbstractFieldBinary.prototype.fieldDependencies, {
__last_update: {type: 'datetime'},
}),
resetOnAnyFieldChange: true,
custom_events: _.extend({}, AbstractFieldBinary.prototype.custom_events, {
upload_signature: '_onUploadSignature',
}),
@@ -231,18 +232,13 @@ var FieldBinarySignature = AbstractFieldBinary.extend({
};
if (this.nodeOptions.full_name) {
var $search = $("[name='" + this.nodeOptions.full_name + "']");
// If full_name correspond to field in read-only mode
var signName = $($search).text();
// If full_name correspond to field to fill
if (!signName && $($search)[0]) {
signName = $($search)[0].value;
}
if (!signName) {
// If full_name is in the recordData. Last option because this value might not be the last value.
signName = this.recordData[this.nodeOptions.full_name] || '';
}
var signName;
if (this.fields[this.nodeOptions.full_name].type === 'many2one') {
// If m2o is empty, it will have falsy value in recordData
signName = this.recordData[this.nodeOptions.full_name] && this.recordData[this.nodeOptions.full_name].data.display_name;
} else {
signName = this.recordData[this.nodeOptions.full_name];
}
nameAndSignatureOptions.defaultName = (signName === '') ? undefined : signName;
}
+112
View File
@@ -0,0 +1,112 @@
odoo.define('web.signature_field_tests', function (require) {
"use strict";
var FormView = require('web.FormView');
var testUtils = require('web.test_utils');
var createView = testUtils.createView;
QUnit.module('fields', {}, function () {
QUnit.module('signature', {
beforeEach: function () {
this.data = {
partner: {
fields: {
display_name: {string: "Name", type: "char" },
product_id: {string: "Product Name", type: "many2one", relation: 'product'},
sign: {string: "Signature", type: "binary"},
},
records: [{
id: 1,
display_name: "Pop's Chock'lit",
product_id: 7,
}],
onchanges: {},
},
product: {
fields: {
name: {string: "Product Name", type: "char"}
},
records: [{
id: 7,
display_name: "Veggie Burger",
}]
},
};
}
}, function () {
QUnit.module('Signature Field');
QUnit.test('Set simple field in "full_name" node option', async function (assert) {
assert.expect(3);
var form = await createView({
View: FormView,
model: 'partner',
res_id: 1,
data: this.data,
arch: '<form>' +
'<field name="display_name"/>' +
'<field name="sign" widget="signature" options="{\'full_name\': \'display_name\'}" />' +
'</form>',
mockRPC: function (route, args) {
if (route === '/web/sign/get_fonts/') {
return Promise.resolve();
}
return this._super(route, args);
},
});
await testUtils.form.clickEdit(form);
assert.containsOnce(form, 'div[name=sign] div.o_signature svg',
"should have a valid signature widget");
// Click on the widget to open signature modal
await testUtils.dom.click(form.$('div[name=sign] div.o_signature'));
assert.strictEqual($('.modal .modal-body a.o_web_sign_auto_button').length, 1,
'should open a modal with "Auto" button');
assert.strictEqual($('.modal .modal-body .o_web_sign_name_input').val(), "Pop's Chock'lit",
'Correct Value should be set in the input for auto drawing the signature');
form.destroy();
});
QUnit.test('Set m2o field in "full_name" node option', async function (assert) {
assert.expect(3);
var form = await createView({
View: FormView,
model: 'partner',
res_id: 1,
data: this.data,
arch: '<form>' +
'<field name="product_id"/>' +
'<field name="sign" widget="signature" options="{\'full_name\': \'product_id\'}" />' +
'</form>',
mockRPC: function (route, args) {
if (route === '/web/sign/get_fonts/') {
return Promise.resolve();
}
return this._super(route, args);
},
});
await testUtils.form.clickEdit(form);
assert.containsOnce(form, 'div[name=sign] div.o_signature svg',
"should have a valid signature widget");
// Click on the widget to open signature modal
await testUtils.dom.click(form.$('div[name=sign] div.o_signature'));
assert.strictEqual($('.modal .modal-body a.o_web_sign_auto_button').length, 1,
'should open a modal with "Auto" button');
assert.strictEqual($('.modal .modal-body .o_web_sign_name_input').val(), "Veggie Burger",
'Correct Value should be set in the input for auto drawing the signature');
form.destroy();
});
});
});
});
+1
View File
@@ -556,6 +556,7 @@
<script type="text/javascript" src="/web/static/tests/fields/relational_fields/field_many2many_tests.js"></script>
<script type="text/javascript" src="/web/static/tests/fields/relational_fields/field_many2one_tests.js"></script>
<script type="text/javascript" src="/web/static/tests/fields/relational_fields/field_one2many_tests.js"></script>
<script type="text/javascript" src="/web/static/tests/fields/signature.js"></script>
<script type="text/javascript" src="/web/static/tests/fields/special_fields.js"></script>
<script type="text/javascript" src="/web/static/tests/fields/upgrade_fields_tests.js"></script>