diff --git a/addons/account/account_invoice.py b/addons/account/account_invoice.py
index 5c6d6f7e3a1..1bd97855fb2 100644
--- a/addons/account/account_invoice.py
+++ b/addons/account/account_invoice.py
@@ -186,8 +186,8 @@ class account_invoice(osv.osv):
_order = "id desc"
_track = {
'state': {
- 'account.mt_invoice_paid': lambda self, cr, uid, obj, ctx=None: obj.state == 'paid' and obj.type in ('out_invoice','out_refund'),
- 'account.mt_invoice_validated': lambda self, cr, uid, obj, ctx=None: obj.state == 'open' and obj.type in ('out_invoice','out_refund'),
+ 'account.mt_invoice_paid': lambda self, cr, uid, obj, ctx=None: obj['state'] == 'paid' and obj['type'] in ('out_invoice','out_refund'),
+ 'account.mt_invoice_validated': lambda self, cr, uid, obj, ctx=None: obj['state'] == 'open' and obj['type'] in ('out_invoice','out_refund'),
},
}
_columns = {
diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py
index 9079d8b24e8..e450aa81bb1 100644
--- a/addons/crm/crm_lead.py
+++ b/addons/crm/crm_lead.py
@@ -74,10 +74,12 @@ class crm_lead(base_stage, format_address, osv.osv):
_inherit = ['mail.thread', 'ir.needaction_mixin']
_track = {
+ 'state': {
+ 'crm.mt_lead_won': lambda self, cr, uid, obj, ctx=None: obj['state'] == 'done',
+ 'crm.mt_lead_lost': lambda self, cr, uid, obj, ctx=None: obj['state'] == 'cancel',
+ },
'stage_id': {
- 'crm.mt_lead_won': lambda self, cr, uid, obj, ctx=None: obj.stage_id and obj.stage_id.state == 'done' and obj.probability == 100.0,
- 'crm.mt_lead_lost': lambda self, cr, uid, obj, ctx=None: obj.stage_id and obj.stage_id.state == 'cancel' and obj.probability == 0.0,
- 'crm.mt_lead_stage': lambda self, cr, uid, obj, ctx=None: obj.stage_id and obj.stage_id.state not in ['cancel', 'done'],
+ 'crm.mt_lead_stage': lambda self, cr, uid, obj, ctx=None: obj['state'] not in ['cancel', 'done'],
},
}
diff --git a/addons/hr_expense/hr_expense.py b/addons/hr_expense/hr_expense.py
index b62c2003044..4287dbfc779 100644
--- a/addons/hr_expense/hr_expense.py
+++ b/addons/hr_expense/hr_expense.py
@@ -66,9 +66,9 @@ class hr_expense_expense(osv.osv):
_order = "id desc"
_track = {
'state': {
- 'hr_expense.mt_expense_approved': lambda self, cr, uid, obj, ctx=None: obj.state == 'accepted',
- 'hr_expense.mt_expense_refused': lambda self, cr, uid, obj, ctx=None: obj.state == 'cancelled',
- 'hr_expense.mt_expense_confirmed': lambda self, cr, uid, obj, ctx=None: obj.state == 'confirm',
+ 'hr_expense.mt_expense_approved': lambda self, cr, uid, obj, ctx=None: obj['state'] == 'accepted',
+ 'hr_expense.mt_expense_refused': lambda self, cr, uid, obj, ctx=None: obj['state'] == 'cancelled',
+ 'hr_expense.mt_expense_confirmed': lambda self, cr, uid, obj, ctx=None: obj['state'] == 'confirm',
},
}
diff --git a/addons/hr_holidays/hr_holidays.py b/addons/hr_holidays/hr_holidays.py
index 35240c40423..63df9829aed 100644
--- a/addons/hr_holidays/hr_holidays.py
+++ b/addons/hr_holidays/hr_holidays.py
@@ -111,9 +111,9 @@ class hr_holidays(osv.osv):
_inherit = ['mail.thread', 'ir.needaction_mixin']
_track = {
'state': {
- 'hr_holidays.mt_holidays_approved': lambda self, cr, uid, obj, ctx=None: obj.state == 'validate',
- 'hr_holidays.mt_holidays_refused': lambda self, cr, uid, obj, ctx=None: obj.state == 'refuse',
- 'hr_holidays.mt_holidays_confirmed': lambda self, cr, uid, obj, ctx=None: obj.state == 'confirm',
+ 'hr_holidays.mt_holidays_approved': lambda self, cr, uid, obj, ctx=None: obj['state'] == 'validate',
+ 'hr_holidays.mt_holidays_refused': lambda self, cr, uid, obj, ctx=None: obj['state'] == 'refuse',
+ 'hr_holidays.mt_holidays_confirmed': lambda self, cr, uid, obj, ctx=None: obj['state'] == 'confirm',
},
}
diff --git a/addons/hr_recruitment/hr_recruitment.py b/addons/hr_recruitment/hr_recruitment.py
index bd492b5cd83..b2e2cb17d4d 100644
--- a/addons/hr_recruitment/hr_recruitment.py
+++ b/addons/hr_recruitment/hr_recruitment.py
@@ -93,10 +93,12 @@ class hr_applicant(base_stage, osv.Model):
_order = "id desc"
_inherit = ['mail.thread', 'ir.needaction_mixin']
_track = {
+ 'state': {
+ 'hr_recruitment.mt_applicant_hired': lambda self, cr, uid, obj, ctx=None: obj['state'] == 'done',
+ 'hr_recruitment.mt_applicant_refused': lambda self, cr, uid, obj, ctx=None: obj['state'] == 'cancel',
+ },
'stage_id': {
- 'hr_recruitment.mt_applicant_hired': lambda self, cr, uid, obj, ctx=None: obj.stage_id and obj.stage_id.state == 'done' and obj.emp_id,
- 'hr_recruitment.mt_applicant_refused': lambda self, cr, uid, obj, ctx=None: obj.stage_id and obj.stage_id.state == 'cancel' and not obj.emp_id,
- 'hr_recruitment.mt_stage_changed': lambda self, cr, uid, obj, ctx=None: obj.stage_id and obj.stage_id.state not in ['done', 'cancel'],
+ 'hr_recruitment.mt_stage_changed': lambda self, cr, uid, obj, ctx=None: obj['state'] not in ['done', 'cancel'],
},
}
diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py
index 9c3bfe4c4f4..338a46cd762 100644
--- a/addons/mail/mail_thread.py
+++ b/addons/mail/mail_thread.py
@@ -80,7 +80,7 @@ class mail_thread(osv.AbstractModel):
%endif
%for name, change in tracked_values.items():
- - ${name}:
+
- ${change.get('col_info')}:
%if change.get('old_value'):
${change.get('old_value')} ->
%endif
@@ -243,21 +243,20 @@ class mail_thread(osv.AbstractModel):
self.message_subscribe_from_parent(cr, uid, [thread_id], context=context)
# automatic logging
- # self.message_post(cr, uid, thread_id, body='Document created.', context=context)
-
+ self.message_post(cr, uid, thread_id, body='Document created.', context=context)
return thread_id
def write(self, cr, uid, ids, values, context=None):
tracked_fields = self._get_tracked_fields(cr, uid, values.keys(), context=context)
- to_log = [name for name in values.keys() if name in tracked_fields]
- if to_log:
- initial = self.read(cr, uid, ids, [name for name, info in tracked_fields.items()], context=context)
+ #to_log = [name for name in values.keys() if name in tracked_fields]
+ if tracked_fields:
+ initial = self.read(cr, uid, ids, tracked_fields.keys(), context=context)
initial_values = dict((item['id'], item) for item in initial)
result = super(mail_thread, self).write(cr, uid, ids, values, context=context)
- if to_log:
- self.message_track(cr, uid, ids, values.keys(), initial_values, context=context)
+ if tracked_fields:
+ self.message_track(cr, uid, ids, tracked_fields, initial_values, values.keys(), context=context)
return result
def unlink(self, cr, uid, ids, context=None):
@@ -291,89 +290,59 @@ class mail_thread(osv.AbstractModel):
:return list: a list of (field_name, column_info obj), containing
always tracked fields and modified on_change fields
"""
- return dict((name, column_info)
- for name, column_info in self._all_columns.items()
- if getattr(column_info.column, '_track_visibility', False) == 2
- or (getattr(column_info.column, '_track_visibility', False) == 1 and name in updated_fields))
-
- def message_track(self, cr, uid, ids, updated_fields, initial_values, log_message='Document updated', context=None):
- """
- :param list updated_fields: modified field names
- """
- translation_obj = self.pool.get('ir.translation')
-
- def format_false_value(field_obj):
- if field_obj._type == 'boolean':
- return False
- return field_obj._symbol_set[1](False)
-
- def convert_for_comparison(value, field_obj):
- if not value:
- return format_false_value(field_obj)
- if isinstance(value, browse_record): # compare browse record on id only
- return value.id
- if isinstance(value, tuple) and len(value) == 2: # name_get result
- return value[0]
- return value
+ lst = []
+ for name, column_info in self._all_columns.items():
+ vis = getattr(column_info.column, 'track_visibility', False)
+ if (vis==2) or ((vis==1) and (name in updated_fields)) or (name in self._track):
+ lst.append(name)
+ return self.fields_get(cr, uid, lst, context=context)
+ def message_track(self, cr, uid, ids, tracked_fields, initial_values, modified_fields=[], context=None):
+ if not tracked_fields:
+ return True
def convert_for_display(value, field_obj):
if not value:
- return format_false_value(field_obj)
+ return ''
if field_obj._type == 'many2one':
- if isinstance(value, tuple) and len(value) == 2: # already name_get result
- return value[1]
- if not isinstance(value, browse_record): # value should be an ID
- value = self.pool.get(field_obj._obj).browse(cr, SUPERUSER_ID, value, context=None)
- return value.name_get()[0][1]
- if field_obj._type == 'selection': # CHS/TDE TODO: translated value ?
- select_value = filter(lambda item: item[0] == value, field_obj.selection)
- return select_value[0][1]
+ return value[1]
+ if field_obj._type == 'selection':
+ return dict(field_obj.selection)[value]
return value
- def translate_field(column_info):
- model = column_info.parent_model or self._name
- return translation_obj._get_source(cr, uid, '{0},{1}'.format(model, column_info.name), 'field', context.get('lang'), column_info.column.string)
- tracked_fields = self._get_tracked_fields(cr, uid, updated_fields, context=context)
- to_log = [name for name in updated_fields if name in tracked_fields]
- if not to_log:
- return True
+ for record in self.read(cr, uid, ids, tracked_fields, context=context):
+ initial = initial_values[record['id']]
- # browse with SUPERUSER_ID to avoid rights issues (i.e. tracking res.partner relational field -> name_get result should always be visible)
- for record in self.browse(cr, SUPERUSER_ID, ids, context=context):
tracked_values = {}
- default_log = True
changes_found = False
- initial = initial_values[record.id]
-
# generate tracked_values data structure: {'col_name': {col_info, new_value, old_value}}
for col_name, col_info in tracked_fields.items():
- old_value = convert_for_comparison(initial[col_name], col_info.column)
- new_value = convert_for_comparison(record[col_name], col_info.column)
- if old_value == new_value and col_info.column._track_visibility == 2:
- tracked_values[col_name] = dict(col_info=col_info, new_value=convert_for_display(record[col_name], col_info.column))
- elif old_value != new_value:
- tracked_values[col_name] = dict(col_info=col_info, old_value=convert_for_display(initial[col_name], col_info.column), new_value=convert_for_display(record[col_name], col_info.column))
+ if record[col_name] == initial[col_name] and col_info.column.track_visibility == 2:
+ tracked_values[col_name] = dict(col_info=col_info['string'],
+ new_value=convert_for_display(record[col_name], col_info.column))
+ elif record[col_name] != initial[col_name]:
+ tracked_values[col_name] = dict(col_info=col_info['string'],
+ old_value=convert_for_display(initial[col_name], col_info.column),
+ new_value=convert_for_display(record[col_name], col_info.column))
changes_found = True
if not changes_found:
continue
# find subtypes and post messages or log if no subtype found
- subtypes = set([subtype for field, track_info in self._track.items() if field in to_log
+ subtypes = set([subtype for field, track_info in self._track.items() if field in tracked_fields
for subtype, method in track_info.items() if method(self, cr, uid, record, context)])
+ posted = False
for subtype in subtypes:
- subtype_data = subtype.split('.')
- subtype_ref = self.pool.get('ir.model.data').get_object_reference(cr, uid, subtype_data[0], subtype_data[1])
- if not subtype_ref:
+ try:
+ subtype_rec = self.pool.get('ir.model.data').get_object(cr, uid, *subtype.split('.'))
+ except ValueError, e:
continue
- subtype_rec = self.pool.get('mail.message.subtype').browse(cr, uid, subtype_ref[1], context=context)
message = MakoTemplate(self._TRACK_TEMPLATE).render_unicode(message_description=subtype_rec.description, tracked_values=tracked_values)
- self.message_post(cr, uid, record.id, body=message, subtype=subtype, context=context)
- default_log = False
- if default_log:
- message = MakoTemplate(self._TRACK_TEMPLATE).render_unicode(message_description=log_message, tracked_values=tracked_values)
+ self.message_post(cr, uid, record['id'], body=message, subtype=subtype, context=context)
+ posted = True
+ if not posted:
+ message = MakoTemplate(self._TRACK_TEMPLATE).render_unicode(message_description='', tracked_values=tracked_values)
self.message_post(cr, uid, record.id, body=message, context=context)
-
return True
#------------------------------------------------------
diff --git a/addons/project/project.py b/addons/project/project.py
index 8e9eb47ba12..b0fe9a4f6db 100644
--- a/addons/project/project.py
+++ b/addons/project/project.py
@@ -559,13 +559,15 @@ class task(base_stage, osv.osv):
_inherit = ['mail.thread', 'ir.needaction_mixin']
_track = {
+ 'state': {
+ 'project.mt_project_task_closed': lambda self, cr, uid, obj, ctx=None: obj['state'] == 'done',
+ 'project.mt_project_task_started': lambda self, cr, uid, obj, ctx=None: obj['state'] == 'open',
+ },
'stage_id': {
- 'project.mt_project_task_closed': lambda self, cr, uid, obj, ctx=None: obj.stage_id and obj.stage_id.state == 'done',
- 'project.mt_project_task_started': lambda self, cr, uid, obj, ctx=None: obj.stage_id and obj.stage_id.state == 'open',
- 'project.mt_project_task_stage': lambda self, cr, uid, obj, ctx=None: obj.stage_id and obj.stage_id.state not in ['done', 'open'],
+ 'project.mt_project_task_stage': lambda self, cr, uid, obj, ctx=None: obj['state'] not in ['done', 'open'],
},
'kanban_state': { # kanban state: tracked, but only block subtype
- 'project.mt_project_task_blocked': lambda self, cr, uid, obj, ctx=None: obj.kanban_state == 'blocked',
+ 'project.mt_project_task_blocked': lambda self, cr, uid, obj, ctx=None: obj['kanban_state'] == 'blocked',
},
}
diff --git a/addons/project_issue/project_issue.py b/addons/project_issue/project_issue.py
index 01fb35456f5..6ead80b9619 100644
--- a/addons/project_issue/project_issue.py
+++ b/addons/project_issue/project_issue.py
@@ -51,13 +51,15 @@ class project_issue(base_stage, osv.osv):
_inherit = ['mail.thread', 'ir.needaction_mixin']
_track = {
+ 'state': {
+ 'project_issue.mt_project_issue_closed': lambda self, cr, uid, obj, ctx=None: obj['state'] == 'done',
+ 'project_issue.mt_project_issue_started': lambda self, cr, uid, obj, ctx=None: obj['state'] == 'open',
+ },
'stage_id': {
- 'project_issue.mt_project_issue_closed': lambda self, cr, uid, obj, ctx=None: obj.stage_id and obj.stage_id.state == 'done',
- 'project_issue.mt_project_issue_started': lambda self, cr, uid, obj, ctx=None: obj.stage_id and obj.stage_id.state == 'open',
- 'project_issue.mt_project_issue_stage': lambda self, cr, uid, obj, ctx=None: obj.stage_id and obj.stage_id.state not in ['done', 'open'],
+ 'project_issue.mt_project_issue_stage': lambda self, cr, uid, obj, ctx=None: obj['state'] not in ['done', 'open'],
},
'kanban_state': {
- 'project_issue.mt_project_issue_blocked': lambda self, cr, uid, obj, ctx=None: obj.kanban_state == 'blocked',
+ 'project_issue.mt_project_issue_blocked': lambda self, cr, uid, obj, ctx=None: obj['kanban_state'] == 'blocked',
},
}
diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py
index 7624d679ac5..257d22f25a1 100644
--- a/addons/purchase/purchase.py
+++ b/addons/purchase/purchase.py
@@ -161,8 +161,8 @@ class purchase_order(osv.osv):
]
_track = {
'state': {
- 'purchase.mt_rfq_confirmed': lambda self, cr, uid, obj, ctx=None: obj.state=='confirmed',
- 'purchase.mt_rfq_approved': lambda self, cr, uid, obj, ctx=None: obj.state=='approved',
+ 'purchase.mt_rfq_confirmed': lambda self, cr, uid, obj, ctx=None: obj['state']=='confirmed',
+ 'purchase.mt_rfq_approved': lambda self, cr, uid, obj, ctx=None: obj['state']=='approved',
},
}
_columns = {
diff --git a/addons/sale/sale.py b/addons/sale/sale.py
index b491d247329..f750f2a0585 100644
--- a/addons/sale/sale.py
+++ b/addons/sale/sale.py
@@ -51,8 +51,8 @@ class sale_order(osv.osv):
_description = "Sales Order"
_track = {
'state': {
- 'sale.mt_order_confirmed': lambda self, cr, uid, obj, ctx=None: obj.state in ['manual', 'progress'],
- 'sale.mt_quotation_sent': lambda self, cr, uid, obj, ctx=None: obj.state in ['sent']
+ 'sale.mt_order_confirmed': lambda self, cr, uid, obj, ctx=None: obj['state'] in ['manual', 'progress'],
+ 'sale.mt_quotation_sent': lambda self, cr, uid, obj, ctx=None: obj['state'] in ['sent']
},
}