- def write(self, cr, uid, ids, values, context=None):
-
- if context is None:
- context = {}
- #import pudb;pudb.set_trace()
-
- def false_value(f):
- if f._type == 'boolean':
- return False
- return f._symbol_set[1](False)
-
- def convert_for_comparison(v, f):
- # It will convert value for comparison between current and new.
- if not v:
- return false_value(f)
- if isinstance(v, browse_record):
- return v.id
- return v
-
- tracked = dict((n, f) for n, f in self._all_columns.items() if getattr(f.column, 'tracked', False))
- to_log = [k for k in values if k in tracked]
-
- from_ = None
- changes = defaultdict(list)
- if to_log:
- for record in self.browse(cr, uid, ids, context):
- for tl in to_log:
- column = tracked[tl].column
- current = convert_for_comparison(record[tl], column)
- new = convert_for_comparison(values[tl], column)
- if new != current:
- changes[record].append(tl)
- from_ = record[tl]
-
- result = super(mail_thread, self).write(cr, uid, ids, values, context=context)
-
- updated_fields = _('Updated Fields:')
-
- Trans = self.pool['ir.translation']
- def _t(c):
- # translate field
- model = c.parent_model or self._name
- lang = context.get('lang')
- return Trans._get_source(cr, uid, '{0},{1}'.format(model, c.name), 'field', lang, ci.column.string)
-
- def get_subtype(model, record):
- # it will return subtype name(xml_id) for stage.
- record_model = self.pool[model].browse(cr, SUPERUSER_ID, record)
- if record_model.__hasattr__('subtype'):
- return record_model.subtype
- return False
-
- for record, changed_fields in changes.items():
- # TODO tpl changed_fields
- chg = []
- subtype = False
- for f in changed_fields:
- to = self.browse(cr, uid, ids[0], context)[f]
- ci = tracked[f]
- if ci.column._type == "many2one":
- if to:
- to = to.name_get()[0][1]
- else:
- to = "Removed"
- if isinstance(from_, browse_record):
- from_ = from_.name_get()[0][1]
-
- subtype = get_subtype(ci.column._obj,values[f])
- chg.append((_t(ci), from_, to))
-
- message = MakoTemplate(self._TRACK_TEMPLATE).render_unicode(updated_fields=updated_fields,
- changes=chg)
-
- record.message_post(message,subtype=subtype)
-
- return result
+ def _get_tracked_fields(self, cr, uid, updated_fields, context=None):
+ """ Return a structure of tracked fields for the current model.
+ :param list updated_fields: modified field names
+ :return list: a list of (field_name, column_info obj), containing
+ always tracked fields and modified on_change fields
+ """
+ lst = []
+ for name, column_info in self._all_columns.items():
+ visibility = getattr(column_info.column, 'track_visibility', False)
+ if visibility == 'always' or (visibility == 'onchange' and name in updated_fields) or name in self._track:
+ lst.append(name)
+ if not lst:
+ return lst
+ return self.fields_get(cr, uid, lst, context=context)
+
+ def message_track(self, cr, uid, ids, tracked_fields, initial_values, context=None):
+
+ def convert_for_display(value, col_info):
+ if not value and col_info['type'] == 'boolean':
+ return 'False'
+ if not value:
+ return ''
+ if col_info['type'] == 'many2one':
+ return value[1]
+ if col_info['type'] == 'selection':
+ return dict(col_info['selection'])[value]
+ return value
+
+ def format_message(message_description, tracked_values):
+ message = ''
+ if message_description:
+ message = '<span>%s</span>' % message_description
+ for name, change in tracked_values.items():
+ message += '<div> • <b>%s</b>: ' % change.get('col_info')
+ if change.get('old_value'):
+ message += '%s → ' % change.get('old_value')
+ message += '%s</div>' % change.get('new_value')
+ return message
+
+ if not tracked_fields:
+ return True
+
+ for record in self.read(cr, uid, ids, tracked_fields.keys(), context=context):
+ initial = initial_values[record['id']]
+ changes = []
+ tracked_values = {}
+
+ # generate tracked_values data structure: {'col_name': {col_info, new_value, old_value}}
+ for col_name, col_info in tracked_fields.items():
+ if record[col_name] == initial[col_name] and getattr(self._all_columns[col_name].column, 'track_visibility', None) == 'always':
+ tracked_values[col_name] = dict(col_info=col_info['string'],
+ new_value=convert_for_display(record[col_name], col_info))
+ elif record[col_name] != initial[col_name]:
+ if getattr(self._all_columns[col_name].column, 'track_visibility', None) in ['always', 'onchange']:
+ tracked_values[col_name] = dict(col_info=col_info['string'],
+ old_value=convert_for_display(initial[col_name], col_info),
+ new_value=convert_for_display(record[col_name], col_info))
+ if col_name in tracked_fields:
+ changes.append(col_name)
+ if not changes:
+ continue
+
+ # find subtypes and post messages or log if no subtype found
+ subtypes = []
+ for field, track_info in self._track.items():
+ if field not in changes:
+ continue
+ for subtype, method in track_info.items():
+ if method(self, cr, uid, record, context):
+ subtypes.append(subtype)
+
+ posted = False
+ for subtype in subtypes:
+ try:
+ subtype_rec = self.pool.get('ir.model.data').get_object(cr, uid, subtype.split('.')[0], subtype.split('.')[1])
+ except ValueError, e:
+ _logger.debug('subtype %s not found, giving error "%s"' % (subtype, e))
+ continue
+ message = format_message(subtype_rec.description if subtype_rec.description else subtype_rec.name, tracked_values)
+ self.message_post(cr, uid, record['id'], body=message, subtype=subtype, context=context)
+ posted = True
+ if not posted:
+ message = format_message('', tracked_values)
+ self.message_post(cr, uid, record['id'], body=message, context=context)
+ return True