diff --git a/openerp/addons/base/base_data.xml b/openerp/addons/base/base_data.xml index 2922dd82dc4..6a47325db39 100644 --- a/openerp/addons/base/base_data.xml +++ b/openerp/addons/base/base_data.xml @@ -49,8 +49,6 @@ 0.01 4 - - 1.0 @@ -86,10 +84,6 @@ Administrator - - - - localhost localhost diff --git a/openerp/addons/base/currency_data.xml b/openerp/addons/base/currency_data.xml index 96ff81cc0d1..e38f777d584 100644 --- a/openerp/addons/base/currency_data.xml +++ b/openerp/addons/base/currency_data.xml @@ -466,7 +466,6 @@ 0.01 4 ¢ - 691.3153 diff --git a/openerp/addons/base/ir/ir_actions.py b/openerp/addons/base/ir/ir_actions.py index a130ab13a32..aaaa8513925 100644 --- a/openerp/addons/base/ir/ir_actions.py +++ b/openerp/addons/base/ir/ir_actions.py @@ -657,7 +657,7 @@ class actions_server(osv.osv): if action.state=='client_action': if not action.action_id: - raise osv.except_osv(_('Error'), _("Please specify an action to launch !")) + raise osv.except_osv(_('Error'), _("Please specify an action to launch!")) return self.pool[action.action_id.type].read(cr, uid, action.action_id.id, context=context) if action.state=='code': diff --git a/openerp/addons/base/ir/ir_mail_server.py b/openerp/addons/base/ir/ir_mail_server.py index 2ae2f3d7c5c..e8f96d13bd9 100644 --- a/openerp/addons/base/ir/ir_mail_server.py +++ b/openerp/addons/base/ir/ir_mail_server.py @@ -214,14 +214,14 @@ class ir_mail_server(osv.osv): password=smtp_server.smtp_pass, encryption=smtp_server.smtp_encryption, smtp_debug=smtp_server.smtp_debug) except Exception, e: - raise osv.except_osv(_("Connection test failed!"), _("Here is what we got instead:\n %s") % tools.ustr(e)) + raise osv.except_osv(_("Connection Test Failed!"), _("Here is what we got instead:\n %s") % tools.ustr(e)) finally: try: if smtp: smtp.quit() except Exception: # ignored, just a consequence of the previous exception pass - raise osv.except_osv(_("Connection test succeeded!"), _("Everything seems properly set up!")) + raise osv.except_osv(_("Connection Test Succeeded!"), _("Everything seems properly set up!")) def connect(self, host, port, user=None, password=None, encryption=False, smtp_debug=False): """Returns a new SMTP connection to the give SMTP server, authenticated diff --git a/openerp/addons/base/ir/ir_model.py b/openerp/addons/base/ir/ir_model.py index b39162ff80e..165fd8a4be9 100644 --- a/openerp/addons/base/ir/ir_model.py +++ b/openerp/addons/base/ir/ir_model.py @@ -82,7 +82,7 @@ class ir_model(osv.osv): return [] __, operator, value = domain[0] if operator not in ['=', '!=']: - raise osv.except_osv(_('Invalid search criterions'), _('The osv_memory field can only be compared with = and != operator.')) + raise osv.except_osv(_("Invalid Search Criteria"), _('The osv_memory field can only be compared with = and != operator.')) value = bool(value) if operator == '=' else not bool(value) all_model_ids = self.search(cr, uid, [], context=context) is_osv_mem = self._is_osv_memory(cr, uid, all_model_ids, 'osv_memory', arg=None, context=context) @@ -863,11 +863,24 @@ class ir_model_data(osv.osv): def get_object_reference(self, cr, uid, module, xml_id): """Returns (model, res_id) corresponding to a given module and xml_id (cached) or raise ValueError if not found""" data_id = self._get_id(cr, uid, module, xml_id) + #assuming data_id is not False, as it was checked upstream res = self.read(cr, uid, data_id, ['model', 'res_id']) if not res['res_id']: raise ValueError('No such external ID currently defined in the system: %s.%s' % (module, xml_id)) return res['model'], res['res_id'] + def check_object_reference(self, cr, uid, module, xml_id, raise_on_access_error=False): + """Returns (model, res_id) corresponding to a given module and xml_id (cached), if and only if the user has the necessary access rights + to see that object, otherwise raise a ValueError if raise_on_access_error is True or returns a tuple (model found, False)""" + model, res_id = self.get_object_reference(cr, uid, module, xml_id) + #search on id found in result to check if current user has read access right + check_right = self.pool.get(model).search(cr, uid, [('id', '=', res_id)]) + if check_right: + return model, res_id + if raise_on_access_error: + raise ValueError('Not enough access rights on the external ID: %s.%s' % (module, xml_id)) + return model, False + def get_object(self, cr, uid, module, xml_id, context=None): """Returns a browsable record for the given module name and xml_id or raise ValueError if not found""" res_model, res_id = self.get_object_reference(cr, uid, module, xml_id) diff --git a/openerp/addons/base/ir/ir_values.py b/openerp/addons/base/ir/ir_values.py index dd8501230ec..a21b034d1b0 100644 --- a/openerp/addons/base/ir/ir_values.py +++ b/openerp/addons/base/ir/ir_values.py @@ -411,8 +411,8 @@ class ir_values(osv.osv): (tuple(groups), uid)) if not cr.fetchone(): if action['name'] == 'Menuitem': - raise osv.except_osv('Error !', - 'You do not have the permission to perform this operation !!!') + raise osv.except_osv('Error!', + 'You do not have the permission to perform this operation!!!') continue # keep only the first action registered for each action name results[action['name']] = (action['id'], action['name'], action_def) diff --git a/openerp/addons/base/ir/workflow/workflow.py b/openerp/addons/base/ir/workflow/workflow.py index 0ce951940a9..a7e792072e3 100644 --- a/openerp/addons/base/ir/workflow/workflow.py +++ b/openerp/addons/base/ir/workflow/workflow.py @@ -94,7 +94,7 @@ class wkf_activity(osv.osv): def unlink(self, cr, uid, ids, context=None): if context is None: context = {} if not context.get('_force_unlink') and self.pool.get('workflow.workitem').search(cr, uid, [('act_id', 'in', ids)]): - raise osv.except_osv(_('Operation forbidden'), + raise osv.except_osv(_('Operation Forbidden'), _('Please make sure no workitems refer to an activity before deleting it!')) super(wkf_activity, self).unlink(cr, uid, ids, context=context) diff --git a/openerp/addons/base/module/wizard/base_module_import.py b/openerp/addons/base/module/wizard/base_module_import.py index 67408b60669..61694d5f8c3 100644 --- a/openerp/addons/base/module/wizard/base_module_import.py +++ b/openerp/addons/base/module/wizard/base_module_import.py @@ -55,7 +55,7 @@ class base_module_import(osv.osv_memory): try: file_data = zipfile.ZipFile(fp, 'r') except zipfile.BadZipfile: - raise osv.except_osv(_('Error !'), _('File is not a zip file!')) + raise osv.except_osv(_('Error!'), _('File is not a zip file!')) init_file_name = sorted(file_data.namelist())[0] module_name = os.path.split(init_file_name)[0] @@ -63,8 +63,8 @@ class base_module_import(osv.osv_memory): try: zip_file = open(file_path, 'wb') except IOError: - raise osv.except_osv(_('Error !'), - _('Can not create the module file: %s !') % \ + raise osv.except_osv(_('Error!'), + _('Can not create the module file: %s!') % \ (file_path,) ) zip_file.write(zip_data) zip_file.close() diff --git a/openerp/addons/base/module/wizard/base_module_upgrade.py b/openerp/addons/base/module/wizard/base_module_upgrade.py index c081663d8ed..c75058ab835 100644 --- a/openerp/addons/base/module/wizard/base_module_upgrade.py +++ b/openerp/addons/base/module/wizard/base_module_upgrade.py @@ -81,7 +81,7 @@ class base_module_upgrade(osv.osv_memory): (tuple(ids), ('uninstalled',))) unmet_packages = [x[0] for x in cr.fetchall()] if unmet_packages: - raise osv.except_osv(_('Unmet dependency !'), + raise osv.except_osv(_('Unmet Dependency!'), _('Following modules are not installed or unknown: %s') % ('\n\n' + '\n'.join(unmet_packages))) ir_module.download(cr, uid, ids, context=context) diff --git a/openerp/addons/base/res/res_bank_view.xml b/openerp/addons/base/res/res_bank_view.xml index 1c289d07141..7c1e07e37fb 100644 --- a/openerp/addons/base/res/res_bank_view.xml +++ b/openerp/addons/base/res/res_bank_view.xml @@ -53,7 +53,13 @@ res.bank form tree,form - Manage bank records you want to be used in the system. + +

