Trytond: update es_ES and ca_ES + source code

This commit is contained in:
resteve 2013-04-16 10:53:42 +02:00
parent 1ab6979034
commit 48d5adc269
13 changed files with 253 additions and 72 deletions

View File

@ -391,10 +391,6 @@ Class attributes are:
Class methods:
.. classmethod:: ModelSQL.default_sequence()
Return default value for sequence field if the model has one.
.. classmethod:: ModelSQL.table_query()
Could be overrided to use a custom SQL query instead of a table of the

View File

@ -23,6 +23,7 @@ except ImportError:
from sqlite3 import OperationalError as DatabaseOperationalError
QUOTE_SEPARATION = re.compile(r"(.*?)('.*?')", re.DOTALL)
EXTRACT_PATTERN = re.compile(r'EXTRACT\s*\(\s*(\S*)\s+FROM', re.I)
POSITION_PATTERN = re.compile(r'POSITION\s*\(([^\)]*)\s+IN', re.I)
def extract(lookup_type, date):
@ -87,6 +88,15 @@ def split_part(text, delimiter, count):
return (text.split(delimiter) + [''] * (count - 1))[count - 1]
def position(substring, string):
if string is None:
return
try:
return string.index(substring) + 1
except ValueError:
return 0
def replace(text, pattern, replacement):
return str(text).replace(pattern, replacement)
@ -122,6 +132,7 @@ class Database(DatabaseInterface):
self._conn.create_function('extract', 2, extract)
self._conn.create_function('date_trunc', 2, date_trunc)
self._conn.create_function('split_part', 3, split_part)
self._conn.create_function('position', 2, position)
if sqlite.sqlite_version_info < (3, 3, 14):
self._conn.create_function('replace', 3, replace)
return self
@ -278,6 +289,7 @@ class Cursor(CursorInterface):
def execute(self, sql, params=None):
buf = ""
sql = re.sub(POSITION_PATTERN, r'POSITION(\1,', sql)
for nquote, quote in QUOTE_SEPARATION.findall(sql + "''"):
nquote = nquote.replace('?', '??')
nquote = nquote.replace('%s', '?')

View File

