From a3ab33f2121c487920d370675d0e1a32dfc96c65 Mon Sep 17 00:00:00 2001 From: Goffin Simon Date: Thu, 24 May 2018 09:46:36 +0200 Subject: [PATCH 1/5] [FIX] mass_mailing: unsubscribe not working in multi lang When installing the website with a lang different than the one set on the user, the button unsubscribe in the mass mailing snippets didn't work because the unsubscribe link contains the code of the language. The function send_get_email_dict in model mail.mail didn't expect this behavior and so couldn't set the right unsubscribe link in the mail. opw:1850696 --- addons/mass_mailing/models/mail_mail.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/mass_mailing/models/mail_mail.py b/addons/mass_mailing/models/mail_mail.py index f4611a3250c..f7ef42ff223 100644 --- a/addons/mass_mailing/models/mail_mail.py +++ b/addons/mass_mailing/models/mail_mail.py @@ -99,9 +99,9 @@ class MailMail(osv.Model): emails = tools.email_split(res.get('email_to')[0]) email_to = emails and emails[0] or False unsubscribe_url= self._get_unsubscribe_url(cr, uid, mail, email_to, context=context) - link_to_replace = base_url+'/unsubscribe_from_list' + regex_link_to_replace = re.escape(base_url) + '(/[a-z]{2}_[A-Z]{2})?' + '/unsubscribe_from_list' if link_to_replace in res['body']: - res['body'] = res['body'].replace(link_to_replace, unsubscribe_url if unsubscribe_url else '#') + res['body'] = res['body'].replace(regex_link_to_replace, unsubscribe_url if unsubscribe_url else '#') return res def _postprocess_sent_message(self, cr, uid, mail, context=None, mail_sent=True): From 28179bc8cb9d98a60936634e50ca733beec0393f Mon Sep 17 00:00:00 2001 From: Yannick Tivisse Date: Thu, 24 May 2018 13:13:47 +0200 Subject: [PATCH 2/5] [IMP] base: Add support for private addresses This is a backport of commit https://github.com/odoo/odoo/commit/2f15a5fa647d55df36c9019df467802a3aa9b4e3 Purpose ======= Add the possibility to create private addresses, only accessible for a subset of users. Specification ============= - Add a new 'Private' partner type - Add a res.groups in base 'Access to Private Addresses' - Add ir.rules for the following behavior: - Every employees/internal users can read non-private addresses - Only users in group_private_addresses can access private addresses - Add in base a simplified form view for private addresses The following points won't be backported: - A HR Officer is automatically granted in group_private_addresses - Use the simplified form view to open the address_home_id form on employees That's because it requires to update 'base' to make it work. If a user only update 'hr', this will break his instance while 'base' isn't updated. But these modifications can be applied manually quite easily. --- openerp/addons/base/res/res_partner.py | 3 +- openerp/addons/base/res/res_partner_view.xml | 44 +++++++++++++++++++ .../addons/base/security/base_security.xml | 35 +++++++++++++++ 3 files changed, 81 insertions(+), 1 deletion(-) diff --git a/openerp/addons/base/res/res_partner.py b/openerp/addons/base/res/res_partner.py index 4995c13b975..5214d9384ec 100644 --- a/openerp/addons/base/res/res_partner.py +++ b/openerp/addons/base/res/res_partner.py @@ -212,7 +212,8 @@ class res_partner(osv.Model, format_address): [('contact', 'Contact'), ('invoice', 'Invoice address'), ('delivery', 'Shipping address'), - ('other', 'Other address')], 'Address Type', + ('other', 'Other address'), + ("private", "Private Address")], string='Address Type', help="Used to select automatically the right address according to the context in sales and purchases documents."), 'street': fields.char('Street'), 'street2': fields.char('Street2'), diff --git a/openerp/addons/base/res/res_partner_view.xml b/openerp/addons/base/res/res_partner_view.xml index e7e51b2f54b..201e0c8964a 100644 --- a/openerp/addons/base/res/res_partner_view.xml +++ b/openerp/addons/base/res/res_partner_view.xml @@ -330,6 +330,50 @@ + + + res.partner.view.form.private + res.partner + + +
+ + + +
+
+
+ res.partner.select res.partner diff --git a/openerp/addons/base/security/base_security.xml b/openerp/addons/base/security/base_security.xml index e3de88cf30b..aab7d358f8d 100644 --- a/openerp/addons/base/security/base_security.xml +++ b/openerp/addons/base/security/base_security.xml @@ -59,6 +59,10 @@ Contact Creation + + Access to Private Addresses + + + + res.partner.rule.private.employee + + + [('type', '!=', 'private')] + + + + + + + + + + res.partner.rule.private.group + + + [('type', '=', 'private')] + + + + + + + + From 919a1af93601f3873b78c755575cf0486da24e4e Mon Sep 17 00:00:00 2001 From: jem-odoo Date: Thu, 24 May 2018 14:10:50 +0200 Subject: [PATCH 3/5] [FIX] purchase: correct product cost in reporting product.product inheritS from product.template, and they both define the 'standard_price' field, but implement it differently; - product: the field is a company dependent one (so non stored) - template: the field is a computed one based on tis variants For the first case, since the field is not stored in database, when doing SQL query, we have to get the value from the table ir_property. That is what purchase report does, but instead of searching on resource 'product.product', it does it on 'product.template'. There are obviously no entries in ir_property table for 'standard_price' field on product template. As consequence, the "product value" (cost) is always null in purchase reporting. This commit fixes that by modifying SQL query to get the good value from ir_property table. --- addons/purchase/report/purchase_report.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/purchase/report/purchase_report.py b/addons/purchase/report/purchase_report.py index a1a6cb4e3b2..b5ef4110c31 100644 --- a/addons/purchase/report/purchase_report.py +++ b/addons/purchase/report/purchase_report.py @@ -82,7 +82,7 @@ class purchase_report(osv.osv): join res_partner partner on s.partner_id = partner.id left join product_product p on (l.product_id=p.id) left join product_template t on (p.product_tmpl_id=t.id) - LEFT JOIN ir_property ip ON (ip.name='standard_price' AND ip.res_id=CONCAT('product.template,',t.id) AND ip.company_id=s.company_id) + LEFT JOIN ir_property ip ON (ip.name='standard_price' AND ip.res_id=CONCAT('product.product,',p.id) AND ip.company_id=s.company_id) left join product_uom u on (u.id=l.product_uom) left join product_uom u2 on (u2.id=t.uom_id) left join stock_picking_type spt on (spt.id=s.picking_type_id) From 6e1b660f9c76a412dcd78d7f7de593ae318c00bd Mon Sep 17 00:00:00 2001 From: LofbergValentin Date: Thu, 24 May 2018 16:00:11 +0200 Subject: [PATCH 4/5] [FIX] hr_attendance: Keep the kiosk session alive MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit closes #1800442 Purpose ======= Odoo sessions are expired when no action has been triggered for the last 7 days. For kiosk mode, this doesn’t make sense. It means that once a week, a person with the rights to the employee under kiosk mode, has to come to the screen and log in again. Specification ============= Trigger an action to keep the Odoo session alive. --- addons/hr_attendance/static/src/js/kiosk_mode.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/addons/hr_attendance/static/src/js/kiosk_mode.js b/addons/hr_attendance/static/src/js/kiosk_mode.js index 51c78bd34b4..9a7e2898df1 100644 --- a/addons/hr_attendance/static/src/js/kiosk_mode.js +++ b/addons/hr_attendance/static/src/js/kiosk_mode.js @@ -36,6 +36,8 @@ var KioskMode = Widget.extend(BarcodeHandlerMixin, { self.$el.html(QWeb.render("HrAttendanceKioskMode", {widget: self})); self.start_clock(); }); + // Make a RPC call every day to keep the session alive + self._interval = window.setInterval(this._callServer.bind(this), (60*60*1000*24)); return self._super.apply(this, arguments); }, @@ -60,8 +62,15 @@ var KioskMode = Widget.extend(BarcodeHandlerMixin, { destroy: function () { clearInterval(this.clock_start); + clearInterval(this._interval); this._super.apply(this, arguments); }, + + _callServer: function () { + // Make a call to the database to avoid the auto close of the session + return Session.rpc('/web/webclient/version_info', {}) + }, + }); core.action_registry.add('hr_attendance_kiosk_mode', KioskMode); From 34f567dd397a016e526c3923024ee1cf9234ca5d Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Thu, 24 May 2018 16:50:09 +0200 Subject: [PATCH 5/5] Revert "[FIX] mass_mailing: unsubscribe not working in multi lang" commit a3ab33f2121c487920d370675d0e1a32dfc96c65 introduced invalid code --- addons/mass_mailing/models/mail_mail.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/mass_mailing/models/mail_mail.py b/addons/mass_mailing/models/mail_mail.py index f7ef42ff223..f4611a3250c 100644 --- a/addons/mass_mailing/models/mail_mail.py +++ b/addons/mass_mailing/models/mail_mail.py @@ -99,9 +99,9 @@ class MailMail(osv.Model): emails = tools.email_split(res.get('email_to')[0]) email_to = emails and emails[0] or False unsubscribe_url= self._get_unsubscribe_url(cr, uid, mail, email_to, context=context) - regex_link_to_replace = re.escape(base_url) + '(/[a-z]{2}_[A-Z]{2})?' + '/unsubscribe_from_list' + link_to_replace = base_url+'/unsubscribe_from_list' if link_to_replace in res['body']: - res['body'] = res['body'].replace(regex_link_to_replace, unsubscribe_url if unsubscribe_url else '#') + res['body'] = res['body'].replace(link_to_replace, unsubscribe_url if unsubscribe_url else '#') return res def _postprocess_sent_message(self, cr, uid, mail, context=None, mail_sent=True):