diff --git a/web_readonly_bypass/README.rst b/web_readonly_bypass/README.rst
index 12d8ac173..8bd216ff9 100644
--- a/web_readonly_bypass/README.rst
+++ b/web_readonly_bypass/README.rst
@@ -8,9 +8,10 @@ This module provides a solution to the problem of the interaction between
'readonly' attribute and 'on_change' attribute when used together. It allows
saving onchange modifications to readonly fields.
-Behavior: add readonly fields changed by `on_change` methods to the values
-passed to write or create. If `filter_out_readonly` is in the context and
-True then apply native behavior.
+Behavior: add readonly fields changed by `on_change` methods to the values
+passed to write or create. If `readonly_by_pass` is in the context and
+True then it will by pass readonly fields and save its data provide by onchange
+method.
Installation
============
@@ -25,11 +26,23 @@ There is nothing to configure.
Usage
=====
-This module changes the default behaviour of Odoo by propagating
+This module changes the behaviour of Odoo by propagating
on_change modifications to readonly fields to the backend create and write
methods.
-To restore the standard behaviour, set `filter_out_readonly` in the context.
+To change that behavior you have to set context on ``ur.actions.act_window``::
+
+
+ {'readonly_by_pass': True}
+
+
+or by telling fields allowed to change::
+
+
+
+ {'readonly_by_pass': ['readonly_field_1', 'readonly_field_2',]}
+
+
For further information, please visit:
@@ -38,7 +51,6 @@ For further information, please visit:
Known issues / Roadmap
======================
-None
Bug Tracker
===========
diff --git a/web_readonly_bypass/static/src/js/readonly_bypass.js b/web_readonly_bypass/static/src/js/readonly_bypass.js
index 0635c74df..691121c00 100644
--- a/web_readonly_bypass/static/src/js/readonly_bypass.js
+++ b/web_readonly_bypass/static/src/js/readonly_bypass.js
@@ -1,38 +1,65 @@
-/*
- * Allow to bypass readonly fi the value is changed
- */
-
-openerp.web_readonly_bypass = function(instance) {
-
+(function(){
+ var instance = openerp;
var QWeb = instance.web.qweb, _t = instance.web._t;
- /**
- * ignore readonly: place options['readonly_fields'] into the data
- * if nothing is specified into the context
- *
- * create mode: remove read-only keys having a 'false' value
- *
- * @param boolean mode: True case of create, false case of write
- * @param {Object} context->filter_out_readonly
- * @param {Object} data field values to possibly be updated
- * @param {Object} options Dictionary that can contain the following keys:
- * - readonly_fields: Values from readonly fields to merge into the data object
- */
- function ignore_readonly(data, options, mode, context){
- if (options){
- if ('readonly_fields' in options && options['readonly_fields'] &&
- !('filter_out_readonly' in context && context['filter_out_readonly'] == true )) {
- if(mode){
+
+ instance.web_readonly_bypass = {
+ /**
+ * ignore readonly: place options['readonly_fields'] into the data
+ * if nothing is specified into the context
+ *
+ * create mode: remove read-only keys having a 'false' value
+ *
+ * @param {Object} data field values to possibly be updated
+ * @param {Object} options Dictionary that can contain the following keys:
+ * - readonly_fields: Values from readonly fields to merge into the data object
+ * @param boolean mode: True case of create, false case of write
+ * @param {Object} context->readonly_by_pass
+ */
+ ignore_readonly: function(data, options, mode, context){
+ var readonly_by_pass_fields = this.retrieve_readonly_by_pass_fields(
+ options, context);
+ if(mode){
+ $.each( readonly_by_pass_fields, function( key, value ) {
+ if(value==false){
+ delete(readonly_by_pass_fields[key]);
+ }
+ });
+ }
+ data = $.extend(data,readonly_by_pass_fields);
+ },
+
+ /**
+ * retrieve_readonly_by_pass_fields: retrieve readonly fields to save
+ * according context.
+ *
+ * @param {Object} options Dictionary that can contain the following keys:
+ * - readonly_fields: all values from readonly fields
+ * @param {Object} context->readonly_by_pass: Can be true if all
+ * all readonly fields should be saved or an array of field name to
+ * save ie: ['readonly_field_1', 'readonly_field_2']
+ * @returns {Object}: readonly key/value fields to save according context
+ */
+ retrieve_readonly_by_pass_fields: function(options, context){
+ var readonly_by_pass_fields = {};
+ if (options && 'readonly_fields' in options &&
+ options['readonly_fields'] && context &&
+ 'readonly_by_pass' in context && context['readonly_by_pass']){
+ if (_.isArray(context['readonly_by_pass'])){
$.each( options.readonly_fields, function( key, value ) {
- if(value==false){
- delete(options.readonly_fields[key]);
+ if(_.contains(context['readonly_by_pass'], key)){
+ readonly_by_pass_fields[key] = value;
}
});
+ }else{
+ readonly_by_pass_fields = options.readonly_fields;
}
- data = $.extend(data,options['readonly_fields'])
}
- }
+ return readonly_by_pass_fields;
+ },
};
+ readonly_bypass = instance.web_readonly_bypass;
+
instance.web.BufferedDataSet.include({
init : function() {
@@ -49,7 +76,9 @@ openerp.web_readonly_bypass = function(instance) {
*/
create : function(data, options) {
var self = this;
- ignore_readonly(data, options, true, self.context);
+ var context = instance.web.pyeval.eval('contexts',
+ self.context.__eval_context);
+ readonly_bypass.ignore_readonly(data, options, true, context);
return self._super(data,options);
},
/**
@@ -63,7 +92,9 @@ openerp.web_readonly_bypass = function(instance) {
*/
write : function(id, data, options) {
var self = this;
- ignore_readonly(data, options, false, self.context);
+ var context = instance.web.pyeval.eval('contexts',
+ self.context.__eval_context);
+ readonly_bypass.ignore_readonly(data, options, false, context);
return self._super(id,data,options);
},
@@ -87,7 +118,7 @@ openerp.web_readonly_bypass = function(instance) {
*/
create : function(data, options) {
var self = this;
- ignore_readonly(data, options, true, self.context);
+ readonly_bypass.ignore_readonly(data, options, true, self.context);
return self._super(data,options);
},
/**
@@ -101,9 +132,9 @@ openerp.web_readonly_bypass = function(instance) {
*/
write : function(id, data, options) {
var self = this;
- ignore_readonly(data, options, false, self.context);
+ readonly_bypass.ignore_readonly(data, options, false, self.context);
return self._super(id,data,options);
},
});
-};
+})();
diff --git a/web_readonly_bypass/static/test/web_readonly_bypass.js b/web_readonly_bypass/static/test/web_readonly_bypass.js
new file mode 100644
index 000000000..fbc44f729
--- /dev/null
+++ b/web_readonly_bypass/static/test/web_readonly_bypass.js
@@ -0,0 +1,166 @@
+openerp.testing.section( 'web_readonly_bypass', {},
+function(test){
+ test('ignore_readonly', function(instance){
+ var data = {};
+ var mode_create = true;
+ var options = {};
+ var context = {};
+ instance.web_readonly_bypass.ignore_readonly(data, options,
+ mode_create, context);
+ deepEqual(data,
+ {},
+ "Empty context and options mode create"
+ );
+
+ mode_create = false;
+ data = {};
+ instance.web_readonly_bypass.ignore_readonly(data, options,
+ mode_create, context);
+ deepEqual(data,
+ {},
+ "Empty context and options mode write"
+ );
+
+ mode_create = false;
+ data = {};
+ context = {'readonly_by_pass': true};
+ options = {'readonly_fields': {'field_1': 'va1-1',
+ 'field_2': false,
+ 'field_3': 'val-3'}};
+ instance.web_readonly_bypass.ignore_readonly(data, options,
+ mode_create, context);
+ deepEqual(data,
+ {'field_1': 'va1-1', 'field_2': false, 'field_3': 'val-3'},
+ "all fields mode write"
+ );
+
+ mode_create = true;
+ data = {};
+ context = {'readonly_by_pass': true};
+ options = {'readonly_fields': {'field_1': 'va1-1',
+ 'field_2': false,
+ 'field_3': 'val-3'}};
+ instance.web_readonly_bypass.ignore_readonly(data, options,
+ mode_create, context);
+ deepEqual(data,
+ {'field_1': 'va1-1', 'field_3': 'val-3'},
+ "all fields mode create (false value are escaped)"
+ );
+
+ mode_create = true;
+ data = {};
+ context = {};
+ options = {'readonly_fields': {'field_1': 'va1-1',
+ 'field_2': false,
+ 'field_3': 'val-3'}};
+ instance.web_readonly_bypass.ignore_readonly(data, options,
+ mode_create, context);
+ deepEqual(data,
+ {},
+ "without context, default, we won't save readonly fields"
+ );
+ });
+
+ test('retrieve_readonly_by_pass_fields', function(instance){
+ var context = {'readonly_by_pass': true}
+ var options = {'readonly_fields': {'field_1': 'va1-1',
+ 'field_2': 'val-2',
+ 'field_3': 'val-3'}};
+ deepEqual(
+ instance.web_readonly_bypass.retrieve_readonly_by_pass_fields(
+ options, context),
+ {'field_1': 'va1-1', 'field_2': 'val-2', 'field_3': 'val-3'},
+ "All fields should be accepted!"
+ );
+
+ context = {'readonly_by_pass': ['field_1', 'field_3']};
+ deepEqual(
+ instance.web_readonly_bypass.retrieve_readonly_by_pass_fields(
+ options, context),
+ {'field_1': 'va1-1','field_3': 'val-3'},
+ "two field s1"
+ );
+
+ context = {'readonly_by_pass': ['field_1',]};
+ deepEqual(
+ instance.web_readonly_bypass.retrieve_readonly_by_pass_fields(
+ options, context),
+ {'field_1': 'va1-1'},
+ "Only field 1"
+ );
+
+ context = {'readonly_by_pass': []};
+ deepEqual(
+ instance.web_readonly_bypass.retrieve_readonly_by_pass_fields(
+ options, context),
+ {},
+ "Empty context field"
+ );
+
+ context = null;
+ deepEqual(
+ instance.web_readonly_bypass.retrieve_readonly_by_pass_fields(
+ options, context),
+ {},
+ "Null context"
+ );
+
+ context = false;
+ deepEqual(
+ instance.web_readonly_bypass.retrieve_readonly_by_pass_fields(
+ options, context),
+ {},
+ "false context"
+ );
+
+ context = {'readonly_by_pass': true}
+ options = {'readonly_fields': {'field_1': 'va1-1'}};
+ deepEqual(
+ instance.web_readonly_bypass.retrieve_readonly_by_pass_fields(
+ options, context),
+ {'field_1': 'va1-1'},
+ "Only one option"
+ );
+
+
+ options = {'readonly_fields': {}};
+ deepEqual(
+ instance.web_readonly_bypass.retrieve_readonly_by_pass_fields(
+ options, context),
+ {},
+ "Empty readonly_fields option"
+ );
+
+ options = {};
+ deepEqual(
+ instance.web_readonly_bypass.retrieve_readonly_by_pass_fields(
+ options, context),
+ {},
+ "Empty option"
+ );
+
+ options = null;
+ deepEqual(
+ instance.web_readonly_bypass.retrieve_readonly_by_pass_fields(
+ options, context),
+ {},
+ "null option"
+ );
+
+ options = false;
+ deepEqual(
+ instance.web_readonly_bypass.retrieve_readonly_by_pass_fields(
+ options, context),
+ {},
+ "false option"
+ );
+
+ context = false;
+ deepEqual(
+ instance.web_readonly_bypass.retrieve_readonly_by_pass_fields(
+ options, context),
+ {},
+ "false option and false context"
+ );
+ });
+});
diff --git a/web_readonly_bypass/views/readonly_bypass.xml b/web_readonly_bypass/views/readonly_bypass.xml
index 8aff08f55..32c584c06 100644
--- a/web_readonly_bypass/views/readonly_bypass.xml
+++ b/web_readonly_bypass/views/readonly_bypass.xml
@@ -1,12 +1,15 @@
-
-
+
+
+
+
+
+