@ -375,7 +375,7 @@ msgstr "Actiu"
msgctxt "field:ir.action.act_window,auto_refresh:"
msgid "Auto-Refresh"
msgstr "Auto-Refresc"
msgstr "Actualizació automatitzada"
msgctxt "field:ir.action.act_window,context:"
msgid "Context Value"
@ -391,7 +391,7 @@ msgstr "Usuari creació"
msgctxt "field:ir.action.act_window,domain:"
msgid "Domain Value"
msgstr "Valor domini"
msgstr "Valor del domini"
msgctxt "field:ir.action.act_window,domains:"
msgid "Domains"
@ -443,7 +443,7 @@ msgstr "Model"
msgctxt "field:ir.action.act_window,search_value:"
msgid "Search Criteria"
msgstr "Filtrado"
msgstr "Filtrat"
msgctxt "field:ir.action.act_window,type:"
msgid "Type"
@ -2039,7 +2039,7 @@ msgstr "ID recurs"
msgctxt "field:ir.translation,src:"
msgid "Source"
msgstr "Codi"
msgstr "Original"
msgctxt "field:ir.translation,src_md5:"
msgid "Source MD5"
@ -2051,7 +2051,7 @@ msgstr "Tipus"
msgctxt "field:ir.translation,value:"
msgid "Translation Value"
msgstr "Valor de la traducció"
msgstr "Traducció"
msgctxt "field:ir.translation,write_date:"
msgid "Write Date"
@ -2547,7 +2547,7 @@ msgstr "Usuari modificació"
msgctxt "help:ir.action.act_window,auto_refresh:"
msgid "Add an auto-refresh on the view"
msgstr "Afegeix un auto-refresc a la vista"
msgstr "Afegeix un actualizació a la vista automatitzada"
msgctxt "help:ir.action.act_window,limit:"
msgid "Default limit for the list view"
@ -2797,7 +2797,7 @@ msgstr "Neteja traduccions"
msgctxt "model:ir.action,name:act_translation_export"
msgid "Export Translations"
msgstr "Exporta traducció"
msgstr "Exporta traduccions"
msgctxt "model:ir.action,name:act_translation_form"
msgid "Translations"
@ -2805,7 +2805,7 @@ msgstr "Traduccions"
msgctxt "model:ir.action,name:act_translation_set"
msgid "Set Report Translations"
msgstr "Obtenir traduccions dels informes"
msgstr "Obté traduccions dels informes"
msgctxt "model:ir.action,name:act_translation_update"
msgid "Synchronize Translations"
@ -3041,11 +3041,11 @@ msgstr "Traducció"
msgctxt "model:ir.translation.clean.start,name:"
msgid "Clean translation"
msgstr "Neteja traduccions"
msgstr "Neteja traducció"
msgctxt "model:ir.translation.clean.succeed,name:"
msgid "Clean translation"
msgstr "Neteja traduccions"
msgstr "Neteja traducció"
msgctxt "model:ir.translation.export.result,name:"
msgid "Export translation"
@ -3057,11 +3057,11 @@ msgstr "Exporta traducció"
msgctxt "model:ir.translation.set.start,name:"
msgid "Set Translation"
msgstr "Definir traduccions"
msgstr "Defineix traducció"
msgctxt "model:ir.translation.set.succeed,name:"
msgid "Set Translation"
msgstr "Definir traduccions"
msgstr "Defineix traducció"
msgctxt "model:ir.translation.update.start,name:"
msgid "Update translation"
@ -3213,7 +3213,7 @@ msgstr "Neteja traduccions"
msgctxt "model:ir.ui.menu,name:menu_translation_export"
msgid "Export Translations"
msgstr "Exporta traducció"
msgstr "Exporta traduccions"
msgctxt "model:ir.ui.menu,name:menu_translation_form"
msgid "Translations"
@ -3221,7 +3221,7 @@ msgstr "Traduccions"
msgctxt "model:ir.ui.menu,name:menu_translation_set"
msgid "Set Translations"
msgstr "Definir traduccions"
msgstr "Defineix traduccions"
msgctxt "model:ir.ui.menu,name:menu_translation_update"
msgid "Synchronize Translations"
@ -3365,7 +3365,7 @@ msgstr "Realitzat"
msgctxt "selection:ir.module.module.config_wizard.item,state:"
msgid "Open"
msgstr "Obrir"
msgstr "Per obrir"
msgctxt "selection:ir.module.module.dependency,state:"
msgid "Installed"
@ -3804,11 +3804,11 @@ msgstr "Exporta traducció"
msgctxt "view:ir.translation.set.start:"
msgid "Set Translations"
msgstr "Definir traduccions"
msgstr "Defineix traduccions"
msgctxt "view:ir.translation.set.start:"
msgid "Synchronize Translations?"
msgstr "Vol sincronitzar les traduccions?"
msgstr "Voleu sincronitzar les traduccions?"
msgctxt "view:ir.translation.set.succeed:"
msgid "Set Succeed!"
@ -3816,7 +3816,7 @@ msgstr "Les traduccions s'han realitzat correctament."
msgctxt "view:ir.translation.set.succeed:"
msgid "Set Translations"
msgstr "Definir traduccions"
msgstr "Defineix traduccions"
msgctxt "view:ir.translation.update.start:"
msgid "Synchronize Translations"
@ -3860,7 +3860,7 @@ msgstr "Vista"
msgctxt "view:ir.ui.view:"
msgid "_Show"
msgstr "_Mostrar"
msgstr "_Mostra"
msgctxt "view:ir.ui.view_search:"
msgid "View Search"

View File