+ Click to create a new bank. +

+ Manage bank records you want to be used in the system. +

+
@@ -152,7 +158,17 @@ res.partner.bank form tree,form - Configure your company's bank accounts and select those that must appear on the report footer. You can reorder bank accounts from the list view. If you use the accounting application of OpenERP, journals and accounts will be created automatically based on these data. + +

+ Click to create a bank account. +

+ Configure your company's bank accounts and select those that must appear on the report footer. + You can reorder bank accounts from the list view. +

+

+ If you use the accounting application of OpenERP, journals and accounts will be created automatically based on these data. +

+
- + @@ -312,7 +312,7 @@ class res_company(osv.osv): - + diff --git a/openerp/addons/base/res/res_lang.py b/openerp/addons/base/res/res_lang.py index 9abab79e46c..160e86fd8d2 100644 --- a/openerp/addons/base/res/res_lang.py +++ b/openerp/addons/base/res/res_lang.py @@ -182,11 +182,11 @@ class lang(osv.osv): for language in languages: ctx_lang = context.get('lang') if language['code']=='en_US': - raise osv.except_osv(_('User Error'), _("Base Language 'en_US' can not be deleted !")) + raise osv.except_osv(_('User Error'), _("Base Language 'en_US' can not be deleted!")) if ctx_lang and (language['code']==ctx_lang): - raise osv.except_osv(_('User Error'), _("You cannot delete the language which is User's Preferred Language !")) + raise osv.except_osv(_('User Error'), _("You cannot delete the language which is User's Preferred Language!")) if language['active']: - raise osv.except_osv(_('User Error'), _("You cannot delete the language which is Active !\nPlease de-activate the language first.")) + raise osv.except_osv(_('User Error'), _("You cannot delete the language which is Active!\nPlease de-activate the language first.")) trans_obj = self.pool.get('ir.translation') trans_ids = trans_obj.search(cr, uid, [('lang','=',language['code'])], context=context) trans_obj.unlink(cr, uid, trans_ids, context=context) diff --git a/openerp/addons/base/res/res_partner.py b/openerp/addons/base/res/res_partner.py index 69ad16b8106..e2895e1bc52 100644 --- a/openerp/addons/base/res/res_partner.py +++ b/openerp/addons/base/res/res_partner.py @@ -576,7 +576,7 @@ class res_partner(osv.osv, format_address): context = {} name, email = self._parse_partner_name(name, context=context) if context.get('force_email') and not email: - raise osv.except_osv(_('Warning'), _("Couldn't create contact without email address !")) + raise osv.except_osv(_('Warning'), _("Couldn't create contact without email address!")) if not name and email: name = email rec_id = self.create(cr, uid, {self._rec_name: name or email, 'email': email or False}, context=context) @@ -606,10 +606,16 @@ class res_partner(osv.osv, format_address): if limit: limit_str = ' limit %(limit)s' query_args['limit'] = limit + # TODO: simplify this in trunk with _rec_name='display_name', once display_name + # becomes a stored field cr.execute('''SELECT partner.id FROM res_partner partner LEFT JOIN res_partner company ON partner.parent_id = company.id - WHERE partner.email ''' + operator +''' %(name)s - OR partner.name || ' (' || COALESCE(company.name,'') || ')' + WHERE partner.email ''' + operator +''' %(name)s OR + CASE WHEN company.id IS NULL OR partner.is_company + THEN partner.name + ELSE + company.name || ', ' || partner.name + END ''' + operator + ' %(name)s ' + limit_str, query_args) ids = map(lambda x: x[0], cr.fetchall()) ids = self.search(cr, uid, [('id', 'in', ids)] + args, limit=limit, context=context) diff --git a/openerp/addons/base/res/res_partner_view.xml b/openerp/addons/base/res/res_partner_view.xml index 13b500c4cb0..a85272c5616 100644 --- a/openerp/addons/base/res/res_partner_view.xml +++ b/openerp/addons/base/res/res_partner_view.xml @@ -577,7 +577,14 @@ ir.actions.act_window res.partner.category form - Manage the partner categories in order to better classify them for tracking and analysis purposes. A partner may belong to several categories and categories have a hierarchy structure: a partner belonging to a category also belong to his parent category. + +

