[merge] lp:openobject-server/7.0
bzr revid: jam@tinyerp.com-20130611051458-r4bg46apl7j6kfrf
This commit is contained in:
commit
d334814bf5
|
@ -40,7 +40,7 @@ License: GPL-2+
|
|||
.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
.
|
||||
On Debian systems, the complete text of the GNU General Public License
|
||||
can be found in /usr/share/common-licenses/GPL-2 file.
|
||||
|
@ -93,7 +93,7 @@ License: LGPL-2.1
|
|||
.
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
.
|
||||
On Debian systems, the complete text of the GNU Library General Public License
|
||||
can be found in /usr/share/common-licenses/LGPL-2.1 file.
|
||||
|
@ -137,7 +137,7 @@ License: GPL-2+
|
|||
.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
.
|
||||
On Debian systems, the complete text of the GNU General Public License
|
||||
can be found in /usr/share/common-licenses/GPL-2 file.
|
||||
|
@ -159,7 +159,7 @@ License: GPL-2+
|
|||
.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
.
|
||||
On Debian systems, the complete text of the GNU General Public License
|
||||
can be found in /usr/share/common-licenses/GPL-2 file.
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#!/usr/bin/python
|
||||
# WSGI Handler sample configuration file.
|
||||
#
|
||||
# Change the appropriate settings below, in order to provide the parameters
|
||||
|
|
|
@ -49,8 +49,6 @@
|
|||
<field name="symbol">€</field>
|
||||
<field name="rounding">0.01</field>
|
||||
<field name="accuracy">4</field>
|
||||
<!-- Company ID will be set later -->
|
||||
<field name="company_id" eval="None"/>
|
||||
</record>
|
||||
<record id="rateEUR" model="res.currency.rate">
|
||||
<field name="rate">1.0</field>
|
||||
|
@ -86,10 +84,6 @@ Administrator</field>
|
|||
<field name="company_id" ref="main_company"/>
|
||||
</record>
|
||||
|
||||
<record id="EUR" model="res.currency">
|
||||
<field name="company_id" ref="main_company"/>
|
||||
</record>
|
||||
|
||||
<record id="ir_mail_server_localhost0" model="ir.mail_server">
|
||||
<field name="name">localhost</field>
|
||||
<field name="smtp_host">localhost</field>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -603,7 +603,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.get(action.action_id.type)\
|
||||
.read(cr, uid, action.action_id.id, context=context)
|
||||
|
||||
|
|
|
@ -198,7 +198,7 @@ class ir_attachment(osv.osv):
|
|||
continue
|
||||
res_ids.setdefault(rmod,set()).add(rid)
|
||||
if values:
|
||||
if 'res_model' in values and 'res_id' in values:
|
||||
if values.get('res_model') and 'res_id' in values:
|
||||
res_ids.setdefault(values['res_model'],set()).add(values['res_id'])
|
||||
|
||||
ima = self.pool.get('ir.model.access')
|
||||
|
|
|
@ -31,6 +31,7 @@ import re
|
|||
import smtplib
|
||||
import threading
|
||||
|
||||
from openerp import SUPERUSER_ID
|
||||
from openerp.osv import osv, fields
|
||||
from openerp.tools.translate import _
|
||||
from openerp.tools import html2text
|
||||
|
@ -211,14 +212,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
|
||||
|
@ -417,11 +418,11 @@ class ir_mail_server(osv.osv):
|
|||
# Get SMTP Server Details from Mail Server
|
||||
mail_server = None
|
||||
if mail_server_id:
|
||||
mail_server = self.browse(cr, uid, mail_server_id)
|
||||
mail_server = self.browse(cr, SUPERUSER_ID, mail_server_id)
|
||||
elif not smtp_server:
|
||||
mail_server_ids = self.search(cr, uid, [], order='sequence', limit=1)
|
||||
mail_server_ids = self.search(cr, SUPERUSER_ID, [], order='sequence', limit=1)
|
||||
if mail_server_ids:
|
||||
mail_server = self.browse(cr, uid, mail_server_ids[0])
|
||||
mail_server = self.browse(cr, SUPERUSER_ID, mail_server_ids[0])
|
||||
|
||||
if mail_server:
|
||||
smtp_server = mail_server.smtp_host
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -54,6 +54,34 @@ class ir_sequence(openerp.osv.osv.osv):
|
|||
"""
|
||||
_name = 'ir.sequence'
|
||||
_order = 'name'
|
||||
|
||||
def _get_number_next_actual(self, cr, user, ids, field_name, arg, context=None):
|
||||
'''Return number from ir_sequence row when no_gap implementation,
|
||||
and number from postgres sequence when standard implementation.'''
|
||||
res = dict.fromkeys(ids)
|
||||
for element in self.browse(cr, user, ids, context=context):
|
||||
if element.implementation != 'standard':
|
||||
res[element.id] = element.number_next
|
||||
else:
|
||||
# get number from postgres sequence. Cannot use
|
||||
# currval, because that might give an error when
|
||||
# not having used nextval before.
|
||||
statement = (
|
||||
"SELECT last_value, increment_by, is_called"
|
||||
" FROM ir_sequence_%03d"
|
||||
% element.id)
|
||||
cr.execute(statement)
|
||||
(last_value, increment_by, is_called) = cr.fetchone()
|
||||
if is_called:
|
||||
res[element.id] = last_value + increment_by
|
||||
else:
|
||||
res[element.id] = last_value
|
||||
return res
|
||||
|
||||
def _set_number_next_actual(self, cr, uid, id, name, value, args=None, context=None):
|
||||
return self.write(cr, uid, id, {'number_next': value or 0}, context=context)
|
||||
|
||||
|
||||
_columns = {
|
||||
'name': openerp.osv.fields.char('Name', size=64, required=True),
|
||||
'code': openerp.osv.fields.selection(_code_get, 'Code', size=64),
|
||||
|
@ -67,6 +95,7 @@ class ir_sequence(openerp.osv.osv.osv):
|
|||
'prefix': openerp.osv.fields.char('Prefix', size=64, help="Prefix value of the record for the sequence"),
|
||||
'suffix': openerp.osv.fields.char('Suffix', size=64, help="Suffix value of the record for the sequence"),
|
||||
'number_next': openerp.osv.fields.integer('Next Number', required=True, help="Next number of this sequence"),
|
||||
'number_next_actual': openerp.osv.fields.function(_get_number_next_actual, fnct_inv=_set_number_next_actual, type='integer', required=True, string='Next Number', help='Next number that will be used. This number can be incremented frequently so the displayed value might already be obsolete'),
|
||||
'number_increment': openerp.osv.fields.integer('Increment Number', required=True, help="The next number of the sequence will be incremented by this number"),
|
||||
'padding' : openerp.osv.fields.integer('Number Padding', required=True, help="OpenERP will automatically adds some '0' on the left of the 'Next Number' to get the required padding size."),
|
||||
'company_id': openerp.osv.fields.many2one('res.company', 'Company'),
|
||||
|
@ -77,6 +106,7 @@ class ir_sequence(openerp.osv.osv.osv):
|
|||
'company_id': lambda s,cr,uid,c: s.pool.get('res.company')._company_default_get(cr, uid, 'ir.sequence', context=c),
|
||||
'number_increment': 1,
|
||||
'number_next': 1,
|
||||
'number_next_actual': 1,
|
||||
'padding' : 0,
|
||||
}
|
||||
|
||||
|
@ -121,7 +151,7 @@ class ir_sequence(openerp.osv.osv.osv):
|
|||
# object depends on it.
|
||||
cr.execute("DROP SEQUENCE IF EXISTS %s RESTRICT " % names)
|
||||
|
||||
def _alter_sequence(self, cr, id, number_increment, number_next):
|
||||
def _alter_sequence(self, cr, id, number_increment, number_next=None):
|
||||
""" Alter a PostreSQL sequence.
|
||||
|
||||
There is no access rights check.
|
||||
|
@ -129,9 +159,15 @@ class ir_sequence(openerp.osv.osv.osv):
|
|||
if number_increment == 0:
|
||||
raise osv.except_osv(_('Warning!'),_("Increment number must not be zero."))
|
||||
assert isinstance(id, (int, long))
|
||||
cr.execute("""
|
||||
ALTER SEQUENCE ir_sequence_%03d INCREMENT BY %%s RESTART WITH %%s
|
||||
""" % id, (number_increment, number_next))
|
||||
seq_name = 'ir_sequence_%03d' % (id,)
|
||||
cr.execute("SELECT relname FROM pg_class WHERE relkind = %s AND relname=%s", ('S', seq_name))
|
||||
if not cr.fetchone():
|
||||
# sequence is not created yet, we're inside create() so ignore it, will be set later
|
||||
return
|
||||
statement = "ALTER SEQUENCE %s INCREMENT BY %d" % (seq_name, number_increment)
|
||||
if number_next is not None:
|
||||
statement += " RESTART WITH %d" % (number_next, )
|
||||
cr.execute(statement)
|
||||
|
||||
def create(self, cr, uid, values, context=None):
|
||||
""" Create a sequence, in implementation == standard a fast gaps-allowed PostgreSQL sequence is used.
|
||||
|
@ -160,7 +196,13 @@ class ir_sequence(openerp.osv.osv.osv):
|
|||
n = values.get('number_next', row['number_next'])
|
||||
if row['implementation'] == 'standard':
|
||||
if new_implementation in ('standard', None):
|
||||
self._alter_sequence(cr, row['id'], i, n)
|
||||
# Implementation has NOT changed.
|
||||
# Only change sequence if really requested.
|
||||
if row['number_next'] != n:
|
||||
self._alter_sequence(cr, row['id'], i, n)
|
||||
else:
|
||||
# Just in case only increment changed
|
||||
self._alter_sequence(cr, row['id'], i)
|
||||
else:
|
||||
self._drop_sequence(cr, row['id'])
|
||||
else:
|
||||
|
@ -200,7 +242,7 @@ class ir_sequence(openerp.osv.osv.osv):
|
|||
force_company = context.get('force_company')
|
||||
if not force_company:
|
||||
force_company = self.pool.get('res.users').browse(cr, uid, uid).company_id.id
|
||||
sequences = self.read(cr, uid, seq_ids, ['company_id','implementation','number_next','prefix','suffix','padding'])
|
||||
sequences = self.read(cr, uid, seq_ids, ['name','company_id','implementation','number_next','prefix','suffix','padding'])
|
||||
preferred_sequences = [s for s in sequences if s['company_id'] and s['company_id'][0] == force_company ]
|
||||
seq = preferred_sequences[0] if preferred_sequences else sequences[0]
|
||||
if seq['implementation'] == 'standard':
|
||||
|
@ -210,8 +252,11 @@ class ir_sequence(openerp.osv.osv.osv):
|
|||
cr.execute("SELECT number_next FROM ir_sequence WHERE id=%s FOR UPDATE NOWAIT", (seq['id'],))
|
||||
cr.execute("UPDATE ir_sequence SET number_next=number_next+number_increment WHERE id=%s ", (seq['id'],))
|
||||
d = self._interpolation_dict()
|
||||
interpolated_prefix = self._interpolate(seq['prefix'], d)
|
||||
interpolated_suffix = self._interpolate(seq['suffix'], d)
|
||||
try:
|
||||
interpolated_prefix = self._interpolate(seq['prefix'], d)
|
||||
interpolated_suffix = self._interpolate(seq['suffix'], d)
|
||||
except ValueError:
|
||||
raise osv.except_osv(_('Warning'), _('Invalid prefix or suffix for sequence \'%s\'') % (seq.get('name')))
|
||||
return interpolated_prefix + '%%0%sd' % seq['padding'] % seq['number_next'] + interpolated_suffix
|
||||
|
||||
def next_by_id(self, cr, uid, sequence_id, context=None):
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
<field name="suffix"/>
|
||||
<field name="padding"/>
|
||||
<field name="number_increment"/>
|
||||
<field name="number_next"/>
|
||||
<field name="number_next_actual"/>
|
||||
<field name="implementation"/>
|
||||
</group>
|
||||
<group col="3" string="Legend (for prefix, suffix)">
|
||||
|
@ -57,7 +57,7 @@
|
|||
<field name="prefix"/>
|
||||
<field name="padding"/>
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
<field name="number_next"/>
|
||||
<field name="number_next_actual"/>
|
||||
<field name="number_increment"/>
|
||||
<field name="implementation"/>
|
||||
</tree>
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -96,7 +96,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)
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -53,7 +53,13 @@
|
|||
<field name="res_model">res.bank</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="help">Manage bank records you want to be used in the system.</field>
|
||||
<field name="help">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to create a new bank.
|
||||
</p><p>
|
||||
Manage bank records you want to be used in the system.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
<menuitem action="action_res_bank_form" id="menu_action_res_bank_form" parent="base.menu_config_address_book" sequence="11" groups="base.group_no_one"/>
|
||||
|
||||
|
@ -152,7 +158,17 @@
|
|||
<field name="res_model">res.partner.bank</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="help">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.</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to create a bank account.
|
||||
</p><p>
|
||||
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.
|
||||
</p>
|
||||
<p>
|
||||
If you use the accounting application of OpenERP, journals and accounts will be created automatically based on these data.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
<menuitem action="action_res_partner_bank_account_form"
|
||||
id="menu_action_res_partner_bank_form"
|
||||
|
|
|
@ -272,6 +272,10 @@ class res_company(osv.osv):
|
|||
<header>
|
||||
<pageTemplate>
|
||||
<frame id="first" x1="28.0" y1="28.0" width="%s" height="%s"/>
|
||||
<stylesheet>
|
||||
<!-- Set here the default font to use for all <para> tags -->
|
||||
<paraStyle name='Normal' fontName="DejaVu Sans"/>
|
||||
</stylesheet>
|
||||
<pageGraphics>
|
||||
<fill color="black"/>
|
||||
<stroke color="black"/>
|
||||
|
@ -281,6 +285,9 @@ class res_company(osv.osv):
|
|||
<drawCentredString x="%s" y="%s">[[ company.partner_id.name ]]</drawCentredString>
|
||||
<stroke color="#000000"/>
|
||||
<lines>%s</lines>
|
||||
<!-- Set here the default font to use for all <drawString> tags -->
|
||||
<!-- don't forget to change the 2 other occurence of <setFont> above if needed -->
|
||||
<setFont name="DejaVu Sans" size="8"/>
|
||||
</pageGraphics>
|
||||
</pageTemplate>
|
||||
</header>"""
|
||||
|
@ -304,13 +311,16 @@ class res_company(osv.osv):
|
|||
<pageTemplate>
|
||||
<frame id="first" x1="1.3cm" y1="3.0cm" height="%s" width="19.0cm"/>
|
||||
<stylesheet>
|
||||
<paraStyle name="main_footer" fontName="DejaVu Sans" fontSize="8.0" alignment="CENTER"/>
|
||||
<paraStyle name="main_header" fontName="DejaVu Sans" fontSize="8.0" leading="10" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
|
||||
<!-- Set here the default font to use for all <para> tags -->
|
||||
<paraStyle name='Normal' fontName="DejaVu Sans"/>
|
||||
<paraStyle name="main_footer" fontSize="8.0" alignment="CENTER"/>
|
||||
<paraStyle name="main_header" fontSize="8.0" leading="10" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
|
||||
</stylesheet>
|
||||
<pageGraphics>
|
||||
<!-- Set here the default font to use for all <drawString> tags -->
|
||||
<setFont name="DejaVu Sans" size="8"/>
|
||||
<!-- You Logo - Change X,Y,Width and Height -->
|
||||
<image x="1.3cm" y="%s" height="40.0" >[[ company.logo or removeParentNode('image') ]]</image>
|
||||
<setFont name="DejaVu Sans" size="8"/>
|
||||
<fill color="black"/>
|
||||
<stroke color="black"/>
|
||||
|
||||
|
|
|
@ -73,6 +73,7 @@ class res_currency(osv.osv):
|
|||
'position' : 'after',
|
||||
'rounding': 0.01,
|
||||
'accuracy': 4,
|
||||
'company_id': False,
|
||||
}
|
||||
_sql_constraints = [
|
||||
# this constraint does not cover all cases due to SQL NULL handling for company_id,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -74,7 +74,8 @@ class format_address(object):
|
|||
|
||||
|
||||
def _tz_get(self,cr,uid, context=None):
|
||||
return [(x, x) for x in pytz.all_timezones]
|
||||
# put POSIX 'Etc/*' entries at the end to avoid confusing users - see bug 1086728
|
||||
return [(tz,tz) for tz in sorted(pytz.all_timezones, key=lambda tz: tz if not tz.startswith('Etc/') else '_')]
|
||||
|
||||
class res_partner_category(osv.osv):
|
||||
|
||||
|
@ -573,7 +574,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)
|
||||
|
|
|
@ -576,7 +576,14 @@
|
|||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">res.partner.category</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="help">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.</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to create a new partner category.
|
||||
</p><p>
|
||||
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.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem action="action_partner_category_form" id="menu_partner_category_form" name="Partner Tags" sequence="4" parent="menu_config_address_book" groups="base.group_no_one"/>
|
||||
|
|
|
@ -836,6 +836,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
|
||||
|
@ -844,6 +845,7 @@ class users_view(osv.osv):
|
|||
'type': 'boolean',
|
||||
'string': g.name,
|
||||
'help': g.comment,
|
||||
'exportable': False,
|
||||
}
|
||||
return res
|
||||
|
||||
|
|
|
@ -87,6 +87,12 @@
|
|||
<field name="domain_force">['|','|',('company_id.child_ids','child_of',[user.company_id.id]),('company_id','child_of',[user.company_id.id]),('company_id','=',False)]</field>
|
||||
</record>
|
||||
|
||||
<record id="res_currency_rule" model="ir.rule">
|
||||
<field name="name">multi-company currency rule</field>
|
||||
<field model="ir.model" name="model_id" ref="model_res_currency"/>
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
|
|
|
@ -114,7 +114,7 @@
|
|||
"access_ir_filter employee","ir_filters employee","model_ir_filters","group_user",1,1,1,1
|
||||
"access_ir_filters","ir_filters_all","model_ir_filters",,1,1,1,1
|
||||
"access_ir_config_parameter","ir_config_parameter","model_ir_config_parameter",,1,0,0,0
|
||||
"access_ir_mail_server_all","ir_mail_server","model_ir_mail_server",,1,0,0,0
|
||||
"access_ir_mail_server","ir_mail_server","model_ir_mail_server","group_system",1,1,1,1
|
||||
"access_ir_actions_client","ir_actions_client all","model_ir_actions_client",,1,0,0,0
|
||||
"access_ir_needaction_mixin","ir_needaction_mixin","model_ir_needaction_mixin",,1,1,1,1
|
||||
|
||||
|
|
|
|
@ -291,22 +291,22 @@
|
|||
assert res_101 == [], 'res_101: expected %r, got %r' % ([], res_101)
|
||||
assert res_102 == company_ids, 'res_102: expected %r, got %r' % (company_ids, res_102)
|
||||
-
|
||||
Property of the query (one2many != False).
|
||||
Verify domain evaluation for `one2many != False`
|
||||
-
|
||||
!python {model: res.currency }: |
|
||||
ids = self.search(cr, uid, [])
|
||||
referenced_companies = set([x.company_id.id for x in self.browse(cr, uid, ids)])
|
||||
companies = set(self.pool.get('res.company').search(cr, uid, [('currency_ids', '!=', False)]))
|
||||
assert referenced_companies == companies
|
||||
!python {model: res.partner.category }: |
|
||||
all_ids = self.search(cr, uid, [])
|
||||
parent_categs = set([c.parent_id.id for c in self.browse(cr, uid, all_ids) if c.parent_id])
|
||||
result = set(self.search(cr, uid, [('child_ids', '!=', False)]))
|
||||
assert result and result == parent_categs, "Got %r, expected %r" % (result, parent_categs)
|
||||
-
|
||||
Property of the query (one2many = False).
|
||||
Verify domain evaluation for `one2many == False`
|
||||
-
|
||||
!python {model: res.currency }: |
|
||||
ids = self.search(cr, uid, [])
|
||||
referenced_companies = set([x.company_id.id for x in self.browse(cr, uid, ids)])
|
||||
unreferenced_companies = set(self.pool.get('res.company').search(cr, uid, [])).difference(referenced_companies)
|
||||
companies = set(self.pool.get('res.company').search(cr, uid, [('currency_ids', '=', False)]))
|
||||
assert unreferenced_companies == companies
|
||||
!python {model: res.partner.category }: |
|
||||
all_ids = self.search(cr, uid, [])
|
||||
parent_categs = set([c.parent_id.id for c in self.browse(cr, uid, all_ids) if c.parent_id])
|
||||
leaf_categs = set(all_ids) - parent_categs
|
||||
result = set(self.search(cr, uid, [('child_ids', '=', False)]))
|
||||
assert result and result == leaf_categs, "Got %r, expected %r" % (result, leaf_categs)
|
||||
-
|
||||
Equivalent queries.
|
||||
-
|
||||
|
@ -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
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue