def _on_change_set(self, field, value): if (self._fields[field]['type'] in ('one2many', 'many2many') and not isinstance(value, (list, tuple))): to_remove = [] if value and value.get('remove'): for record_id in value['remove']: for record in getattr(self, field): if record.id == record_id: to_remove.append(record) for record in to_remove: # remove without signal getattr(self, field).remove(record, _changed=False) if value and (value.get('add') or value.get('update')): for index, vals in value.get('add', []): group = getattr(self, field) Relation = Model.get(self._fields[field]['relation'], self._config) config = Relation._config with config.reset_context(), \ config.set_context(self._context): record = Relation(_group=group, _default=False) record._set_on_change(vals) # append without signal if index == -1: list.append(group, record) else: list.insert(group, index, record) for vals in value.get('update', []): if 'id' not in vals: continue for record in getattr(self, field): if record.id == vals['id']: record._set_on_change(vals) elif (self._fields[field]['type'] in ('one2many', 'many2many') and len(value) and not isinstance(value[0], int)): self._values[field] = [] for vals in value: Relation = Model.get(self._fields[field]['relation'], self._config) config = Relation._config records = getattr(self, field) with config.reset_context(), \ config.set_context(records._get_context()): record = Relation(_default=False, **vals) records.append(record) else: self._values[field] = value self._changed.add(field)
def new(self, **kwargs): 'Adds a new record to the ModelList and returns it' Relation = Model.get(self.model_name, self.parent._config) config = Relation._config with config.reset_context(), config.set_context(self._get_context()): # Set parent for on_change calls from default_get new_record = Relation(_group=self, **kwargs) self.append(new_record) return new_record
def __get__(self, instance, owner): Relation = Model.get(self.definition['relation'], instance._config) value = super(Many2OneDescriptor, self).__get__(instance, owner) if isinstance(value, int): config = Relation._config with config.reset_context(), config.set_context(instance._context): value = Relation(value) if self.name in instance._values: instance._values[self.name] = value return value
def __get__(self, instance, owner): value = super(ReferenceDescriptor, self).__get__(instance, owner) if isinstance(value, str): model_name, id = value.split(',', 1) if model_name: Relation = Model.get(model_name, instance._config) config = Relation._config with config.reset_context(), \ config.set_context(instance._context): value = Relation(int(id)) instance._values[self.name] = value return value
def __get__(self, instance, owner): from .pyson import PYSONDecoder Relation = Model.get(self.definition['relation'], instance._config) value = super(One2ManyDescriptor, self).__get__(instance, owner) if not isinstance(value, ModelList): ctx = instance._context.copy() if instance._context else {} if self.definition.get('context'): decoder = PYSONDecoder(_EvalEnvironment(instance)) ctx.update(decoder.decode(self.definition.get('context'))) config = Relation._config with config.reset_context(), config.set_context(ctx): value = ModelList(self.definition, (Relation(id) for id in value or []), instance, self.name) instance._values[self.name] = value return value
def find(self, condition=None, offset=0, limit=None, order=None): 'Returns records matching condition taking into account list domain' from .pyson import PYSONDecoder decoder = PYSONDecoder(_EvalEnvironment(self.parent)) Relation = Model.get(self.model_name, self.parent._config) if condition is None: condition = [] field_domain = decoder.decode(self.domain) add_remove_domain = (decoder.decode(self.add_remove) if self.add_remove else []) new_domain = [field_domain, add_remove_domain, condition] context = self._get_context() context.update(decoder.decode(self.search_context)) order = order if order else decoder.decode(self.search_order) config = Relation._config with config.reset_context(), config.set_context(context): return Relation.find(new_domain, offset, limit, order)
def _convert_action(action, data=None, context=None, config=None): if config is None: config = proteus.config.get_config() if data is None: data = {} else: data = data.copy() if 'type' not in (action or {}): return None data['action_id'] = action['id'] if action['type'] == 'ir.action.act_window': from .pyson import PYSONDecoder action.setdefault('pyson_domain', '[]') ctx = { 'active_model': data.get('model'), 'active_id': data.get('id'), 'active_ids': data.get('ids', []), } ctx.update(config.context) ctx['_user'] = config.user decoder = PYSONDecoder(ctx) action_ctx = decoder.decode(action.get('pyson_context') or '{}') ctx.update(action_ctx) ctx.update(context) action_ctx.update(context) if 'date_format' not in action_ctx: action_ctx['date_format'] = config.context.get('locale', {}).get( 'date', '%x') ctx['context'] = ctx decoder = PYSONDecoder(ctx) domain = decoder.decode(action['pyson_domain']) res_model = action.get('res_model', data.get('res_model')) res_id = action.get('res_id', data.get('res_id')) Model_ = Model.get(res_model, config) config = Model_._config with config.reset_context(), config.set_context(action_ctx): if res_id is None: return Model_.find(domain) else: return [Model_(id_) for id_ in res_id] elif action['type'] == 'ir.action.wizard': kwargs = { 'action': action, 'config': config, 'context': context, } if 'model' in data: Model_ = Model.get(data['model'], config) config = Model_._config with config.reset_context(), config.set_context(context): kwargs['models'] = [Model_(id_) for id_ in data.get('ids', [])] return Wizard(action['wiz_name'], **kwargs) elif action['type'] == 'ir.action.report': ActionReport = Report(action['report_name'], context=context) return ActionReport.execute(data=data) elif action['type'] == 'ir.action.url': return action.get('url')
def _on_change_set(self, field, value): if (self._fields[field]['type'] in ('one2many', 'many2many') and not isinstance(value, (list, tuple))): if value and value.get('delete'): for record_id in value['delete']: for record in getattr(self, field): if record.id == record_id: getattr(self, field).remove(record, _changed=False) if value and value.get('remove'): for record_id in value['remove']: for i, record in enumerate(getattr(self, field)): if record.id == record_id: getattr(self, field).pop(i, _changed=False) if value and (value.get('add') or value.get('update')): for index, vals in value.get('add', []): group = getattr(self, field) Relation = Model.get(self._fields[field]['relation'], self._config) config = Relation._config id_ = vals.pop('id', None) with config.reset_context(), \ config.set_context(self._context): record = Relation(id=id_, _group=group, _default=False) try: idx = group.index(record) except ValueError: # append without signal if index == -1: list.append(group, record) else: list.insert(group, index, record) else: record = group[idx] group.record_removed.discard(record) group.record_deleted.discard(record) record._set_on_change(vals) for vals in value.get('update', []): if 'id' not in vals: continue for record in getattr(self, field): if record.id == vals['id']: record._set_on_change(vals) elif (self._fields[field]['type'] in ('one2many', 'many2many') and len(value) and not isinstance(value[0], int)): self._values[field] = [] for vals in value: Relation = Model.get(self._fields[field]['relation'], self._config) config = Relation._config records = getattr(self, field) with config.reset_context(), \ config.set_context(records._get_context()): record = Relation(_default=False, **vals) records.append(record) else: # JCA : Properly clear M2M fields following on_change if self._fields[field]['type'] == 'many2many' and not value: records = getattr(self, field) while len(records): records.pop(_changed=False) else: self._values[field] = value self._changed.add(field)