mirror of https://github.com/OCA/web.git
commit
c15b37dcd3
|
@ -5,6 +5,7 @@ odoo.define("web_widget_one2many_tree_line_duplicate.BasicModel", function(requi
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const BasicModel = require("web.BasicModel");
|
const BasicModel = require("web.BasicModel");
|
||||||
|
const rpc = require("web.rpc");
|
||||||
|
|
||||||
function dateToServer(date) {
|
function dateToServer(date) {
|
||||||
return date
|
return date
|
||||||
|
@ -41,7 +42,8 @@ odoo.define("web_widget_one2many_tree_line_duplicate.BasicModel", function(requi
|
||||||
*/
|
*/
|
||||||
_applyX2ManyChange: function(record, fieldName, command) {
|
_applyX2ManyChange: function(record, fieldName, command) {
|
||||||
if (command.operation === "CLONE") {
|
if (command.operation === "CLONE") {
|
||||||
return this._applyX2ManyChangeOmitOnchange.apply(this, arguments);
|
// Return this._applyX2ManyChangeOmitOnchange.apply(this, arguments);
|
||||||
|
return this._cloneX2Many.apply(this, arguments);
|
||||||
}
|
}
|
||||||
return this._super.apply(this, arguments);
|
return this._super.apply(this, arguments);
|
||||||
},
|
},
|
||||||
|
@ -55,62 +57,81 @@ odoo.define("web_widget_one2many_tree_line_duplicate.BasicModel", function(requi
|
||||||
* @param {Object} options
|
* @param {Object} options
|
||||||
* @returns {Promise}
|
* @returns {Promise}
|
||||||
*/
|
*/
|
||||||
_applyX2ManyChangeOmitOnchange: function(record, fieldName, command, options) {
|
_cloneX2Many: function(record, fieldName, command, options) {
|
||||||
var localID =
|
const localID =
|
||||||
(record._changes && record._changes[fieldName]) ||
|
(record._changes && record._changes[fieldName]) ||
|
||||||
record.data[fieldName];
|
record.data[fieldName];
|
||||||
var list = this.localData[localID];
|
const list = this.localData[localID];
|
||||||
var position = (command && command.position) || "top";
|
const position = (command && command.position) || "bottom";
|
||||||
var viewType = (options && options.viewType) || record.viewType;
|
const viewType = (options && options.viewType) || record.viewType;
|
||||||
var fieldInfo = record.fieldsInfo[viewType][fieldName];
|
const fieldInfo = record.fieldsInfo[viewType][fieldName];
|
||||||
var view = fieldInfo.views && fieldInfo.views[fieldInfo.mode];
|
const record_command = this.get(command.id);
|
||||||
var params = {
|
|
||||||
|
const params = {
|
||||||
fields: list.fields,
|
fields: list.fields,
|
||||||
fieldsInfo: list.fieldsInfo,
|
fieldsInfo: list.fieldsInfo,
|
||||||
parentID: list.id,
|
parentID: list.id,
|
||||||
position: position,
|
position: position,
|
||||||
viewType: view ? view.type : fieldInfo.viewType,
|
|
||||||
allowWarning: options && options.allowWarning,
|
allowWarning: options && options.allowWarning,
|
||||||
|
viewType: viewType,
|
||||||
|
views: fieldInfo.views,
|
||||||
|
clone_parent_record_id: command.id,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (
|
let read_data = Promise.resolve();
|
||||||
command.position === "bottom" &&
|
if (this.isNew(command.id)) {
|
||||||
list.orderedResIDs &&
|
// We need the 'copy_data' of the original parent record
|
||||||
list.orderedResIDs.length >= list.limit
|
if (!_.isEmpty(record_command.clone_data)) {
|
||||||
) {
|
params.clone_copy_data = record_command.clone_copy_data;
|
||||||
list.tempLimitIncrement = (list.tempLimitIncrement || 0) + 1;
|
}
|
||||||
list.limit += 1;
|
} else {
|
||||||
|
// Record state only has loaded data and only for the fields defined in the views.
|
||||||
|
// For this reason we need ensure copy all the model fields.
|
||||||
|
read_data = rpc.query({
|
||||||
|
model: list.model,
|
||||||
|
method: "copy_data",
|
||||||
|
args: [record_command.res_id],
|
||||||
|
kwargs: {context: record.getContext()},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const record_state = this.get(command.id);
|
return read_data.then(result => {
|
||||||
const clone_values = this._getValuesToClone(record_state);
|
const clone_values = _.defaults(
|
||||||
return this._makeDefaultRecordOmitOnchange(list.model, params, clone_values)
|
{},
|
||||||
.then(id => {
|
this._getValuesToClone(record_command, params),
|
||||||
var ids = [id];
|
result
|
||||||
list._changes = list._changes || [];
|
);
|
||||||
list._changes.push({
|
return this._makeCloneRecord(list.model, params, clone_values)
|
||||||
operation: "ADD",
|
.then(id => {
|
||||||
id: id,
|
const ids = [id];
|
||||||
position: position,
|
list._changes = list._changes || [];
|
||||||
isNew: true,
|
list._changes.push({
|
||||||
|
operation: "ADD",
|
||||||
|
id: id,
|
||||||
|
position: position,
|
||||||
|
isNew: true,
|
||||||
|
});
|
||||||
|
const record = this.localData[id];
|
||||||
|
list._cache[record.res_id] = id;
|
||||||
|
if (list.orderedResIDs) {
|
||||||
|
const index =
|
||||||
|
list.offset + (position !== "top" ? list.limit : 0);
|
||||||
|
list.orderedResIDs.splice(index, 0, record.res_id);
|
||||||
|
// List could be a copy of the original one
|
||||||
|
this.localData[list.id].orderedResIDs = list.orderedResIDs;
|
||||||
|
}
|
||||||
|
return ids;
|
||||||
|
})
|
||||||
|
.then(ids => {
|
||||||
|
this._readUngroupedList(list).then(() => {
|
||||||
|
const x2ManysDef = this._fetchX2ManysBatched(list);
|
||||||
|
const referencesDef = this._fetchReferencesBatched(list);
|
||||||
|
return Promise.all([x2ManysDef, referencesDef]).then(
|
||||||
|
() => ids
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
var record = this.localData[id];
|
});
|
||||||
list._cache[record.res_id] = id;
|
|
||||||
if (list.orderedResIDs) {
|
|
||||||
var index = list.offset + (position !== "top" ? list.limit : 0);
|
|
||||||
list.orderedResIDs.splice(index, 0, record.res_id);
|
|
||||||
// List could be a copy of the original one
|
|
||||||
this.localData[list.id].orderedResIDs = list.orderedResIDs;
|
|
||||||
}
|
|
||||||
return ids;
|
|
||||||
})
|
|
||||||
.then(ids => {
|
|
||||||
this._readUngroupedList(list).then(() => {
|
|
||||||
var x2ManysDef = this._fetchX2ManysBatched(list);
|
|
||||||
var referencesDef = this._fetchReferencesBatched(list);
|
|
||||||
return Promise.all([x2ManysDef, referencesDef]).then(() => ids);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -160,20 +181,18 @@ 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));
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
_makeCloneRecord: function(modelName, params, values) {
|
||||||
* Modified implementation of '_makeDefaultRecord' to allow create
|
|
||||||
* without trigger onchanges/default values
|
|
||||||
*
|
|
||||||
* @param {String} modelName
|
|
||||||
* @param {Object} params
|
|
||||||
* @param {Object} values
|
|
||||||
* @returns {Promise}
|
|
||||||
*/
|
|
||||||
_makeDefaultRecordOmitOnchange: function(modelName, params, values) {
|
|
||||||
const targetView = params.viewType;
|
const targetView = params.viewType;
|
||||||
let fields = params.fields;
|
let fields = params.fields;
|
||||||
const fieldsInfo = params.fieldsInfo;
|
const fieldsInfo = params.fieldsInfo;
|
||||||
let fieldNames = Object.keys(fieldsInfo[targetView]);
|
|
||||||
|
// Get available fields
|
||||||
|
for (const view_type in params.views) {
|
||||||
|
fields = _.defaults({}, fields, params.views[view_type].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 =
|
||||||
|
@ -202,6 +221,11 @@ odoo.define("web_widget_one2many_tree_line_duplicate.BasicModel", function(requi
|
||||||
res_ids: params.res_ids,
|
res_ids: params.res_ids,
|
||||||
viewType: targetView,
|
viewType: targetView,
|
||||||
});
|
});
|
||||||
|
// Extend dataPoint with clone info
|
||||||
|
record.clone_data = {
|
||||||
|
record_parent_id: params.clone_parent_record_id,
|
||||||
|
copy_data: params.clone_copy_data || values,
|
||||||
|
};
|
||||||
|
|
||||||
// We want to overwrite the default value of the handle field (if any),
|
// We want to overwrite the default value of the handle field (if any),
|
||||||
// in order for new lines to be added at the correct position.
|
// in order for new lines to be added at the correct position.
|
||||||
|
@ -236,9 +260,10 @@ odoo.define("web_widget_one2many_tree_line_duplicate.BasicModel", function(requi
|
||||||
* Get the values formatted to clone
|
* Get the values formatted to clone
|
||||||
*
|
*
|
||||||
* @param {Object} line_state
|
* @param {Object} line_state
|
||||||
|
* @param {Object} params
|
||||||
* @returns {Object}
|
* @returns {Object}
|
||||||
*/
|
*/
|
||||||
_getValuesToClone: function(line_state) {
|
_getValuesToClone: function(line_state, params) {
|
||||||
const values_to_clone = {};
|
const values_to_clone = {};
|
||||||
const line_data = line_state.data;
|
const line_data = line_state.data;
|
||||||
for (const field_name in line_data) {
|
for (const field_name in line_data) {
|
||||||
|
@ -246,7 +271,7 @@ odoo.define("web_widget_one2many_tree_line_duplicate.BasicModel", function(requi
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const value = line_data[field_name];
|
const value = line_data[field_name];
|
||||||
const field_info = line_state.fields[field_name];
|
const field_info = params.fields[field_name];
|
||||||
if (!field_info) {
|
if (!field_info) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -255,12 +280,23 @@ odoo.define("web_widget_one2many_tree_line_duplicate.BasicModel", function(requi
|
||||||
} else if (field_info.type === "many2one") {
|
} else if (field_info.type === "many2one") {
|
||||||
const rec_id = value.data && value.data.id;
|
const rec_id = value.data && value.data.id;
|
||||||
values_to_clone[field_name] = rec_id || false;
|
values_to_clone[field_name] = rec_id || false;
|
||||||
} else if (
|
} else if (field_info.type === "many2many") {
|
||||||
field_info.type === "many2many" ||
|
values_to_clone[field_name] = [
|
||||||
field_info.type === "one2many"
|
[
|
||||||
) {
|
6,
|
||||||
|
0,
|
||||||
|
_.map(value.data || [], item => {
|
||||||
|
return item.data.id;
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
];
|
||||||
|
} else if (field_info.type === "one2many") {
|
||||||
values_to_clone[field_name] = _.map(value.data || [], item => {
|
values_to_clone[field_name] = _.map(value.data || [], item => {
|
||||||
return item.data.id;
|
return [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
this._getValuesToClone(item, {fields: value.fields}),
|
||||||
|
];
|
||||||
});
|
});
|
||||||
} else if (
|
} else if (
|
||||||
field_info.type === "date" ||
|
field_info.type === "date" ||
|
||||||
|
@ -273,5 +309,14 @@ odoo.define("web_widget_one2many_tree_line_duplicate.BasicModel", function(requi
|
||||||
}
|
}
|
||||||
return values_to_clone;
|
return values_to_clone;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_generateChanges: function(record) {
|
||||||
|
let res = this._super.apply(this, arguments);
|
||||||
|
if (!_.isEmpty(record.clone_data)) {
|
||||||
|
// If a cloned record, ensure that all fields are written (and not only the view fields)
|
||||||
|
res = _.extend({}, record.clone_data.copy_data, res);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -130,7 +130,7 @@ odoo.define(
|
||||||
this._setValue(
|
this._setValue(
|
||||||
{
|
{
|
||||||
operation: "CLONE", // This operation is a special case implemented only in this module
|
operation: "CLONE", // This operation is a special case implemented only in this module
|
||||||
position: this.editable || data.forceEditable,
|
position: "bottom",
|
||||||
context: data.context,
|
context: data.context,
|
||||||
id: ev.data.id,
|
id: ev.data.id,
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue