Merge pull request #743 from simahawk/mig-10-web_readonly_bypass

[MIG][10.0] web_readonly_bypass
pull/763/head
Pedro M. Baeza 2017-10-16 17:33:30 +02:00 committed by GitHub
commit edcbae383b
7 changed files with 250 additions and 213 deletions

View File

@ -22,7 +22,7 @@ This module changes the behaviour of Odoo by propagating
on_change modifications to readonly fields to the backend create and write on_change modifications to readonly fields to the backend create and write
methods. methods.
To change that behavior you have to set context on ``ur.actions.act_window``:: To change that behavior you have to set context on ``ir.actions.act_window``::
<record id="sale.action_quotations" model="ir.actions.act_window"> <record id="sale.action_quotations" model="ir.actions.act_window">
<field name="context">{'readonly_by_pass': True}</field> <field name="context">{'readonly_by_pass': True}</field>
@ -36,13 +36,13 @@ or by telling fields allowed to change::
</field> </field>
</record> </record>
For further information, please visit: On one2many fields, you can also pass the context in the field definition:
* https://www.odoo.com/forum/help-1 <field name="one2many_field" context="{'readonly_by_pass': True}"/>
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas .. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot :alt: Try me on Runbot
:target: https://runbot.odoo-community.org/runbot/162/8.0 :target: https://runbot.odoo-community.org/runbot/162/10.0
Bug Tracker Bug Tracker
@ -50,8 +50,7 @@ Bug Tracker
Bugs are tracked on `GitHub Issues <https://github.com/OCA/web/issues>`_. Bugs are tracked on `GitHub Issues <https://github.com/OCA/web/issues>`_.
In case of trouble, please check there if your issue has already been reported. In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed feedback If you spotted it first, help us smashing it by providing a detailed and welcomed feedback.
`here <https://github.com/OCA/web/issues/new?body=module:%20web_readonly_bypass%0Aversion:%208.0.1.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Credits Credits
@ -63,6 +62,10 @@ Contributors
* Jonathan Nemry <jonathan.nemry@acsone.eu> * Jonathan Nemry <jonathan.nemry@acsone.eu>
* Laetitia Gangloff <laetitia.gangloff@acsone.eu> * Laetitia Gangloff <laetitia.gangloff@acsone.eu>
* Pierre Verkest <pverkest@anybox.fr> * Pierre Verkest <pverkest@anybox.fr>
* Kalpana Hemnani <hemnani.kalpana@gmail.com>
* Agathe Mollé <agathe.molle@savoirfairelinux.com>
* Simone Orsi <simone.orsi@camptocamp.com>
Maintainer Maintainer
---------- ----------

View File

@ -1,33 +1,13 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
############################################################################## # Copyright (c) 2015 ACSONE SA/NV (<http://acsone.eu>)
# # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
# This file is part of web_readonly_bypass,
# an Odoo module.
#
# Copyright (c) 2015 ACSONE SA/NV (<http://acsone.eu>)
#
# web_readonly_bypass is free software:
# you can redistribute it and/or modify it under the terms of the GNU
# Affero General Public License as published by the Free Software
# Foundation,either version 3 of the License, or (at your option) any
# later version.
#
# web_readonly_bypass is distributed
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with web_readonly_bypass.
# If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
{ {
'name': 'Read Only ByPass', 'name': 'Read Only ByPass',
'version': '9.0.1.0.0', 'version': '10.0.1.0.1',
"author": "ACSONE SA/NV, Odoo Community Association (OCA)", "author": "ACSONE SA/NV, Odoo Community Association (OCA)",
"maintainer": "ACSONE SA/NV,Odoo Community Association (OCA)",
"website": "http://www.acsone.eu", "website": "http://www.acsone.eu",
"license": "LGPL-3",
'category': 'Technical Settings', 'category': 'Technical Settings',
'depends': [ 'depends': [
'web', 'web',
@ -36,6 +16,6 @@
'data': [ 'data': [
'views/readonly_bypass.xml', 'views/readonly_bypass.xml',
], ],
'installable': False, 'installable': True,
'auto_install': False, 'auto_install': False,
} }

View File

@ -1,9 +1,10 @@
"use strict"; odoo.define('web_readonly_bypass', function(require) {
(function(){ 'use strict';
var instance = openerp;
var QWeb = instance.web.qweb, _t = instance.web._t;
instance.web_readonly_bypass = { var data = require('web.data'),
pyeval = require('web.pyeval');
var readonly_bypass = {
/** /**
* ignore readonly: place options['readonly_fields'] into the data * ignore readonly: place options['readonly_fields'] into the data
* if nothing is specified into the context * if nothing is specified into the context
@ -26,7 +27,7 @@
} }
}); });
} }
data = $.extend(data,readonly_by_pass_fields); data = $.extend(data, readonly_by_pass_fields);
}, },
/** /**
@ -59,15 +60,13 @@
}, },
}; };
var readonly_bypass = instance.web_readonly_bypass; data.BufferedDataSet.include({
instance.web.BufferedDataSet.include({
init : function() { init : function() {
this._super.apply(this, arguments); this._super.apply(this, arguments);
}, },
/** /**
* Creates Overriding * Create Overriding
* *
* @param {Object} data field values to set on the new record * @param {Object} data field values to set on the new record
* @param {Object} options Dictionary that can contain the following keys: * @param {Object} options Dictionary that can contain the following keys:
@ -77,13 +76,12 @@
*/ */
create : function(data, options) { create : function(data, options) {
var self = this; var self = this;
var context = instance.web.pyeval.eval('contexts', var context = pyeval.eval('contexts', self.context.get_eval_context());
self.context.__eval_context);
readonly_bypass.ignore_readonly(data, options, true, context); readonly_bypass.ignore_readonly(data, options, true, context);
return self._super(data,options); return self._super(data,options);
}, },
/** /**
* Creates Overriding * Write Overriding
* *
* @param {Object} data field values to set on the new record * @param {Object} data field values to set on the new record
* @param {Object} options Dictionary that can contain the following keys: * @param {Object} options Dictionary that can contain the following keys:
@ -93,15 +91,14 @@
*/ */
write : function(id, data, options) { write : function(id, data, options) {
var self = this; var self = this;
var context = instance.web.pyeval.eval('contexts', var context = pyeval.eval('contexts', self.context.get_eval_context());
self.context.__eval_context);
readonly_bypass.ignore_readonly(data, options, false, context); readonly_bypass.ignore_readonly(data, options, false, context);
return self._super(id,data,options); return self._super(id,data,options);
}, },
}); });
instance.web.DataSet.include({ data.DataSet.include({
/* /*
BufferedDataSet: case of 'add an item' into a form view BufferedDataSet: case of 'add an item' into a form view
*/ */
@ -138,4 +135,46 @@
}, },
}); });
})();
data.ProxyDataSet.include({
/*
ProxyDataSet: case of 'pop-up'
*/
init : function() {
this._super.apply(this, arguments);
},
/**
* Create Overriding
*
* @param {Object} data field values to set on the new record
* @param {Object} options Dictionary that can contain the following keys:
* - readonly_fields: Values from readonly fields that were updated by
* on_changes. Only used by the BufferedDataSet to make the o2m work correctly.
* @returns super {$.Deferred}
*/
create : function(data, options) {
var self = this;
var context = pyeval.eval('contexts', self.context.get_eval_context());
readonly_bypass.ignore_readonly(data, options, true, context);
return self._super(data,options);
},
/**
* Write Overriding
*
* @param {Object} data field values to set on the new record
* @param {Object} options Dictionary that can contain the following keys:
* - readonly_fields: Values from readonly fields that were updated by
* on_changes. Only used by the BufferedDataSet to make the o2m work correctly.
* @returns super {$.Deferred}
*/
write : function(id, data, options) {
var self = this;
var context = pyeval.eval('contexts', self.context.get_eval_context());
readonly_bypass.ignore_readonly(data, options, false, context);
return self._super(id,data,options);
},
});
return readonly_bypass;
});

View File

@ -1,166 +1,166 @@
openerp.testing.section( 'web_readonly_bypass', {}, odoo.define_section('web_readonly_bypass', ['web_readonly_bypass'], function(test) {
function(test){ "use strict";
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; test('ignore_readonly', function(assert, ro_bypass){
data = {}; var data = {};
context = {'readonly_by_pass': true}; var mode_create = true;
options = {'readonly_fields': {'field_1': 'va1-1', var options = {};
'field_2': false, var context = {};
ro_bypass.ignore_readonly(data, options, mode_create, context);
assert.deepEqual(data,
{},
"Empty context and options mode create"
);
mode_create = false;
data = {};
ro_bypass.ignore_readonly(data, options, mode_create, context);
assert.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'}};
ro_bypass.ignore_readonly(data, options, mode_create, context);
assert.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'}};
ro_bypass.ignore_readonly(data, options, mode_create, context);
assert.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'}};
ro_bypass.ignore_readonly(data, options, mode_create, context);
assert.deepEqual(data,
{},
"without context, default, we won't save readonly fields"
);
});
test('retrieve_readonly_by_pass_fields', ['web_readonly_bypass'], function(assert, ro_bypass){
var context = {'readonly_by_pass': true}
var options = {'readonly_fields': {'field_1': 'va1-1',
'field_2': 'val-2',
'field_3': 'val-3'}}; 'field_3': 'val-3'}};
instance.web_readonly_bypass.ignore_readonly(data, options, assert.deepEqual(
mode_create, context); ro_bypass.retrieve_readonly_by_pass_fields(
deepEqual(data, options, context),
{'field_1': 'va1-1', 'field_2': false, 'field_3': 'val-3'}, {'field_1': 'va1-1', 'field_2': 'val-2', 'field_3': 'val-3'},
"all fields mode write" "All fields should be accepted!"
); );
mode_create = true; context = {'readonly_by_pass': ['field_1', 'field_3']};
data = {}; assert.deepEqual(
context = {'readonly_by_pass': true}; ro_bypass.retrieve_readonly_by_pass_fields(
options = {'readonly_fields': {'field_1': 'va1-1', options, context),
'field_2': false, {'field_1': 'va1-1','field_3': 'val-3'},
'field_3': 'val-3'}}; "two field s1"
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; context = {'readonly_by_pass': ['field_1',]};
data = {}; assert.deepEqual(
context = {}; ro_bypass.retrieve_readonly_by_pass_fields(
options = {'readonly_fields': {'field_1': 'va1-1', options, context),
'field_2': false, {'field_1': 'va1-1'},
'field_3': 'val-3'}}; "Only field 1"
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){ context = {'readonly_by_pass': []};
var context = {'readonly_by_pass': true} assert.deepEqual(
var options = {'readonly_fields': {'field_1': 'va1-1', ro_bypass.retrieve_readonly_by_pass_fields(
'field_2': 'val-2', options, context),
'field_3': 'val-3'}}; {},
deepEqual( "Empty context field"
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']}; context = null;
deepEqual( assert.deepEqual(
instance.web_readonly_bypass.retrieve_readonly_by_pass_fields( ro_bypass.retrieve_readonly_by_pass_fields(
options, context), options, context),
{'field_1': 'va1-1','field_3': 'val-3'}, {},
"two field s1" "Null context"
); );
context = {'readonly_by_pass': ['field_1',]}; context = false;
deepEqual( assert.deepEqual(
instance.web_readonly_bypass.retrieve_readonly_by_pass_fields( ro_bypass.retrieve_readonly_by_pass_fields(
options, context), options, context),
{'field_1': 'va1-1'}, {},
"Only field 1" "false context"
); );
context = {'readonly_by_pass': []}; context = {'readonly_by_pass': true}
deepEqual( options = {'readonly_fields': {'field_1': 'va1-1'}};
instance.web_readonly_bypass.retrieve_readonly_by_pass_fields( assert.deepEqual(
options, context), ro_bypass.retrieve_readonly_by_pass_fields(
{}, options, context),
"Empty context field" {'field_1': 'va1-1'},
); "Only one option"
);
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': {}}; options = {'readonly_fields': {}};
deepEqual( assert.deepEqual(
instance.web_readonly_bypass.retrieve_readonly_by_pass_fields( ro_bypass.retrieve_readonly_by_pass_fields(
options, context), options, context),
{}, {},
"Empty readonly_fields option" "Empty readonly_fields option"
); );
options = {}; options = {};
deepEqual( assert.deepEqual(
instance.web_readonly_bypass.retrieve_readonly_by_pass_fields( ro_bypass.retrieve_readonly_by_pass_fields(
options, context), options, context),
{}, {},
"Empty option" "Empty option"
); );
options = null; options = null;
deepEqual( assert.deepEqual(
instance.web_readonly_bypass.retrieve_readonly_by_pass_fields( ro_bypass.retrieve_readonly_by_pass_fields(
options, context), options, context),
{}, {},
"null option" "null option"
); );
options = false; options = false;
deepEqual( assert.deepEqual(
instance.web_readonly_bypass.retrieve_readonly_by_pass_fields( ro_bypass.retrieve_readonly_by_pass_fields(
options, context), options, context),
{}, {},
"false option" "false option"
); );
context = false; context = false;
deepEqual( assert.deepEqual(
instance.web_readonly_bypass.retrieve_readonly_by_pass_fields( ro_bypass.retrieve_readonly_by_pass_fields(
options, context), options, context),
{}, {},
"false option and false context" "false option and false context"
); );
}); });
}); });

View File

@ -0,0 +1 @@
from . import test_ui

View File

@ -0,0 +1,15 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017 Simone Orsi <simone.orsi@camptocamp.com>
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
from odoo.tests import HttpCase
class TestUi(HttpCase):
def test_ui_web(self):
self.phantom_js(
"/web/tests?module=web_readonly_bypass",
"",
login="admin",
)

View File

@ -1,15 +1,14 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<openerp> <odoo>
<data> <template id="assets_backend" name="web_readonly_bypass" inherit_id="web.assets_backend">
<template id="assets_backend" name="web_readonly_bypass" inherit_id="web.assets_backend"> <xpath expr="." position="inside">
<xpath expr="." position="inside"> <script type="text/javascript" src="/web_readonly_bypass/static/src/js/readonly_bypass.js"></script>
<script type="text/javascript" src="/web_readonly_bypass/static/src/js/readonly_bypass.js"></script> </xpath>
</xpath> </template>
</template>
<template id="qunit_suite" name="web_readonly_bypass" inherit_id="web.qunit_suite"> <template id="qunit_suite" name="web_readonly_bypass" inherit_id="web.qunit_suite">
<xpath expr="//head" position="inside"> <xpath expr="//t[@t-set='head']" position="inside">
<script type="text/javascript" src="/web_readonly_bypass/static/test/web_readonly_bypass.js"></script> <script type="text/javascript" src="/web_readonly_bypass/static/test/web_readonly_bypass.js"></script>
</xpath> </xpath>
</template> </template>
</data> </odoo>
</openerp>