diff options
| author | Géry Debongnie <ged@odoo.com> | 2017-03-05 09:34:56 +0100 |
|---|---|---|
| committer | Aaron Bohy <aab@odoo.com> | 2017-04-11 19:44:38 +0200 |
| commit | e5740270568404d71a3bc093074a085c9c2eded8 (patch) | |
| tree | 7b84740d92c550236de25a37cf37d244760bdbf3 /addons/web/static/src/js/views/basic | |
| parent | 0df9968433389e0d504276cd711473c2eef937ae (diff) | |
[REF] web,*: remove 'web.model' and 'web.dataModel
Use this.rpc instead of Model object, with web.ajax if necessary.
nb: EventDispatcherMixin include now the custom_events managment instead
of widget
Diffstat (limited to 'addons/web/static/src/js/views/basic')
| -rw-r--r-- | addons/web/static/src/js/views/basic/basic_model.js | 983 |
1 files changed, 497 insertions, 486 deletions
diff --git a/addons/web/static/src/js/views/basic/basic_model.js b/addons/web/static/src/js/views/basic/basic_model.js index a66e3a9d3ab..5c0facecef1 100644 --- a/addons/web/static/src/js/views/basic/basic_model.js +++ b/addons/web/static/src/js/views/basic/basic_model.js @@ -182,7 +182,7 @@ var BasicModel = AbstractModel.extend({ }); }, /** - * Delete a list of records, then, if a parent_id is given, reload the + * Delete a list of records, then, if a parentID is given, reload the * parent. * * @todo we should remove the deleted records from the localData @@ -193,24 +193,26 @@ var BasicModel = AbstractModel.extend({ * @param {string[]} recordIds list of local resources ids. They should all * be of type 'record', and of the same model * @param {string} modelName - * @param {string} parent_id + * @param {string} parentID * @returns {Deferred} */ - deleteRecords: function (recordIds, modelName, parent_id) { + deleteRecords: function (recordIds, modelName, parentID) { var self = this; var records = _.map(recordIds, function (id) { return self.localData[id]; }); - return this.performModelRPC(modelName, 'unlink', [_.pluck(records, 'res_id')], { - context: session.user_context, // todo: combine with view context - }).then(function () { - _.each(records, function (record) { - record.res_ids.splice(record.offset, 1)[0]; - record.res_id = record.res_ids[record.offset]; - record.count--; + return this.rpc(modelName, 'unlink') + .args([_.pluck(records, 'res_id')]) + .withContext(session.user_context) // todo: combine with view context + .exec() + .then(function () { + _.each(records, function (record) { + record.res_ids.splice(record.offset, 1)[0]; + record.res_id = record.res_ids[record.offset]; + record.count--; + }); + if (parentID) { + return self.reload(parentID); + } }); - if (parent_id) { - return self.reload(parent_id); - } - }); }, /** * Discard all changes in a local resource. Basically, it removes @@ -233,20 +235,22 @@ var BasicModel = AbstractModel.extend({ duplicateRecord: function (recordID) { var self = this; var record = this.localData[recordID]; - return this.performModelRPC(record.model, 'copy', [record.data.id], { - context: this._getContext(record), - }).then(function (res_id) { - var index = record.res_ids.indexOf(record.res_id); - record.res_ids.splice(index + 1, 0, res_id); - return self.load({ - fieldAttrs: record.fieldAttrs, - fieldNames: record.fieldNames, - fields: record.fields, - modelName: record.model, - res_id: res_id, - res_ids: record.res_ids.slice(0), + return this.rpc(record.model, 'copy') + .args([record.data.id]) + .withContext(this._getContext(record)) + .exec() + .then(function (res_id) { + var index = record.res_ids.indexOf(record.res_id); + record.res_ids.splice(index + 1, 0, res_id); + return self.load({ + fieldAttrs: record.fieldAttrs, + fieldNames: record.fieldNames, + fields: record.fields, + modelName: record.model, + res_id: res_id, + res_ids: record.res_ids.slice(0), + }); }); - }); }, /** * The get method first argument is the handle returned by the load method. @@ -442,156 +446,158 @@ var BasicModel = AbstractModel.extend({ var self = this; var fields_key = _.without(params.fieldNames, '__last_update'); - return this.performModelRPC(modelName, 'default_get', [fields_key], { - context: params.context, - }).then(function (result) { - // fill default values for missing fields - for (var i = 0; i < params.fieldNames.length; i++) { - var fieldName = params.fieldNames[i]; - if (!(fieldName in result)) { - var field = params.fields[fieldName]; - if (field.type === 'one2many' || field.type === 'many2many') { - result[fieldName] = []; - } else { - result[fieldName] = null; + return this.rpc(modelName, 'default_get') + .args([fields_key]) + .withContext(params.context) + .exec() + .then(function (result) { + // fill default values for missing fields + for (var i = 0; i < params.fieldNames.length; i++) { + var fieldName = params.fieldNames[i]; + if (!(fieldName in result)) { + var field = params.fields[fieldName]; + if (field.type === 'one2many' || field.type === 'many2many') { + result[fieldName] = []; + } else { + result[fieldName] = null; + } } } - } - var data = {}; - var record = self._makeDataPoint({ - modelName: modelName, - data: data, - fields: params.fields, - fieldNames: params.fieldNames, - fieldAttrs: params.fieldAttrs, - context: params.context, - parentID: params.parentID, - relationField: params.relationField, - res_ids: params.res_ids, - }); + var data = {}; + var record = self._makeDataPoint({ + modelName: modelName, + data: data, + fields: params.fields, + fieldNames: params.fieldNames, + fieldAttrs: params.fieldAttrs, + context: params.context, + parentID: params.parentID, + relationField: params.relationField, + res_ids: params.res_ids, + }); - var defs = []; // FIXME: remove defs? - _.each(params.fieldNames, function (name) { - var field = params.fields[name]; - data[name] = null; - record._changes = record._changes || {}; - if (field.type === 'many2one' && result[name]) { - var rec = self._makeDataPoint({ - context: record.context, - data: {id: result[name]}, - modelName: field.relation, - }); - record._changes[name] = rec.id; - } else if (field.type === 'one2many' || field.type === 'many2many') { - var attrs = record.fieldAttrs[name]; - var x2manyList = self._makeDataPoint({ - context: record.context, - fieldAttrs: field.fieldAttrs, - fields: field.relatedFields, - limit: field.limit, - modelName: field.relation, - parentID: record.id, - rawContext: attrs && attrs.context, - relationField: field.relation_field, - res_ids: [], - static: true, - type: 'list', - }); - record._changes[name] = x2manyList.id; - var many2ones = {}; - var r; - _.each(result[name], function (value) { - if (_.isArray(value)) { - // value is a command - if (value[0] === 0) { - // CREATE + var defs = []; // FIXME: remove defs? + _.each(params.fieldNames, function (name) { + var field = params.fields[name]; + data[name] = null; + record._changes = record._changes || {}; + if (field.type === 'many2one' && result[name]) { + var rec = self._makeDataPoint({ + context: record.context, + data: {id: result[name]}, + modelName: field.relation, + }); + record._changes[name] = rec.id; + } else if (field.type === 'one2many' || field.type === 'many2many') { + var attrs = record.fieldAttrs[name]; + var x2manyList = self._makeDataPoint({ + context: record.context, + fieldAttrs: field.fieldAttrs, + fields: field.relatedFields, + limit: field.limit, + modelName: field.relation, + parentID: record.id, + rawContext: attrs && attrs.context, + relationField: field.relation_field, + res_ids: [], + static: true, + type: 'list', + }); + record._changes[name] = x2manyList.id; + var many2ones = {}; + var r; + _.each(result[name], function (value) { + if (_.isArray(value)) { + // value is a command + if (value[0] === 0) { + // CREATE + r = self._makeDataPoint({ + modelName: x2manyList.model, + context: x2manyList.context, + fields: field.relatedFields, + fieldAttrs: field.fieldAttrs, + }); + x2manyList._changes.push(r.id); + r._changes = value[2]; + + // this is necessary so the fields are initialized + for (var fieldName in value[2]) { + r.data[fieldName] = null; + } + + for (var name in r._changes) { + if (r.fields[name].type === 'many2one') { + var rec = self._makeDataPoint({ + context: r.context, + modelName: r.fields[name].relation, + data: {id: r._changes[name]} + }); + r._changes[name] = rec.id; + many2ones[name] = true; + } + } + } + if (value[0] === 6) { + // REPLACE_WITH + x2manyList._changes = []; + } + } else { + // value is an id r = self._makeDataPoint({ modelName: x2manyList.model, context: x2manyList.context, fields: field.relatedFields, fieldAttrs: field.fieldAttrs, + res_id: value, }); - x2manyList._changes.push(r.id); - r._changes = value[2]; - - // this is necessary so the fields are initialized - for (var fieldName in value[2]) { - r.data[fieldName] = null; - } - - for (var name in r._changes) { - if (r.fields[name].type === 'many2one') { - var rec = self._makeDataPoint({ - context: r.context, - modelName: r.fields[name].relation, - data: {id: r._changes[name]} - }); - r._changes[name] = rec.id; - many2ones[name] = true; - } + if (!x2manyList._changes) { + x2manyList._changes = []; } + x2manyList._changes.push(r.id); } - if (value[0] === 6) { - // REPLACE_WITH - x2manyList._changes = []; + }); + + // fetch many2ones display_name + _.each(_.keys(many2ones), function (name) { + defs.push(self._fetchNameGets(x2manyList, name)); + }); + } else if (field.type === 'date') { + // process date: convert into a moment instance + record._changes[name] = fieldUtils.parse.date(result[name]); + } else if (field.type === 'datetime') { + // process datetime: convert into a moment instance + record._changes[name] = fieldUtils.parse.datetime(result[name]); + } else { + record._changes[name] = result[name]; + } + }); + return $.when.apply($, defs) + .then(function () { + var shouldApplyOnchange = false; + var field; + for (var field_name in record.data) { + field = record.fields[field_name]; + if (field.onChange) { + shouldApplyOnchange = true; } + } + if (shouldApplyOnchange) { + return self._applyOnChange(record, fields_key); } else { - // value is an id - r = self._makeDataPoint({ - modelName: x2manyList.model, - context: x2manyList.context, - fields: field.relatedFields, - fieldAttrs: field.fieldAttrs, - res_id: value, - }); - if (!x2manyList._changes) { - x2manyList._changes = []; - } - x2manyList._changes.push(r.id); + return $.when(); } + }) + .then(function () { + return self._fetchRelationalData(record); + }) + .then(function () { + return self._postprocess(record); + }) + .then(function () { + return record.id; }); - - // fetch many2ones display_name - _.each(_.keys(many2ones), function (name) { - defs.push(self._fetchNameGets(x2manyList, name)); - }); - } else if (field.type === 'date') { - // process date: convert into a moment instance - record._changes[name] = fieldUtils.parse.date(result[name]); - } else if (field.type === 'datetime') { - // process datetime: convert into a moment instance - record._changes[name] = fieldUtils.parse.datetime(result[name]); - } else { - record._changes[name] = result[name]; - } }); - return $.when.apply($, defs) - .then(function () { - var shouldApplyOnchange = false; - var field; - for (var field_name in record.data) { - field = record.fields[field_name]; - if (field.onChange) { - shouldApplyOnchange = true; - } - } - if (shouldApplyOnchange) { - return self._applyOnChange(record, fields_key); - } else { - return $.when(); - } - }) - .then(function () { - return self._fetchRelationalData(record); - }) - .then(function () { - return self._postprocess(record); - }) - .then(function () { - return record.id; - }); - }); }, /** * This helper method is designed to help developpers that want to use a @@ -808,21 +814,23 @@ var BasicModel = AbstractModel.extend({ // in the case of a write, only perform the RPC if there are changes to save if (method === 'create' || Object.keys(changes).length) { var args = method === 'write' ? [[record.data.id], changes] : [changes]; - return self.performModelRPC(record.model, method, args, { - context: session.user_context, // todo: combine with view context - }).then(function (id) { - if (method === 'create') { - record.res_id = id; // create returns an id, write returns a boolean - record.data.id = id; - record.offset = record.res_ids.length; - record.res_ids.push(id); - record.count++; - } - // erase changes as they have been applied - record._changes = {}; + return self.rpc(record.model, method) + .args(args) + .withContext(session.user_context) // todo: combine with view context + .exec() + .then(function (id) { + if (method === 'create') { + record.res_id = id; // create returns an id, write returns a boolean + record.data.id = id; + record.offset = record.res_ids.length; + record.res_ids.push(id); + record.count++; + } + // erase changes as they have been applied + record._changes = {}; - return shouldReload ? self._fetchRecord(record) : false; - }); + return shouldReload ? self._fetchRecord(record) : false; + }); } else { return $.when(record_id); } @@ -881,7 +889,7 @@ var BasicModel = AbstractModel.extend({ * @param {Array} recordIDs local ids of the records to (un)archive * @param {boolean} value false to archive, true to unarchive (value of the active field) * @param {string} parentID id of the parent resource to reload - * @returns {Deferred -> string} resolves to the parent id + * @returns {Deferred<string>} resolves to the parent id */ toggleActive: function (recordIDs, value, parentID) { var self = this; @@ -889,8 +897,9 @@ var BasicModel = AbstractModel.extend({ var resIDs = _.map(recordIDs, function (recordID) { return self.localData[recordID].res_id; }); - return this - .performModelRPC(parent.model, 'write', [resIDs, { active: value }]) + return this.rpc(parent.model, 'write') + .args([resIDs, { active: value }]) + .exec() .then(this.reload.bind(this, parentID)); }, @@ -960,11 +969,13 @@ var BasicModel = AbstractModel.extend({ var def; if (!('display_name' in rel_data)) { var field = record.fields[fieldName]; - def = this.performModelRPC(field.relation, 'name_get', [data.id], { - context: record.context, - }).then(function (result) { - rel_data.display_name = result[0][1]; - }); + def = this.rpc(field.relation, 'name_get') + .args([data.id]) + .withContext(record.context) + .exec() + .then(function (result) { + rel_data.display_name = result[0][1]; + }); } return $.when(def).then(function () { var rec = self._makeDataPoint({ @@ -1010,96 +1021,98 @@ var BasicModel = AbstractModel.extend({ fields = fields[0]; } return this.mutex.exec(function () { - var args = [idList, currentData, fields, onchange_spec, context]; - return self.performModelRPC(record.model, 'onchange', args, {}).then(function (result) { - if (result.warning) { - self.trigger_up('warning', { - message: result.warning.message, - title: result.warning.title, - type: 'dialog', - }); - } - var defs = []; - _.each(result.value, function (val, name) { - var field = record.fields[name]; - if (!field) { return; } // ignore changes of unknown fields - - var rec; - if (field.type === 'many2one' ) { - // in some case, the value returned by the onchange can - // be false (no value), so we need to avoid creating a - // local record for that. - // FIXME: shouldn't we erase the value in that case? - if (val) { - // when the value isn't false, it can be either - // an array [id, display_name] or just an id. - var data = _.isArray(val) ? - {id: val[0], display_name: val[1]} : - {id: val}; - rec = self._makeDataPoint({ - context: context, - data: data, - modelName: field.relation, - }); - record._changes[name] = rec.id; - } - } else if (field.type === 'one2many' || field.type === 'many2many') { - record._changes = record._changes || {}; - var listId = record._changes[name] || record.data[name]; - var list = self.localData[listId]; - _.each(val, function (command) { - if (command[0] === 0 || command[0] === 1) { - // CREATE or UPDATE - var params = { + return self.rpc(record.model, 'onchange') + .args([idList, currentData, fields, onchange_spec, context]) + .exec() + .then(function (result) { + if (result.warning) { + self.trigger_up('warning', { + message: result.warning.message, + title: result.warning.title, + type: 'dialog', + }); + } + var defs = []; + _.each(result.value, function (val, name) { + var field = record.fields[name]; + if (!field) { return; } // ignore changes of unknown fields + + var rec; + if (field.type === 'many2one' ) { + // in some case, the value returned by the onchange can + // be false (no value), so we need to avoid creating a + // local record for that. + // FIXME: shouldn't we erase the value in that case? + if (val) { + // when the value isn't false, it can be either + // an array [id, display_name] or just an id. + var data = _.isArray(val) ? + {id: val[0], display_name: val[1]} : + {id: val}; + rec = self._makeDataPoint({ context: context, - fields: list.fields, - fieldAttrs: list.fieldAttrs, - modelName: list.model, - fieldNames: _.keys(command[2]), - }; - if (command[0] === 1) { - params.res_id = command[1]; - } - rec = self._makeDataPoint(params); - var data = command[2]; - _.each(rec.fieldNames, function (name) { - var field = rec.fields[name]; - if (field.type === 'many2one') { - var r = self._makeDataPoint({ - modelName: field.relation, - data: { - id: data[name][0], - display_name: data[name][1], - }, - }); - data[name] = r.id; - } + data: data, + modelName: field.relation, }); - rec._changes = data; - for (var f in rec._changes) { - rec.data[f] = null; - } - list._changes.push(rec.id); - } - if (command[0] === 5) { - // DELETE ALL - list._changes = []; + record._changes[name] = rec.id; } - }); - } else if (field.type === 'date') { - // process data: convert into a moment instance - record._changes[name] = fieldUtils.parse.date(val); - } else if (field.type === 'datetime') { - // process datetime: convert into a moment instance - record._changes[name] = fieldUtils.parse.datetime(val); - } else { - record._changes[name] = val; - } - }); - return $.when.apply($, defs).then(function () { - return result; + } else if (field.type === 'one2many' || field.type === 'many2many') { + record._changes = record._changes || {}; + var listId = record._changes[name] || record.data[name]; + var list = self.localData[listId]; + _.each(val, function (command) { + if (command[0] === 0 || command[0] === 1) { + // CREATE or UPDATE + var params = { + context: context, + fields: list.fields, + fieldAttrs: list.fieldAttrs, + modelName: list.model, + fieldNames: _.keys(command[2]), + }; + if (command[0] === 1) { + params.res_id = command[1]; + } + rec = self._makeDataPoint(params); + var data = command[2]; + _.each(rec.fieldNames, function (name) { + var field = rec.fields[name]; + if (field.type === 'many2one') { + var r = self._makeDataPoint({ + modelName: field.relation, + data: { + id: data[name][0], + display_name: data[name][1], + }, + }); + data[name] = r.id; + } + }); + rec._changes = data; + for (var f in rec._changes) { + rec.data[f] = null; + } + list._changes.push(rec.id); + } + if (command[0] === 5) { + // DELETE ALL + list._changes = []; + } + }); + } else if (field.type === 'date') { + // process data: convert into a moment instance + record._changes[name] = fieldUtils.parse.date(val); + } else if (field.type === 'datetime') { + // process datetime: convert into a moment instance + record._changes[name] = fieldUtils.parse.datetime(val); + } else { + record._changes[name] = val; + } + }); + return $.when.apply($, defs).then(function () { + return result; + }); }); - }); }); }, /** @@ -1158,8 +1171,9 @@ var BasicModel = AbstractModel.extend({ // _changes so this is a very specific case) // this could be optimized by registering the fetched records in the list's _cache // so that if a record is removed and then re-added, it won't be fetched twice - var def = this - .performModelRPC(list.model, 'read', [_.pluck(data, 'id'), list.fieldNames], {}) + var def = this.rpc(list.model, 'read') + .args([_.pluck(data, 'id'), list.fieldNames]) + .exec() .then(function (records) { _.each(records, function (record) { list_records[record.id].data = record; @@ -1241,14 +1255,16 @@ var BasicModel = AbstractModel.extend({ _fetchMany2OneGroup: function (group) { var ids = _.uniq(_.pluck(group, 'res_id')); - return this.performModelRPC(group[0].model, 'name_get', [ids], { - context: group[0].context, - }).then(function (name_gets) { - _.each(group, function (record) { - var nameGet = _.find(name_gets, function (n) { return n[0] === record.res_id;}); - record.data.display_name = nameGet[1]; + return this.rpc(group[0].model, 'name_get') + .args([ids]) + .withContext(group[0].context) + .exec() + .then(function (name_gets) { + _.each(group, function (record) { + var nameGet = _.find(name_gets, function (n) { return n[0] === record.res_id;}); + record.data.display_name = nameGet[1]; + }); }); - }); }, _fetchNameGets: function (list, fieldName) { var self = this; @@ -1263,13 +1279,15 @@ var BasicModel = AbstractModel.extend({ model = many2oneRecord.model; return many2oneRecord.res_id; }); - return this.performModelRPC(model, 'name_get', [ids], { - context: list.context, - }).then(function (name_gets) { - for (var i = 0; i < name_gets.length; i++) { - records[i].data.display_name = name_gets[i][1]; - } - }); + return this.rpc(model, 'name_get') + .args([ids]) + .withContext(list.context) + .exec() + .then(function (name_gets) { + for (var i = 0; i < name_gets.length; i++) { + records[i].data.display_name = name_gets[i][1]; + } + }); }, /** * For a given resource of type 'record', fetch all data. @@ -1283,45 +1301,47 @@ var BasicModel = AbstractModel.extend({ var self = this; fieldNames = fieldNames || _.uniq(record.fieldNames.concat(['display_name'])); var oldData = record.data; - return this.performModelRPC(record.model, 'read', [record.res_id, fieldNames], { - // context: { 'bin_size': true }, // FIXME: when editing a subrecord in the partner form view, it tries to write the bin_size on the image field - }).then(function (result) { - result = result[0]; - record.data = _.extend({}, record.data, result); - }).then(function () { - return self._fetchX2Manys(record, oldData, fieldNames).then(function () { - return self._postprocess(record); - }); - }).then(function (record) { - _.each(fieldNames, function (name) { - var field = record.fields[name]; - var val = record.data[name]; - if (field.type === 'many2one') { - // process many2one: split [id, nameget] and create corresponding record - if (val !== false) { - // the many2one value is of the form [id, display_name] - var r = self._makeDataPoint({ - modelName: field.relation, - data: { - display_name: val[1], - id: val[0], - }, - }); - record.data[name] = r.id; - } else { - // no value for the many2one - record.data[name] = false; + return this.rpc(record.model, 'read') + .args([[record.res_id], fieldNames]) + // .withContext({ bin_size: true }) // FIXME: when editing a subrecord in the partner form view, it tries to write the bin_size on the image field + .exec() + .then(function (result) { + result = result[0]; + record.data = _.extend({}, record.data, result); + }).then(function () { + return self._fetchX2Manys(record, oldData, fieldNames).then(function () { + return self._postprocess(record); + }); + }).then(function (record) { + _.each(fieldNames, function (name) { + var field = record.fields[name]; + var val = record.data[name]; + if (field.type === 'many2one') { + // process many2one: split [id, nameget] and create corresponding record + if (val !== false) { + // the many2one value is of the form [id, display_name] + var r = self._makeDataPoint({ + modelName: field.relation, + data: { + display_name: val[1], + id: val[0], + }, + }); + record.data[name] = r.id; + } else { + // no value for the many2one + record.data[name] = false; + } + } else if (field.type === 'date') { + // process data: convert into a moment instance + record.data[name] = fieldUtils.parse.date(val); + } else if (field.type === 'datetime') { + // process datetime: convert into a moment instance + record.data[name] = fieldUtils.parse.datetime(val); } - } else if (field.type === 'date') { - // process data: convert into a moment instance - record.data[name] = fieldUtils.parse.date(val); - } else if (field.type === 'datetime') { - // process datetime: convert into a moment instance - record.data[name] = fieldUtils.parse.datetime(val); - } + }); + return record; }); - return record; - }); }, /** * This method is incorrectly named. It should be named something like @@ -1473,33 +1493,35 @@ var BasicModel = AbstractModel.extend({ } // step 2: fetch data from server - return this.performModelRPC(field.relation, 'read', [ids, _.keys(field.relatedFields)], { - context: {}, // FIXME - }).then(function (results) { - // step 3: assign values to correct datapoints - var dataPoints = _.map(results, function (result) { - return self._makeDataPoint({ - modelName: field.relation, - data: result, - fields: field.relatedFields, - fieldAttrs: field.fieldAttrs, + return this.rpc(field.relation, 'read') + .args([ids, _.keys(field.relatedFields)]) + .withContext({}) // FIXME + .exec() + .then(function (results) { + // step 3: assign values to correct datapoints + var dataPoints = _.map(results, function (result) { + return self._makeDataPoint({ + modelName: field.relation, + data: result, + fields: field.relatedFields, + fieldAttrs: field.fieldAttrs, + }); }); - }); - _.each(list.data, function (dataPoint) { - var record = self.localData[dataPoint]; - var m2mList = self.localData[record.data[fieldName]]; + _.each(list.data, function (dataPoint) { + var record = self.localData[dataPoint]; + var m2mList = self.localData[record.data[fieldName]]; - m2mList.data = []; - _.each(m2mList.res_ids, function (res_id) { - var dataPoint = _.find(dataPoints, function (d) { - return d.res_id === res_id; + m2mList.data = []; + _.each(m2mList.res_ids, function (res_id) { + var dataPoint = _.find(dataPoints, function (d) { + return d.res_id === res_id; + }); + m2mList.data.push(dataPoint.id); + m2mList.count++; }); - m2mList.data.push(dataPoint.id); - m2mList.count++; }); }); - }); }, /** * batch request for x2ms for datapoint of type list @@ -1740,46 +1762,50 @@ var BasicModel = AbstractModel.extend({ var _domain = new data.CompoundDomain(field.domain || {}).set_eval_context(field_values); var domain = pyeval.eval('domain', _domain); var fold_field = pyeval.py_eval(attrs.options || '{}').fold_field; - var fetch_status_information = self.performRPC('/web/dataset/search_read', { - model: field.relation, - fields: ['id'].concat(fold_field ? [fold_field] : []), - domain: domain, - }).then(function (result) { - var ids = _.pluck(result.records, 'id'); - return self.performModelRPC(field.relation, 'name_get', [ids], { - context: self._getContext(record, {fieldName: name}), - }).then(function (name_gets) { - _.each(result.records, function (record) { - var name_get = _.find(name_gets, function (n) { - return n[0] === record.id; + var fetch_status_information = self.rpc(field.relation, 'search_read') + .withFields(['id'].concat(fold_field ? [fold_field] : [])) + .withDomain(domain) + .exec() + .then(function (result) { + var ids = _.pluck(result.records, 'id'); + return self.rpc(field.relation, 'name_get') + .args([ids]) + .withContext(self._getContext(record, {fieldName: name})) + .exec() + .then(function (name_gets) { + _.each(result.records, function (record) { + var name_get = _.find(name_gets, function (n) { + return n[0] === record.id; + }); + record.display_name = name_get[1]; + }); + field.__status_information = result.records; }); - record.display_name = name_get[1]; - }); - field.__status_information = result.records; }); - }); defs.push(fetch_status_information); } if (field.__always_reload) { if (record.data[name] instanceof Array) { - defs.push(self.performModelRPC(field.relation, 'name_get', [record.data[name][0]], { - context: self._getContext(record, {fieldName: name}), - }).then(function (result) { - record.data[name] = result[0]; - })); + defs.push(self.rpc(field.relation, 'name_get') + .args([record.data[name][0]]) + .withContext(self._getContext(record, {fieldName: name})) + .exec() + .then(function (result) { + record.data[name] = result[0]; + })); } } if (field.__fetch_selection && !self.many2ones[field.relation]) { - var fetchSelection = self - .performModelRPC(field.relation, 'name_search', [], {}) + var fetchSelection = self.rpc(field.relation, 'name_search') + .exec() .then(function (result) { self.many2ones[field.relation] = result; }); defs.push(fetchSelection); } if (field.__fetch_many2manys) { - var fetchMany2Manys = self - .performModelRPC(field.relation, 'name_search', [], {}) + var fetchMany2Manys = self.rpc(field.relation, 'name_search') + .exec() .then(function (result) { self.many2manys[field.relation] = result; }); @@ -1802,69 +1828,68 @@ var BasicModel = AbstractModel.extend({ _readGroup: function (list) { var self = this; var fields = _.uniq(list.fieldNames.concat(list.groupedBy)); - return this.performModelRPC(list.model, 'read_group', [], { - fields: fields, - context: list.context, - groupby: list.groupedBy, - domain: list.domain, - orderby: false, - lazy: true, - }).then(function (groups) { - var rawGroupBy = list.groupedBy[0].split(':')[0]; - var previousGroups = _.map(list.data, function (groupID) { - return self.localData[groupID]; - }); - list.data = []; - list.count = groups.length; - var defs = []; - - _.each(groups, function (group) { - var aggregateValues = {}; - _.each(group, function (value, key) { - if (_.contains(fields, key) && key !== list.groupedBy[0]) { - aggregateValues[key] = value; - } + return this.rpc(list.model, 'read_group') + .withFields(fields) + .withContext(list.context) + .groupBy(list.groupedBy) + .lazy(true) + .exec() + .then(function (groups) { + var rawGroupBy = list.groupedBy[0].split(':')[0]; + var previousGroups = _.map(list.data, function (groupID) { + return self.localData[groupID]; }); - var newGroup = self._makeDataPoint({ - modelName: list.model, - count: group[rawGroupBy + '_count'], - domain: group.__domain, - context: list.context, - fields: list.fields, - fieldNames: list.fieldNames, - fieldAttrs: list.fieldAttrs, - value: group[rawGroupBy], - aggregateValues: aggregateValues, - groupedBy: list.groupedBy.slice(1), - orderedBy: list.orderedBy, - limit: list.limit, - openGroupByDefault: list.openGroupByDefault, - type: 'list', // nested groupedBys not handled yet + list.data = []; + list.count = groups.length; + var defs = []; + + _.each(groups, function (group) { + var aggregateValues = {}; + _.each(group, function (value, key) { + if (_.contains(fields, key) && key !== list.groupedBy[0]) { + aggregateValues[key] = value; + } + }); + var newGroup = self._makeDataPoint({ + modelName: list.model, + count: group[rawGroupBy + '_count'], + domain: group.__domain, + context: list.context, + fields: list.fields, + fieldNames: list.fieldNames, + fieldAttrs: list.fieldAttrs, + value: group[rawGroupBy], + aggregateValues: aggregateValues, + groupedBy: list.groupedBy.slice(1), + orderedBy: list.orderedBy, + limit: list.limit, + openGroupByDefault: list.openGroupByDefault, + type: 'list', // nested groupedBys not handled yet + }); + list.data.push(newGroup.id); + var old_group = _.find(previousGroups, function (g) { + return g.res_id === newGroup.res_id && g.value === newGroup.value; + }); + if (old_group) { + newGroup.isOpen = old_group.isOpen; + } else if (!newGroup.openGroupByDefault) { + newGroup.isOpen = false; + } else { + newGroup.isOpen = '__fold' in group ? !group.__fold : true; + } + if (newGroup.isOpen && newGroup.count > 0) { + defs.push(self._fetchUngroupedList(newGroup)); + } }); - list.data.push(newGroup.id); - var old_group = _.find(previousGroups, function (g) { - return g.res_id === newGroup.res_id && g.value === newGroup.value; + return $.when.apply($, defs).then(function () { + // generate the res_ids of the main list, being the concatenation + // of the fetched res_ids in each group + list.res_ids = _.flatten(_.map(arguments, function (group) { + return group ? group.res_ids : []; + })); + return list; }); - if (old_group) { - newGroup.isOpen = old_group.isOpen; - } else if (!newGroup.openGroupByDefault) { - newGroup.isOpen = false; - } else { - newGroup.isOpen = '__fold' in group ? !group.__fold : true; - } - if (newGroup.isOpen && newGroup.count > 0) { - defs.push(self._fetchUngroupedList(newGroup)); - } }); - return $.when.apply($, defs).then(function () { - // generate the res_ids of the main list, being the concatenation - // of the fetched res_ids in each group - list.res_ids = _.flatten(_.map(arguments, function (group) { - return group ? group.res_ids : []; - })); - return list; - }); - }); }, /** * For 'static' list, such as one2manys in a form view, we can do a /read @@ -1887,9 +1912,10 @@ var BasicModel = AbstractModel.extend({ } } if (missingIds.length) { - def = this.performModelRPC(list.model, 'read', [missingIds, list.fieldNames], { - context: {}, // FIXME - }); + def = this.rpc(list.model, 'read') + .args([missingIds, list.fieldNames]) + .withContext({}) // FIXME + .exec(); } else { def = $.when(); } @@ -1946,67 +1972,52 @@ var BasicModel = AbstractModel.extend({ */ _searchReadUngroupedList: function (list) { var self = this; - return this.performRPC('/web/dataset/search_read', { - model: list.model, - fields: list.fieldNames, - domain: list.domain || [], - offset: list.offset, - limit: list.limit, - sort: this._serializeSort(list.orderedBy), - }).then(function (result) { - list.count = result.length; - var data = _.map(result.records, function (record) { - var dataPoint = self._makeDataPoint({ - data: record, - fields: list.fields, - fieldNames: list.fieldNames, - fieldAttrs: list.fieldAttrs, - modelName: list.model, - parentID: list.id, - }); + return this.rpc(list.model, 'search_read') + .withFields(list.fieldNames) + .withDomain(list.domain || []) + .withLimit(list.limit) + .withOffset(list.offset) + .orderBy(list.orderedBy) + .exec() + .then(function (result) { + list.count = result.length; + var data = _.map(result.records, function (record) { + var dataPoint = self._makeDataPoint({ + data: record, + fields: list.fields, + fieldNames: list.fieldNames, + fieldAttrs: list.fieldAttrs, + modelName: list.model, + parentID: list.id, + }); - // add many2one records - _.each(dataPoint.fieldNames, function (name) { - var field = dataPoint.fields[name]; - if (field.type === 'many2one') { - var r = self._makeDataPoint({ - modelName: field.relation, - data: { - id: dataPoint.data[name][0], - display_name: dataPoint.data[name][1], - } - }); + // add many2one records + _.each(dataPoint.fieldNames, function (name) { + var field = dataPoint.fields[name]; + if (field.type === 'many2one') { + var r = self._makeDataPoint({ + modelName: field.relation, + data: { + id: dataPoint.data[name][0], + display_name: dataPoint.data[name][1], + } + }); - dataPoint.data[name] = r.id; - } - if (field.type === 'date') { - dataPoint.data[name] = fieldUtils.parse.date(dataPoint.data[name]); - } - if (field.type === 'datetime') { - dataPoint.data[name] = fieldUtils.parse.datetime(dataPoint.data[name]); - } + dataPoint.data[name] = r.id; + } + if (field.type === 'date') { + dataPoint.data[name] = fieldUtils.parse.date(dataPoint.data[name]); + } + if (field.type === 'datetime') { + dataPoint.data[name] = fieldUtils.parse.datetime(dataPoint.data[name]); + } + }); + return dataPoint.id; }); - return dataPoint.id; + list.data = data; + list.res_ids = _.pluck(result.records, 'id'); + return list; }); - list.data = data; - list.res_ids = _.pluck(result.records, 'id'); - return list; - }); - }, - /** - * Helper method, generates a string to describe a ordered by sequence for - * SQL. - * - * For example, [{name: 'foo', asc: true}, {name: 'bar', asc: false}] will - * be converted into 'foo ASC, bar DESC' - * - * @param {Object[]} orderBy list of objects {name:..., asc: ...} - * @returns {string} - */ - _serializeSort: function (orderBy) { - return _.map(orderBy, function (order) { - return order.asc ? order.name + ' ASC' : order.name + ' DESC'; - }).join(', '); }, /** * Change the offset of a record. Note that this does not reload the data. |
