From 6d3855e9dc5031b3a87d730f79fcecfda93d5bc6 Mon Sep 17 00:00:00 2001 From: Humberto Arocha Date: Thu, 17 Jul 2014 12:14:58 -0430 Subject: [PATCH 1/6] [FIX] account: remove orphan analytic lines If the analytic account is not present on an entry, still removes the Analytic Journal Items linked to it. Fixes #1194, opw 610784 --- addons/account/account_move_line.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/account/account_move_line.py b/addons/account/account_move_line.py index cf14d465f47..756c40ea612 100644 --- a/addons/account/account_move_line.py +++ b/addons/account/account_move_line.py @@ -190,11 +190,11 @@ class account_move_line(osv.osv): def create_analytic_lines(self, cr, uid, ids, context=None): acc_ana_line_obj = self.pool.get('account.analytic.line') for obj_line in self.browse(cr, uid, ids, context=context): + if obj_line.analytic_lines: + acc_ana_line_obj.unlink(cr,uid,[obj.id for obj in obj_line.analytic_lines]) if obj_line.analytic_account_id: if not obj_line.journal_id.analytic_journal_id: raise osv.except_osv(_('No Analytic Journal!'),_("You have to define an analytic journal on the '%s' journal!") % (obj_line.journal_id.name, )) - if obj_line.analytic_lines: - acc_ana_line_obj.unlink(cr,uid,[obj.id for obj in obj_line.analytic_lines]) vals_line = self._prepare_analytic_line(cr, uid, obj_line, context=context) acc_ana_line_obj.create(cr, uid, vals_line) return True From e30a5a11a5fc3fabc1cd5102d12248f9fe0a396c Mon Sep 17 00:00:00 2001 From: Ravi Gohil Date: Thu, 31 Jul 2014 15:40:27 +0530 Subject: [PATCH 2/6] [FIX] account: avoid closing fiscalyear with unpost entries As when closing fiscal periods, forbid to close a fiscal year with unposted entries. Fixes #1194, opw 610784 --- addons/account/wizard/account_fiscalyear_close_state.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/addons/account/wizard/account_fiscalyear_close_state.py b/addons/account/wizard/account_fiscalyear_close_state.py index 746f1c47976..eb12db1cf4e 100644 --- a/addons/account/wizard/account_fiscalyear_close_state.py +++ b/addons/account/wizard/account_fiscalyear_close_state.py @@ -41,9 +41,15 @@ class account_fiscalyear_close_state(osv.osv_memory): @param ids: List of Account fiscalyear close state’s IDs """ + account_move_obj = self.pool.get('account.move') + for data in self.read(cr, uid, ids, context=context): fy_id = data['fy_id'][0] + account_move_ids = account_move_obj.search(cr, uid, [('period_id.fiscalyear_id', '=', fy_id), ('state', '=', "draft")], context=context) + if account_move_ids: + raise osv.except_osv(_('Invalid Action!'), _('In order to close a fiscalyear, you must first post related journal entries.')) + cr.execute('UPDATE account_journal_period ' \ 'SET state = %s ' \ 'WHERE period_id IN (SELECT id FROM account_period \ From 78144410a4e3e59e8e7f06fb527e7aba8321d4b2 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Thu, 2 Oct 2014 10:12:51 +0200 Subject: [PATCH 3/6] [IMP] product: name_get matching on commercial_partner_id for suppliers The name_get of a product will use some information (e.g. default_code) based on the supplier. The matching of the supplier should use the commercial_partner_id in case the supplier info are on the company and the partner_id in the context belongs to the company (e.g. creates quotation with a contact of the company). Fixes #1219 --- addons/product/product.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/addons/product/product.py b/addons/product/product.py index 124ce313f37..7a36507aa79 100644 --- a/addons/product/product.py +++ b/addons/product/product.py @@ -645,10 +645,14 @@ class product_product(osv.osv): return (d['id'], name) partner_id = context.get('partner_id', False) + if partner_id: + partner_ids = [partner_id, self.pool['res.partner'].browse(cr, user, partner_id, context=context).commercial_partner_id.id] + else: + partner_ids = [] result = [] for product in self.browse(cr, user, ids, context=context): - sellers = filter(lambda x: x.name.id == partner_id, product.seller_ids) + sellers = partner_ids and filter(lambda x: x.name.id in partner_ids, product.seller_ids) or [] if sellers: for s in sellers: mydict = { From 12df3fe5a025a95c079e2f9f84e4c6ad691e802e Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Thu, 2 Oct 2014 11:52:06 +0200 Subject: [PATCH 4/6] [FIX] account_analytic_analysis: invoiced field takes customer invoices only Besides, it subtracts customer invoices with customer refund invoices --- .../account_analytic_analysis.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/addons/account_analytic_analysis/account_analytic_analysis.py b/addons/account_analytic_analysis/account_analytic_analysis.py index e6847c60151..125ed72464d 100644 --- a/addons/account_analytic_analysis/account_analytic_analysis.py +++ b/addons/account_analytic_analysis/account_analytic_analysis.py @@ -208,9 +208,13 @@ class account_analytic_account(osv.osv): if child_ids: #Search all invoice lines not in cancelled state that refer to this analytic account inv_line_obj = self.pool.get("account.invoice.line") - inv_lines = inv_line_obj.search(cr, uid, ['&', ('account_analytic_id', 'in', child_ids), ('invoice_id.state', '!=', 'cancel')], context=context) + inv_lines = inv_line_obj.search(cr, uid, ['&', ('account_analytic_id', 'in', child_ids), ('invoice_id.state', 'not in', ['draft', 'cancel']), ('invoice_id.type', 'in', ['out_invoice', 'out_refund'])], context=context) for line in inv_line_obj.browse(cr, uid, inv_lines, context=context): - res[line.account_analytic_id.id] += line.price_subtotal + if line.invoice_id.type == 'out_refund': + res[line.account_analytic_id.id] -= line.price_subtotal + else: + res[line.account_analytic_id.id] += line.price_subtotal + for acc in self.browse(cr, uid, res.keys(), context=context): res[acc.id] = res[acc.id] - (acc.timesheet_ca_invoiced or 0.0) @@ -308,11 +312,14 @@ class account_analytic_account(osv.osv): inv_ids = [] for account in self.browse(cr, uid, ids, context=context): res[account.id] = 0.0 - line_ids = lines_obj.search(cr, uid, [('account_id','=', account.id), ('invoice_id','!=',False), ('to_invoice','!=', False), ('journal_id.type', '=', 'general')], context=context) + line_ids = lines_obj.search(cr, uid, [('account_id','=', account.id), ('invoice_id','!=',False), ('to_invoice','!=', False), ('journal_id.type', '=', 'general'), ('invoice_id.type', 'in', ['out_invoice', 'out_refund'])], context=context) for line in lines_obj.browse(cr, uid, line_ids, context=context): if line.invoice_id not in inv_ids: inv_ids.append(line.invoice_id) - res[account.id] += line.invoice_id.amount_untaxed + if line.invoice_id.type == 'out_refund': + res[account.id] -= line.invoice_id.amount_untaxed + else: + res[account.id] += line.invoice_id.amount_untaxed return res def _remaining_ca_calc(self, cr, uid, ids, name, arg, context=None): From f5cf5fd4ebc020e7eaa4056336c3491aca782d04 Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Thu, 2 Oct 2014 12:32:02 +0200 Subject: [PATCH 5/6] [FIX] auth_oauth: fb and google oauth providers reset on general settings apply - The res_config.xml file was missing in the manifest (so couldn't check the use of FB and Google OAuth from the general settings) - The default value for these oauth configuration were not set --- addons/auth_oauth/__openerp__.py | 1 + addons/auth_oauth/res_config.py | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/addons/auth_oauth/__openerp__.py b/addons/auth_oauth/__openerp__.py index c81f52663c4..aa7ec5f8b95 100644 --- a/addons/auth_oauth/__openerp__.py +++ b/addons/auth_oauth/__openerp__.py @@ -36,6 +36,7 @@ Allow users to login through OAuth2 Provider. 'auth_oauth_data.xml', 'auth_oauth_data.yml', 'auth_oauth_view.xml', + 'res_config.xml', 'security/ir.model.access.csv' ], 'js': ['static/src/js/auth_oauth.js'], diff --git a/addons/auth_oauth/res_config.py b/addons/auth_oauth/res_config.py index 82d79c767f5..de5f1a74b2d 100644 --- a/addons/auth_oauth/res_config.py +++ b/addons/auth_oauth/res_config.py @@ -34,6 +34,11 @@ class base_config_settings(osv.TransientModel): 'auth_oauth_facebook_client_id' : fields.char('Client ID'), } + def default_get(self, cr, uid, fields, context=None): + res = super(base_config_settings, self).default_get(cr, uid, fields, context=context) + res.update(self.get_oauth_providers(cr, uid, fields, context=context)) + return res + def get_oauth_providers(self, cr, uid, fields, context=None): google_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'auth_oauth', 'provider_google')[1] facebook_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'auth_oauth', 'provider_facebook')[1] From eb9113c04d66627fbe04b473b9010e5de973c6aa Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Thu, 2 Oct 2014 15:17:48 +0200 Subject: [PATCH 6/6] [FIX] ir_attachment: restrict access to orphan attachments to employees --- openerp/addons/base/ir/ir_attachment.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/openerp/addons/base/ir/ir_attachment.py b/openerp/addons/base/ir/ir_attachment.py index 19c66635938..996b0f69c4b 100644 --- a/openerp/addons/base/ir/ir_attachment.py +++ b/openerp/addons/base/ir/ir_attachment.py @@ -28,6 +28,8 @@ import re from openerp import tools from openerp.osv import fields,osv from openerp import SUPERUSER_ID +from openerp.osv.orm import except_orm +from openerp.tools.translate import _ _logger = logging.getLogger(__name__) @@ -189,12 +191,14 @@ class ir_attachment(osv.osv): more complex ones apply there. """ res_ids = {} + require_employee = False if ids: if isinstance(ids, (int, long)): ids = [ids] cr.execute('SELECT DISTINCT res_model, res_id FROM ir_attachment WHERE id = ANY (%s)', (ids,)) for rmod, rid in cr.fetchall(): if not (rmod and rid): + require_employee = True continue res_ids.setdefault(rmod,set()).add(rid) if values: @@ -206,10 +210,16 @@ class ir_attachment(osv.osv): # ignore attachments that are not attached to a resource anymore when checking access rights # (resource was deleted but attachment was not) if not self.pool.get(model): + require_employee = True continue - mids = self.pool.get(model).exists(cr, uid, mids) + existing_ids = self.pool.get(model).exists(cr, uid, mids) + if len(existing_ids) != len(mids): + require_employee = True ima.check(cr, uid, model, mode) - self.pool.get(model).check_access_rule(cr, uid, mids, mode, context=context) + self.pool.get(model).check_access_rule(cr, uid, existing_ids, mode, context=context) + if require_employee: + if not self.pool['res.users'].has_group(cr, uid, 'base.group_user'): + raise except_orm(_('Access Denied'), _("Sorry, you are not allowed to access this document.")) def _search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False, access_rights_uid=None): ids = super(ir_attachment, self)._search(cr, uid, args, offset=offset,