From 8322c7c7316a25025ab10827b3ae96f6a1851c48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E5=BF=97=E4=BA=AE?= Date: Tue, 8 Jan 2019 07:36:02 +0000 Subject: [PATCH 01/66] [CLA] alexcn signs cla closes odoo/odoo#30010 --- doc/cla/individual/alexcn.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 doc/cla/individual/alexcn.md diff --git a/doc/cla/individual/alexcn.md b/doc/cla/individual/alexcn.md new file mode 100644 index 00000000000..fb0cf0d8232 --- /dev/null +++ b/doc/cla/individual/alexcn.md @@ -0,0 +1,9 @@ +China, 2019-01-08 + +I hereby agree to the terms of the Odoo Individual Contributor License Agreement v1.0. + +I declare that I am authorized and able to make this agreement and sign this declaration. + +Signed, + +Alex Zhang zhilight@gmail.com https://github.com/Alexcn \ No newline at end of file From 91882dd97238a006ef711b33a96ba88acb862847 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Tue, 8 Jan 2019 09:16:49 +0000 Subject: [PATCH 02/66] [FIX] base: delete linked record only if last external id In case a record is no longer referenced in the updated module, its external id is deleted. If the linked record still exists, it is deleted as well. This last clause was incorrect as the record may still be referenced in other modules. If a field is declared in module A class FooA(models.Model): _name = 'foo' bar = fields.Char() and overriden in module B class FooB(models.Model: _inherit = 'foo' bar = fields.Char(translate=True) In case the field is no longer inherited in module B (code change, moved to another module,...), the ir.model.field record for bar was deleted. Two external ids are linked to field bar: A.field_foo__bar B.field_foo__bar The ir.model.field record should be dropped only if both ir.model.data entries are no longer loaded. Otherwise, only the ir.model.data entry should be deleted (i.e. B.field_foo__bar in the above example). Fixes odoo/odoo#29820 closes odoo/odoo#30018 --- odoo/addons/base/models/ir_model.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/odoo/addons/base/models/ir_model.py b/odoo/addons/base/models/ir_model.py index 533654004ac..38ecd83888a 100644 --- a/odoo/addons/base/models/ir_model.py +++ b/odoo/addons/base/models/ir_model.py @@ -1624,6 +1624,16 @@ class IrModelData(models.Model): for (id, xmlid, model, res_id) in self._cr.fetchall(): if xmlid not in loaded_xmlids: if model in self.env: + if self.search_count([ + ("model", "=", model), + ("res_id", "=", res_id), + ("id", "!=", id), + ("id", "not in", bad_imd_ids), + ]): + # another external id is still linked to the same record, only deleting the old imd + bad_imd_ids.append(id) + continue + _logger.info('Deleting %s@%s (%s)', res_id, model, xmlid) record = self.env[model].browse(res_id) if record.exists(): From d0d8b7b4de78aa2c38c91257af2a07caf1107d1c Mon Sep 17 00:00:00 2001 From: Nicolas Martinelli Date: Tue, 8 Jan 2019 14:37:02 +0000 Subject: [PATCH 03/66] [FIX] mrp: BoM Structure report Send the context for proper translation of the report. opw-1908220 closes odoo/odoo#30038 --- addons/mrp/static/src/js/mrp_bom_report.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/mrp/static/src/js/mrp_bom_report.js b/addons/mrp/static/src/js/mrp_bom_report.js index 77d57dcf01e..fa505b5a052 100644 --- a/addons/mrp/static/src/js/mrp_bom_report.js +++ b/addons/mrp/static/src/js/mrp_bom_report.js @@ -25,7 +25,8 @@ var MrpBomReport = stock_report_generic.extend({ return this._rpc({ model: 'report.mrp.report_bom_structure', method: 'get_html', - args: args + args: args, + context: this.given_context, }) .then(function (result) { self.data = result; From 270171752f6b9cb9ad87644cb36ab16c9e84f4f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veikko=20Va=CC=88a=CC=88ta=CC=88ja=CC=88?= Date: Tue, 8 Jan 2019 16:49:10 +0000 Subject: [PATCH 04/66] [FIX] doc: fix numbered list in guidelines Fix rst-formating for numbered list under heading "Inherited XML". closes odoo/odoo#30043 --- doc/reference/guidelines.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/reference/guidelines.rst b/doc/reference/guidelines.rst index 10bd221a51e..5710bd36ff6 100644 --- a/doc/reference/guidelines.rst +++ b/doc/reference/guidelines.rst @@ -281,6 +281,7 @@ Inherited XML ~~~~~~~~~~~~~ The naming pattern of inherited view is + #. Extension mode: Use the same xml id than the original view you are extending, and suffix it by :samp:`{_inherit}` . For instance, the view :samp:`project.project_view_form` can be extended by :samp:`project_forecast.project_view_form_inherit`. #. Primary mode: Keep the original xml id. From 171d1e7bc3bf1df28c6c4aaf8e39abb3e0e9b75e Mon Sep 17 00:00:00 2001 From: Jorge Pinna Puissant Date: Mon, 7 Jan 2019 10:43:40 +0000 Subject: [PATCH 05/66] [FIX] web_editor: Media dialog next btn reload page opw-1910505 Before this commit, the next button in the media dialog widget reloaded the page and opened only the iframe of the widget. Now, the button only update the media dialog widget. closes odoo/odoo#29981 --- addons/web_editor/static/src/js/widgets/widgets.js | 1 + 1 file changed, 1 insertion(+) diff --git a/addons/web_editor/static/src/js/widgets/widgets.js b/addons/web_editor/static/src/js/widgets/widgets.js index 7c33ab53b97..30de8171e53 100644 --- a/addons/web_editor/static/src/js/widgets/widgets.js +++ b/addons/web_editor/static/src/js/widgets/widgets.js @@ -1288,6 +1288,7 @@ var MediaDialog = Dialog.extend({ * @private */ _onPagerClick: function (ev) { + ev.preventDefault(); this.active.goToPage(this.active.page + ($(ev.currentTarget).hasClass('previous') ? -1 : 1)); this._updateControlPanel(); }, From 59956805424808beed82f1afa5c5e6996e34eb13 Mon Sep 17 00:00:00 2001 From: Jorge Pinna Puissant Date: Fri, 4 Jan 2019 16:07:39 +0000 Subject: [PATCH 06/66] [FIX] hr_holidays: validation_type same behavior opw-1919744 Before this commit, the user in the leave_type had the choice between three validations : 'hr', 'manager' and 'both'. The behaviour of the application was exactly the same if 'hr' or 'manager' was chosen. In this commit, a computed field was added only to hide this choice, and restrict the user to choice between the 'double validation' or the normal validation. This commit must be reverted once the fonctional part is implemented. closes odoo/odoo#29952 --- addons/hr_holidays/i18n/hr_holidays.pot | 5 ++++ addons/hr_holidays/models/hr_leave_type.py | 28 +++++++++++++++++++ .../hr_holidays/views/hr_leave_type_views.xml | 6 ++-- 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/addons/hr_holidays/i18n/hr_holidays.pot b/addons/hr_holidays/i18n/hr_holidays.pot index 5628d1427d4..7f60f82ba22 100644 --- a/addons/hr_holidays/i18n/hr_holidays.pot +++ b/addons/hr_holidays/i18n/hr_holidays.pot @@ -661,6 +661,11 @@ msgstr "" msgid "Analyze from" msgstr "" +#. module: hr_holidays +#: model:ir.model.fields,field_description:hr_holidays.field_hr_leave_type__double_validation +msgid "Apply Double Validation" +msgstr "" + #. module: hr_holidays #: model_terms:ir.ui.view,arch_db:hr_holidays.view_evaluation_report_graph msgid "Appraisal Analysis" diff --git a/addons/hr_holidays/models/hr_leave_type.py b/addons/hr_holidays/models/hr_leave_type.py index f0d8eddd1a0..1911faf2d88 100644 --- a/addons/hr_holidays/models/hr_leave_type.py +++ b/addons/hr_holidays/models/hr_leave_type.py @@ -65,6 +65,15 @@ class HolidaysType(models.Model): ('hr', 'Human Resource officer'), ('manager', 'Employee Manager'), ('both', 'Double Validation')], default='hr', string='Validation By') + + # TODO: remove me in master, the behavior is exactly the same if you choose 'hr' or 'manager' + # in the validation_type field. This field is used only to hide this possibility to the user + # to avoid misunderstandings. This field and its corresponding's functions must be removed once + # the functional part is implemented. + double_validation = fields.Boolean(string='Apply Double Validation', + compute='_compute_validation_type', inverse='_inverse_validation_type', + help="When selected, the Allocation/Leave Requests for this type require a second validation to be approved.") + allocation_type = fields.Selection([ ('fixed', 'Fixed by HR'), ('fixed_allocation', 'Fixed by HR + allocation request'), @@ -84,6 +93,25 @@ class HolidaysType(models.Model): default='day', string='Take Leaves in', required=True) unpaid = fields.Boolean('Is Unpaid', default=False) + # TODO: remove me in master + @api.depends('validation_type') + def _compute_validation_type(self): + for holiday_type in self: + if holiday_type.validation_type == 'both': + holiday_type.double_validation = True + else: + holiday_type.double_validation = False + + # TODO: remove me in master + def _inverse_validation_type(self): + for holiday_type in self: + if holiday_type.double_validation == True: + holiday_type.validation_type = 'both' + else: + #IF to preserve the information (hr or manager) + if holiday_type.validation_type == 'both': + holiday_type.validation_type = 'hr' + @api.multi @api.constrains('validity_start', 'validity_stop') def _check_validity_dates(self): diff --git a/addons/hr_holidays/views/hr_leave_type_views.xml b/addons/hr_holidays/views/hr_leave_type_views.xml index 759972e36ea..d0c30a22c48 100644 --- a/addons/hr_holidays/views/hr_leave_type_views.xml +++ b/addons/hr_holidays/views/hr_leave_type_views.xml @@ -47,7 +47,8 @@ - + + @@ -97,7 +98,8 @@ - + + From e95b4e959433db45bc5c227f67763cd509fee333 Mon Sep 17 00:00:00 2001 From: Nicolas Martinelli Date: Mon, 7 Jan 2019 09:25:12 +0000 Subject: [PATCH 07/66] [FIX] web: graph view translation The control labels 'Grouped' and 'Stacked' are not translated since they are default values from nvd3. opw-1908220 closes odoo/odoo#29975 --- addons/web/i18n/web.pot | 14 ++++++++++++++ .../static/src/js/views/graph/graph_renderer.js | 4 ++++ 2 files changed, 18 insertions(+) diff --git a/addons/web/i18n/web.pot b/addons/web/i18n/web.pot index 9210c9bb81a..9cb0f0b9ba7 100644 --- a/addons/web/i18n/web.pot +++ b/addons/web/i18n/web.pot @@ -1603,6 +1603,13 @@ msgstr "" msgid "Group by: %s" msgstr "" +#. module: web +#. openerp-web +#: code:addons/web/static/src/js/views/graph/graph_renderer.js:214 +#, python-format +msgid "Grouped" +msgstr "" + #. module: web #: model:ir.model,name:web.model_ir_http msgid "HTTP Routing" @@ -3004,6 +3011,13 @@ msgstr "" msgid "Special:" msgstr "" +#. module: web +#. openerp-web +#: code:addons/web/static/src/js/views/graph/graph_renderer.js:215 +#, python-format +msgid "Stacked" +msgstr "" + #. module: web #. openerp-web #: code:addons/web/static/src/js/core/misc.js:14 diff --git a/addons/web/static/src/js/views/graph/graph_renderer.js b/addons/web/static/src/js/views/graph/graph_renderer.js index 5deba9d69bd..5ec89635dc8 100644 --- a/addons/web/static/src/js/views/graph/graph_renderer.js +++ b/addons/web/static/src/js/views/graph/graph_renderer.js @@ -210,6 +210,10 @@ return AbstractRenderer.extend({ margin: {left: 80, bottom: 100, top: 80, right: 0}, delay: 100, transition: 10, + controlLabels: { + 'grouped': _t('Grouped'), + 'stacked': _t('Stacked'), + }, showLegend: _.size(data) <= MAX_LEGEND_LENGTH, showXAxis: true, showYAxis: true, From 69f6b9510db36570698e472f797ef5e4e3685d2e Mon Sep 17 00:00:00 2001 From: Nicolas Martinelli Date: Tue, 8 Jan 2019 13:15:16 +0000 Subject: [PATCH 08/66] [FIX] web: decimal separator of percentage When a percentage if formatted, the decimal separator used is always `.`, while it should be the decimal separator of the language. opw-1908220 closes odoo/odoo#30030 --- .../web/static/src/js/fields/field_utils.js | 2 +- .../static/tests/fields/field_utils_tests.js | 30 +++++++++++++++++-- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/addons/web/static/src/js/fields/field_utils.js b/addons/web/static/src/js/fields/field_utils.js index bbdee83c4f9..ec99f4fa0f6 100644 --- a/addons/web/static/src/js/fields/field_utils.js +++ b/addons/web/static/src/js/fields/field_utils.js @@ -363,7 +363,7 @@ function formatPercentage(value, field, options) { if (options.humanReadable && options.humanReadable(value * 100)) { return result + "%"; } - return parseFloat(result) + "%"; + return (parseFloat(result) + "%").replace('.', _t.database.parameters.decimal_point); } /** * Returns a string representing the value of the selection. diff --git a/addons/web/static/tests/fields/field_utils_tests.js b/addons/web/static/tests/fields/field_utils_tests.js index 6b7cda13264..940f5674780 100644 --- a/addons/web/static/tests/fields/field_utils_tests.js +++ b/addons/web/static/tests/fields/field_utils_tests.js @@ -135,7 +135,9 @@ QUnit.test('format binary', function (assert) { }); QUnit.test('format percentage', function (assert) { - assert.expect(9); + assert.expect(11); + + var originalParameters = _.clone(core._t.database.parameters); assert.strictEqual(fieldUtils.format.percentage(0), '0%'); assert.strictEqual(fieldUtils.format.percentage(0.5), '50%'); @@ -151,6 +153,16 @@ QUnit.test('format percentage', function (assert) { assert.strictEqual(fieldUtils.format.percentage(50, null, {humanReadable: function (val) {return true;}}), '5k%' ); + + _.extend(core._t.database.parameters, { + grouping: [3, 0], + decimal_point: ',', + thousands_sep: '.' + }); + assert.strictEqual(fieldUtils.format.percentage(0.125), '12,5%'); + assert.strictEqual(fieldUtils.format.percentage(0.666666), '66,67%'); + + core._t.database.parameters = originalParameters; }); QUnit.test('parse float', function(assert) { @@ -262,7 +274,9 @@ QUnit.test('parse monetary', function(assert) { }); QUnit.test('parse percentage', function(assert) { - assert.expect(7); + assert.expect(9); + + var originalParameters = _.clone(core._t.database.parameters); assert.strictEqual(fieldUtils.parse.percentage(""), 0); assert.strictEqual(fieldUtils.parse.percentage("0"), 0); @@ -271,6 +285,18 @@ QUnit.test('parse percentage', function(assert) { assert.strictEqual(fieldUtils.parse.percentage("1"), 1); assert.strictEqual(fieldUtils.parse.percentage("2%"), 0.02); assert.strictEqual(fieldUtils.parse.percentage("100%"), 1); + + _.extend(core._t.database.parameters, { + grouping: [3, 0], + decimal_point: ',', + thousands_sep: '.' + }); + + assert.strictEqual(fieldUtils.parse.percentage("0,04"), 0.04); + assert.strictEqual(fieldUtils.parse.percentage("6,02%"), 0.0602); + + core._t.database.parameters = originalParameters; + }) }); From 07befd19a7b9ffb4b8174502c124bb5e97112fa8 Mon Sep 17 00:00:00 2001 From: Nicolas Martinelli Date: Mon, 7 Jan 2019 13:06:38 +0000 Subject: [PATCH 09/66] [FIX] web: make pie chart title translatable The Pie Chart title is not translatable, since a string defined in a `t-att-` cannot be translated. We use the attribute `title` instead. Tests are adapted in https://github.com/odoo/enterprise/pull/3379 opw-1908220 closes odoo/odoo#29991 --- addons/web/static/src/js/widgets/pie_chart.js | 1 + addons/web/static/src/xml/pie_chart.xml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/web/static/src/js/widgets/pie_chart.js b/addons/web/static/src/js/widgets/pie_chart.js index 663e2b4cc98..c483c23c73d 100644 --- a/addons/web/static/src/js/widgets/pie_chart.js +++ b/addons/web/static/src/js/widgets/pie_chart.js @@ -31,6 +31,7 @@ var PieChart = Widget.extend({ Domain.prototype.stringToArray(modifiers.domain || '[]')); var arch = qweb.render('web.PieChart', { modifiers: modifiers, + title: node.attrs.title || modifiers.title || modifiers.measure, }); this.subViewParams = { diff --git a/addons/web/static/src/xml/pie_chart.xml b/addons/web/static/src/xml/pie_chart.xml index 5c3411bc882..d45bef7af6f 100644 --- a/addons/web/static/src/xml/pie_chart.xml +++ b/addons/web/static/src/xml/pie_chart.xml @@ -1,7 +1,7 @@