summaryrefslogtreecommitdiff
path: root/addons/web/static/src/js/data.js
diff options
context:
space:
mode:
authorKunal Chavda (OpenERP) <kch@tinyerp.com>2011-10-17 16:07:40 +0530
committerKunal Chavda (OpenERP) <kch@tinyerp.com>2011-10-17 16:07:40 +0530
commitf76bdfb1fa4a2de837eacf619a211c805d23a226 (patch)
tree4bdcb2ef8e8b8e199b11574da215576f9ee29eef /addons/web/static/src/js/data.js
parentc5f5637e0992158734adda1782b725e24546dc6e (diff)
parentf1f48e69f0e654487234ced0537a03dd46fb3e12 (diff)
[MERGE]merge main view editor branch upto 884 revision.
bzr revid: kch@tinyerp.com-20111017103740-v7lrybz3gkq2ujxa
Diffstat (limited to 'addons/web/static/src/js/data.js')
-rw-r--r--addons/web/static/src/js/data.js172
1 files changed, 138 insertions, 34 deletions
diff --git a/addons/web/static/src/js/data.js b/addons/web/static/src/js/data.js
index fcf6a65dcf5..1eaffcd0e30 100644
--- a/addons/web/static/src/js/data.js
+++ b/addons/web/static/src/js/data.js
@@ -610,40 +610,120 @@ openerp.web.BufferedDataSet = openerp.web.DataSetStatic.extend({
on_default_get: function(res) {
this.last_default_get = res;
},
+ /**
+ * Makes sure this dataset has the fields_get for its model stored locally,
+ * so create/write methods are able to determine if written fields are m2os
+ * and can name_get those fields if that's the case (in order to cache a
+ * correct m2o value for them)
+ *
+ * @returns {$.Deferred} whether the fields_get is done executing, provides the fields_get value to its callbacks
+ */
+ ensure_has_fields: function () {
+ var self = this;
+
+ if (this.fields_get) {
+ var d = $.Deferred();
+ setTimeout(function () { d.resolve(self.fields_get, true); }, 0);
+ return d.promise();
+ } else {
+ return self.call('fields_get', [], function (fields_get) {
+ self.fields_get = fields_get;
+ });
+ }
+ },
+ /**
+ * Relational fields may not be written in the same format they are read.
+ *
+ * Since the BufferedDataSet is a bit dumb, it returns what it's got stored
+ * in its cache, which for modified value is what it was given. This breaks
+ * some basic contracts of openerp such as m2o read being in the
+ * ``name_get`` format.
+ *
+ * Because create & write are supposed to be asynchronous, though, it
+ * should be easy to just name_get all incorrect values.
+ *
+ * @param {Object} data form-data to write to the cache
+ * @returns {$.Deferred} resolved with a fixed data dictionary
+ */
+ fix_relational: function (data) {
+ var self = this;
+ var results = $.Deferred();
+ this.ensure_has_fields().then(function (fields) {
+ var fields_to_fix = _(fields).chain()
+ .map(function (d, k) { return {key: k, descriptor: d}; })
+ .filter(function (field) {
+ // keep m2o fields which are in the data dict
+ return field.descriptor.type === 'many2one' &&
+ data[field.key];
+ }).pluck('key')
+ .value();
+ var name_gets = _(fields_to_fix).map(function (field) {
+ return new openerp.web.DataSet(self, self.fields_get[field].relation)
+ .name_get([data[field]], null);
+ });
+ // null-concat forces stupid bastard `when` to always return an
+ // array containing the Array-ified results of all the name_gets.
+ // otherwise, if there's a single field to fix it returns the
+ // results of the unique name_get directly.
+ $.when.apply(null, name_gets.concat([null])).then(function () {
+ var record = _.extend({}, data);
+ for(var i=0; i<fields_to_fix.length; ++i) {
+ // Each argument is [[name_get], success, jqXhr] and we
+ // want just the name_get pair
+ record[fields_to_fix[i]] = arguments[i][0][0];
+ }
+ results.resolve(record);
+ });
+ });
+ return results;
+ },
create: function(data, callback, error_callback) {
- var cached = {id:_.uniqueId(this.virtual_id_prefix), values: data,
- defaults: this.last_default_get};
- this.to_create.push(cached);
- this.cache.push(cached);
- this.on_change();
+ var self = this;
var prom = $.Deferred().then(callback);
- setTimeout(function() {prom.resolve({result: cached.id});}, 0);
+ this.fix_relational(data).then(function (fixed_m2o_data) {
+ var cached = {
+ id:_.uniqueId(self.virtual_id_prefix),
+ values: fixed_m2o_data,
+ defaults: self.last_default_get
+ };
+ self.to_create.push(_.extend(_.clone(cached), {
+ values: _.clone(data)}));
+ self.cache.push(cached);
+ self.on_change();
+ prom.resolve({result: cached.id});
+ });
return prom.promise();
},
write: function (id, data, options, callback) {
var self = this;
- var record = _.detect(this.to_create, function(x) {return x.id === id;});
- record = record || _.detect(this.to_write, function(x) {return x.id === id;});
- var dirty = false;
- if (record) {
- for (var k in data) {
- if (record.values[k] === undefined || record.values[k] !== data[k]) {
- dirty = true;
- break;
+ var to_return = $.Deferred().then(callback);
+ this.fix_relational(data).then(function (fixed_m2o_data) {
+ var record = _.detect(self.to_create, function(x) {return x.id === id;});
+ record = record || _.detect(self.to_write, function(x) {return x.id === id;});
+ var dirty = false;
+ if (record) {
+ for (var k in data) {
+ if (record.values[k] === undefined || record.values[k] !== data[k]) {
+ dirty = true;
+ break;
+ }
}
+ _.extend(record.values, data);
+ } else {
+ dirty = true;
+ record = {id: id, values: data};
+ self.to_write.push(record);
}
- $.extend(record.values, data);
- } else {
- dirty = true;
- record = {id: id, values: data};
- self.to_write.push(record);
- }
- var cached = _.detect(this.cache, function(x) {return x.id === id;});
- $.extend(cached.values, record.values);
- if (dirty)
- this.on_change();
- var to_return = $.Deferred().then(callback);
- to_return.resolve({result: true});
+ var cached = _.detect(self.cache, function(x) {return x.id === id;});
+ if (!cached) {
+ cached = {id: id, values: {}};
+ this.cache.push(cached);
+ }
+ _.extend(cached.values, fixed_m2o_data);
+ if (dirty)
+ self.on_change();
+ to_return.resolve({result: true});
+ });
return to_return.promise();
},
unlink: function(ids, callback, error_callback) {
@@ -695,7 +775,7 @@ openerp.web.BufferedDataSet = openerp.web.DataSetStatic.extend({
throw "Record not correctly loaded";
}
}
- setTimeout(function () {completion.resolve(records);}, 0);
+ completion.resolve(records);
};
if(to_get.length > 0) {
var rpc_promise = this._super(to_get, fields, function(records) {
@@ -720,27 +800,51 @@ openerp.web.BufferedDataSet = openerp.web.DataSetStatic.extend({
});
openerp.web.BufferedDataSet.virtual_id_regex = /^one2many_v_id_.*$/;
-openerp.web.ReadOnlyDataSetSearch = openerp.web.DataSetSearch.extend({
+openerp.web.ProxyDataSet = openerp.web.DataSetSearch.extend({
+ init: function() {
+ this._super.apply(this, arguments);
+ this.create_function = null;
+ this.write_function = null;
+ this.read_function = null;
+ },
+ read_ids: function () {
+ if (this.read_function) {
+ return this.read_function.apply(null, arguments);
+ } else {
+ return this._super.apply(this, arguments);
+ }
+ },
default_get: function(fields, callback) {
return this._super(fields, callback).then(this.on_default_get);
},
on_default_get: function(result) {},
create: function(data, callback, error_callback) {
this.on_create(data);
- var to_return = $.Deferred().then(callback);
- setTimeout(function () {to_return.resolve({"result": undefined});}, 0);
- return to_return.promise();
+ if (this.create_function) {
+ return this.create_function(data, callback, error_callback);
+ } else {
+ console.warn("trying to create a record using default proxy dataset behavior");
+ var to_return = $.Deferred().then(callback);
+ setTimeout(function () {to_return.resolve({"result": undefined});}, 0);
+ return to_return.promise();
+ }
},
on_create: function(data) {},
write: function (id, data, options, callback) {
this.on_write(id, data);
- var to_return = $.Deferred().then(callback);
- setTimeout(function () {to_return.resolve({"result": true});}, 0);
- return to_return.promise();
+ if (this.write_function) {
+ return this.write_function(id, data, options, callback);
+ } else {
+ console.warn("trying to write a record using default proxy dataset behavior");
+ var to_return = $.Deferred().then(callback);
+ setTimeout(function () {to_return.resolve({"result": true});}, 0);
+ return to_return.promise();
+ }
},
on_write: function(id, data) {},
unlink: function(ids, callback, error_callback) {
this.on_unlink(ids);
+ console.warn("trying to unlink a record using default proxy dataset behavior");
var to_return = $.Deferred().then(callback);
setTimeout(function () {to_return.resolve({"result": true});}, 0);
return to_return.promise();