@ -2040,11 +2040,11 @@ msgstr "ID del recurso"
msgctxt "field:ir.translation,src:"
msgid "Source"
msgstr "Origen"
msgstr "Original"
msgctxt "field:ir.translation,src_md5:"
msgid "Source MD5"
msgstr "Origen MD5"
msgstr "MD5 original"
msgctxt "field:ir.translation,type:"
msgid "Type"
@ -2648,7 +2648,7 @@ msgstr ""
msgctxt "help:ir.rule.group,rules:"
msgid "The rule is satisfied if at least one test is True"
msgstr "La regla se satisface si al menos una condición es cierta."
msgstr "La regla es correcta si al menos una condición es cierta."
msgctxt "help:ir.trigger,condition:"
msgid ""
@ -3368,7 +3368,7 @@ msgstr "Realizado"
msgctxt "selection:ir.module.module.config_wizard.item,state:"
msgid "Open"
msgstr "Abrir"
msgstr "Para abrir"
msgctxt "selection:ir.module.module.dependency,state:"
msgid "Installed"
@ -3721,7 +3721,7 @@ msgctxt "view:ir.rule.group:"
msgid ""
"If there is no test defined, the rule is always satisfied if not global"
msgstr ""
"Si no hay ningún test definido, la regla se satisface siempre si no es "
"Si no hay ningún test definido, la regla es correcta siempre si no es "
"global."
msgctxt "view:ir.rule.group:"
@ -3730,7 +3730,7 @@ msgstr "Reglas de registros"
msgctxt "view:ir.rule.group:"
msgid "The rule is satisfied if at least one test is True"
msgstr "La regla se satisface si al menos una condición es cierta."
msgstr "La regla es correcta si al menos una condición es cierta."
msgctxt "view:ir.rule:"
msgid "Test"

View File

