3
0
Fork 0

[FIX] web_widget_one2many_tree_line_duplicate: cloned record relations

On the cloned record we were unable to change the values of the
relational fields we we just had edited it. Here is solved adding a
pseudo onchange method that triggers the proper refreshed values as if
the record was made manually.

TT38191
16.0
david 2022-08-04 08:59:33 +02:00 committed by Carlos Roca
parent 65d984f538
commit b0d1dd59b7
4 changed files with 130 additions and 47 deletions

View File

@ -2,10 +2,13 @@
Web Widget One2many Tree Line Duplicate Web Widget One2many Tree Line Duplicate
======================================= =======================================
.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !! !! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !! !! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:9cd7a43eab907d7d3ed3380c20cda1be40d288c01feb25dd54108e69cb350314
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status :target: https://odoo-community.org/page/development-status
@ -19,11 +22,11 @@ Web Widget One2many Tree Line Duplicate
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/web-13-0/web-13-0-web_widget_one2many_tree_line_duplicate :target: https://translation.odoo-community.org/projects/web-13-0/web-13-0-web_widget_one2many_tree_line_duplicate
:alt: Translate me on Weblate :alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runbot.odoo-community.org/runbot/162/13.0 :target: https://runboat.odoo-community.org/builds?repo=OCA/web&target_branch=13.0
:alt: Try me on Runbot :alt: Try me on Runboat
|badge1| |badge2| |badge3| |badge4| |badge5| |badge1| |badge2| |badge3| |badge4| |badge5|
Allow to add a icon to clone the line. Allow to add a icon to clone the line.
@ -57,7 +60,7 @@ Bug Tracker
Bugs are tracked on `GitHub Issues <https://github.com/OCA/web/issues>`_. Bugs are tracked on `GitHub Issues <https://github.com/OCA/web/issues>`_.
In case of trouble, please check there if your issue has already been reported. In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/web/issues/new?body=module:%20web_widget_one2many_tree_line_duplicate%0Aversion:%2013.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_. `feedback <https://github.com/OCA/web/issues/new?body=module:%20web_widget_one2many_tree_line_duplicate%0Aversion:%2013.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues. Do not contact contributors directly about support or help with technical issues.

View File

@ -4,7 +4,7 @@
{ {
"name": "Web Widget One2many Tree Line Duplicate", "name": "Web Widget One2many Tree Line Duplicate",
"category": "web", "category": "web",
"version": "13.0.1.0.1", "version": "13.0.1.0.2",
"author": "Tecnativa, Odoo Community Association (OCA)", "author": "Tecnativa, Odoo Community Association (OCA)",
"license": "AGPL-3", "license": "AGPL-3",
"website": "https://github.com/OCA/web", "website": "https://github.com/OCA/web",

View File

@ -1,20 +1,20 @@
<?xml version="1.0" encoding="utf-8" ?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.15.1: http://docutils.sourceforge.net/" /> <meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
<title>Web Widget One2many Tree Line Duplicate</title> <title>Web Widget One2many Tree Line Duplicate</title>
<style type="text/css"> <style type="text/css">
/* /*
:Author: David Goodger (goodger@python.org) :Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 7952 2016-07-26 18:15:59Z milde $ :Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $
:Copyright: This stylesheet has been placed in the public domain. :Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils. Default cascading style sheet for the HTML output of Docutils.
See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet. customize this style sheet.
*/ */
@ -366,25 +366,27 @@ ul.auto-toc {
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! <!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !! !! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !! !! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:9cd7a43eab907d7d3ed3380c20cda1be40d288c01feb25dd54108e69cb350314
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/OCA/web/tree/13.0/web_widget_one2many_tree_line_duplicate"><img alt="OCA/web" src="https://img.shields.io/badge/github-OCA%2Fweb-lightgray.png?logo=github" /></a> <a class="reference external" href="https://translation.odoo-community.org/projects/web-13-0/web-13-0-web_widget_one2many_tree_line_duplicate"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external" href="https://runbot.odoo-community.org/runbot/162/13.0"><img alt="Try me on Runbot" src="https://img.shields.io/badge/runbot-Try%20me-875A7B.png" /></a></p> <p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/web/tree/13.0/web_widget_one2many_tree_line_duplicate"><img alt="OCA/web" src="https://img.shields.io/badge/github-OCA%2Fweb-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/web-13-0/web-13-0-web_widget_one2many_tree_line_duplicate"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/web&amp;target_branch=13.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>Allow to add a icon to clone the line.</p> <p>Allow to add a icon to clone the line.</p>
<p><strong>Table of contents</strong></p> <p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents"> <div class="contents local topic" id="contents">
<ul class="simple"> <ul class="simple">
<li><a class="reference internal" href="#usage" id="id1">Usage</a></li> <li><a class="reference internal" href="#usage" id="toc-entry-1">Usage</a></li>
<li><a class="reference internal" href="#known-issues-roadmap" id="id2">Known issues / Roadmap</a></li> <li><a class="reference internal" href="#known-issues-roadmap" id="toc-entry-2">Known issues / Roadmap</a></li>
<li><a class="reference internal" href="#bug-tracker" id="id3">Bug Tracker</a></li> <li><a class="reference internal" href="#bug-tracker" id="toc-entry-3">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="id4">Credits</a><ul> <li><a class="reference internal" href="#credits" id="toc-entry-4">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="id5">Authors</a></li> <li><a class="reference internal" href="#authors" id="toc-entry-5">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="id6">Contributors</a></li> <li><a class="reference internal" href="#contributors" id="toc-entry-6">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="id7">Maintainers</a></li> <li><a class="reference internal" href="#maintainers" id="toc-entry-7">Maintainers</a></li>
</ul> </ul>
</li> </li>
</ul> </ul>
</div> </div>
<div class="section" id="usage"> <div class="section" id="usage">
<h1><a class="toc-backref" href="#id1">Usage</a></h1> <h1><a class="toc-backref" href="#toc-entry-1">Usage</a></h1>
<p>This module works on all one2many tree views. The cloning process doesnt trigger onchange/default calls.</p> <p>This module works on all one2many tree views. The cloning process doesnt trigger onchange/default calls.</p>
<p><strong>Available Options</strong></p> <p><strong>Available Options</strong></p>
<ul class="simple"> <ul class="simple">
@ -392,33 +394,33 @@ ul.auto-toc {
</ul> </ul>
<p><strong>Examples</strong></p> <p><strong>Examples</strong></p>
<pre class="code xml literal-block"> <pre class="code xml literal-block">
<span class="nt">&lt;field</span> <span class="na">name=</span><span class="s">&quot;order_line&quot;</span> <span class="na">widget=</span><span class="s">&quot;section_and_note_one2many&quot;</span> <span class="na">mode=</span><span class="s">&quot;tree,kanban&quot;</span> <span class="na">options=</span><span class="s">&quot;{'allow_clone': True}&quot;</span> <span class="na">attrs=</span><span class="s">&quot;{'readonly': [('state', 'in', ('done','cancel'))]}&quot;</span><span class="nt">&gt;</span> <span class="nt">&lt;field</span><span class="w"> </span><span class="na">name=</span><span class="s">&quot;order_line&quot;</span><span class="w"> </span><span class="na">widget=</span><span class="s">&quot;section_and_note_one2many&quot;</span><span class="w"> </span><span class="na">mode=</span><span class="s">&quot;tree,kanban&quot;</span><span class="w"> </span><span class="na">options=</span><span class="s">&quot;{'allow_clone': True}&quot;</span><span class="w"> </span><span class="na">attrs=</span><span class="s">&quot;{'readonly': [('state', 'in', ('done','cancel'))]}&quot;</span><span class="nt">&gt;</span>
</pre> </pre>
</div> </div>
<div class="section" id="known-issues-roadmap"> <div class="section" id="known-issues-roadmap">
<h1><a class="toc-backref" href="#id2">Known issues / Roadmap</a></h1> <h1><a class="toc-backref" href="#toc-entry-2">Known issues / Roadmap</a></h1>
<ul class="simple"> <ul class="simple">
<li>Add an option to control which columns are copied</li> <li>Add an option to control which columns are copied</li>
</ul> </ul>
</div> </div>
<div class="section" id="bug-tracker"> <div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#id3">Bug Tracker</a></h1> <h1><a class="toc-backref" href="#toc-entry-3">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/web/issues">GitHub Issues</a>. <p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/web/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported. In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed If you spotted it first, help us to smash it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/OCA/web/issues/new?body=module:%20web_widget_one2many_tree_line_duplicate%0Aversion:%2013.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p> <a class="reference external" href="https://github.com/OCA/web/issues/new?body=module:%20web_widget_one2many_tree_line_duplicate%0Aversion:%2013.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p> <p>Do not contact contributors directly about support or help with technical issues.</p>
</div> </div>
<div class="section" id="credits"> <div class="section" id="credits">
<h1><a class="toc-backref" href="#id4">Credits</a></h1> <h1><a class="toc-backref" href="#toc-entry-4">Credits</a></h1>
<div class="section" id="authors"> <div class="section" id="authors">
<h2><a class="toc-backref" href="#id5">Authors</a></h2> <h2><a class="toc-backref" href="#toc-entry-5">Authors</a></h2>
<ul class="simple"> <ul class="simple">
<li>Tecnativa</li> <li>Tecnativa</li>
</ul> </ul>
</div> </div>
<div class="section" id="contributors"> <div class="section" id="contributors">
<h2><a class="toc-backref" href="#id6">Contributors</a></h2> <h2><a class="toc-backref" href="#toc-entry-6">Contributors</a></h2>
<ul class="simple"> <ul class="simple">
<li><a class="reference external" href="https://www.tecnativa.com/">Tecnativa</a>:<ul> <li><a class="reference external" href="https://www.tecnativa.com/">Tecnativa</a>:<ul>
<li>Alexandre Díaz</li> <li>Alexandre Díaz</li>
@ -427,7 +429,7 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
</ul> </ul>
</div> </div>
<div class="section" id="maintainers"> <div class="section" id="maintainers">
<h2><a class="toc-backref" href="#id7">Maintainers</a></h2> <h2><a class="toc-backref" href="#toc-entry-7">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p> <p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a> <a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose <p>OCA, or the Odoo Community Association, is a nonprofit organization whose

View File

@ -62,6 +62,7 @@ odoo.define("web_widget_one2many_tree_line_duplicate.BasicModel", function(requi
(record._changes && record._changes[fieldName]) || (record._changes && record._changes[fieldName]) ||
record.data[fieldName]; record.data[fieldName];
const list = this.localData[localID]; const list = this.localData[localID];
const context = _.extend({}, this._getContext(list));
const position = (command && command.position) || "bottom"; const position = (command && command.position) || "bottom";
const viewType = (options && options.viewType) || record.viewType; const viewType = (options && options.viewType) || record.viewType;
const fieldInfo = record.fieldsInfo[viewType][fieldName]; const fieldInfo = record.fieldsInfo[viewType][fieldName];
@ -92,6 +93,7 @@ odoo.define("web_widget_one2many_tree_line_duplicate.BasicModel", function(requi
}); });
const params = { const params = {
context: context,
fields: list.fields, fields: list.fields,
fieldsInfo: list.fieldsInfo, fieldsInfo: list.fieldsInfo,
parentID: list.id, parentID: list.id,
@ -135,12 +137,12 @@ odoo.define("web_widget_one2many_tree_line_duplicate.BasicModel", function(requi
position: position, position: position,
isNew: true, isNew: true,
}); });
const record = this.localData[id]; const local_record = this.localData[id];
list._cache[record.res_id] = id; list._cache[local_record.res_id] = id;
if (list.orderedResIDs) { if (list.orderedResIDs) {
const index = const index =
list.offset + (position !== "top" ? list.limit : 0); list.offset + (position !== "top" ? list.limit : 0);
list.orderedResIDs.splice(index, 0, record.res_id); list.orderedResIDs.splice(index, 0, local_record.res_id);
// List could be a copy of the original one // List could be a copy of the original one
this.localData[list.id].orderedResIDs = list.orderedResIDs; this.localData[list.id].orderedResIDs = list.orderedResIDs;
} }
@ -205,6 +207,62 @@ odoo.define("web_widget_one2many_tree_line_duplicate.BasicModel", function(requi
return Promise.all(defs).then(() => _.keys(changes)); return Promise.all(defs).then(() => _.keys(changes));
}, },
/**
* Modified implementation of '_performOnChange' to properly unfold the cloned
* record properties son we can interact with it as if we'd created it. We
* don't really do an onchange and the only fields that we're getting are those
* relational.
*
* @param {Object} record
* @param {String} [viewType] current viewType. If not set, we will assume
* main viewType from the record
* @returns {Promise}
*/
_pseudoOnChange: function(record, viewType) {
var self = this;
var onchangeSpec = this._buildOnchangeSpecs(record, viewType);
if (!onchangeSpec) {
return Promise.resolve();
}
var idList = record.data.id ? [record.data.id] : [];
var options = {
full: true,
};
var context = this._getContext(record, options);
var currentData = this._generateOnChangeData(record, {changesOnly: false});
return self
._rpc({
model: record.model,
method: "onchange",
args: [idList, currentData, [], onchangeSpec],
context: context,
})
.then(function(result) {
if (!record._changes) {
// If the _changes key does not exist anymore, it means that
// it was removed by discarding the changes after the rpc
// to onchange. So, in that case, the proper response is to
// ignore the onchange.
return;
}
if (result.warning) {
self.trigger_up("warning", result.warning);
record._warning = true;
}
if (result.domain) {
record._domains = _.extend(record._domains, result.domain);
}
// We're only interested in relational fields
const values = _.pick(result.value, v => {
return typeof v === "object";
});
return self._applyOnChange(values, record).then(function() {
return result;
});
});
},
_makeCloneRecord: function(modelName, params, values) { _makeCloneRecord: function(modelName, params, values) {
const targetView = params.viewType; const targetView = params.viewType;
let fields = params.fields; let fields = params.fields;
@ -214,9 +272,7 @@ odoo.define("web_widget_one2many_tree_line_duplicate.BasicModel", function(requi
for (const view_type in params.views) { for (const view_type in params.views) {
fields = _.defaults({}, fields, params.views[view_type].fields); fields = _.defaults({}, fields, params.views[view_type].fields);
} }
let fieldNames = Object.keys(fields); let fieldNames = Object.keys(fields);
// Fields that are present in the originating view, that need to be initialized // Fields that are present in the originating view, that need to be initialized
// Hence preventing their value to crash when getting back to the originating view // Hence preventing their value to crash when getting back to the originating view
const parentRecord = const parentRecord =
@ -264,20 +320,42 @@ odoo.define("web_widget_one2many_tree_line_duplicate.BasicModel", function(requi
if (overrideDefaultFields) { if (overrideDefaultFields) {
values[overrideDefaultFields.field] = overrideDefaultFields.value; values[overrideDefaultFields.field] = overrideDefaultFields.value;
} }
const _this = this;
return this.applyDefaultValues(record.id, values, {fieldNames: fieldNames}) return (
.then(() => { this.applyDefaultValues(record.id, values, {fieldNames: fieldNames})
return this._fetchRelationalData(record); // This will ensure we refresh the proper properties
}) .then(() => {
.then(() => { var def = new Promise(function(resolve, reject) {
return this._postprocess(record); var always = function() {
}) if (record._warning) {
.then(() => { if (params.allowWarning) {
// Save initial changes, so they can be restored later, delete record._warning;
// if we need to discard. } else {
this.save(record.id, {savePoint: true}); reject();
return record.id; }
}); }
resolve();
};
_this
._pseudoOnChange(record, targetView)
.then(always)
.guardedCatch(always);
});
return def;
})
.then(() => {
return this._fetchRelationalData(record);
})
.then(() => {
return this._postprocess(record);
})
.then(() => {
// Save initial changes, so they can be restored later,
// if we need to discard.
this.save(record.id, {savePoint: true});
return record.id;
})
);
}, },
/** /**