def _validate(self, ids): pool = Pool() if (Transaction().user == 0 and Transaction().context.get('user')): with Transaction().set_user(Transaction().context.get('user')): return self._validate(ids) for field in self._constraints: if not getattr(self, field[0])(ids): self.raise_user_error(field[1]) if not 'res.user' in pool.object_name_list() \ or Transaction().user == 0: ctx_pref = { } else: user_obj = pool.get('res.user') ctx_pref = user_obj.get_preferences(context_only=True) def is_pyson(test): if isinstance(test, PYSON): return True if isinstance(test, (list, tuple)): for i in test: if isinstance(i, PYSON): return True if isinstance(i, (list, tuple)): if is_pyson(i): return True return False with Transaction().set_context(ctx_pref): records = self.browse(ids) for field_name, field in self._columns.iteritems(): if isinstance(field, fields.Function) and \ not field.setter: continue # validate domain if (field._type in ('many2one', 'many2many', 'one2many', 'one2one') and field.domain): if field._type in ('many2one', 'one2many'): relation_obj = pool.get(field.model_name) else: relation_obj = field.get_target() if is_pyson(field.domain): pyson_domain = PYSONEncoder().encode(field.domain) for record in records: env = EvalEnvironment(record, self) env.update(Transaction().context) env['current_date'] = datetime.datetime.today() env['time'] = time env['context'] = Transaction().context env['active_id'] = record.id domain = PYSONDecoder(env).decode(pyson_domain) relation_ids = [] if record[field_name]: if field._type in ('many2one',): relation_ids.append(record[field_name].id) else: relation_ids.extend( [x.id for x in record[field_name]]) if relation_ids and not relation_obj.search([ 'AND', [('id', 'in', relation_ids)], domain, ]): self.raise_user_error( 'domain_validation_record', error_args=self._get_error_args( field_name)) else: relation_ids = [] for record in records: if record[field_name]: if field._type in ('many2one',): relation_ids.append(record[field_name].id) else: relation_ids.extend( [x.id for x in record[field_name]]) if relation_ids: find_ids = relation_obj.search([ 'AND', [('id', 'in', relation_ids)], field.domain, ]) if not set(relation_ids) == set(find_ids): self.raise_user_error( 'domain_validation_record', error_args=self._get_error_args( field_name)) # validate states required if field.states and 'required' in field.states: if is_pyson(field.states['required']): pyson_required = PYSONEncoder().encode( field.states['required']) for record in records: env = EvalEnvironment(record, self) env.update(Transaction().context) env['current_date'] = datetime.datetime.today() env['time'] = time env['context'] = Transaction().context env['active_id'] = record.id required = PYSONDecoder(env).decode(pyson_required) if required and record[field_name] is None: self.raise_user_error( 'required_validation_record', error_args=self._get_error_args( field_name)) else: if field.states['required']: for record in records: if not record[field_name]: self.raise_user_error( 'required_validation_record', error_args=self._get_error_args( field_name)) # validate required if field.required: for record in records: if (isinstance(record[field_name], (BrowseRecordNull, type(None), type(False))) and not record[field_name]): self.raise_user_error( 'required_validation_record', error_args=self._get_error_args(field_name)) # validate size if hasattr(field, 'size') and field.size: for record in records: if len(record[field_name] or '') > field.size: self.raise_user_error( 'size_validation_record', error_args=self._get_error_args(field_name)) def digits_test(value, digits, field_name): def raise_user_error(): self.raise_user_error('digits_validation_record', error_args=self._get_error_args(field_name)) if value is None: return if isinstance(value, Decimal): if (value.quantize(Decimal(str(10.0 ** -digits[1]))) != value): raise_user_error() elif CONFIG.options['db_type'] != 'mysql': if not (round(value, digits[1]) == float(value)): raise_user_error() # validate digits if hasattr(field, 'digits') and field.digits: if is_pyson(field.digits): pyson_digits = PYSONEncoder().encode(field.digits) for record in records: env = EvalEnvironment(record, self) env.update(Transaction().context) env['current_date'] = datetime.datetime.today() env['time'] = time env['context'] = Transaction().context env['active_id'] = record.id digits = PYSONDecoder(env).decode(pyson_digits) digits_test(record[field_name], digits, field_name) else: for record in records: digits_test(record[field_name], field.digits, field_name)
def __export_row(self, record, fields_names): pool = Pool() lines = [] data = ['' for x in range(len(fields_names))] done = [] for fpos in range(len(fields_names)): fields_tree = fields_names[fpos] if not fields_tree: continue value = record i = 0 while i < len(fields_tree): if not isinstance(value, BrowseRecord): break field_name = fields_tree[i] model_obj = pool.get(value._model_name) if field_name in model_obj._columns: field = model_obj._columns[field_name] elif field_name in model_obj._inherit_fields: field = model_obj._inherit_fields[field_name][2] else: raise Exception('Field %s not available on object "%s"' % (field_name, model_obj._name)) if field.states and 'invisible' in field.states: pyson_invisible = PYSONEncoder().encode( field.states['invisible']) env = EvalEnvironment(value, model_obj) env.update(Transaction().context) env['current_date'] = datetime.datetime.today() env['time'] = time env['context'] = Transaction().context env['active_id'] = value.id invisible = PYSONDecoder(env).decode(pyson_invisible) if invisible: value = '' break value = value[field_name] if isinstance(value, (BrowseRecordList, list)): first = True child_fields_names = [(x[:i + 1] == fields_tree[:i + 1] and x[i + 1:]) or [] for x in fields_names] if child_fields_names in done: break done.append(child_fields_names) for child_record in value: child_lines = self.__export_row(child_record, child_fields_names) if first: for child_fpos in xrange(len(fields_names)): if child_lines and child_lines[0][child_fpos]: data[child_fpos] = \ child_lines[0][child_fpos] lines += child_lines[1:] first = False else: lines += child_lines break i += 1 if i == len(fields_tree): if value is None: value = '' data[fpos] = value return [data] + lines