From 7a63d471edec45a106fef5f783aeb7eaf43447f6 Mon Sep 17 00:00:00 2001 From: Nicolas Lempereur Date: Mon, 22 Jan 2018 12:04:27 +0100 Subject: [PATCH 01/19] [FIX] website_event_track: use event timezone Depending on the location, on the website different timezone were used to display tracks: - in `Agenda` day date (as of saas-14): the current user timezone - in `Agenda` track times: the event timezone - in `Talks` subtitle: the event timezone - in `Talks` tracks: the current user timezone - in a track page: the first user (admin) timezone With this change in all those instance the event timezone is used. There is still a usability hindrance in the backend: the timezone used when encoding track or event datetime is the browser timezone. So if the browser is GMT+2 and the event is GMT+6, encoding a 4h00 time would save it as 2h00 (in UTC) and display it on the website as 8h00. This would make sense to encode these datetime in user timezone but currently there is no framework option to do it. opw-805358 closes #22427 --- addons/website_event_track/controllers/main.py | 4 +++- .../views/website_event_track_templates.xml | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/addons/website_event_track/controllers/main.py b/addons/website_event_track/controllers/main.py index 296ba70ecc6..cf69304a87c 100644 --- a/addons/website_event_track/controllers/main.py +++ b/addons/website_event_track/controllers/main.py @@ -14,7 +14,7 @@ class WebsiteEventTrackController(http.Controller): @http.route(['''/event//track/
Date
-
+ + () +
Duration

