diff --git a/src/common.js b/src/common.js index fa69caa37b..4b6c28fabc 100644 --- a/src/common.js +++ b/src/common.js @@ -64,6 +64,28 @@ return result; }; + // Cartesian product + Sao.common.product = function(array, repeat) { + repeat = repeat || 1; + var pools = []; + var i = 0; + while (i < repeat) { + pools = pools.concat(array); + i++; + } + var result = [[]]; + pools.forEach(function(pool) { + var tmp = []; + result.forEach(function(x) { + pool.forEach(function(y) { + tmp.push(x.concat([y])); + }); + }); + result = tmp; + }); + return result; + }; + Sao.common.selection = function(title, values, alwaysask) { if (alwaysask === undefined) { alwaysask = false; diff --git a/src/model.js b/src/model.js index 8a32520b4c..e67bf799ef 100644 --- a/src/model.js +++ b/src/model.js @@ -636,7 +636,10 @@ // TODO return values; }; - prm = prm.pipe(force_parent).done(this.set_default.bind(this)); + prm = prm.pipe(force_parent).then(function(values) { + this.set_default(values); + return values; + }.bind(this)); } else { prm = jQuery.when(); } diff --git a/src/screen.js b/src/screen.js index bb63c93e6e..966f800f74 100644 --- a/src/screen.js +++ b/src/screen.js @@ -725,7 +725,7 @@ this.current_view.view_type == 'graph')) { prm = this.switch_view('form'); } - prm.done(function() { + return prm.then(function() { var group; if (this.current_record) { group = this.current_record.group; @@ -737,6 +737,7 @@ this.set_current_record(record); this.display(); // TODO set_cursor + return record; }.bind(this)); }, new_model_position: function() { diff --git a/src/view.js b/src/view.js index 4f7b77bba7..ed1dc9d196 100644 --- a/src/view.js +++ b/src/view.js @@ -2848,26 +2848,104 @@ return; } this.validate().done(function() { - var context = jQuery.extend({}, - this.field().get_context(this.record())); - // TODO sequence - if (this.screen.current_view.type == 'form' || - this.screen.current_view.editable) { - this.screen.new_(); - this.screen.current_view.el.prop('disabled', false); + if (this.attributes.product) { + this.new_product(); } else { - var record = this.record(); - var field_size = record.expr_eval( - this.attributes.size) || -1; - field_size -= this.field().get_eval(record); - var win = new Sao.Window.Form(this.screen, function() {}, { - new_: true, - many: field_size, - context: context - }); + this.new_single(); } }.bind(this)); }, + new_single: function() { + var context = jQuery.extend({}, + this.field().get_context(this.record())); + // TODO sequence + if (this.screen.current_view.type == 'form' || + this.screen.current_view.editable) { + this.screen.new_(); + this.screen.current_view.el.prop('disabled', false); + } else { + var record = this.record(); + var field_size = record.expr_eval( + this.attributes.size) || -1; + field_size -= this.field().get_eval(record); + var win = new Sao.Window.Form(this.screen, function() {}, { + new_: true, + many: field_size, + context: context + }); + } + }, + new_product: function() { + var fields = this.attributes.product.split(','); + var product = {}; + var screen = this.screen; + + screen.new_(false).then(function(first) { + first.default_get().then(function(default_) { + first.set_default(default_); + + var search_set = function() { + if (jQuery.isEmptyObject(fields)) { + return make_product(); + } + var field = screen.model.fields[fields.pop()]; + var relation = field.description.relation; + if (!relation) { + search_set(); + } + + var domain = field.get_domain(first); + var context = field.get_context(first); + + var callback = function(result) { + if (!jQuery.isEmptyObject(result)) { + product[field.name] = result; + } + search_set(); + }; + var win_search = new Sao.Window.Search(relation, + callback, { + sel_multi: true, + context: context, + domain: domain, + search_filter: '' + }); + }; + + var make_product = function() { + if (jQuery.isEmptyObject(product)) { + screen.group.remove(first, true); + return; + } + + var fields = Object.keys(product); + var values = fields.map(function(field) { + return product[field]; + }); + Sao.common.product(values).forEach(function(values) { + var set_default = function(record) { + var default_value = jQuery.extend({}, default_); + fields.forEach(function(field, i) { + default_value[field] = values[i][0]; + default_value[field + '.rec_name'] = values[i][1]; + }); + record.set_default(default_value); + }; + + var record; + if (first) { + set_default(first); + first = null; + } else { + screen.new_(false).then(set_default); + } + }); + }; + + search_set(); + }); + }); + }, open: function(event_) { this.edit(); },