@ -144,7 +144,7 @@ class Translation(ModelSQL, ModelView):
def search_model(cls, name, clause):
cursor = Transaction().cursor
cursor.execute('SELECT id FROM "%s" '
'WHERE split_part(name, \',\', 1) %s %%s' %
'WHERE SUBSTR(name, 1, POSITION(\',\' IN name) - 1) %s %%s' %
(cls._table, clause[1]), (clause[2],))
return [('id', 'in', [x[0] for x in cursor.fetchall()])]
@ -374,7 +374,7 @@ class Translation(ModelSQL, ModelView):
'AND value IS NOT NULL '
'AND fuzzy = %s '
'AND res_id IS NULL',
(lang, ttype, str(name), source, False))
(lang, ttype, name, source, False))
else:
cursor.execute('SELECT value '
'FROM ir_translation '
@ -385,7 +385,7 @@ class Translation(ModelSQL, ModelView):
'AND value IS NOT NULL '
'AND fuzzy = %s '
'AND res_id IS NULL',
(lang, ttype, str(name), False))
(lang, ttype, name, False))
res = cursor.fetchone()
if res:
cls._translation_cache.set((lang, ttype, name, source), res[0])
@ -430,7 +430,7 @@ class Translation(ModelSQL, ModelView):
'AND value IS NOT NULL '
'AND fuzzy = %s '
'AND res_id IS NULL)',
(lang, ttype, str(name), source, False))]
(lang, ttype, name, source, False))]
else:
clause += [('(lang = %s '
'AND type = %s '
@ -439,7 +439,7 @@ class Translation(ModelSQL, ModelView):
'AND value IS NOT NULL '
'AND fuzzy = %s '
'AND res_id IS NULL)',
(lang, ttype, str(name), False))]
(lang, ttype, name, False))]
if clause:
for i in range(0, len(clause), cursor.IN_MAX):
sub_clause = clause[i:i + cursor.IN_MAX]
@ -509,6 +509,17 @@ class Translation(ModelSQL, ModelView):
vals['src_md5'] = cls.get_src_md5(vals.get('src'))
return super(Translation, cls).write(translations, vals)
@classmethod
def extra_model_data(cls, model_data):
"Yield extra model linked to the model data"
if model_data.model in (
'ir.action.report',
'ir.action.act_window',
'ir.action.wizard',
'ir.action.url',
):
yield 'ir.action'
@classmethod
def translation_import(cls, lang, module, po_path):
pool = Pool()
@ -520,6 +531,9 @@ class Translation(ModelSQL, ModelView):
for model_data in models_data:
fs_id2model_data.setdefault(model_data.model, {})
fs_id2model_data[model_data.model][model_data.fs_id] = model_data
for extra_model in cls.extra_model_data(model_data):
fs_id2model_data.setdefault(extra_model, {})
fs_id2model_data[extra_model][model_data.fs_id] = model_data
translations = set()
to_create = []
@ -629,6 +643,9 @@ class Translation(ModelSQL, ModelView):
for model_data in models_data:
db_id2fs_id.setdefault(model_data.model, {})
db_id2fs_id[model_data.model][model_data.db_id] = model_data.fs_id
for extra_model in cls.extra_model_data(model_data):
db_id2fs_id.setdefault(extra_model, {})
db_id2fs_id[extra_model][model_data.db_id] = model_data.fs_id
pofile = TrytonPOFile(wrapwidth=78)
pofile.metadata = {

View File

@ -90,7 +90,8 @@ class Property(Function):
#Fetch res ids that comply with the domain
cursor.execute(
'SELECT CAST('
'SPLIT_PART("' + Property._table + '".res,\',\',2) '
'SUBSTR("' + Property._table + '".res, '
'POSITION(\',\' IN "' + Property._table + '".res) + 1) '
'AS INTEGER), '
'"' + Property._table + '".id '
'FROM "' + Property._table + '" '
@ -135,7 +136,7 @@ class Property(Function):
#Fetch the res ids that doesn't use the default value
cursor.execute(
"SELECT cast(split_part(res,',',2) as integer) "
"SELECT CAST(SUBSTR(res, POSITION(',' IN res) + 1) AS integer) "
'FROM "' + Property._table + '"'
'WHERE ' + property_query + ' AND res is not null',
property_val)
@ -160,23 +161,22 @@ class Property(Function):
if sql_type == 'NUMERIC':
operator = 'CAST(%s AS NUMERIC)'
value = "SUBSTR(value, POSITION(',' IN value) + 1)"
# All negative clauses will be negated later
if clause[1] in ('in', 'not in'):
operator = operator % '%%s'
return ("(CAST(SPLIT_PART(value,',',2) AS %s) IN ("
return ("(CAST(" + value + " AS %s) IN ("
+ ",".join((operator,) * len(clause[2])) + ")) ") % sql_type
elif ((clause[2] is False or clause[2] is None)
and clause[1] in ['=', '!=']):
return "((cast(split_part(value,',',2) as %s) IS NULL " \
") = %%s) " % sql_type
return "((CAST(" + value + " AS %s) IS NULL) = %%s) " % sql_type
elif clause[1] in ['not like', 'not ilike']:
return "(cast(split_part(value,',',2) as %s) %s %s) " % \
return "(CAST(" + value + " AS %s) %s %s) " % \
(sql_type, clause[1].split()[1], operator)
elif clause[1] == '!=':
return "(cast(split_part(value,',',2) as %s) = %s) " % \
(sql_type, operator)
return "(CAST(" + value + " AS %s) = %s) " % (sql_type, operator)
else:
return "(cast(split_part(value,',',2) as %s) %s %s) " % \
return "(CAST(" + value + " AS %s) %s %s) " % \
(sql_type, clause[1], operator)
@staticmethod

View File

@ -1269,8 +1269,9 @@ class ModelSQL(ModelStorage):
sql_type = FIELDS[
cls.id._type].sql_type(cls.id)[0]
query = ('SELECT id FROM "' + cls._table + '" '
'WHERE CAST(SPLIT_PART('
'"' + fargs[0] + '", \',\', 2) '
'WHERE CAST(SUBSTR("' + fargs[0] + '", '
'POSITION(\',\' IN "' + fargs[0] + '")'
+ '+ 1) '
'AS ' + sql_type + ') '
'IN (' + in_query[0] + ') '
'AND "' + fargs[0] + '" ilike %s')
@ -1293,10 +1294,15 @@ class ModelSQL(ModelStorage):
if rev_field._type == 'reference':
sql_type = FIELDS[
cls.id._type].sql_type(cls.id)[0]
origin = ('CAST(SPLIT_PART("%s", \',\', 2) AS %s)'
% (origin, sql_type))
where = ' AND "' + origin + '" LIKE %s'
where_args = [cls.__name__ + ',%']
origin = ('CAST(SUBSTR("%s", '
'POSITION(\',\' IN "%s") + 1) AS %s)'
% (origin, origin, sql_type))
else:
origin = '"%s"' % origin
where = ''
where_args = []
if hasattr(field, 'search'):
domain.extend([(fargs[0], 'in',
map(int, Target.search([
@ -1310,6 +1316,8 @@ class ModelSQL(ModelStorage):
], order=[], query_string=True)
query1 = ('SELECT %s FROM "%s" WHERE "%s" IN (%s)' %
(origin, Relation._table, target, query1))
query1 += where
query2 += where_args
domain[i] = ('id', 'inselect', (query1, query2))
i += 1
continue
@ -1330,16 +1338,21 @@ class ModelSQL(ModelStorage):
rev_field = Field._fields[field.field]
if rev_field._type == 'reference':
sql_type = FIELDS[cls.id._type].sql_type(cls.id)[0]
select = ('CAST(SPLIT_PART("%s", \',\', 2) AS %s)'
% (field.field, sql_type))
select = ('CAST(SUBSTR("%s", '
'POSITION(\',\' IN "%s") + 1) AS %s)'
% (field.field, field.field, sql_type))
where = ' AND "' + field.field + '" LIKE %s'
where_args = [cls.__name__ + ',%']
else:
select = '"' + field.field + '"'
where = ''
where_args = []
if isinstance(domain[i][2], bool) or domain[i][2] is None:
query1 = ('SELECT ' + select + ' '
'FROM ' + table_query + '"' + Field._table + '" '
'WHERE "' + field.field + '" IS NOT NULL')
query2 = table_args
'WHERE "' + field.field + '" IS NOT NULL' + where)
query2 = table_args + where_args
clause = 'inselect'
if not domain[i][2]:
clause = 'notinselect'
@ -1355,8 +1368,8 @@ class ModelSQL(ModelStorage):
query1 = ('SELECT ' + select + ' '
'FROM ' + table_query +
'"' + Field._table + '" '
'WHERE id IN (' + query1 + ')')
query2 = table_args + query2
'WHERE id IN (' + query1 + ')' + where)
query2 = table_args + query2 + where_args
domain[i] = ('id', 'inselect', (query1, query2))
i += 1
elif field._type in ('many2many', 'one2one'):
@ -1421,16 +1434,21 @@ class ModelSQL(ModelStorage):
origin_field = Relation._fields[field.origin]
if origin_field._type == 'reference':
sql_type = FIELDS[cls.id._type].sql_type(cls.id)[0]
select = ('CAST(SPLIT_PART("%s", \',\', 2) AS %s)'
% (field.origin, sql_type))
select = ('CAST(SUBSTR("%s", '
'POSITION(\',\' IN "%s") + 1) AS %s)'
% (field.origin, field.origin, sql_type))
where = ' AND "' + field.origin + '" LIKE %s'
where_args = [cls.__name__ + ',%']
else:
select = '"' + field.origin + '"'
where = ''
where_args = []
if isinstance(domain[i][2], bool) or domain[i][2] is None:
query1 = ('SELECT ' + select + ' '
'FROM ' + table_query + ' '
'"' + Relation._table + '" '
'WHERE "' + field.origin + '" IS NOT NULL')
query2 = table_args
'WHERE "' + field.origin + '" IS NOT NULL' + where)
query2 = table_args + where_args
clause = 'inselect'
if not domain[i][2]:
clause = 'notinselect'
@ -1447,8 +1465,9 @@ class ModelSQL(ModelStorage):
query1 = ('SELECT ' + select + ' '
'FROM ' + table_query +
'"' + Relation._table + '" '
'WHERE "' + field.target + '" IN (' + query1 + ')')
query2 = table_args + query2
'WHERE "' + field.target + '" IN (' + query1 + ')'
+ where)
query2 = table_args + query2 + where_args
domain[i] = ('id', 'inselect', (query1, query2))
i += 1

View File

@ -272,7 +272,7 @@ class ModelStorage(Model):
elif ftype in ('one2many',):
if data[field_name]:
data_o2m[field_name] = data[field_name]
data[field_name] = False
data[field_name] = None
elif ftype == 'many2many':
if data[field_name]:
data[field_name] = [('set', data[field_name])]
@ -566,7 +566,7 @@ class ModelStorage(Model):
warn('too_many_relations_found', value, relation)
res = None
else:
res = res[0]
res = res[0].id
return res
def get_many2many(relation, value):
@ -586,7 +586,7 @@ class ModelStorage(Model):
else:
res.extend(res2)
if len(res):
res = [('set', res)]
res = [('set', [x.id for x in res])]
return res
def get_one2one(relation, value):
@ -678,11 +678,11 @@ class ModelStorage(Model):
else:
res = bool(int(value))
elif field_type == 'integer':
res = value and int(value) or None
res = int(value) if value else None
elif field_type == 'float':
res = value and float(value) or None
res = float(value) if value else None
elif field_type == 'numeric':
res = value and Decimal(value) or None
res = Decimal(value) if value else None
elif field_type == 'date':
res = value and datetime.date(*time.strptime(value,
'%Y-%m-%d')[:3])

View File

@ -883,11 +883,11 @@ msgstr "Alerta usuari"
msgctxt "selection:res.request,priority:"
msgid "High"
msgstr "Alt"
msgstr "Alta"
msgctxt "selection:res.request,priority:"
msgid "Low"
msgstr "Sota"
msgstr "Baixa"
msgctxt "selection:res.request,priority:"
msgid "Normal"
@ -911,11 +911,11 @@ msgstr "Esperant"
msgctxt "selection:res.request.history,priority:"
msgid "High"
msgstr "Alt"
msgstr "Alta"
msgctxt "selection:res.request.history,priority:"
msgid "Low"
msgstr "Sota"
msgstr "Baixa"
msgctxt "selection:res.request.history,priority:"
msgid "Normal"

View File

@ -94,8 +94,11 @@ def register():
MPTT,
ImportDataBoolean,
ImportDataInteger,
ImportDataIntegerRequired,
ImportDataFloat,
ImportDataFloatRequired,
ImportDataNumeric,
ImportDataNumericRequired,
ImportDataChar,
ImportDataText,
ImportDataSha,

View File

@ -4,8 +4,10 @@
from trytond.model import ModelSQL, fields
__all__ = [
'ImportDataBoolean', 'ImportDataInteger', 'ImportDataFloat',
'ImportDataNumeric', 'ImportDataChar', 'ImportDataText', 'ImportDataSha',
'ImportDataBoolean', 'ImportDataInteger', 'ImportDataIntegerRequired',
'ImportDataFloat', 'ImportDataFloatRequired',
'ImportDataNumeric', 'ImportDataNumericRequired',
'ImportDataChar', 'ImportDataText', 'ImportDataSha',
'ImportDataDate', 'ImportDataDateTime', 'ImportDataSelection',
'ImportDataMany2OneTarget', 'ImportDataMany2One',
'ImportDataMany2ManyTarget', 'ImportDataMany2Many',
@ -27,18 +29,36 @@ class ImportDataInteger(ModelSQL):
integer = fields.Integer('Integer')
class ImportDataIntegerRequired(ModelSQL):
"Import Data Integer Required"
__name__ = 'test.import_data.integer_required'
integer = fields.Integer('Integer', required=True)
class ImportDataFloat(ModelSQL):
"Import Data Float"
__name__ = 'test.import_data.float'
float = fields.Float('Float')
class ImportDataFloatRequired(ModelSQL):
"Import Data Float Required"
__name__ = 'test.import_data.float_required'
float = fields.Float('Float', required=True)
class ImportDataNumeric(ModelSQL):
"Import Data Numeric"
__name__ = 'test.import_data.numeric'
numeric = fields.Numeric('Numeric')
class ImportDataNumericRequired(ModelSQL):
"Import Data Numeric Required"
__name__ = 'test.import_data.numeric_required'
numeric = fields.Numeric('Numeric', required=True)
class ImportDataChar(ModelSQL):
"Import Data Char"
__name__ = 'test.import_data.char'

View File

@ -17,8 +17,11 @@ class ImportDataTestCase(unittest.TestCase):
install_module('test')
self.boolean = POOL.get('test.import_data.boolean')
self.integer = POOL.get('test.import_data.integer')
self.integer_required = POOL.get('test.import_data.integer_required')
self.float = POOL.get('test.import_data.float')
self.float_required = POOL.get('test.import_data.float_required')
self.numeric = POOL.get('test.import_data.numeric')
self.numeric_required = POOL.get('test.import_data.numeric_required')
self.char = POOL.get('test.import_data.char')
self.text = POOL.get('test.import_data.text')
self.sha = POOL.get('test.import_data.sha')
@ -86,6 +89,41 @@ class ImportDataTestCase(unittest.TestCase):
self.assertEqual(self.integer.import_data(['integer'],
[['foo']])[0], -1)
self.assertEqual(self.integer.import_data(['integer'],
[['0']]), (1, 0, 0, 0))
transaction.cursor.rollback()
def test0021integer_required(self):
'''
Test required integer.
'''
with Transaction().start(DB_NAME, USER,
context=CONTEXT) as transaction:
self.assertEqual(self.integer_required.import_data(['integer'],
[['1']]), (1, 0, 0, 0))
self.assertEqual(self.integer_required.import_data(['integer'],
[['-1']]), (1, 0, 0, 0))
self.assertEqual(self.integer_required.import_data(['integer'],
[['']])[0], -1)
self.assertEqual(self.integer_required.import_data(['integer'],
[['1'], ['2']]), (2, 0, 0, 0))
self.assertEqual(self.integer_required.import_data(['integer'],
[['1.1']])[0], -1)
self.assertEqual(self.integer_required.import_data(['integer'],
[['-1.1']])[0], -1)
self.assertEqual(self.integer_required.import_data(['integer'],
[['foo']])[0], -1)
self.assertEqual(self.integer_required.import_data(['integer'],
[['0']]), (1, 0, 0, 0))
transaction.cursor.rollback()
def test0030float(self):
@ -112,6 +150,44 @@ class ImportDataTestCase(unittest.TestCase):
self.assertEqual(self.float.import_data(['float'],
[['foo']])[0], -1)
self.assertEqual(self.float.import_data(['float'],
[['0']]), (1, 0, 0, 0))
self.assertEqual(self.float.import_data(['float'],
[['0.0']]), (1, 0, 0, 0))
transaction.cursor.rollback()
def test0031float_required(self):
'''
Test required float.
'''
with Transaction().start(DB_NAME, USER,
context=CONTEXT) as transaction:
self.assertEqual(self.float_required.import_data(['float'],
[['1.1']]), (1, 0, 0, 0))
self.assertEqual(self.float_required.import_data(['float'],
[['-1.1']]), (1, 0, 0, 0))
self.assertEqual(self.float_required.import_data(['float'],
[['1']]), (1, 0, 0, 0))
self.assertEqual(self.float_required.import_data(['float'],
[['']])[0], -1)
self.assertEqual(self.float_required.import_data(['float'],
[['1.1'], ['2.2']]), (2, 0, 0, 0))
self.assertEqual(self.float_required.import_data(['float'],
[['foo']])[0], -1)
self.assertEqual(self.float_required.import_data(['float'],
[['0']]), (1, 0, 0, 0))
self.assertEqual(self.float_required.import_data(['float'],
[['0.0']]), (1, 0, 0, 0))
transaction.cursor.rollback()
def test0040numeric(self):
@ -138,6 +214,44 @@ class ImportDataTestCase(unittest.TestCase):
self.assertEqual(self.numeric.import_data(['numeric'],
[['foo']])[0], -1)
self.assertEqual(self.numeric.import_data(['numeric'],
[['0']]), (1, 0, 0, 0))
self.assertEqual(self.numeric.import_data(['numeric'],
[['0.0']]), (1, 0, 0, 0))
transaction.cursor.rollback()
def test0041numeric_required(self):
'''
Test required numeric.
'''
with Transaction().start(DB_NAME, USER,
context=CONTEXT) as transaction:
self.assertEqual(self.numeric_required.import_data(['numeric'],
[['1.1']]), (1, 0, 0, 0))
self.assertEqual(self.numeric_required.import_data(['numeric'],
[['-1.1']]), (1, 0, 0, 0))
self.assertEqual(self.numeric_required.import_data(['numeric'],
[['1']]), (1, 0, 0, 0))
self.assertEqual(self.numeric_required.import_data(['numeric'],
[['']])[0], -1)
self.assertEqual(self.numeric_required.import_data(['numeric'],
[['1.1'], ['2.2']]), (2, 0, 0, 0))
self.assertEqual(self.numeric_required.import_data(['numeric'],
[['foo']])[0], -1)
self.assertEqual(self.numeric_required.import_data(['numeric'],
[['0']]), (1, 0, 0, 0))
self.assertEqual(self.numeric_required.import_data(['numeric'],
[['0.0']]), (1, 0, 0, 0))
transaction.cursor.rollback()
def test0050char(self):

View File

@ -541,7 +541,7 @@ class Collection(ModelSQL, ModelView):
object_name, object_id = cls._uri2object(get_uriparentpath(uri),
cache=cache)
if not object_name \
or object_name in ('ir.attachment') \
or object_name == 'ir.attachment' \
or not object_id:
raise DAV_Forbidden
pool = Pool()