+ Click to create a new partner category. +

+ Manage the partner categories in order to better classify them for tracking and analysis purposes. + A partner may belong to several categories and categories have a hierarchy structure: a partner belonging to a category also belong to his parent category. +

+
diff --git a/openerp/addons/base/res/res_users.py b/openerp/addons/base/res/res_users.py index e5d55e56bdd..09be95a1acf 100644 --- a/openerp/addons/base/res/res_users.py +++ b/openerp/addons/base/res/res_users.py @@ -842,6 +842,7 @@ class users_view(osv.osv): 'string': app and app.name or _('Other'), 'selection': [(False, '')] + [(g.id, g.name) for g in gs], 'help': '\n'.join(tips), + 'exportable': False, } else: # boolean group fields @@ -850,6 +851,7 @@ class users_view(osv.osv): 'type': 'boolean', 'string': g.name, 'help': g.comment, + 'exportable': False, } return res diff --git a/openerp/addons/base/test/test_osv_expression.yml b/openerp/addons/base/test/test_osv_expression.yml index 1516f090e94..111ce40f2ce 100644 --- a/openerp/addons/base/test/test_osv_expression.yml +++ b/openerp/addons/base/test/test_osv_expression.yml @@ -375,6 +375,11 @@ currency_ids3 = self.pool.get('res.currency').search(cr, uid, [('id', 'not in', [])]) assert currency_ids1 == currency_ids2 == currency_ids3, 'All 3 results should have be the same: all currencies' default_company = self.browse(cr, uid, 1) + + # Due to currency data definition change (in relation with bug 1111298), this test now needs + # a manual setup where all currencies are assigned to the default company. + self.pool['res.currency'].write(cr, uid, currency_ids1, {'company_id': default_company.id}) + # one2many towards same model res_1 = self.search(cr, uid, [('child_ids', 'in', [x.id for x in company.child_ids])]) # any company having a child of company3 as child res_2 = self.search(cr, uid, [('child_ids', 'in', [company.child_ids[0].id])]) # any company having the first child of company3 as child diff --git a/openerp/report/render/rml2pdf/trml2pdf.py b/openerp/report/render/rml2pdf/trml2pdf.py index 243cc02a0b3..2052b128ad9 100644 --- a/openerp/report/render/rml2pdf/trml2pdf.py +++ b/openerp/report/render/rml2pdf/trml2pdf.py @@ -160,7 +160,7 @@ class _rml_styles(object,): for style in node.findall('paraStyle'): sname = style.get('name') self.styles[sname] = self._para_style_update(style) - if sname in self.default_style: + if self.default_style.has_key(sname): for key, value in self.styles[sname].items(): setattr(self.default_style[sname], key, value) else: @@ -277,11 +277,24 @@ class _rml_doc(object): fname = font.get('fontFile').encode('ascii') if name not in pdfmetrics._fonts: pdfmetrics.registerFont(TTFont(name, fname)) + #by default, we map the fontName to each style (bold, italic, bold and italic), so that + #if there isn't any font defined for one of these style (via a font family), the system + #will fallback on the normal font. addMapping(name, 0, 0, name) #normal addMapping(name, 0, 1, name) #italic addMapping(name, 1, 0, name) #bold addMapping(name, 1, 1, name) #italic and bold + #if registerFontFamily is defined, we register the mapping of the fontName to use for each style. + for font_family in node.findall('registerFontFamily'): + family_name = font_family.get('normal').encode('ascii') + if font_family.get('italic'): + addMapping(family_name, 0, 1, font_family.get('italic').encode('ascii')) + if font_family.get('bold'): + addMapping(family_name, 1, 0, font_family.get('bold').encode('ascii')) + if font_family.get('boldItalic'): + addMapping(family_name, 1, 1, font_family.get('boldItalic').encode('ascii')) + def setTTFontMapping(self,face, fontname, filename, mode='all'): from reportlab.lib.fonts import addMapping from reportlab.pdfbase import pdfmetrics diff --git a/openerp/service/__init__.py b/openerp/service/__init__.py index d66904615ba..2c6c80eb80c 100644 --- a/openerp/service/__init__.py +++ b/openerp/service/__init__.py @@ -3,7 +3,7 @@ # # OpenERP, Open Source Management Solution # Copyright (C) 2004-2009 Tiny SPRL (). -# Copyright (C) 2010-2012 OpenERP SA () +# Copyright (C) 2010-2013 OpenERP SA () # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as @@ -37,6 +37,7 @@ import openerp.netsvc import openerp.osv from openerp.release import nt_service_name import openerp.tools +from openerp.tools.misc import stripped_sys_argv import common import db @@ -128,9 +129,7 @@ def _reexec(): if openerp.tools.osutil.is_running_as_nt_service(): subprocess.call('net stop {0} && net start {0}'.format(nt_service_name), shell=True) exe = os.path.basename(sys.executable) - strip_args = ['-d', '-u'] - a = sys.argv[:] - args = [x for i, x in enumerate(a) if x not in strip_args and a[max(i - 1, 0)] not in strip_args] + args = stripped_sys_argv() if not args or args[0] != exe: args.insert(0, exe) os.execv(sys.executable, args) diff --git a/openerp/tools/misc.py b/openerp/tools/misc.py index 1b476fb9b2a..7a54d6b9b6e 100644 --- a/openerp/tools/misc.py +++ b/openerp/tools/misc.py @@ -3,7 +3,7 @@ # # OpenERP, Open Source Management Solution # Copyright (C) 2004-2009 Tiny SPRL (). -# Copyright (C) 2010-2012 OpenERP s.a. (). +# Copyright (C) 2010-2013 OpenERP s.a. (). # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as @@ -37,7 +37,7 @@ import time import zipfile from collections import defaultdict from datetime import datetime -from itertools import islice, izip +from itertools import islice, izip, groupby from lxml import etree from which import which from threading import local @@ -1059,4 +1059,22 @@ class CountingStream(object): raise StopIteration() return val +def stripped_sys_argv(*strip_args): + """Return sys.argv with some arguments stripped, suitable for reexecution or subprocesses""" + strip_args = sorted(set(strip_args) | set(['-s', '--save', '-d', '--database', '-u', '--update', '-i', '--init'])) + assert all(config.parser.has_option(s) for s in strip_args) + takes_value = dict((s, config.parser.get_option(s).takes_value()) for s in strip_args) + + longs, shorts = list(tuple(y) for _, y in groupby(strip_args, lambda x: x.startswith('--'))) + longs_eq = tuple(l + '=' for l in longs if takes_value[l]) + + args = sys.argv[:] + + def strip(args, i): + return args[i].startswith(shorts) \ + or args[i].startswith(longs_eq) or (args[i] in longs) \ + or (i >= 1 and (args[i - 1] in strip_args) and takes_value[args[i - 1]]) + + return [x for i, x in enumerate(args) if not strip(args, i)] + # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: