offset: this._offset,
limit: this._limit,
sort: instance.web.serialize_sort(this._order_by)
- }).pipe(function (results) {
+ }).then(function (results) {
self._count = results.length;
return results.records;
}, null);
*/
first: function () {
var self = this;
- return this.clone({limit: 1})._execute().pipe(function (records) {
+ return this.clone({limit: 1})._execute().then(function (records) {
delete self._count;
if (records.length) { return records[0]; }
return null;
if (_.isEmpty(grouping)) { return null; }
var self = this;
+
+ // FIXME: when pyeval is merged
+ var ctx = instance.session.test_eval_contexts(
+ [this._model.context(this._context)]);
return this._model.call('read_group', {
groupby: grouping,
fields: _.uniq(grouping.concat(this._fields || [])),
offset: this._offset,
limit: this._limit,
orderby: instance.web.serialize_sort(this._order_by) || false
- }).pipe(function (results) {
+ }).then(function (results) {
return _(results).map(function (result) {
+ // FIX: querygroup initialization
+ result.__context = result.__context || {};
+ result.__context.group_by = result.__context.group_by || [];
+ _.defaults(result.__context, ctx);
return new instance.web.QueryGroup(
self._model.name, grouping[0], result);
});
* @param {String} method name of the method to call
* @param {Array} [args] positional arguments
* @param {Object} [kwargs] keyword arguments
+ * @param {Object} [options] additional options for the rpc() method
* @returns {jQuery.Deferred<>} call result
*/
- call: function (method, args, kwargs) {
+ call: function (method, args, kwargs, options) {
args = args || [];
kwargs = kwargs || {};
if (!_.isArray(args)) {
args = [];
}
instance.web.pyeval.ensure_evaluated(args, kwargs);
- return instance.session.rpc('/web/dataset/call_kw', {
+ var debug = instance.session.debug ? '/'+this.name+':'+method : '';
+ return instance.session.rpc('/web/dataset/call_kw' + debug, {
model: this.name,
method: method,
args: args,
kwargs: kwargs
- });
+ }, options);
},
/**
* Fetches a Query instance bound to this model, for searching
},
});
-instance.web.DataGroup = instance.web.CallbackEnabled.extend({
- /**
- * Management interface between views and grouped collections of OpenERP
- * records.
- *
- * The root DataGroup is instantiated with the relevant information
- * (a session, a model, a domain, a context and a group_by sequence), the
- * domain and context may be empty. It is then interacted with via
- * :js:func:`~instance.web.DataGroup.list`, which is used to read the
- * content of the current grouping level.
- *
- * @constructs instance.web.DataGroup
- * @extends instance.web.CallbackEnabled
- *
- * @param {instance.web.CallbackEnabled} parent widget
- * @param {String} model name of the model managed by this DataGroup
- * @param {Array} domain search domain for this DataGroup
- * @param {Object} context context of the DataGroup's searches
- * @param {Array} group_by sequence of fields by which to group
- * @param {Number} [level=0] nesting level of the group
- */
- init: function(parent, model, domain, context, group_by, level) {
- this._super(parent, null);
- this.model = new instance.web.Model(model, context, domain);
- this.group_by = group_by;
- this.context = context;
- this.domain = domain;
-
- this.level = level || 0;
- },
- list: function (fields, ifGroups, ifRecords) {
- var self = this;
- var query = this.model.query(fields).order_by(this.sort).group_by(this.group_by);
- $.when(query).then(function (querygroups) {
- // leaf node
- if (!querygroups) {
- var ds = new instance.web.DataSetSearch(self, self.model.name, self.model.context(), self.model.domain());
- ds._sort = self.sort;
- ifRecords(ds);
- return;
- }
- // internal node
- var child_datagroups = _(querygroups).map(function (group) {
- var child_context = _.extend(
- {}, self.model.context(), group.model.context());
- var child_dg = new instance.web.DataGroup(
- self, self.model.name, group.model.domain(),
- child_context, group.model._context.group_by,
- self.level + 1);
- child_dg.sort = self.sort;
- // copy querygroup properties
- child_dg.__context = child_context;
- child_dg.__domain = group.model.domain();
- child_dg.folded = group.get('folded');
- child_dg.grouped_on = group.get('grouped_on');
- child_dg.length = group.get('length');
- child_dg.value = group.get('value');
- child_dg.openable = group.get('has_children');
- child_dg.aggregates = group.get('aggregates');
- return child_dg;
- });
- ifGroups(child_datagroups);
- });
- }
-});
-
-instance.web.StaticDataGroup = instance.web.DataGroup.extend({
- /**
- * A specialization of data groups, relying on a single static
- * dataset as its records provider.
- *
- * @constructs instance.web.StaticDataGroup
- * @extends instance.web.DataGroup
- * @param {openep.web.DataSetStatic} dataset a static dataset backing the groups
- */
- init: function (dataset) {
- this.dataset = dataset;
- },
- list: function (fields, ifGroups, ifRecords) {
- ifRecords(this.dataset);
- }
-});
-
-instance.web.DataSet = instance.web.CallbackEnabled.extend({
+instance.web.DataSet = instance.web.Class.extend(instance.web.PropertiesMixin, {
/**
* Collection of OpenERP records, used to share records and the current selection between views.
*
* @constructs instance.web.DataSet
- * @extends instance.web.CallbackEnabled
*
* @param {String} model the OpenERP model this dataset will manage
*/
init: function(parent, model, context) {
- this._super(parent);
+ instance.web.PropertiesMixin.init.call(this);
this.model = model;
this.context = context || {};
this.index = null;
return this._model.query(fields)
.limit(options.limit || false)
.offset(options.offset || 0)
- .all().then(function (records) {
+ .all().done(function (records) {
self.ids = _(records).pluck('id');
});
},
*/
read_index: function (fields, options) {
options = options || {};
- return this.read_ids([this.ids[this.index]], fields, options).pipe(function (records) {
+ return this.read_ids([this.ids[this.index]], fields, options).then(function (records) {
if (_.isEmpty(records)) { return $.Deferred().reject().promise(); }
return records[0];
});
default_get: function(fields, options) {
options = options || {};
return this._model.call('default_get',
- [fields], {context: this._model.context(options.context)});
+ [fields], {context: this.get_context(options.context)});
},
/**
* Creates a new record in db
* @returns {$.Deferred}
*/
create: function(data) {
- return this._model.call('create', [data], {context: this._model.context()});
+ return this._model.call('create', [data], {context: this.get_context()});
},
/**
* Saves the provided data in an existing db record
*/
write: function (id, data, options) {
options = options || {};
- return this._model.call('write', [[id], data], {context: this._model.context(options.context)});
+ return this._model.call('write', [[id], data], {context: this.get_context(options.context)}).done(this.trigger('dataset_changed', id, data, options));
},
/**
* Deletes an existing record from the database
* @param {Number|String} ids identifier of the record to delete
*/
unlink: function(ids) {
- return this._model.call('unlink', [ids], {context: this._model.context()});
+ return this._model.call('unlink', [ids], {context: this.get_context()}).done(this.trigger('dataset_changed', ids));
},
/**
* Calls an arbitrary RPC method
* @param {Function} error_callback
* @returns {$.Deferred}
*/
- call: function (method, args, callback, error_callback) {
- return this._model.call(method, args).then(callback, error_callback);
- },
- /**
- * Calls an arbitrary method, with more crazy
- *
- * @param {String} method
- * @param {Array} [args]
- * @param {Number} [domain_index] index of a domain to evaluate in the args array
- * @param {Number} [context_index] index of a context to evaluate in the args array
- * @returns {$.Deferred}
- */
- call_and_eval: function (method, args, domain_index, context_index) {
- instance.web.pyeval.ensure_evaluated(args, {});
- return instance.session.rpc('/web/dataset/call', {
- model: this.model,
- method: method,
- // Should not be necessary anymore as ensure_evaluated traverses
- // all of the args array
- domain_id: domain_index == undefined ? null : domain_index,
- context_id: context_index == undefined ? null : context_index,
- args: args || []
- });
+ call: function (method, args) {
+ return this._model.call(method, args);
},
/**
* Calls a button method, usually returning some sort of action
* @returns {$.Deferred}
*/
name_get: function(ids) {
- return this._model.call('name_get', [ids], {context: this._model.context()});
+ return this._model.call('name_get', [ids], {context: this.get_context()});
},
/**
*
* @param name
*/
name_create: function(name) {
- return this._model.call('name_create', [name], {context: this._model.context()});
+ return this._model.call('name_create', [name], {context: this.get_context()});
},
exec_workflow: function (id, signal) {
- return this._model.exec_workflow(id, signal)
- .pipe(function (result) { return { result: result }; });
+ return this._model.exec_workflow(id, signal);
},
get_context: function(request_context) {
return this._model.context(request_context);
return instance.session.rpc('/web/dataset/resequence', {
model: this.model,
ids: ids,
- context: this._model.context(options.context),
- }).pipe(function (results) {
+ context: this.get_context(options.context),
+ }).then(function (results) {
return results;
});
},
instance.web.DataSetStatic = instance.web.DataSet.extend({
init: function(parent, model, context, ids) {
+ var self = this;
this._super(parent, model, context);
// all local records
this.ids = ids || [];
}
},
unlink: function(ids) {
- this.on_unlink(ids);
+ this.set_ids(_.without.apply(null, [this.ids].concat(ids)));
+ this.trigger('unlink', ids);
return $.Deferred().resolve({result: true});
},
- on_unlink: function(ids) {
- this.set_ids(_.without.apply(null, [this.ids].concat(ids)));
- }
});
instance.web.DataSetSearch = instance.web.DataSet.extend({
.limit(options.limit || false);
q = q.order_by.apply(q, this._sort);
- return q.all().then(function (records) {
+ return q.all().done(function (records) {
// FIXME: not sure about that one, *could* have discarded count
- q.count().then(function (count) { self._length = count; });
+ q.count().done(function (count) { self._length = count; });
self.ids = _(records).pluck('id');
});
},
},
unlink: function(ids, callback, error_callback) {
var self = this;
- return this._super(ids).then(function(result) {
+ return this._super(ids).done(function(result) {
self.ids = _(self.ids).difference(ids);
if (self._length) {
self._length -= 1;
}
- if (this.index !== null) {
+ if (self.index !== null) {
self.index = self.index <= self.ids.length - 1 ?
self.index : (self.ids.length > 0 ? self.ids.length -1 : 0);
}
+ self.trigger("dataset_changed", ids, callback, error_callback);
});
},
size: function () {
this.last_default_get = {};
},
default_get: function(fields, options) {
- return this._super(fields, options).then(this.on_default_get);
- },
- on_default_get: function(res) {
- this.last_default_get = res;
+ var self = this;
+ return this._super(fields, options).done(function(res) {
+ self.last_default_get = res;
+ });
},
create: function(data) {
var cached = {id:_.uniqueId(this.virtual_id_prefix), values: data,
}
$.extend(cached.values, record.values);
if (dirty)
- this.on_change();
+ this.trigger("dataset_changed", id, data, options);
return $.Deferred().resolve(true).promise();
},
unlink: function(ids, callback, error_callback) {
this.to_write = _.reject(this.to_write, function(x) { return _.include(ids, x.id);});
this.cache = _.reject(this.cache, function(x) { return _.include(ids, x.id);});
this.set_ids(_.without.apply(_, [this.ids].concat(ids)));
- this.on_change();
- return $.async_when({result: true}).then(callback);
+ this.trigger("dataset_changed", ids, callback, error_callback);
+ return $.async_when({result: true}).done(callback);
},
reset_ids: function(ids) {
this.set_ids(ids);
this.cache = [];
this.delete_all = false;
},
- on_change: function() {
- },
read_ids: function (ids, fields, options) {
var self = this;
var to_get = [];
completion.resolve(records);
};
if(to_get.length > 0) {
- var rpc_promise = this._super(to_get, fields, options).then(function(records) {
+ var rpc_promise = this._super(to_get, fields, options).done(function(records) {
_.each(records, function(record, index) {
var id = to_get[index];
var cached = _.detect(self.cache, function(x) {return x.id === id;});
},
alter_ids: function(n_ids) {
this._super(n_ids);
- this.on_change();
+ this.trigger("dataset_changed", n_ids);
},
});
instance.web.BufferedDataSet.virtual_id_regex = /^one2many_v_id_.*$/;
var res = $.Deferred();
var self = this, seq = this.lsn++;
- deferred.then(function () {
+ deferred.done(function () {
if (seq > self.rsn) {
self.rsn = seq;
res.resolve.apply(res, arguments);
} else if (self.failMisordered) {
res.reject();
}
- }, function () {
+ }).fail(function () {
res.reject.apply(res, arguments);
});