[MERGE]:trunk

bzr revid: apa@tinyerp.com-20120914053836-rt02ojybaaeirlr5
This commit is contained in:
Amit Patel
2012-09-14 11:08:36 +05:30
18 changed files with 210 additions and 174 deletions
+1 -1
View File
@@ -36,7 +36,7 @@ The kernel of OpenERP, needed for all installation.
'data': [
'base_data.xml',
'currency_data.xml',
'country_data.xml',
'res/res_country_data.xml',
'security/base_security.xml',
'base_menu.xml',
'res/res_security.xml',
-2
View File
@@ -62,8 +62,6 @@
<field name="name">Your Company</field>
<field name="partner_id" ref="main_partner"/>
<field name="rml_header1">Your Company Slogan</field>
<field name="rml_footer1">Web: http://www.yourcompany.com - Tel: +33 1 49 51 23 94</field>
<field name="rml_footer2">Bank Accounts... to be configured in menu Settings > Accounting/Invoicing.</field>
<field name="currency_id" ref="base.EUR"/>
</record>
+1 -1
View File
@@ -267,7 +267,7 @@ class ir_translation(osv.osv):
# FIXME: should assert that `source` is unicode and fix all callers to always pass unicode
# so we can remove the string encoding/decoding.
if not lang:
return u''
return tools.ustr(source or '')
if isinstance(types, basestring):
types = (types,)
if source:
+24 -26
View File
@@ -172,37 +172,35 @@ class res_partner_bank(osv.osv):
('required', field.required)]
return res
def _prepare_name_get(self, cr, uid, bank_type_obj, bank_obj, context=None):
def _prepare_name_get(self, cr, uid, bank_dicts, context=None):
""" Format the name of a res.partner.bank.
This function is designed to be inherited to add replacement fields.
:param bank_dicts: a list of res.partner.bank dicts, as returned by the method read()
:return: [(id, name), ...], as returned by the method name_get()
"""
Format the name of a res.partner.bank.
This function is designed to be inherited to add replacement fields.
:param browse_record bank_type_obj: res.partner.bank.type object
:param browse_record bank_obj: res.partner.bank object
:rtype: str
:return: formatted name of a res.partner.bank record
"""
return bank_type_obj.format_layout % bank_obj._data[bank_obj.id]
# prepare a mapping {code: format_layout} for all bank types
bank_type_obj = self.pool.get('res.partner.bank.type')
bank_types = bank_type_obj.browse(cr, uid, bank_type_obj.search(cr, uid, []), context=context)
bank_code_format = dict((bt.code, bt.format_layout) for bt in bank_types)
res = []
for data in bank_dicts:
name = data['acc_number']
if data['state'] and bank_code_format.get(data['state']):
try:
if not data.get('bank_name'):
data['bank_name'] = _('BANK')
name = bank_code_format[data['state']] % data
except Exception:
raise osv.except_osv(_("Formating Error"), _("Invalid Bank Account Type Name format."))
res.append((data.get('id', False), name))
return res
def name_get(self, cr, uid, ids, context=None):
if not len(ids):
return []
bank_type_obj = self.pool.get('res.partner.bank.type')
res = []
for val in self.browse(cr, uid, ids, context=context):
result = val.acc_number
if val.state:
type_ids = bank_type_obj.search(cr, uid, [('code','=',val.state)])
if type_ids:
t = bank_type_obj.browse(cr, uid, type_ids[0], context=context)
try:
# avoid the default format_layout to result in "False: ..."
if not val._data[val.id]['bank_name']:
val._data[val.id]['bank_name'] = _('BANK')
result = self._prepare_name_get(cr, uid, t, val, context=context)
except Exception:
raise osv.except_osv(_("Formating Error"), _("Invalid Bank Account Type Name format."))
res.append((val.id, result))
return res
bank_dicts = self.read(cr, uid, ids, context=context)
return self._prepare_name_get(cr, uid, bank_dicts, context=context)
def onchange_company_id(self, cr, uid, ids, company_id, context=None):
result = {}
+23 -37
View File
@@ -111,8 +111,8 @@ class res_company(osv.osv):
'rml_header1': fields.char('Company Slogan', size=200, help="Appears by default on the top right corner of your printed documents (report header)."),
'rml_header2': fields.text('RML Internal Header', required=True),
'rml_header3': fields.text('RML Internal Header for Landscape Reports', required=True),
'rml_footer': fields.text('Report Footer', help="Footer text displayed at the bottom of all reports. Automatically set based on company details, "\
"but may also be customized by directly editing it."),
'rml_footer': fields.text('Report Footer', help="Footer text displayed at the bottom of all reports."),
'rml_footer_readonly': fields.related('rml_footer', type='text', string='Report Footer', readonly=True),
'custom_footer': fields.boolean('Custom Footer', help="Check this to define the report footer manually. Otherwise it will be filled in automatically."),
'logo': fields.related('partner_id', 'image', string="Logo", type="binary"),
'currency_id': fields.many2one('res.currency', 'Currency', required=True),
@@ -138,36 +138,28 @@ class res_company(osv.osv):
('name_uniq', 'unique (name)', 'The company name must be unique !')
]
def onchange_footer(self, cr, uid, ids, context=None):
# when touched, the footer becomes custom
return {'value': {'custom_footer': True}}
def onchange_footer(self, cr, uid, ids, custom_footer, phone, fax, email, website, vat, company_registry, bank_ids, context=None):
if custom_footer:
return {}
def set_auto_footer(self, cr, uid, ids, context=None):
# unset the flag 'custom_footer'; this will automatically compute the footer
return self.write(cr, uid, ids, {'custom_footer': False}, context=context)
def compute_footer(self, cr, uid, ids, context=None):
# first line (notice that missing elements are filtered out before the join)
res = ' | '.join(filter(bool, [
phone and '%s: %s' % (_('Phone'), phone),
fax and '%s: %s' % (_('Fax'), fax),
email and '%s: %s' % (_('Email'), email),
website and '%s: %s' % (_('Website'), website),
vat and '%s: %s' % (_('TIN'), vat),
company_registry and '%s: %s' % (_('Reg'), company_registry),
]))
# second line: bank accounts
res_partner_bank = self.pool.get('res.partner.bank')
for company in self.browse(cr, uid, ids, context):
if not company.custom_footer:
# first line (notice that missing elements are filtered out before the join)
res = ' | '.join(filter(bool, [
company.phone and '%s: %s' % (_('Phone'), company.phone),
company.fax and '%s: %s' % (_('Fax'), company.fax),
company.email and '%s: %s' % (_('Email'), company.email),
company.website and '%s: %s' % (_('Website'), company.website),
company.vat and '%s: %s' % (_('TIN'), company.vat),
company.company_registry and '%s: %s' % (_('Reg'), company.company_registry),
]))
# second line: bank accounts
account_ids = [acc.id for acc in company.bank_ids if acc.footer]
account_names = res_partner_bank.name_get(cr, uid, account_ids, context=context)
if account_names:
title = _('Bank Accounts') if len(account_names) > 1 else _('Bank Account')
res += '\n%s: %s' % (title, ', '.join(name for id, name in account_names))
# update footer
self.write(cr, uid, [company.id], {'rml_footer': res}, context=context)
return True
account_data = self.resolve_2many_commands(cr, uid, 'bank_ids', bank_ids, context=context)
account_names = res_partner_bank._prepare_name_get(cr, uid, account_data, context=context)
if account_names:
title = _('Bank Accounts') if len(account_names) > 1 else _('Bank Account')
res += '\n%s: %s' % (title, ', '.join(name for id, name in account_names))
return {'value': {'rml_footer': res, 'rml_footer_readonly': res}}
def on_change_country(self, cr, uid, ids, country_id, context=None):
currency_id = self._get_euro(cr, uid, context=context)
@@ -248,17 +240,11 @@ class res_company(osv.osv):
self.cache_restart(cr)
company_id = super(res_company, self).create(cr, uid, vals, context=context)
obj_partner.write(cr, uid, partner_id, {'company_id': company_id}, context=context)
self.compute_footer(cr, uid, [company_id], context=context)
return company_id
def write(self, cr, uid, ids, values, context=None):
self.cache_restart(cr)
if isinstance(ids, (int, long)):
ids = [ids]
super(res_company, self).write(cr, uid, ids, values, context=context)
if 'rml_footer' not in values:
self.compute_footer(cr, uid, ids, context=context)
return True
return super(res_company, self).write(cr, uid, ids, values, context=context)
def _get_euro(self, cr, uid, context=None):
rate_obj = self.pool.get('res.currency.rate')
+12 -15
View File
@@ -55,29 +55,26 @@
<div>
<field name="rml_header1" placeholder="e.g. Global Business Solutions"/>
</div>
<field name="website" widget="url" placeholder="e.g. www.openerp.com"/>
<field name="website" widget="url" placeholder="e.g. www.openerp.com"
on_change="onchange_footer(custom_footer, phone, fax, email, website, vat, company_registry, bank_ids)"/>
</group>
<group>
<field name="phone"/>
<field name="fax"/>
<field name="email"/>
<field name="vat"/>
<field name="company_registry"/>
<field name="phone" on_change="onchange_footer(custom_footer, phone, fax, email, website, vat, company_registry, bank_ids)"/>
<field name="fax" on_change="onchange_footer(custom_footer, phone, fax, email, website, vat, company_registry, bank_ids)"/>
<field name="email" on_change="onchange_footer(custom_footer, phone, fax, email, website, vat, company_registry, bank_ids)"/>
<field name="vat" on_change="onchange_footer(custom_footer, phone, fax, email, website, vat, company_registry, bank_ids)"/>
<field name="company_registry" on_change="onchange_footer(custom_footer, phone, fax, email, website, vat, company_registry, bank_ids)"/>
</group>
</group>
<group string="Bank Accounts">
<field name="bank_ids" nolabel="1"
context="{'default_company_id': active_id, 'footer_hide': False}"/>
<field name="bank_ids" nolabel="1" context="{'default_company_id': active_id, 'footer_hide': False}"
on_change="onchange_footer(custom_footer, phone, fax, email, website, vat, company_registry, bank_ids)"/>
</group>
<group string="Report Footer Configuration">
<field name="paper_format" on_change="onchange_paper_format(paper_format)"/>
<field name="custom_footer" invisible="1"/>
<label for="rml_footer"/>
<div>
<field name="rml_footer" on_change="onchange_footer()"/>
<button string="Set Automatic Footer" type="object" name="set_auto_footer"
attrs="{'invisible': [('custom_footer','=',False)]}" class="oe_edit_only"/>
</div>
<field name="custom_footer" on_change="onchange_footer(custom_footer, phone, fax, email, website, vat, company_registry, bank_ids)"/>
<field name="rml_footer" attrs="{'invisible': [('custom_footer','=',False)]}"/>
<field name="rml_footer_readonly" attrs="{'invisible': [('custom_footer','=',True)]}"/>
</group>
</page>
<page string="Header/Footer" groups="base.group_no_one">
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="1">
<record id="ad" model="res.country">
<field name="name">Andorra, Principality of</field>
<field name="code">ad</field>
@@ -106,7 +106,7 @@
<record id="be" model="res.country">
<field name="name">Belgium</field>
<field name="code">be</field>
<field name="address_format" eval="'%(street)s\n%(street2)s\n%(zip)s %(city)s\n%(country_name)s'" />
<field name="address_format" eval="'%(street)s\n%(street2)s\n%(zip)s %(city)s\n%(country_name)s'" />
<field name="currency_id" ref="EUR"/>
</record>
<record id="bf" model="res.country">
@@ -386,7 +386,7 @@
<record id="fr" model="res.country">
<field name="name">France</field>
<field name="code">fr</field>
<field name="address_format" eval="'%(street)s\n%(street2)s\n%(zip)s %(city)s\n%(country_name)s'" />
<field name="address_format" eval="'%(street)s\n%(street2)s\n%(zip)s %(city)s\n%(country_name)s'" />
<field name="currency_id" ref="EUR"/>
</record>
<record id="ga" model="res.country">
@@ -532,7 +532,7 @@
<record id="in" model="res.country">
<field name="name">India</field>
<field name="code">in</field>
<field name="address_format" eval="'%(street)s\n%(street2)s\n%(city)s %(zip)s\n%(state_name)s\n%(country_name)s'" />
<field name="address_format" eval="'%(street)s\n%(street2)s\n%(city)s %(zip)s\n%(state_name)s\n%(country_name)s'" />
<field name="currency_id" ref="INR"/>
</record>
<record id="io" model="res.country">
@@ -838,7 +838,7 @@
<record id="nl" model="res.country">
<field name="name">Netherlands</field>
<field name="code">nl</field>
<field name="address_format" eval="'%(street)s\n%(street2)s\n%(zip)s %(city)s\n%(country_name)s'" />
<field name="address_format" eval="'%(street)s\n%(street2)s\n%(zip)s %(city)s\n%(country_name)s'" />
<field name="currency_id" ref="EUR"/>
</record>
<record id="no" model="res.country">
@@ -1174,7 +1174,7 @@
</record>
<record id="uk" model="res.country">
<field name="name">United Kingdom</field>
<field name="address_format" eval="'%(street)s\n%(street2)s\n%(city)s\n%(state_name)s\n%(zip)s\n%(country_name)s'" />
<field name="address_format" eval="'%(street)s\n%(street2)s\n%(city)s\n%(state_name)s\n%(zip)s\n%(country_name)s'" />
<field name="code">gb</field>
<field name="currency_id" ref="GBP"/>
</record>
@@ -1186,7 +1186,7 @@
<record id="us" model="res.country">
<field name="name">United States</field>
<field name="code">us</field>
<field name="address_format" eval="'%(street)s\n%(street2)s\n%(city)s %(state_code)s %(zip)s\n%(country_name)s'" />
<field name="address_format" eval="'%(street)s\n%(street2)s\n%(city)s %(state_code)s %(zip)s\n%(country_name)s'" />
<field name="currency_id" ref="USD"/>
</record>
<record id="uy" model="res.country">
@@ -1281,5 +1281,5 @@
<field name="code">zw</field>
<field name="currency_id" ref="ZWD"/>
</record>
</data>
</data>
</openerp>
+1 -1
View File
@@ -77,7 +77,7 @@ class lang(osv.osv):
_logger.warning(msg, lang, lc)
if not lang_name:
lang_name = tools.get_languages().get(lang, lang)
lang_name = tools.ALL_LANGUAGES.get(lang, lang)
def fix_xa0(s):
+48 -5
View File
@@ -28,6 +28,48 @@ from tools.translate import _
import logging
import pooler
import pytz
from lxml import etree
class format_address(object):
def fields_view_get_address(self, cr, uid, arch, context={}):
user_obj = self.pool.get('res.users')
fmt = user_obj.browse(cr, uid, uid,context).company_id.country_id
fmt = fmt and fmt.address_format
layouts = {
'%(city)s %(state_code)s\n%(zip)s': """
<div class="address_format">
<field name="city" placeholder="City" style="width: 50%%"/>
<field name="state_id" class="oe_no_button" placeholder="State" style="width: 47%%" options='{"no_open": true}'/>
<br/>
<field name="zip" placeholder="ZIP"/>
</div>
""",
'%(zip)s %(city)s': """
<div class="address_format">
<field name="zip" placeholder="ZIP" style="width: 40%%"/>
<field name="city" placeholder="City" style="width: 57%%"/>
<br/>
<field name="state_id" class="oe_no_button" placeholder="State" options='{"no_open": true}'/>
</div>
""",
'%(city)s\n%(state_name)s\n%(zip)s': """
<div class="address_format">
<field name="city" placeholder="City"/>
<field name="state_id" class="oe_no_button" placeholder="State" options='{"no_open": true}'/>
<field name="zip" placeholder="ZIP"/>
</div>
"""
}
for k,v in layouts.items():
if fmt and (k in fmt):
doc = etree.fromstring(arch)
for node in doc.xpath("//div[@class='address_format']"):
tree = etree.fromstring(v)
node.getparent().replace(node, tree)
arch = etree.tostring(doc)
break
return arch
def _tz_get(self,cr,uid, context=None):
return [(x, x) for x in pytz.all_timezones]
@@ -119,7 +161,7 @@ def _lang_get(self, cr, uid, context=None):
POSTAL_ADDRESS_FIELDS = ('street', 'street2', 'zip', 'city', 'state_id', 'country_id')
ADDRESS_FIELDS = POSTAL_ADDRESS_FIELDS + ('email', 'phone', 'fax', 'mobile', 'website', 'ref', 'lang')
class res_partner(osv.osv):
class res_partner(osv.osv, format_address):
_description = 'Partner'
_name = "res.partner"
@@ -143,7 +185,7 @@ class res_partner(osv.osv):
'name': fields.char('Name', size=128, required=True, select=True),
'date': fields.date('Date', select=1),
'title': fields.many2one('res.partner.title', 'Title'),
'parent_id': fields.many2one('res.partner', 'Owned by'),
'parent_id': fields.many2one('res.partner', 'Company'),
'child_ids': fields.one2many('res.partner', 'parent_id', 'Contacts'),
'ref': fields.char('Reference', size=64, select=1),
'lang': fields.selection(_lang_get, 'Language',
@@ -226,9 +268,10 @@ class res_partner(osv.osv):
def fields_view_get(self, cr, user, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
if (not view_id) and (view_type=='form') and context and context.get('force_email', False):
view_id = self.pool.get('ir.model.data').get_object_reference(cr, user, 'base', 'view_partner_simple_form')[1]
return super(res_partner, self).fields_view_get(cr, user, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar, submenu=submenu)
res = super(res_partner,self).fields_view_get(cr, user, view_id, view_type, context, toolbar=toolbar, submenu=submenu)
if view_type == 'form':
res['arch'] = self.fields_view_get_address(cr, user, res['arch'], context=context)
return res
_defaults = {
'active': True,
+12 -1
View File
@@ -96,8 +96,18 @@
<form string="Contact" version="7.0">
<field name="image" widget='image' class="oe_avatar oe_left" options='{"preview_image": "image_medium"}'/>
<div class="oe_title">
<div class="oe_edit_only">
<label for="name"/> (
<field name="is_company" on_change="onchange_type(is_company)" class="oe_inline"/> <label for="is_company" string="Is a Company?"/>)
</div>
<h1>
<field name="name" default_focus="1" placeholder="Name" />
</h1>
<field name="parent_id"
placeholder="Company"
domain="[('is_company', '=', True)]" context="{'default_is_company': True}"
attrs="{'invisible': [('is_company','=', True)]}"/>
<group>
<field name="name"/>
<field name="category_id" widget="many2many_tags" placeholder="Tags..."/>
<field name="function" placeholder="e.g. Sales Director"/>
<field name="email" required="context.get('force_email', False)"/>
@@ -112,6 +122,7 @@
<record id="view_partner_form" model="ir.ui.view">
<field name="name">res.partner.form</field>
<field name="model">res.partner</field>
<field eval="1" name="priority"/>
<field name="arch" type="xml">
<form string="Partners" version="7.0">
<sheet>
@@ -1,5 +1,5 @@
.oe_module_vignette {
padding: 8px;
padding: 4px;
}
.oe_module_icon, .oe_module_desc {
display: inline-block;
+26 -24
View File
@@ -1443,7 +1443,7 @@ class BaseModel(object):
def _validate(self, cr, uid, ids, context=None):
context = context or {}
lng = context.get('lang', False) or 'en_US'
lng = context.get('lang')
trans = self.pool.get('ir.translation')
error_msgs = []
for constraint in self._constraints:
@@ -1459,7 +1459,7 @@ class BaseModel(object):
else:
translated_msg = tmp_msg
else:
translated_msg = trans._get_source(cr, uid, self._name, 'constraint', lng, msg) or msg
translated_msg = trans._get_source(cr, uid, self._name, 'constraint', lng, msg)
error_msgs.append(
_("Error occurred while validating the field(s) %s: %s") % (','.join(fields), translated_msg)
)
@@ -3412,7 +3412,8 @@ class BaseModel(object):
if context is None:
context = {}
write_access = self.check_access_rights(cr, user, 'write') or self.check_access_rights(cr, user, 'create')
write_access = self.check_access_rights(cr, user, 'write', raise_exception=False) \
or self.check_access_rights(cr, user, 'create', raise_exception=False)
res = {}
@@ -3431,24 +3432,25 @@ class BaseModel(object):
res[f]['readonly'] = True
res[f]['states'] = {}
if 'string' in res[f]:
res_trans = translation_obj._get_source(cr, user, self._name + ',' + f, 'field', context.get('lang', False) or 'en_US')
if res_trans:
res[f]['string'] = res_trans
if 'help' in res[f]:
help_trans = translation_obj._get_source(cr, user, self._name + ',' + f, 'help', context.get('lang', False) or 'en_US')
if help_trans:
res[f]['help'] = help_trans
if 'selection' in res[f]:
if isinstance(field.selection, (tuple, list)):
sel = field.selection
sel2 = []
for key, val in sel:
val2 = None
if val:
val2 = translation_obj._get_source(cr, user, self._name + ',' + f, 'selection', context.get('lang', False) or 'en_US', val)
sel2.append((key, val2 or val))
res[f]['selection'] = sel2
if 'lang' in context:
if 'string' in res[f]:
res_trans = translation_obj._get_source(cr, user, self._name + ',' + f, 'field', context['lang'])
if res_trans:
res[f]['string'] = res_trans
if 'help' in res[f]:
help_trans = translation_obj._get_source(cr, user, self._name + ',' + f, 'help', context['lang'])
if help_trans:
res[f]['help'] = help_trans
if 'selection' in res[f]:
if isinstance(field.selection, (tuple, list)):
sel = field.selection
sel2 = []
for key, val in sel:
val2 = None
if val:
val2 = translation_obj._get_source(cr, user, self._name + ',' + f, 'selection', context['lang'], val)
sel2.append((key, val2 or val))
res[f]['selection'] = sel2
return res
@@ -4273,9 +4275,9 @@ class BaseModel(object):
and vals[field]:
self._check_selection_field_value(cr, user, field, vals[field], context=context)
if self._log_access:
upd0 += ',create_uid,create_date'
upd1 += ",%s,(now() at time zone 'UTC')"
upd2.append(user)
upd0 += ',create_uid,create_date,write_uid,write_date'
upd1 += ",%s,(now() at time zone 'UTC'),%s,(now() at time zone 'UTC')"
upd2.extend((user, user))
cr.execute('insert into "'+self._table+'" (id'+upd0+") values ("+str(id_new)+upd1+')', tuple(upd2))
self.check_access_rule(cr, user, [id_new], 'create', context=context)
upd_todo.sort(lambda x, y: self._columns[x].priority-self._columns[y].priority)
+30 -31
View File
@@ -18,7 +18,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from __future__ import with_statement
import contextlib
import base64
import locale
import logging
@@ -98,8 +99,6 @@ class db(netsvc.ExportService):
self.id = 0
self.id_protect = threading.Semaphore()
self._pg_psw_env_var_is_set = False # on win32, pg_dump need the PGPASSWORD env var
def dispatch(self, method, params):
if method in [ 'create', 'get_progress', 'drop', 'dump',
'restore', 'rename',
@@ -118,7 +117,7 @@ class db(netsvc.ExportService):
return fn(*params)
def _create_empty_database(self, name):
db = sql_db.db_connect('template1')
db = sql_db.db_connect('postgres')
cr = db.cursor()
chosen_template = tools.config['db_template']
try:
@@ -179,7 +178,7 @@ class db(netsvc.ExportService):
openerp.modules.registry.RegistryManager.delete(db_name)
sql_db.close_db(db_name)
db = sql_db.db_connect('template1')
db = sql_db.db_connect('postgres')
cr = db.cursor()
cr.autocommit(True) # avoid transaction block
try:
@@ -205,23 +204,28 @@ class db(netsvc.ExportService):
cr.close()
return True
@contextlib.contextmanager
def _set_pg_password_in_environment(self):
""" On Win32, pg_dump (and pg_restore) require that
:envvar:`PGPASSWORD` be set
def _set_pg_psw_env_var(self):
# see http://www.postgresql.org/docs/8.4/static/libpq-envars.html
# FIXME: This is not thread-safe, and should never be enabled for
# SaaS (giving SaaS users the super-admin password is not a good idea
# anyway)
if tools.config['db_password'] and not os.environ.get('PGPASSWORD', ''):
This context management method handles setting
:envvar:`PGPASSWORD` iif win32 and the envvar is not already
set, and removing it afterwards.
"""
if os.name != 'nt' or os.environ.get('PGPASSWORD'):
yield
else:
os.environ['PGPASSWORD'] = tools.config['db_password']
self._pg_psw_env_var_is_set = True
try:
yield
finally:
del os.environ['PGPASSWORD']
def _unset_pg_psw_env_var(self):
if self._pg_psw_env_var_is_set:
os.environ['PGPASSWORD'] = ''
def exp_dump(self, db_name):
try:
self._set_pg_psw_env_var()
logger = logging.getLogger('openerp.service.web_services.db.dump')
with self._set_pg_password_in_environment():
cmd = ['pg_dump', '--format=c', '--no-owner']
if tools.config['db_user']:
cmd.append('--username=' + tools.config['db_user'])
@@ -237,23 +241,20 @@ class db(netsvc.ExportService):
res = stdout.close()
if not data or res:
_logger.error(
logger.error(
'DUMP DB: %s failed! Please verify the configuration of the database password on the server. '
'It should be provided as a -w <PASSWD> command-line option, or as `db_password` in the '
'server configuration file.\n %s', db_name, data)
raise Exception, "Couldn't dump database"
_logger.info('DUMP DB successful: %s', db_name)
logger.info('DUMP DB successful: %s', db_name)
return base64.encodestring(data)
finally:
self._unset_pg_psw_env_var()
def exp_restore(self, db_name, data):
try:
self._set_pg_psw_env_var()
logger = logging.getLogger('openerp.service.web_services.db.restore')
with self._set_pg_password_in_environment():
if self.exp_db_exist(db_name):
_logger.warning('RESTORE DB: %s already exists', db_name)
logger.warning('RESTORE DB: %s already exists', db_name)
raise Exception, "Database already exists"
self._create_empty_database(db_name)
@@ -282,17 +283,15 @@ class db(netsvc.ExportService):
res = stdout.close()
if res:
raise Exception, "Couldn't restore database"
_logger.info('RESTORE DB: %s', db_name)
logger.info('RESTORE DB: %s', db_name)
return True
finally:
self._unset_pg_psw_env_var()
def exp_rename(self, old_name, new_name):
openerp.modules.registry.RegistryManager.delete(old_name)
sql_db.close_db(old_name)
db = sql_db.db_connect('template1')
db = sql_db.db_connect('postgres')
cr = db.cursor()
cr.autocommit(True) # avoid transaction block
try:
@@ -320,7 +319,7 @@ class db(netsvc.ExportService):
raise openerp.exceptions.AccessDenied()
chosen_template = tools.config['db_template']
templates_list = tuple(set(['template0', 'template1', 'postgres', chosen_template]))
db = sql_db.db_connect('template1')
db = sql_db.db_connect('postgres')
cr = db.cursor()
try:
try:
@@ -557,7 +556,7 @@ GNU Public Licence.
return http_server.list_http_services()
def exp_check_connectivity(self):
return bool(sql_db.db_connect('template1'))
return bool(sql_db.db_connect('postgres'))
def exp_get_os_time(self):
return os.times()
@@ -245,7 +245,7 @@ class test_selection(CreatorCase):
'translatable': True,
'date_format': '%d.%m.%Y',
'decimal_point': ',',
'thousand_sep': ' ',
'thousands_sep': ' ',
})
Translations = self.registry('ir.translation')
for source, value in self.translations_fr:
@@ -393,7 +393,7 @@ class test_selection(ImporterCase):
'translatable': True,
'date_format': '%d.%m.%Y',
'decimal_point': ',',
'thousand_sep': ' ',
'thousands_sep': ' ',
})
Translations = self.registry('ir.translation')
for source, value in self.translations_fr:
@@ -466,7 +466,7 @@ class test_selection_function(ImporterCase):
'translatable': True,
'date_format': '%d.%m.%Y',
'decimal_point': ',',
'thousand_sep': ' ',
'thousands_sep': ' ',
})
Translations = self.registry('ir.translation')
for source, value in self.translations_fr:
+1 -1
View File
@@ -223,7 +223,7 @@ class configmanager(object):
help="specify the database port", type="int")
group.add_option("--db_maxconn", dest="db_maxconn", type='int', my_default=64,
help="specify the the maximum number of physical connections to posgresql")
group.add_option("--db-template", dest="db_template", my_default="template0",
group.add_option("--db-template", dest="db_template", my_default="template1",
help="specify a custom database template to create a new database")
parser.add_option_group(group)
+2 -1
View File
@@ -66,8 +66,9 @@ def image_resize_image(base64_source, size=(1024, 1024), encoding='base64', file
# check image size: do not create a thumbnail if avoiding smaller images
if avoid_if_small and image.size[0] <= size[0] and image.size[1] <= size[1]:
return base64_source
# create a thumbnail: will resize and keep ratios
# create a thumbnail: will resize and keep ratios, then sharpen for better looking result
image.thumbnail(size, Image.ANTIALIAS)
image.convert('RGB')
image = image.filter(ImageFilter.SHARPEN)
# create a transparent image for background
background = Image.new('RGBA', size, (255, 255, 255, 0))
+17 -16
View File
@@ -142,6 +142,8 @@ def file_open(name, mode="r", subdir='addons', pathinfo=False):
adps = addons.module.ad_paths
rtp = os.path.normcase(os.path.abspath(config['root_path']))
basename = name
if os.path.isabs(name):
# It is an absolute path
# Is it below 'addons_path' or 'root_path'?
@@ -154,7 +156,7 @@ def file_open(name, mode="r", subdir='addons', pathinfo=False):
else:
# It is outside the OpenERP root: skip zipfile lookup.
base, name = os.path.split(name)
return _fileopen(name, mode=mode, basedir=base, pathinfo=pathinfo)
return _fileopen(name, mode=mode, basedir=base, pathinfo=pathinfo, basename=basename)
if name.replace(os.sep, '/').startswith('addons/'):
subdir = 'addons'
@@ -172,16 +174,19 @@ def file_open(name, mode="r", subdir='addons', pathinfo=False):
for adp in adps:
try:
return _fileopen(name2, mode=mode, basedir=adp,
pathinfo=pathinfo)
pathinfo=pathinfo, basename=basename)
except IOError:
pass
# Second, try to locate in root_path
return _fileopen(name, mode=mode, basedir=rtp, pathinfo=pathinfo)
return _fileopen(name, mode=mode, basedir=rtp, pathinfo=pathinfo, basename=basename)
def _fileopen(path, mode, basedir, pathinfo):
def _fileopen(path, mode, basedir, pathinfo, basename=None):
name = os.path.normpath(os.path.join(basedir, path))
if basename is None:
basename = name
# Give higher priority to module directories, which is
# a more common case than zipped modules.
if os.path.isfile(name):
@@ -220,8 +225,8 @@ def _fileopen(path, mode, basedir, pathinfo):
pass
# Not found
if name.endswith('.rml'):
raise IOError('Report %r doesn\'t exist or deleted' % name)
raise IOError('File not found: %s' % name)
raise IOError('Report %r doesn\'t exist or deleted' % basename)
raise IOError('File not found: %s' % basename)
#----------------------------------------------------------
@@ -601,10 +606,7 @@ def get_iso_codes(lang):
lang = lang.split('_')[0]
return lang
def get_languages():
# The codes below are those from Launchpad's Rosetta, with the exception
# of some trivial codes where the Launchpad code is xx and we have xx_XX.
languages={
ALL_LANGUAGES = {
'ab_RU': u'Abkhazian / аҧсуа',
'ar_AR': u'Arabic / الْعَرَبيّة',
'bg_BG': u'Bulgarian / български език',
@@ -685,15 +687,14 @@ def get_languages():
'th_TH': u'Thai / ภาษาไทย',
'tlh_TLH': u'Klingon',
}
return languages
def scan_languages():
# Now it will take all languages from get languages function without filter it with base module languages
lang_dict = get_languages()
ret = [(lang, lang_dict.get(lang, lang)) for lang in list(lang_dict)]
ret.sort(key=lambda k:k[1])
return ret
""" Returns all languages supported by OpenERP for translation
:returns: a list of (lang_code, lang_name) pairs
:rtype: [(str, unicode)]
"""
return sorted(ALL_LANGUAGES.iteritems(), key=lambda k: k[1])
def get_user_companies(cr, user):
def _get_company_children(cr, ids):