From 6fb7680ef808003b965e0929731afdde53e3bde0 Mon Sep 17 00:00:00 2001 From: Fabrice Henrion Date: Mon, 26 Sep 2016 16:55:09 -0700 Subject: [PATCH 1/9] [IMP] policy clarification --- doc/setup/install.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/setup/install.rst b/doc/setup/install.rst index 0f1de4f14c0..3e5940d8ba1 100644 --- a/doc/setup/install.rst +++ b/doc/setup/install.rst @@ -61,11 +61,11 @@ refer to :ref:`setup/enterprise` (except for :ref:`setup/install/source`). If you wish to access the Enterprise installers/source code, you can: * Go to the Download_ page and log in with your customer credentials -* Download the source on GitHub using git_ +* Download the source on GitHub using git_(available to partners only) .. note:: If you do not have access to our Enterprise repository, you can request it be e-mailing your sales representative or our online support with - your subscription number and GitHub username. + your subscription number and GitHub username. (available to partners only) .. warning:: Enterprise deb and rpm packages do not have repositories, so automatic update will not work. Reinstalling the latest package version will be needed From 1bb162c913d4bada5bf21a2a536ac5939a0c1dd2 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Tue, 9 Aug 2016 08:32:35 +0100 Subject: [PATCH 2/9] [CLA] Michael Brown Signed-off-by: Michael Brown Closes #13070 --- doc/cla/individual/mcb30.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 doc/cla/individual/mcb30.md diff --git a/doc/cla/individual/mcb30.md b/doc/cla/individual/mcb30.md new file mode 100644 index 00000000000..b3c601a1ff6 --- /dev/null +++ b/doc/cla/individual/mcb30.md @@ -0,0 +1,11 @@ +United Kingdom, 2016-08-09 + +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, + +Michael Brown mbrown@fensystems.co.uk https://github.com/mcb30 From ccd6fc621ba81c3c6b632053796a14ee99f529a2 Mon Sep 17 00:00:00 2001 From: tdi-odoo Date: Thu, 15 Sep 2016 09:52:24 +0200 Subject: [PATCH 3/9] [FIX] expense: fixes #13446 mutliple taxes on expenses --- addons/hr_expense/models/hr_expense.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/hr_expense/models/hr_expense.py b/addons/hr_expense/models/hr_expense.py index 2433c18efe8..cf8c05b2e13 100644 --- a/addons/hr_expense/models/hr_expense.py +++ b/addons/hr_expense/models/hr_expense.py @@ -288,7 +288,7 @@ class HrExpense(models.Model): # Calculate tax lines and adjust base line taxes = expense.tax_ids.compute_all(expense.unit_amount, expense.currency_id, expense.quantity, expense.product_id) account_move[-1]['price'] = taxes['total_excluded'] - account_move[-1]['tax_ids'] = expense.tax_ids.id + account_move[-1]['tax_ids'] = expense.tax_ids.ids for tax in taxes['taxes']: account_move.append({ 'type': 'tax', From 6490bdc26323423c9a6b3fe11ea362401c5c0ba9 Mon Sep 17 00:00:00 2001 From: "Denis Vermylen (dve)" Date: Tue, 27 Sep 2016 10:51:37 +0200 Subject: [PATCH 4/9] [IMP] hr_holiday: remove leave onchange date check When you create a leave, you first set the start date. The date widget triggers and automatically sets you at today, which triggers the onchange and puts the end date at today + 8 hours. You then set your start date in the future -> invalid dates because start date > end date. This commit removes the onchange verification of the dates, because almost everyone gets the above problem and because it is redundant with the sql constraint that triggers anyway when you try to save with invalid dates. --- addons/hr_holidays/hr_holidays.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/addons/hr_holidays/hr_holidays.py b/addons/hr_holidays/hr_holidays.py index 1001bb6e8e6..3697e7bfa92 100644 --- a/addons/hr_holidays/hr_holidays.py +++ b/addons/hr_holidays/hr_holidays.py @@ -299,10 +299,6 @@ class hr_holidays(osv.osv): the date_from. Also update the number_of_days. """ - # date_to has to be greater than date_from - if (date_from and date_to) and (date_from > date_to): - raise UserError(_('The start date must be anterior to the end date.')) - result = {'value': {}} # No date_to set so far: automatically compute one 8 hours later @@ -323,10 +319,6 @@ class hr_holidays(osv.osv): """ Update the number_of_days. """ - # date_to has to be greater than date_from - if (date_from and date_to) and (date_from > date_to): - raise UserError(_('The start date must be anterior to the end date.')) - result = {'value': {}} # Compute and update the number of days From c952e1fc55e6b2dfae948a92f191fba9537519d5 Mon Sep 17 00:00:00 2001 From: qsm-odoo Date: Tue, 27 Sep 2016 12:09:20 +0200 Subject: [PATCH 5/9] [FIX] website_sale: fix shop list view publish buttons Publish buttons appeared in list view item in /shop with commit 5a5dd1e100bb2e5bc2a6e215a963322bbfbe98b1. They however never worked for some reasons: * The publish buttons were unclickable as the around style was badly implemented: the section title was over the publish button * Even if it was clickable, the publish button handler had no prevent default, thus it submitted the form it is in -> crash when no cart button or added to cart on click on publish button if there was a cart button... Note: the style should be reviewed in next versions, this commit, as a 9.0 fix, fixes the style with the minimum code and so that it does not break any theme. --- addons/website/static/src/js/website.js | 5 +++-- addons/website_sale/static/src/css/website_sale.css | 6 ++++-- addons/website_sale/static/src/css/website_sale.sass | 6 ++++-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/addons/website/static/src/js/website.js b/addons/website/static/src/js/website.js index 7c2ad6cc48c..4e5b805fa8c 100644 --- a/addons/website/static/src/js/website.js +++ b/addons/website/static/src/js/website.js @@ -186,9 +186,10 @@ base.ready().then(function () { */ /* ----- PUBLISHING STUFF ---- */ - $(document).on('click', '.js_publish_management .js_publish_btn', function () { + $(document).on('click', '.js_publish_management .js_publish_btn', function (e) { + e.preventDefault(); + var $data = $(this).parents(".js_publish_management:first"); - var self=this; ajax.jsonRpc($data.data('controller') || '/website/publish', 'call', {'id': +$data.data('id'), 'object': $data.data('object')}) .then(function (result) { $data.toggleClass("css_unpublished css_published"); diff --git a/addons/website_sale/static/src/css/website_sale.css b/addons/website_sale/static/src/css/website_sale.css index 1a6a148f6fa..22983ab9c85 100644 --- a/addons/website_sale/static/src/css/website_sale.css +++ b/addons/website_sale/static/src/css/website_sale.css @@ -359,6 +359,7 @@ min-height: 100px; position: relative; padding-bottom: 5px; + padding-left: 180px; } .oe_product.oe_list .oe_product_image { top: 0; @@ -370,9 +371,10 @@ .oe_product.oe_list section { position: relative; border: 0; - top: 0; + top: auto; bottom: auto; - left: 180px; + left: auto; + right: auto; background: transparent; } } diff --git a/addons/website_sale/static/src/css/website_sale.sass b/addons/website_sale/static/src/css/website_sale.sass index f8179bd6bc0..009657b2bcf 100644 --- a/addons/website_sale/static/src/css/website_sale.sass +++ b/addons/website_sale/static/src/css/website_sale.sass @@ -306,6 +306,7 @@ min-height: 100px position: relative padding-bottom: 5px + padding-left: 180px .oe_product_image top: 0 bottom: 0 @@ -315,9 +316,10 @@ section position: relative border: 0 - top: 0 + top: auto bottom: auto - left: 180px + left: auto + right: auto background: transparent .oe_website_sale .row .row .col-md-12 From 1df161db6b9eb63c3012fde34da07bbdfb15108a Mon Sep 17 00:00:00 2001 From: qsm-odoo Date: Tue, 27 Sep 2016 16:23:40 +0200 Subject: [PATCH 6/9] [FIX] website_blog: keep consistent cover classes when changing cover image ! Note forward port: this is a partial backport, ignore when conflict For some strange reason, the cover_full class was added when the cover image was changed, without checking if the cover_narrow class was already there. The cover was then a hybrid cover_narrow cover_full. The problem was reinforced by the graphene theme which does some animation on cover_full covers. --- addons/website_blog/static/src/js/website_blog.editor.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/addons/website_blog/static/src/js/website_blog.editor.js b/addons/website_blog/static/src/js/website_blog.editor.js index 42965e68fca..1d074dc0ac0 100644 --- a/addons/website_blog/static/src/js/website_blog.editor.js +++ b/addons/website_blog/static/src/js/website_blog.editor.js @@ -102,8 +102,12 @@ odoo.define('website_blog.editor', function (require) { editor.on('saved', self, function (event, img) { var url = self.$image.attr('src'); self.$cover.css({"background-image": url ? 'url(' + url + ')' : "", 'min-height': $(window).height()-this.$cover.offset().top}); - self.$target.addClass('o_dirty cover cover_full'); + if (!self.$target.hasClass("cover")) { + var $li = self.$el.find("[data-cover_class]").first(); + self.cover_class(type, $li.data("cover_class"), $li); + } self.set_active(); + self.$target.addClass("o_dirty"); }); }, cover_class : function(type, value, $li) { From 40bce50ddbffa5ef663fe02c9b2025d0b2d6b6d3 Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Tue, 27 Sep 2016 19:36:54 +0200 Subject: [PATCH 7/9] Revert "[FIX] mail: onchange_template_id" This reverts commit dc02f773ce616e1eba564e574c654fe51d665d11. This commit caused a side-effect that is worse than the issue it tried to fix, which was purely cosmetic. Now in mass-mail mode the template is only rendered once and all recipients receive the same PDF, which completely defeats the goal of a dynamic report. We have static attachments for that. Original fix related to opw-657152 Reverts PR #10568 --- addons/mail/models/mail_template.py | 2 +- addons/mail/wizard/mail_compose_message.py | 23 +--------------------- 2 files changed, 2 insertions(+), 23 deletions(-) diff --git a/addons/mail/models/mail_template.py b/addons/mail/models/mail_template.py index c4346fd6c71..c84bc1bca2b 100644 --- a/addons/mail/models/mail_template.py +++ b/addons/mail/models/mail_template.py @@ -493,7 +493,7 @@ class MailTemplate(models.Model): ) # Add report in attachments: generate once for all template_res_ids - if template.report_template and not 'report_template_in_attachment' in self.env.context: + if template.report_template: for res_id in template_res_ids: attachments = [] report_name = self.render_template(template.report_name, template.model, res_id) diff --git a/addons/mail/wizard/mail_compose_message.py b/addons/mail/wizard/mail_compose_message.py index 6296496662a..6898341bb7f 100644 --- a/addons/mail/wizard/mail_compose_message.py +++ b/addons/mail/wizard/mail_compose_message.py @@ -187,7 +187,7 @@ class MailComposer(models.TransientModel): @api.multi def send_mail_action(self): # TDE/ ??? - return self.with_context(report_template_in_attachment=True).send_mail() + return self.send_mail() @api.multi def send_mail(self, auto_commit=False): @@ -346,20 +346,6 @@ class MailComposer(models.TransientModel): if template.user_signature and 'body_html' in values: signature = self.env.user.signature values['body_html'] = tools.append_content_to_html(values['body_html'], signature, plaintext=False) - if template.report_template: - attachment = self.env['ir.attachment'] - attach = self.generate_attachment_from_report(template_id, res_id) - for attach_fname, attach_datas in attach[res_id].pop('attachments', []): - data_attach = { - 'name': attach_fname, - 'datas': attach_datas, - 'datas_fname': attach_fname, - 'res_model': 'mail.compose.message', - 'res_id': 0, - 'type': 'binary', - } - values.setdefault('attachment_ids', list()).append(attachment.create(data_attach).id) - elif template_id: values = self.generate_email_for_composer(template_id, [res_id])[res_id] # transform attachments into attachment_ids; not attached to the document because this will @@ -390,13 +376,6 @@ class MailComposer(models.TransientModel): return {'value': values} - @api.multi - def generate_attachment_from_report(self, template_id, res_id): - fields = ['attachment_ids'] - result = self.env['mail.template'].with_context(tpl_partners_only=True).browse(template_id).generate_email([res_id], fields=fields) - return result - - @api.multi def save_as_template(self): """ hit save as template button: current form value will be a new From 8469fe2eace33019f7b82ecf83a3648358342498 Mon Sep 17 00:00:00 2001 From: Nicolas Martinelli Date: Wed, 28 Sep 2016 09:45:14 +0200 Subject: [PATCH 8/9] [FIX] account: exchange rate date The fields `amount_total_company_signed` and `amount_untaxed_signed` are always converted using the exchange rate of today. opw-688838 --- addons/account/models/account_invoice.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/addons/account/models/account_invoice.py b/addons/account/models/account_invoice.py index eb3d5cde5e3..8b9d07a27ec 100644 --- a/addons/account/models/account_invoice.py +++ b/addons/account/models/account_invoice.py @@ -39,7 +39,7 @@ class AccountInvoice(models.Model): _order = "date_invoice desc, number desc, id desc" @api.one - @api.depends('invoice_line_ids.price_subtotal', 'tax_line_ids.amount', 'currency_id', 'company_id') + @api.depends('invoice_line_ids.price_subtotal', 'tax_line_ids.amount', 'currency_id', 'company_id', 'date_invoice') def _compute_amount(self): self.amount_untaxed = sum(line.price_subtotal for line in self.invoice_line_ids) self.amount_tax = sum(line.amount for line in self.tax_line_ids) @@ -47,8 +47,9 @@ class AccountInvoice(models.Model): amount_total_company_signed = self.amount_total amount_untaxed_signed = self.amount_untaxed if self.currency_id and self.currency_id != self.company_id.currency_id: - amount_total_company_signed = self.currency_id.compute(self.amount_total, self.company_id.currency_id) - amount_untaxed_signed = self.currency_id.compute(self.amount_untaxed, self.company_id.currency_id) + currency_id = self.currency_id.with_context(date=self.date_invoice) + amount_total_company_signed = currency_id.compute(self.amount_total, self.company_id.currency_id) + amount_untaxed_signed = currency_id.compute(self.amount_untaxed, self.company_id.currency_id) sign = self.type in ['in_refund', 'out_refund'] and -1 or 1 self.amount_total_company_signed = amount_total_company_signed * sign self.amount_total_signed = self.amount_total * sign From 9ba569874c494fa2065d1fa2ec79a79e4cf09d00 Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Wed, 28 Sep 2016 12:39:55 +0200 Subject: [PATCH 9/9] [FIX] calendar: fix attendees list in invitation email Upon the creation of an event, the list of attendees displayed in the invitation emails were not complete because the emails were sent as the attendees were being added to the event, in the loop. e.g.: - Create an event with Joseph and Michel - Joseph received the invitation email with only him as attendee - Michel received the invitaiton email with Joseph and him. The invitation email of Joseph now contains all the attendees. opw-681242 --- addons/calendar/calendar.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/addons/calendar/calendar.py b/addons/calendar/calendar.py index 85dc1035b3f..5ed50a207a9 100644 --- a/addons/calendar/calendar.py +++ b/addons/calendar/calendar.py @@ -1063,6 +1063,7 @@ class calendar_event(osv.Model): attendees[att.partner_id.id] = True new_attendees = [] new_att_partner_ids = [] + attendees_to_mail = [] for partner in event.partner_ids: if partner.id in attendees: continue @@ -1084,8 +1085,7 @@ class calendar_event(osv.Model): if not current_user.email or current_user.email != partner.email: mail_from = current_user.email or tools.config.get('email_from', False) if not context.get('no_email'): - if self.pool['calendar.attendee']._send_mail_to_attendees(cr, uid, att_id, email_from=mail_from, context=context): - self.message_post(cr, uid, event.id, body=_("An invitation email has been sent to attendee %s") % (partner.name,), subtype="calendar.subtype_invitation", context=context) + attendees_to_mail.append((att_id, mail_from, partner.name)) if new_attendees: self.write(cr, uid, [event.id], {'attendee_ids': [(4, att) for att in new_attendees]}, context=context) @@ -1105,6 +1105,10 @@ class calendar_event(osv.Model): if attendee_ids_to_remove: self.pool['calendar.attendee'].unlink(cr, uid, attendee_ids_to_remove, context) + for att_id, mail_from, partner_name in attendees_to_mail: + if self.pool['calendar.attendee']._send_mail_to_attendees(cr, uid, att_id, email_from=mail_from, context=context): + self.message_post(cr, uid, event.id, body=_("An invitation email has been sent to attendee %s") % (partner_name,), subtype="calendar.subtype_invitation", context=context) + res[event.id] = { 'new_attendee_ids': new_attendees, 'old_attendee_ids': all_attendee_ids,