Location
From 2d777d5ade94f4a80862608e2807660f289d9923 Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Mon, 22 Jan 2018 17:17:52 +0100 Subject: [PATCH 02/19] [FIX] hr: extend employee privacy protection to a few fields A few fields present in the "Private Info" tab of the Employee form did not have the corresponding `groups` attribute. This could cause access rights problems. --- addons/hr/models/hr.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/addons/hr/models/hr.py b/addons/hr/models/hr.py index da78143625a..7ff1b74a56a 100644 --- a/addons/hr/models/hr.py +++ b/addons/hr/models/hr.py @@ -111,9 +111,10 @@ class Employee(models.Model): active = fields.Boolean('Active', related='resource_id.active', default=True, store=True) # private partner address_home_id = fields.Many2one( - 'res.partner', 'Private Address', help='Enter here the private address of the employee, not the one linked to your company.') + 'res.partner', 'Private Address', help='Enter here the private address of the employee, not the one linked to your company.', + groups="hr.group_hr_user") country_id = fields.Many2one( - 'res.country', 'Nationality (Country)') + 'res.country', 'Nationality (Country)', groups="hr.group_hr_user") gender = fields.Selection([ ('male', 'Male'), ('female', 'Female'), @@ -135,9 +136,9 @@ class Employee(models.Model): domain="[('partner_id', '=', address_home_id)]", groups="hr.group_hr_user", help='Employee bank salary account') - permit_no = fields.Char('Work Permit No') - visa_no = fields.Char('Visa No') - visa_expire = fields.Date('Visa Expire Date') + permit_no = fields.Char('Work Permit No', groups="hr.group_hr_user") + visa_no = fields.Char('Visa No', groups="hr.group_hr_user") + visa_expire = fields.Date('Visa Expire Date', groups="hr.group_hr_user") # image: all image fields are base64 encoded and PIL-supported image = fields.Binary( From 779afb7ac534f003eee0cf3fd0afae401682095d Mon Sep 17 00:00:00 2001 From: "Lucas Perais (lpe)" Date: Fri, 19 Jan 2018 15:47:02 +0100 Subject: [PATCH 03/19] [FIX] point_of_sale: pos manager should have unlink rights --- addons/point_of_sale/security/ir.model.access.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/point_of_sale/security/ir.model.access.csv b/addons/point_of_sale/security/ir.model.access.csv index b83298d0c09..48dfef83314 100644 --- a/addons/point_of_sale/security/ir.model.access.csv +++ b/addons/point_of_sale/security/ir.model.access.csv @@ -28,7 +28,7 @@ access_product_category_manager,product.category manager,product.model_product_c access_product_pricelist_manager,product.pricelist manager,product.model_product_pricelist,group_pos_manager,1,0,0,0 access_pos_session_user,pos.session user,model_pos_session,group_pos_user,1,1,1,0 access_pos_config_user,pos.config user,model_pos_config,group_pos_user,1,0,0,0 -access_pos_config_manager,pos.config user,model_pos_config,group_pos_manager,1,1,1,0 +access_pos_config_manager,pos.config manager,model_pos_config,group_pos_manager,1,1,1,1 access_product_category_pos_manager,pos.category manager,model_pos_category,group_pos_manager,1,1,1,1 access_product_category_pos_user,pos.category user,model_pos_category,group_pos_user,1,0,0,0 access_barcode_nomenclature_pos_user,barcode.nomenclature.pos.user,barcodes.model_barcode_nomenclature,group_pos_user,1,0,0,0 From 296c5a2106950b57445c4fd1cb6cac4cd4be15af Mon Sep 17 00:00:00 2001 From: "Lucas Perais (lpe)" Date: Wed, 17 Jan 2018 13:31:59 +0100 Subject: [PATCH 04/19] [FIX] point_of_sale: automatic reconciliation with returns In the case where: 1- Do an order on the pos selling a product A (amount = 10) 2- Do another order returning a certain quantity of A (with a quantity < 0) 3- Do a third order selling something else (amount = 5) Before this commit, the account move lines of the payment move and of the sale move of operation 2 weren't reconciled This was because the credit to the receivable account of the return was reconciled with the debit of the first operation, leaving the debit of the payment of the return alone (i. e. the lines number 1 & 3 & 5 were reconciled together, instead of 1 & 2 & 5, and 3 & 4) We end up in a situation like this (at validation time) RECEIVABLE D | C || OPERATION | Line Number ---------------------------------------------------------------------------- 15 | || (1 & 3-Engaging Sale) | 1 | 10 || (1-Payment) | 2 | 10 || (2-Engaging Return) | 3 10 | || (2-Payment Return) | 4 | 5 || (3-Payment) | 5 After this commit, we reconcile the returns for each order before reconciling other transaction chains The fix is limited in its scope as the automatic reconciliation for the pos transaction is fairly recent and a "nice to have" OPW 787298 --- addons/point_of_sale/models/pos_order.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/addons/point_of_sale/models/pos_order.py b/addons/point_of_sale/models/pos_order.py index 94d198c0f3d..ca379710e9d 100644 --- a/addons/point_of_sale/models/pos_order.py +++ b/addons/point_of_sale/models/pos_order.py @@ -339,15 +339,22 @@ class PosOrder(models.Model): for order in self: aml = order.statement_ids.mapped('journal_entry_ids').mapped('line_ids') | order.account_move.line_ids | order.invoice_id.move_id.line_ids aml = aml.filtered(lambda r: not r.reconciled and r.account_id.internal_type == 'receivable' and r.partner_id == order.partner_id.commercial_partner_id) + + # Reconcile returns first + # to avoid mixing up the credit of a payment and the credit of a return + # in the receivable account + aml_returns = aml.filtered(lambda l: (l.journal_id.type == 'sale' and l.credit) or (l.journal_id.type != 'sale' and l.debit)) try: - aml.reconcile() + aml_returns.reconcile() + (aml - aml_returns).reconcile() except: # There might be unexpected situations where the automatic reconciliation won't # work. We don't want the user to be blocked because of this, since the automatic # reconciliation is introduced for convenience, not for mandatory accounting # reasons. - _logger.error('Reconciliation did not work for order %s', order.name) - continue + # It may be interesting to have the Traceback logged anyway + # for debugging and support purposes + _logger.exception('Reconciliation did not work for order %s', order.name) def _default_session(self): return self.env['pos.session'].search([('state', '=', 'opened'), ('user_id', '=', self.env.uid)], limit=1) From b3b8a471cc3e02488dcc0da991fd1d828978220d Mon Sep 17 00:00:00 2001 From: Florent de Labarre Date: Thu, 21 Dec 2017 13:38:41 +0100 Subject: [PATCH 05/19] [FIX] stock: To avoid singleton error In this way, it ensures that a single record is used when calling the function _get_move_values opw:806668 --- addons/stock/models/stock_inventory.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/stock/models/stock_inventory.py b/addons/stock/models/stock_inventory.py index c6bfc0549dd..81d273da48e 100644 --- a/addons/stock/models/stock_inventory.py +++ b/addons/stock/models/stock_inventory.py @@ -454,9 +454,9 @@ class InventoryLine(models.Model): continue diff = line.theoretical_qty - line.product_qty if diff < 0: # found more than expected - vals = self._get_move_values(abs(diff), line.product_id.property_stock_inventory.id, line.location_id.id) + vals = line._get_move_values(abs(diff), line.product_id.property_stock_inventory.id, line.location_id.id) else: - vals = self._get_move_values(abs(diff), line.location_id.id, line.product_id.property_stock_inventory.id) + vals = line._get_move_values(abs(diff), line.location_id.id, line.product_id.property_stock_inventory.id) move = moves.create(vals) if diff > 0: From 822a5e9085ebb2a774c44ca9b5d91d006f379968 Mon Sep 17 00:00:00 2001 From: Nicolas Martinelli Date: Tue, 23 Jan 2018 13:37:06 +0100 Subject: [PATCH 06/19] [FIX] account: default FY day and month In any piece of code, execute the following: ``` self.env['account.config.settings'].create({}) ``` It overwrites the values of `fiscalyear_last_day` and `fiscalyear_last_month` to 31 and 12. Setting a default value on a related field will automatically write these values on the related. opw-805205 --- addons/account/models/res_config.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/addons/account/models/res_config.py b/addons/account/models/res_config.py index a14a05dc265..1d10392719d 100644 --- a/addons/account/models/res_config.py +++ b/addons/account/models/res_config.py @@ -15,6 +15,12 @@ class AccountConfigSettings(models.TransientModel): _name = 'account.config.settings' _inherit = 'res.config.settings' + def _default_fiscalyear_last_day(self): + return self.env.user.company_id.fiscalyear_last_day or 31 + + def _default_fiscalyear_last_month(self): + return self.env.user.company_id.fiscalyear_last_month or 12 + @api.one @api.depends('company_id') def _get_currency_id(self): @@ -70,8 +76,10 @@ class AccountConfigSettings(models.TransientModel): the sales and purchase rates or use the usual m2o fields. This last choice assumes that the set of tax defined for the chosen template is complete''') - fiscalyear_last_day = fields.Integer(related='company_id.fiscalyear_last_day', default=31) - fiscalyear_last_month = fields.Selection([(1, 'January'), (2, 'February'), (3, 'March'), (4, 'April'), (5, 'May'), (6, 'June'), (7, 'July'), (8, 'August'), (9, 'September'), (10, 'October'), (11, 'November'), (12, 'December')], related='company_id.fiscalyear_last_month', default=12) + fiscalyear_last_day = fields.Integer(related='company_id.fiscalyear_last_day', + default=lambda self: self._default_fiscalyear_last_day()) + fiscalyear_last_month = fields.Selection([(1, 'January'), (2, 'February'), (3, 'March'), (4, 'April'), (5, 'May'), (6, 'June'), (7, 'July'), (8, 'August'), (9, 'September'), (10, 'October'), (11, 'November'), (12, 'December')], + related='company_id.fiscalyear_last_month', default=lambda self: self._default_fiscalyear_last_month()) period_lock_date = fields.Date(string="Lock Date for Non-Advisers", related='company_id.period_lock_date', help="Only users with the 'Adviser' role can edit accounts prior to and inclusive of this date. Use it for period locking inside an open fiscal year, for example.") fiscalyear_lock_date = fields.Date(string="Lock Date", related='company_id.fiscalyear_lock_date', help="No users, including Advisers, can edit accounts prior to and inclusive of this date. Use it for fiscal year locking for example.") From bc69b470731480d5add57c4441599a1f7d639a6c Mon Sep 17 00:00:00 2001 From: tbe-odoo Date: Tue, 26 Dec 2017 12:16:08 +0100 Subject: [PATCH 07/19] [FIX] http: Implicit session deactivation -> Explicit destruction - Replace the implicit session deactivation with explicit destruction. --- odoo/addons/base/res/res_users.py | 8 +++++++- odoo/http.py | 16 ++++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/odoo/addons/base/res/res_users.py b/odoo/addons/base/res/res_users.py index 8a79813ba96..a68abf41026 100644 --- a/odoo/addons/base/res/res_users.py +++ b/odoo/addons/base/res/res_users.py @@ -14,6 +14,7 @@ from odoo.exceptions import AccessDenied, AccessError, UserError, ValidationErro from odoo.osv import expression from odoo.service.db import check_super from odoo.tools import partition +from odoo.http import root _logger = logging.getLogger(__name__) @@ -372,6 +373,8 @@ class Users(models.Model): if any(key.startswith('context_') or key in ('lang', 'tz') for key in values): self.context_get.clear_cache(self) if any(key in values for key in ['active'] + USER_PRIVATE_FIELDS): + # force deletion of all sessions for these users + root.session_store.delete_sessions_for_uids(self.ids) db = self._cr.dbname for id in self.ids: self.__uid_cache[db].pop(id, None) @@ -385,7 +388,10 @@ class Users(models.Model): db = self._cr.dbname for id in self.ids: self.__uid_cache[db].pop(id, None) - return super(Users, self).unlink() + res = super(Users, self).unlink() + # force deletion of all sessions for these users + root.session_store.delete_sessions_for_uids(self.ids) + return res @api.model def name_search(self, name='', args=None, operator='ilike', limit=100): diff --git a/odoo/http.py b/odoo/http.py index 56b1f8e6930..46d744f2f36 100644 --- a/odoo/http.py +++ b/odoo/http.py @@ -1040,7 +1040,6 @@ class OpenERPSession(werkzeug.contrib.sessions.Session): self.db = db self.uid = uid self.login = login - self.password = password request.uid = uid request.disable_db = False @@ -1055,7 +1054,6 @@ class OpenERPSession(werkzeug.contrib.sessions.Session): """ if not self.db or not self.uid: raise SessionExpiredException("Session expired") - security.check(self.db, self.uid, self.password) def logout(self, keep_db=False): for k in self.keys(): @@ -1068,7 +1066,6 @@ class OpenERPSession(werkzeug.contrib.sessions.Session): self.setdefault("db", None) self.setdefault("uid", None) self.setdefault("login", None) - self.setdefault("password", None) self.setdefault("context", {}) def get_context(self): @@ -1281,6 +1278,17 @@ class DisableCacheMiddleware(object): start_response(status, new_headers) return self.app(environ, start_wrapped) +class OdooSessionStore(werkzeug.contrib.sessions.FilesystemSessionStore): + def delete_sessions_for_uids(self, uids): + # pretty expensive on large session stores, especially non-local! + uids = set(uids) + _logger.info('Deleting all HTTP sessions for UIDs %s', uids) + for sid in self.list(): + s = self.get(sid) + if s.uid and s.uid in uids: + _logger.debug('Deleting session %s', sid) + self.delete(s) + class Root(object): """Root WSGI application for the OpenERP Web Client. """ @@ -1292,7 +1300,7 @@ class Root(object): # Setup http sessions path = odoo.tools.config.session_dir _logger.debug('HTTP sessions stored in: %s', path) - return werkzeug.contrib.sessions.FilesystemSessionStore(path, session_class=OpenERPSession) + return OdooSessionStore(path, session_class=OpenERPSession) @lazy_property def nodb_routing_map(self): From c0f004205d9c5696584fbe79180342d7bece3082 Mon Sep 17 00:00:00 2001 From: tbe-odoo Date: Tue, 26 Dec 2017 12:16:08 +0100 Subject: [PATCH 08/19] [FIX] http: Implicit session deactivation -> Explicit destruction - Replace the implicit session deactivation with explicit destruction. --- odoo/addons/base/res/res_users.py | 8 +++++++- odoo/http.py | 16 ++++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/odoo/addons/base/res/res_users.py b/odoo/addons/base/res/res_users.py index caf652d0545..3c3dcf010cc 100644 --- a/odoo/addons/base/res/res_users.py +++ b/odoo/addons/base/res/res_users.py @@ -14,6 +14,7 @@ from odoo.exceptions import AccessDenied, AccessError, UserError, ValidationErro from odoo.osv import expression from odoo.service.db import check_super from odoo.tools import partition +from odoo.http import root _logger = logging.getLogger(__name__) @@ -373,6 +374,8 @@ class Users(models.Model): if any(key.startswith('context_') or key in ('lang', 'tz') for key in values): self.context_get.clear_cache(self) if any(key in values for key in ['active'] + USER_PRIVATE_FIELDS): + # force deletion of all sessions for these users + root.session_store.delete_sessions_for_uids(self.ids) db = self._cr.dbname for id in self.ids: self.__uid_cache[db].pop(id, None) @@ -386,7 +389,10 @@ class Users(models.Model): db = self._cr.dbname for id in self.ids: self.__uid_cache[db].pop(id, None) - return super(Users, self).unlink() + res = super(Users, self).unlink() + # force deletion of all sessions for these users + root.session_store.delete_sessions_for_uids(self.ids) + return res @api.model def name_search(self, name='', args=None, operator='ilike', limit=100): diff --git a/odoo/http.py b/odoo/http.py index 8f9c5932f0f..4bb9253c885 100644 --- a/odoo/http.py +++ b/odoo/http.py @@ -1035,7 +1035,6 @@ class OpenERPSession(werkzeug.contrib.sessions.Session): self.db = db self.uid = uid self.login = login - self.password = password request.uid = uid request.disable_db = False @@ -1050,7 +1049,6 @@ class OpenERPSession(werkzeug.contrib.sessions.Session): """ if not self.db or not self.uid: raise SessionExpiredException("Session expired") - security.check(self.db, self.uid, self.password) def logout(self, keep_db=False): for k in self.keys(): @@ -1063,7 +1061,6 @@ class OpenERPSession(werkzeug.contrib.sessions.Session): self.setdefault("db", None) self.setdefault("uid", None) self.setdefault("login", None) - self.setdefault("password", None) self.setdefault("context", {}) def get_context(self): @@ -1276,6 +1273,17 @@ class DisableCacheMiddleware(object): start_response(status, new_headers) return self.app(environ, start_wrapped) +class OdooSessionStore(werkzeug.contrib.sessions.FilesystemSessionStore): + def delete_sessions_for_uids(self, uids): + # pretty expensive on large session stores, especially non-local! + uids = set(uids) + _logger.info('Deleting all HTTP sessions for UIDs %s', uids) + for sid in self.list(): + s = self.get(sid) + if s.uid and s.uid in uids: + _logger.debug('Deleting session %s', sid) + self.delete(s) + class Root(object): """Root WSGI application for the OpenERP Web Client. """ @@ -1287,7 +1295,7 @@ class Root(object): # Setup http sessions path = odoo.tools.config.session_dir _logger.debug('HTTP sessions stored in: %s', path) - return werkzeug.contrib.sessions.FilesystemSessionStore(path, session_class=OpenERPSession) + return OdooSessionStore(path, session_class=OpenERPSession) @lazy_property def nodb_routing_map(self): From 1ac7257dd24492a294f14903baaab68a1058a73a Mon Sep 17 00:00:00 2001 From: Sergei Ruzki Date: Wed, 17 Jan 2018 18:39:20 +0300 Subject: [PATCH 09/19] [CLA] signature for sergeiruzkiicode Done at #22307 --- doc/cla/individual/sergeiruzkiicode.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 doc/cla/individual/sergeiruzkiicode.md diff --git a/doc/cla/individual/sergeiruzkiicode.md b/doc/cla/individual/sergeiruzkiicode.md new file mode 100644 index 00000000000..44af0359a97 --- /dev/null +++ b/doc/cla/individual/sergeiruzkiicode.md @@ -0,0 +1,11 @@ +Belarus, 2017-01-17 + +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, + +Sergei Ruzki sergei.ruzki@icode.by https://github.com/sergeiruzkiicode From 53e221fc169ba54c677b356379e93a933340883c Mon Sep 17 00:00:00 2001 From: Sergei Ruzki Date: Wed, 17 Jan 2018 18:22:25 +0300 Subject: [PATCH 10/19] [FIX] base: adding BYN to currenciest list From 2016-07-01 BYN is new currency sign for Belarus See https://en.wikipedia.org/wiki/Belarusian_ruble BYR is no longer used. Kept for backward compatibility and stability reason Closes #22307 --- odoo/addons/base/res/res_country_data.xml | 4 ++-- odoo/addons/base/res/res_currency_data.xml | 9 +++++++++ odoo/addons/base/res/res_currency_demo.xml | 6 ++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/odoo/addons/base/res/res_country_data.xml b/odoo/addons/base/res/res_country_data.xml index 59808f3d6ab..5da077bc962 100644 --- a/odoo/addons/base/res/res_country_data.xml +++ b/odoo/addons/base/res/res_country_data.xml @@ -258,8 +258,8 @@ Belarus by - - + + Belize diff --git a/odoo/addons/base/res/res_currency_data.xml b/odoo/addons/base/res/res_currency_data.xml index 8b108fa978d..6785bc98c00 100644 --- a/odoo/addons/base/res/res_currency_data.xml +++ b/odoo/addons/base/res/res_currency_data.xml @@ -406,6 +406,15 @@ BR 0.01 + Ruble BYR + Kapeyka + + + + BYN + Br + 0.01 + diff --git a/odoo/addons/base/res/res_currency_demo.xml b/odoo/addons/base/res/res_currency_demo.xml index a6e406e783d..ba316d0a7db 100644 --- a/odoo/addons/base/res/res_currency_demo.xml +++ b/odoo/addons/base/res/res_currency_demo.xml @@ -349,6 +349,12 @@ 10228.19 + + + 2016-07-01 + 2.23151 + + 2010-01-01 From 0ac6043ec746ef4c4d4ddb66edc93c0ae098ca0b Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Wed, 24 Jan 2018 11:39:56 +0100 Subject: [PATCH 11/19] [FIX] base: bad back-port 53e221fc was intended for 11.0 and backported too quickly in 10.0 Remove fields that do not exist yet --- odoo/addons/base/res/res_currency_data.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/odoo/addons/base/res/res_currency_data.xml b/odoo/addons/base/res/res_currency_data.xml index 6785bc98c00..8746f4d0b1b 100644 --- a/odoo/addons/base/res/res_currency_data.xml +++ b/odoo/addons/base/res/res_currency_data.xml @@ -406,8 +406,6 @@ BR 0.01 - Ruble BYR - Kapeyka From bf5c90d0be7808a08ad8b1b676bcd698181e1d7b Mon Sep 17 00:00:00 2001 From: qsm-odoo Date: Wed, 24 Jan 2018 13:13:22 +0100 Subject: [PATCH 12/19] [FIX] web_editor: strange horizontal scroll on mousedown Before this commit, when pressing the mouse button on the end of the ace editor, it scrolled to the right, selecting the whole sentence end. This strange behavior was due to some initialization mistake made by commit https://github.com/odoo/odoo/commit/5a030db3eb77b6d80187f8ae1a64303b2f50391d --- addons/web_editor/static/src/js/ace.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/addons/web_editor/static/src/js/ace.js b/addons/web_editor/static/src/js/ace.js index b33b3c479be..7629d1465c8 100644 --- a/addons/web_editor/static/src/js/ace.js +++ b/addons/web_editor/static/src/js/ace.js @@ -107,12 +107,11 @@ var ViewEditor = Widget.extend({ */ start: function () { this.$viewEditor = this.$('#ace-view-editor'); - this.$editor = this.$(".ace_editor"); this.$viewList = this.$('#ace-view-list'); this.$viewID = this.$('#ace-view-id'); - this.aceEditor = window.ace.edit(this.$viewEditor[0]); this.aceEditor.setTheme("ace/theme/monokai"); + this.$editor = this.$(".ace_editor"); var refX = 0; var resizing = false; From 34bfadb2f2f2f57f4f72515fbc610a521e8f4619 Mon Sep 17 00:00:00 2001 From: Nicolas Martinelli Date: Wed, 24 Jan 2018 04:12:39 -0800 Subject: [PATCH 13/19] [FIX] web: suggested date - Set the OS to a GMT- timezone (e.g. 'America/Los Angeles') - Set the format of the date to '%d/%m/%Y' - Go to 'Account > Adviser > Journal Entries' - Type '02-01-2018' The suggested date is 31/01/2018. Setting the moment object as UTC will lead to a conversion of the date to the OS timezone when calling `toDate`, e.g.: Mon Jan 31 2018 16:00:00 GMT-0800 (PST) UTC should only be used in case of datetime, not date. opw-803466 --- addons/web/static/src/js/views/search_inputs.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/addons/web/static/src/js/views/search_inputs.js b/addons/web/static/src/js/views/search_inputs.js index 6459fba77b8..91d85a1901a 100644 --- a/addons/web/static/src/js/views/search_inputs.js +++ b/addons/web/static/src/js/views/search_inputs.js @@ -354,7 +354,11 @@ var DateField = Field.extend(/** @lends instance.web.search.DateField# */{ } // THIS SHOULD BE FORWARDPORTED UP TO SAAS-15, NOT LATER - var m = moment.utc(v, t === 'datetime' ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD'); + if (t === 'datetime') { + var m = moment.utc(v, 'YYYY-MM-DD HH:mm:ss'); + } else { + var m = moment(v, 'YYYY-MM-DD'); + } if (!m.isValid()) { return $.when(null); } var d = m.toDate(); var date_string = formats.format_value(d, this.attrs); From 3c998acaaf5ca8d745e5dc3af13c32e84c339de2 Mon Sep 17 00:00:00 2001 From: Romain Derie Date: Fri, 12 Jan 2018 13:56:30 +0100 Subject: [PATCH 14/19] [FIX] website_blog: archive multiple blog.post throws a server error Step to reproduce: - Go to 'Blog' > 'Blog Posts' in the 'Website Admin' module - Select several blog.post on the list view - Click on 'Archive' in the 'Action' dropdown This will throw a server error since write() is overriden for blog.post and do an ensure_one() This commit closes #22208 --- addons/website_blog/models/website_blog.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/addons/website_blog/models/website_blog.py b/addons/website_blog/models/website_blog.py index c2747094b62..e5c39e8b594 100644 --- a/addons/website_blog/models/website_blog.py +++ b/addons/website_blog/models/website_blog.py @@ -207,11 +207,12 @@ class BlogPost(models.Model): @api.multi def write(self, vals): - self.ensure_one() - if 'website_published' in vals and 'published_date' not in vals: - if self.published_date <= fields.Datetime.now(): - vals['published_date'] = vals['website_published'] and fields.Datetime.now() - result = super(BlogPost, self).write(vals) + result = True + for post in self: + copy_vals = vals + if 'website_published' in vals and 'published_date' not in vals and post.published_date <= fields.Datetime.now(): + copy_vals['published_date'] = vals['website_published'] and fields.Datetime.now() or False + result &= super(BlogPost, self).write(copy_vals) self._check_for_publication(vals) return result From 9a2b9b1ae1dc77ad9a59de585e22388dd2a5f828 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Wed, 24 Jan 2018 15:48:19 +0100 Subject: [PATCH 15/19] [FIX] l10n_fr: correct taxes' tags migration script --- .../l10n_fr/migrations/2.0/post-migrate_tags_on_taxes.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/addons/l10n_fr/migrations/2.0/post-migrate_tags_on_taxes.py b/addons/l10n_fr/migrations/2.0/post-migrate_tags_on_taxes.py index a37770d2c1c..44367687c8f 100644 --- a/addons/l10n_fr/migrations/2.0/post-migrate_tags_on_taxes.py +++ b/addons/l10n_fr/migrations/2.0/post-migrate_tags_on_taxes.py @@ -1,7 +1,5 @@ -from openerp.modules.registry import RegistryManager - +# -*- coding: utf-8 -*- +from odoo.addons.account.models.chart_template import migrate_tags_on_taxes def migrate(cr, version): - registry = RegistryManager.get(cr.dbname) - from openerp.addons.account.models.chart_template import migrate_tags_on_taxes - migrate_tags_on_taxes(cr, registry) + migrate_tags_on_taxes(cr, None) From 7dd3ab9c55c0faa7929d6377063dfe64c11cc4db Mon Sep 17 00:00:00 2001 From: "Lucas Perais (lpe)" Date: Wed, 27 Dec 2017 11:34:13 +0100 Subject: [PATCH 16/19] [FIX] website_sale: pending message do not disappear On the payment confirmation page, when the payment is still pending. Before this commit: the user friendly message disappeared and a warning icon took its place After this commit, the warning icon is prepended to the message. OPW 787799 --- addons/website_sale/static/src/js/website_sale_validate.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/addons/website_sale/static/src/js/website_sale_validate.js b/addons/website_sale/static/src/js/website_sale_validate.js index 614e8901484..3bef4bc4f9a 100644 --- a/addons/website_sale/static/src/js/website_sale_validate.js +++ b/addons/website_sale/static/src/js/website_sale_validate.js @@ -21,7 +21,10 @@ $(document).ready(function () { setTimeout(function () { payment_transaction_poll_status(); }, Math.ceil(_poll_nbr / 3) * 1000); } else { - result.message = ""; + var $message = $(result.message); + $message.find('span:first').prepend($( + "")); + result.message = $message.html(); } } $('div.oe_website_sale_tx_status').html(result.message); From 2e515a61bc9da0660d906d2b2931fba1ac8793e3 Mon Sep 17 00:00:00 2001 From: "Lucas Perais (lpe)" Date: Tue, 23 Jan 2018 14:07:57 +0100 Subject: [PATCH 17/19] [FIX] mail: res_model of followers should compute as uid=1 Take as example: having demo user as expense manager create with demo user an expense sheet for the employee linked to admin on save, there was an access rights error for the write on mail_followers After this commit, there isn't the error anymore, since the computation of the field related is done with sudo OPW 804740 --- addons/mail/models/mail_followers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/mail/models/mail_followers.py b/addons/mail/models/mail_followers.py index ce169c91127..d437c520c80 100644 --- a/addons/mail/models/mail_followers.py +++ b/addons/mail/models/mail_followers.py @@ -23,7 +23,7 @@ class Followers(models.Model): index=True, required=True, ondelete='cascade', help='Model of the followed resource') res_model = fields.Char( - 'Related Document Model Name', index=True, readonly=True, related='res_model_id.model', store=True) + 'Related Document Model Name', index=True, readonly=True, related='res_model_id.model', store=True, compute_sudo=True) res_id = fields.Integer( 'Related Document ID', index=True, help='Id of the followed resource') partner_id = fields.Many2one( From adad192cc0018ce6838feb2a954044ee0b623841 Mon Sep 17 00:00:00 2001 From: "Lucas Perais (lpe)" Date: Fri, 19 Jan 2018 12:02:04 +0100 Subject: [PATCH 18/19] [FIX] account: reconciliation on payment terms The case: create an invoice of 2000 euros. Payment terms have been configured as: 1) fixed amount 150, 0 days after invoice date. 2) fixed amount 200, 10 days after invoice date. 3) fixed amount 200, 20 days after invoice date. 4) balance, 30 days after invoice date Before this commit, when issuing a payment of 150 at day 0, that payment got reconciled with the balance line. After this commit, the payment is reconciled with the right payment term line OPW 805006 --- addons/account/models/account_move.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py index a31acf43e84..a3c37846348 100644 --- a/addons/account/models/account_move.py +++ b/addons/account/models/account_move.py @@ -799,7 +799,7 @@ class AccountMoveLine(models.Model): elif self._context.get('skip_full_reconcile_check') == 'amount_currency_only': field = 'amount_residual_currency' #target the pair of move in self that are the oldest - sorted_moves = sorted(self, key=lambda a: a.date) + sorted_moves = sorted(self, key=lambda a: a.date_maturity or a.date) debit = credit = False for aml in sorted_moves: if credit and debit: From d29c2dbbddb2e7407e714b0bb11ffdf6fa317672 Mon Sep 17 00:00:00 2001 From: "Lucas Perais (lpe)" Date: Mon, 22 Jan 2018 16:19:23 +0100 Subject: [PATCH 19/19] [FIX] account: no payment terms on refund In the case where: create an invoice with payment terms that contains at least 2 term lines Validate create a refund by clicking cancel and reconcile Before this commit, the refund move lines were wrongly created and reconciled with the invoice's move lines After this commit, since payment terms are irrelevant on refunds, we set it to false and the problem doesn't raise OPW 804752 --- addons/account/models/account_invoice.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/addons/account/models/account_invoice.py b/addons/account/models/account_invoice.py index 5b09af3be43..f653941e7b6 100644 --- a/addons/account/models/account_invoice.py +++ b/addons/account/models/account_invoice.py @@ -985,6 +985,7 @@ class AccountInvoice(models.Model): values['state'] = 'draft' values['number'] = False values['origin'] = invoice.number + values['payment_term_id'] = False if date: values['date'] = date @@ -1365,6 +1366,7 @@ class AccountPaymentTerm(models.Model): def compute(self, value, date_ref=False): date_ref = date_ref or fields.Date.today() amount = value + sign = value < 0 and -1 or 1 result = [] if self.env.context.get('currency_id'): currency = self.env['res.currency'].browse(self.env.context['currency_id']) @@ -1373,7 +1375,7 @@ class AccountPaymentTerm(models.Model): prec = currency.decimal_places for line in self.line_ids: if line.value == 'fixed': - amt = round(line.value_amount, prec) + amt = sign * round(line.value_amount, prec) elif line.value == 'percent': amt = round(value * (line.value_amount / 100.0), prec) elif line.value == 'balance':