diff --git a/addons/account/static/src/js/reconciliation/reconciliation_model.js b/addons/account/static/src/js/reconciliation/reconciliation_model.js index b136af9a4ed..9caea6d8712 100644 --- a/addons/account/static/src/js/reconciliation/reconciliation_model.js +++ b/addons/account/static/src/js/reconciliation/reconciliation_model.js @@ -1073,7 +1073,7 @@ var ManualModel = StatementModel.extend({ return self._rpc({ model: 'account.move.line', method: 'get_data_for_manual_reconciliation', - args: ['account', model.account_ids || self.account_ids], + args: ['account', context.account_ids || self.account_ids], context: context, }) .then(function (result) { diff --git a/addons/mail/static/src/js/client_action.js b/addons/mail/static/src/js/client_action.js index a3cbc75a949..866d431bd67 100644 --- a/addons/mail/static/src/js/client_action.js +++ b/addons/mail/static/src/js/client_action.js @@ -673,7 +673,9 @@ var ChatAction = Widget.extend(ControlPanelMixin, { }); }, destroy: function() { - this.$buttons.off().destroy(); + if (this.$buttons) { + this.$buttons.off().destroy(); + } this._super.apply(this, arguments); }, diff --git a/addons/payment_ogone/tests/test_ogone.py b/addons/payment_ogone/tests/test_ogone.py index b27e7a3c4ce..76215ebf72e 100644 --- a/addons/payment_ogone/tests/test_ogone.py +++ b/addons/payment_ogone/tests/test_ogone.py @@ -175,7 +175,4 @@ class OgonePayment(PaymentAcquirerCommon): 'number': '4000000000000002', 'brand': 'VISA'}) - # check an alias is set, containing at least OPENERP - self.assertIn('OPENERP', tx.partner_reference, 'ogone: wrong partner reference after creating an alias') - res = tx.ogone_s2s_execute({}) diff --git a/addons/payment_sips/models/payment.py b/addons/payment_sips/models/payment.py index a6c9b390eae..2069d34e004 100644 --- a/addons/payment_sips/models/payment.py +++ b/addons/payment_sips/models/payment.py @@ -49,7 +49,8 @@ class AcquirerSips(models.Model): 'prod': 'https://payment-webinit.sips-atos.com/paymentInit', 'test': 'https://payment-webinit.simu.sips-atos.com/paymentInit', } - return {'sips_form_url': url.get(environment, url['test']), } + icp_value = self.env['ir.config_parameter'].sudo().get_param('acquirer_sips_url_%s' % environment) + return {'sips_form_url': icp_value or url.get(environment, url['test']), } def _sips_generate_shasign(self, values): """ Generate the shasign for incoming or outgoing communications. @@ -172,8 +173,6 @@ class TxSips(models.Model): # check what is bought if float_compare(float(data.get('amount', '0.0')) / 100, self.amount, 2) != 0: invalid_parameters.append(('amount', data.get('amount'), '%.2f' % self.amount)) - if self.partner_reference and data.get('customerId') != self.partner_reference: - invalid_parameters.append(('customerId', data.get('customerId'), self.partner_reference)) return invalid_parameters diff --git a/addons/point_of_sale/static/src/js/models.js b/addons/point_of_sale/static/src/js/models.js index 647339cb3b2..35b745d64b9 100644 --- a/addons/point_of_sale/static/src/js/models.js +++ b/addons/point_of_sale/static/src/js/models.js @@ -2070,6 +2070,8 @@ exports.Order = Backbone.Model.extend({ initialize_validation_date: function () { this.validation_date = new Date(); + this.formatted_validation_date = field_utils.format.datetime( + moment(this.validation_date), {}, {timezone: false}); }, set_tip: function(tip) { diff --git a/addons/point_of_sale/static/src/xml/pos.xml b/addons/point_of_sale/static/src/xml/pos.xml index 498b0d4c516..fb1d255873f 100644 --- a/addons/point_of_sale/static/src/xml/pos.xml +++ b/addons/point_of_sale/static/src/xml/pos.xml @@ -1418,7 +1418,7 @@
-
+


diff --git a/addons/web/static/src/js/chrome/view_manager.js b/addons/web/static/src/js/chrome/view_manager.js index d89f035d34d..dd50929537d 100644 --- a/addons/web/static/src/js/chrome/view_manager.js +++ b/addons/web/static/src/js/chrome/view_manager.js @@ -26,7 +26,7 @@ var ViewManager = Widget.extend(ControlPanelMixin, { search: function(event) { var d = event.data; _.extend(this.env, this._process_search_data(d.domains, d.contexts, d.groupbys)); - this.active_view.controller.reload(_.extend({}, this.env)); + this.active_view.controller.reload(_.extend({offset: 0}, this.env)); }, switch_view: function(event) { if ('res_id' in event.data) { diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js index 3af10dbb930..a142ab0738a 100644 --- a/addons/web/static/src/js/fields/basic_fields.js +++ b/addons/web/static/src/js/fields/basic_fields.js @@ -2040,8 +2040,9 @@ var FieldDomain = AbstractField.extend({ "click .o_field_domain_dialog_button": "_onDialogEditButtonClick", }), custom_events: _.extend({}, AbstractField.prototype.custom_events, { - "domain_changed": "_onDomainSelectorValueChange", - "domain_selected": "_onDomainSelectorDialogValueChange", + domain_changed: "_onDomainSelectorValueChange", + domain_selected: "_onDomainSelectorDialogValueChange", + open_record: "_onOpenRecord", }), /** * @constructor @@ -2222,6 +2223,15 @@ var FieldDomain = AbstractField.extend({ _onDomainSelectorDialogValueChange: function (e) { this._setValue(Domain.prototype.arrayToString(e.data.domain)); }, + /** + * Stops the propagation of the 'open_record' event, as we don't want the + * user to be able to open records from the list opened in a dialog. + * + * @param {OdooEvent} event + */ + _onOpenRecord: function (event) { + event.stopPropagation(); + }, }); /** diff --git a/addons/web/static/src/js/views/abstract_view.js b/addons/web/static/src/js/views/abstract_view.js index 9a73ad67057..d9ddc4914b2 100644 --- a/addons/web/static/src/js/views/abstract_view.js +++ b/addons/web/static/src/js/views/abstract_view.js @@ -257,7 +257,7 @@ var AbstractView = Class.extend({ attrs.limit = attrs.mode === "tree" ? 80 : 40; - if (attrs.Widget.prototype.useSubview && !(attrs.invisible && JSON.parse(attrs.invisible)) && !attrs.views[attrs.mode]) { + if (attrs.Widget.prototype.useSubview && !attrs.__no_fetch && !attrs.views[attrs.mode]) { var context = {}; var regex = /'([a-z]*_view_ref)' *: *'(.*?)'/g; var matches; diff --git a/addons/web/static/src/js/views/form/form_controller.js b/addons/web/static/src/js/views/form/form_controller.js index 0bd3c263666..e1a834b2c18 100644 --- a/addons/web/static/src/js/views/form/form_controller.js +++ b/addons/web/static/src/js/views/form/form_controller.js @@ -510,6 +510,7 @@ var FormController = BasicController.extend({ * @param {OdooEvent} event */ _onToggleColumnOrder: function (event) { + event.stopPropagation(); this.model.setSort(event.data.id, event.data.name); var field = event.data.field; var state = this.model.get(this.handle); diff --git a/addons/web/static/src/less/form_view_extra.less b/addons/web/static/src/less/form_view_extra.less index 6e48c173c6e..cc153825d1c 100644 --- a/addons/web/static/src/less/form_view_extra.less +++ b/addons/web/static/src/less/form_view_extra.less @@ -115,6 +115,18 @@ vertical-align: middle; } } + + &.o_full { + position: relative; + .o_button_more { + padding: 0 10px; + } + .o_dropdown_more { + .o-position-absolute(@top: 100%, @right: 0); + min-width: 0; + padding: 0px; + } + } } // Avatar diff --git a/addons/web/static/tests/fields/basic_fields_tests.js b/addons/web/static/tests/fields/basic_fields_tests.js index b63bd27cba7..01c67fbb877 100644 --- a/addons/web/static/tests/fields/basic_fields_tests.js +++ b/addons/web/static/tests/fields/basic_fields_tests.js @@ -3813,6 +3813,46 @@ QUnit.module('basic_fields', { form.destroy(); }); + + QUnit.test('basic domain field: show the selection', function (assert) { + assert.expect(2); + + this.data.partner.records[0].foo = "[]"; + + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: + '
' + + '' + + '' + + '' + + '' + + '' + + '
', + archs: { + 'partner_type,false,list': '', + 'partner_type,false,search': '', + }, + res_id: 1, + }); + + assert.equal(form.$(".o_domain_show_selection_button").text().trim().substr(0, 2), "2 ", + "selection should contain 2 records"); + + // open the selection + form.$(".o_domain_show_selection_button").click(); + assert.strictEqual($('.modal .o_list_view .o_data_row').length, 2, + "should have open a list view with 2 records in a dialog"); + + // click on a record -> should not open the record + // we don't actually check that it doesn't open the record because even + // if it tries to, it will crash as we don't define an arch in this test + $('.modal .o_list_view .o_data_row:first .o_data_cell').click(); + + form.destroy(); + }); }); }); }); diff --git a/addons/web/static/tests/helpers/mock_server.js b/addons/web/static/tests/helpers/mock_server.js index 9523f8b0c0f..4f73e15f9ae 100644 --- a/addons/web/static/tests/helpers/mock_server.js +++ b/addons/web/static/tests/helpers/mock_server.js @@ -910,8 +910,7 @@ var MockServer = Class.extend({ return $.when(this.data[args.model][args.method](args.args, args.kwargs)); } - console.error("Unimplemented route", route, args); - return $.when(); + throw new Error("Unimplemented route: " + route); }, /** * helper function: traverse a tree and apply the function f to each of its diff --git a/addons/web/static/tests/views/form_tests.js b/addons/web/static/tests/views/form_tests.js index 78e4fc5dc68..de3274c23ba 100644 --- a/addons/web/static/tests/views/form_tests.js +++ b/addons/web/static/tests/views/form_tests.js @@ -211,7 +211,7 @@ QUnit.module('Views', { }); QUnit.test('invisible fields are properly hidden', function (assert) { - assert.expect(3); + assert.expect(4); var form = createView({ View: FormView, @@ -224,6 +224,10 @@ QUnit.module('Views', { '' + '' + '' + + // x2many field without inline view: as it is always invisible, the view + // should not be fetched. we don't specify any view in this test, so if it + // ever tries to fetch it, it will crash, indicating that this is wrong. + '' + '' + '', res_id: 1, @@ -235,6 +239,8 @@ QUnit.module('Views', { "should not contain span with field value"); assert.strictEqual(form.$('.o_field_widget.o_invisible_modifier:contains(0.4)').length, 1, "field qux should be invisible"); + assert.ok(form.$('.o_field_widget[name=p]').hasClass('o_invisible_modifier'), + "field p should be invisible"); form.destroy(); }); @@ -5843,6 +5849,46 @@ QUnit.module('Views', { form.destroy(); }); + QUnit.test('can toggle column in x2many in sub form view', function (assert) { + assert.expect(2); + + this.data.partner.records[2].p = [1,2]; + this.data.partner.fields.foo.sortable = true; + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: '
' + + '' + + '', + res_id: 1, + mockRPC: function (route, args) { + if (route === '/web/dataset/call_kw/partner/get_formview_id') { + return $.when(false); + } + return this._super.apply(this, arguments); + }, + archs: { + 'partner,false,form': '
' + + '' + + '' + + '' + + '' + + '' + + '
', + }, + viewOptions: {mode: 'edit'}, + }); + form.$('.o_external_button').click(); + assert.strictEqual($('.modal-body .o_form_view .o_list_view .o_data_cell').text(), "yopblip", + "table has some initial order"); + + $('.modal-body .o_form_view .o_list_view th').click(); + assert.strictEqual($('.modal-body .o_form_view .o_list_view .o_data_cell').text(), "blipyop", + "table is now sorted"); + form.destroy(); + }); + QUnit.test('rainbowman attributes correctly passed on button click', function (assert) { assert.expect(1);