[MERGE] Merged branch holding subtype work by APA.

bzr revid: tde@openerp.com-20121218131142-2jb6wac6y9q6dc7v
This commit is contained in:
Thibault Delavallée 2012-12-18 14:11:42 +01:00
commit b95b32d644
36 changed files with 528 additions and 206 deletions

View File

@ -373,10 +373,7 @@ class account_invoice(osv.osv):
if context is None:
context = {}
try:
res = super(account_invoice, self).create(cr, uid, vals, context)
if res:
self.create_send_note(cr, uid, [res], context=context)
return res
return super(account_invoice, self).create(cr, uid, vals, context)
except Exception, e:
if '"journal_id" viol' in e.args[0]:
raise orm.except_orm(_('Configuration Error!'),
@ -1079,7 +1076,7 @@ class account_invoice(osv.osv):
if obj_inv.type in ('out_invoice', 'out_refund'):
ctx = self.get_log_context(cr, uid, context=ctx)
message = _("Invoice '%s' is validated.") % name
self.message_post(cr, uid, [inv_id], body=message, context=context)
self.message_post(cr, uid, [inv_id], body=message, subtype="account.mt_invoice_validated", context=context)
return True
def action_cancel(self, cr, uid, ids, context=None):
@ -1335,11 +1332,6 @@ class account_invoice(osv.osv):
}
return type_dict.get(type, 'Invoice')
def create_send_note(self, cr, uid, ids, context=None):
for obj in self.browse(cr, uid, ids, context=context):
self.message_post(cr, uid, [obj.id], body=_("%s <b>created</b>.") % (self._get_document_type(obj.type)),
subtype="account.mt_invoice_new", context=context)
def confirm_paid_send_note(self, cr, uid, ids, context=None):
for obj in self.browse(cr, uid, ids, context=context):
self.message_post(cr, uid, [obj.id], body=_("%s <b>paid</b>.") % (self._get_document_type(obj.type)),

View File

@ -151,13 +151,14 @@
<field name="object">account.invoice</field>
</record>
<!-- mail: subtypes -->
<record id="mt_invoice_new" model="mail.message.subtype">
<field name="name">created</field>
<!-- Account-related subtypes for messaging / Chatter -->
<record id="mt_invoice_validated" model="mail.message.subtype">
<field name="name">Validated</field>
<field name="res_model">account.invoice</field>
<field name="default" eval="False"/>
</record>
<record id="mt_invoice_paid" model="mail.message.subtype">
<field name="name">paid</field>
<field name="name">Paid</field>
<field name="res_model">account.invoice</field>
</record>
</data>

View File

@ -13,7 +13,7 @@
<p>You can track customer payments easily and automate follow-ups. You get an overview of the discussion with your customers on each invoice for easier traceability. For advanced accounting features, you should install the "Accounting and Finance" module.</p>]]></field>
</record>
<!-- mail: subtypes -->
<!-- Voucher-related subtypes for messaging / Chatter -->
<record id="mt_voucher" model="mail.message.subtype">
<field name="name">Status Change</field>
<field name="res_model">account.voucher</field>

View File

@ -38,8 +38,7 @@ that have no counterpart in the general financial accounts.
'security/analytic_security.xml',
'security/ir.model.access.csv',
'analytic_sequence.xml',
'analytic_view.xml',
'analytic_data.xml'
'analytic_view.xml'
],
'demo': [],
'installable': True,

View File

@ -320,7 +320,7 @@ class account_analytic_account(osv.osv):
if obj.partner_id:
message = _("Contract for <em>%s</em> has been <b>created</b>.") % (obj.partner_id.name,)
self.message_post(cr, uid, [obj.id], body=message,
subtype="analytic.mt_account_status", context=context)
context=context)
account_analytic_account()

View File

@ -1,12 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="1">
<!-- mail: subtypes -->
<record id="mt_account_status" model="mail.message.subtype">
<field name="name">Status Change</field>
<field name="res_model">account.analytic.account</field>
</record>
</data>
</openerp>

View File

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import analytic_contract_crm
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,41 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
{
'name': 'CRM: Contract link',
'version': '1.1',
'category': 'Hidden',
'description': """
This module is for set subtype of sales team in contract.
======================================================================================================
""",
'author': 'OpenERP S.A.',
'website': 'http://www.openerp.com/',
'depends': ['account_analytic_analysis','crm'],
'data': [],
'demo': [],
'css' : [],
'installable': True,
'auto_install': True,
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,56 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from osv import osv, fields
from tools.translate import _
class account_analytic_account(osv.osv):
_inherit = "account.analytic.account"
def create(self, cr, uid, vals, context=None):
obj_id = super(account_analytic_account, self).create(cr, uid, vals, context=context)
manager_id = self.browse(cr, uid, obj_id, context=context).manager_id
if manager_id:
if manager_id.default_section_id:
# subscribe salesteam followers & subtypes to the contract
self._subscribe_followers_subtype(cr, uid, [obj_id], manager_id.default_section_id, 'crm.case.section', context=context)
if obj_id:
self.create_send_note(cr, uid, [obj_id], context=context)
return obj_id
def write(self, cr, uid, ids, vals, context=None):
if isinstance(ids, (int, long)):
ids = [ids]
if vals.get('manager_id'):
section_id = self.pool.get('res.users').browse(cr, uid, vals.get('manager_id'), context=context).default_section_id
if section_id:
vals.setdefault('message_follower_ids', [])
vals['message_follower_ids'] += [(6, 0,[follower.id]) for follower in section_id.message_follower_ids]
res = super(account_analytic_account, self).write(cr, uid, ids, vals, context=context)
# subscribe new salesteam followers & subtypes to the contract
if vals.get('manager_id'):
if section_id:
self._subscribe_followers_subtype(cr, uid, ids, section_id, 'crm.case.section', context=context)
return res
account_analytic_account()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -315,8 +315,8 @@ class crm_lead(base_stage, format_address, osv.osv):
obj_id = super(crm_lead, self).create(cr, uid, vals, context)
section_id = self.browse(cr, uid, obj_id, context=context).section_id
if section_id:
followers = [follow.id for follow in section_id.message_follower_ids]
self.message_subscribe(cr, uid, [obj_id], followers, context=context)
# subscribe salesteam followers & subtypes to the lead
self._subscribe_followers_subtype(cr, uid, [obj_id], section_id, 'crm.case.section', context=context)
return obj_id
def onchange_stage_id(self, cr, uid, ids, stage_id, context=None):
@ -920,10 +920,13 @@ class crm_lead(base_stage, format_address, osv.osv):
vals['probability'] = stage.probability
if vals.get('section_id'):
section_id = self.pool.get('crm.case.section').browse(cr, uid, vals.get('section_id'), context=context)
if section_id:
vals.setdefault('message_follower_ids', [])
vals['message_follower_ids'] += [(4, follower.id) for follower in section_id.message_follower_ids]
return super(crm_lead,self).write(cr, uid, ids, vals, context)
vals.setdefault('message_follower_ids', [])
vals['message_follower_ids'] += [(6, 0,[follower.id]) for follower in section_id.message_follower_ids]
res = super(crm_lead,self).write(cr, uid, ids, vals, context)
# subscribe new salesteam followers & subtypes to the lead
if vals.get('section_id'):
self._subscribe_followers_subtype(cr, uid, ids, vals.get('section_id'), 'crm.case.section', context=context)
return res
# ----------------------------------------
# Mail Gateway
@ -992,7 +995,7 @@ class crm_lead(base_stage, format_address, osv.osv):
def convert_opportunity_send_note(self, cr, uid, lead, context=None):
message = _("Lead has been <b>converted to an opportunity</b>.")
lead.message_post(body=message)
lead.message_post(body=message, subtype="crm.mt_lead_convert_to_opportunity")
return True
def onchange_state(self, cr, uid, ids, state_id, context=None):

View File

@ -154,23 +154,60 @@
<field name="object_id" search="[('model','=','crm.lead')]" model="ir.model"/>
</record>
<!-- mail subtype -->
<record id="crm.mt_crm_won" model="mail.message.subtype">
<field name="name">Won</field>
<field name="res_model">crm.lead</field>
<field name="description">Opportunity &lt;b&gt;won&lt;/&gt;</field>
</record>
<record id="crm.mt_crm_lost" model="mail.message.subtype">
<field name="name">Lost</field>
<!-- CRM-related subtypes for messaging / Chatter -->
<record id="mt_lead_create" model="mail.message.subtype">
<field name="name">Lead Created</field>
<field name="res_model">crm.lead</field>
<field name="default" eval="False"/>
<field name="description">Opportunity &lt;b&gt;lost&lt;/&gt;</field>
</record>
<record id="crm.mt_crm_stage" model="mail.message.subtype">
<record id="mt_lead_lost" model="mail.message.subtype">
<field name="name">Opportunity Lost</field>
<field name="res_model">crm.lead</field>
<field name="default" eval="False"/>
<field name="description">Opportunity &lt;b&gt;lost&lt;/b&gt;</field>
</record>
<record id="mt_lead_won" model="mail.message.subtype">
<field name="name">Opportunity Won</field>
<field name="res_model">crm.lead</field>
<field name="description">Opportunity &lt;b&gt;won&lt;/b&gt;</field>
</record>
<record id="mt_lead_stage" model="mail.message.subtype">
<field name="name">Stage Changed</field>
<field name="res_model">crm.lead</field>
<field name="default" eval="False"/>
<field name="description">Stage &lt;b&gt;changed&lt;/&gt;</field>
<field name="description">Stage &lt;b&gt;changed&lt;/b&gt;</field>
</record>
<record id="mt_lead_convert_to_opportunity" model="mail.message.subtype">
<field name="name">Lead to Opportunity</field>
<field name="res_model">crm.lead</field>
<field name="default" eval="False"/>
</record>
<!-- Salesteam-related subtypes for messaging / Chatter -->
<record id="mt_salesteam_lead" model="mail.message.subtype">
<field name="name">Lead Created</field>
<field name="res_model">crm.case.section</field>
<field name="default" eval="False"/>
</record>
<record id="mt_salesteam_lead_opportunity" model="mail.message.subtype">
<field name="name">Lead to Opportunity</field>
<field name="res_model">crm.case.section</field>
<field name="default" eval="False"/>
</record>
<record id="mt_salesteam_stage" model="mail.message.subtype">
<field name="name">Lead Stage Changed</field>
<field name="res_model">crm.case.section</field>
<field name="default" eval="False"/>
</record>
<record id="mt_salesteam_lost" model="mail.message.subtype">
<field name="name">Opportunity Lost</field>
<field name="res_model">crm.case.section</field>
<field name="default" eval="False"/>
</record>
<record id="mt_salesteam_won" model="mail.message.subtype">
<field name="name">Opportunity Won</field>
<field name="res_model">crm.case.section</field>
>>>>>>> MERGE-SOURCE
</record>
</data>

View File

@ -128,7 +128,7 @@
</page>
</notebook>
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers" help="Followers of this salesteam follow automatically all opportunities related to this salesteam."/>
<field name="message_follower_ids" widget="mail_followers" help="Follow this salesteam to automatically track the events associated to users of this team."/>
<field name="message_ids" widget="mail_thread"/>
</div>
</form>

View File

@ -12,9 +12,9 @@
<field name="state">open</field>
</record>
<!-- mail: event subtype -->
<!-- Event-related subtypes for messaging / Chatter -->
<record id="event.mt_event_registration" model="mail.message.subtype">
<field name="name">New Registrations</field>
<field name="name">New Registration</field>
<field name="res_model">event.event</field>
<field name="default" eval="False"/>
</record>

View File

@ -128,6 +128,8 @@ class hr_expense_expense(osv.osv):
for expense in self.browse(cr, uid, ids):
if expense.employee_id and expense.employee_id.parent_id.user_id:
self.message_subscribe_users(cr, uid, [expense.id], user_ids=[expense.employee_id.parent_id.user_id.id])
self.message_post(cr, uid, ids, body=_("The request is <b>waiting for Approval</b>"),
subtype="hr_expense.mt_expense_approve")
self.write(cr, uid, ids, {
'state':'confirm',
'date_confirm': time.strftime('%Y-%m-%d')
@ -135,6 +137,8 @@ class hr_expense_expense(osv.osv):
return True
def expense_accept(self, cr, uid, ids, *args):
self.message_post(cr, uid, ids, body=_("The request has been <b>approved</b>"),
subtype="hr_expense.mt_expense_approved")
self.write(cr, uid, ids, {
'state':'accepted',
'date_valid':time.strftime('%Y-%m-%d'),
@ -143,6 +147,8 @@ class hr_expense_expense(osv.osv):
return True
def expense_canceled(self, cr, uid, ids, *args):
self.message_post(cr, uid, ids, body=_("Request <b>refused</b>"),
subtype="hr_expense.mt_expense_refused")
self.write(cr, uid, ids, {'state':'cancelled'})
return True

View File

@ -17,5 +17,25 @@
<field name="parent_id" ref="product.product_category_all"/>
<field name="name">Expenses</field>
</record>
<!--subtype for expense -->
<record id="mt_expense_approve" model="mail.message.subtype">
<field name="name">To Approve</field>
<field name="res_model">hr.expense.expense</field>
<field name="default" eval="False"/>
</record>
<!-- Expense-related subtypes for messaging / Chatter -->
<record id="mt_expense_approved" model="mail.message.subtype">
<field name="name">Approved</field>
<field name="res_model">hr.expense.expense</field>
<field name="default" eval="False"/>
</record>
<record id="mt_expense_refused" model="mail.message.subtype">
<field name="name">Refused</field>
<field name="res_model">hr.expense.expense</field>
<field name="default" eval="False"/>
</record>
</data>
</openerp>

View File

@ -431,7 +431,7 @@ class hr_holidays(osv.osv):
def holidays_confirm_notificate(self, cr, uid, ids, context=None):
for obj in self.browse(cr, uid, ids):
self.message_post(cr, uid, [obj.id],
_("Request <b>submitted</b>, waiting for validation by the manager."), context=context)
_("Request <b>submitted</b>, waiting for validation by the manager."), subtype="hr_holidays.mt_approve", context=context)
def holidays_first_validate_notificate(self, cr, uid, ids, context=None):
for obj in self.browse(cr, uid, ids, context=context):
@ -445,12 +445,12 @@ class hr_holidays(osv.osv):
_("Request <b>validated</b>."), context=context)
else:
self.message_post(cr, uid, [obj.id],
_("The request has been <b>approved</b>."), context=context)
_("The request has been <b>approved</b>."), subtype="hr_holidays.mt_approved", context=context)
def holidays_refuse_notificate(self, cr, uid, ids, context=None):
for obj in self.browse(cr, uid, ids):
self.message_post(cr, uid, [obj.id],
_("Request <b>refused</b>"), context=context)
_("Request <b>refused</b>"), subtype="hr_holidays.mt_refused", context=context)
class resource_calendar_leaves(osv.osv):

View File

@ -44,5 +44,23 @@
<field name="limit">True</field>
<field name="color_name">brown</field>
</record>
<!-- Holidays-related subtypes for messaging / Chatter -->
<record id="mt_approve" model="mail.message.subtype">
<field name="name">To Approve</field>
<field name="res_model">hr.holidays</field>
<field name="default" eval="False"/>
</record>
<record id="mt_approved" model="mail.message.subtype">
<field name="name">Approved</field>
<field name="res_model">hr.holidays</field>
<field name="default" eval="False"/>
</record>
<record id="mt_refused" model="mail.message.subtype">
<field name="name">Refused</field>
<field name="res_model">hr.holidays</field>
<field name="default" eval="False"/>
</record>
</data>
</openerp>

View File

@ -469,12 +469,6 @@ class hr_applicant(base_stage, osv.Model):
# OpenChatter methods and notifications
# -------------------------------------------------------
def stage_set_send_note(self, cr, uid, ids, stage_id, context=None):
""" Override of the (void) default notification method. """
if not stage_id: return True
stage_name = self.pool.get('hr.recruitment.stage').name_get(cr, uid, [stage_id], context=context)[0][1]
return self.message_post(cr, uid, ids, body=_("Stage changed to <b>%s</b>.") % (stage_name), context=context)
def case_get_note_msg_prefix(self, cr, uid, id, context=None):
return 'Applicant'
@ -487,18 +481,18 @@ class hr_applicant(base_stage, osv.Model):
context = {}
for applicant in self.browse(cr, uid, ids, context=context):
if applicant.job_id:
self.pool.get('hr.job').message_post(cr, uid, [applicant.job_id.id], body=_('New employee joined the company %s.')%(applicant.name,), subtype="hr_recruitment.mt_hired", context=context)
self.pool.get('hr.job').message_post(cr, uid, [applicant.job_id.id], body=_('New employee joined the company %s.')%(applicant.name,), context=context)
if applicant.emp_id:
message = _("Applicant has been <b>hired</b> and created as an employee.")
self.message_post(cr, uid, [applicant.id], body=message, context=context)
self.message_post(cr, uid, [applicant.id], body=message, subtype="hr_recruitment.mt_applicant_hired", context=context)
else:
message = _("Applicant has been <b>hired</b>.")
self.message_post(cr, uid, [applicant.id], body=message, context=context)
self.message_post(cr, uid, [applicant.id], body=message, subtype="hr_recruitment.mt_applicant_hired", context=context)
return True
def case_cancel_send_note(self, cr, uid, ids, context=None):
msg = 'Applicant <b>refused</b>.'
return self.message_post(cr, uid, ids, body=msg, context=context)
return self.message_post(cr, uid, ids, body=msg, subtype="hr_recruitment.mt_applicant_refused",context=context)
def case_reset_send_note(self, cr, uid, ids, context=None):
message =_("Applicant has been set as <b>new</b>.")

View File

@ -461,14 +461,42 @@
<field name="alias_user_id" ref="base.user_root"/>
</record>
<!-- mail: subtypes -->
<record id="mt_hired" model="mail.message.subtype">
<field name="name">Employee Hired</field>
<field name="res_model">hr.job</field>
</record>
<!-- Job-related subtypes for messaging / Chatter -->
<record id="mt_applicant_new" model="mail.message.subtype">
<field name="name">New Applicant</field>
<field name="res_model">hr.job</field>
</record>
<record id="mt_job_stage_changed" model="mail.message.subtype">
<field name="name">Stage Changed</field>
<field name="res_model">hr.job</field>
<field name="default" eval="False"/>
</record>
<record id="mt_job_applicant_hired" model="mail.message.subtype">
<field name="name">Applicant Hired</field>
<field name="res_model">hr.job</field>
<field name="default" eval="False"/>
</record>
<record id="mt_job_applicant_refused" model="mail.message.subtype">
<field name="name">Refused</field>
<field name="res_model">hr.job</field>
<field name="default" eval="False"/>
</record>
<!-- Applicant-related subtypes for messaging / Chatter -->
<record id="mt_stage_changed" model="mail.message.subtype">
<field name="name">Stage Changed</field>
<field name="res_model">hr.applicant</field>
<field name="default" eval="False"/>
</record>
<record id="mt_applicant_hired" model="mail.message.subtype">
<field name="name">Applicant Hired</field>
<field name="res_model">hr.applicant</field>
<field name="default" eval="False"/>
</record>
<record id="mt_applicant_refused" model="mail.message.subtype">
<field name="name">Applicant Refused</field>
<field name="res_model">hr.applicant</field>
<field name="default" eval="False"/>
</record>
</data>
</openerp>

View File

@ -95,19 +95,19 @@ class account_analytic_account(osv.osv):
def set_cancel(self, cr, uid, ids, context=None):
self.write(cr, uid, ids, {'state': 'cancelled'}, context=context)
message = _("Contract has been <b>canceled</b>.")
self.message_post(cr, uid, ids, body=message, subtype="hr_timesheet_invoice.mt_account_canceled", context=context)
self.message_post(cr, uid, ids, body=message, context=context)
return True
def set_open(self, cr, uid, ids, context=None):
self.write(cr, uid, ids, {'state': 'open'}, context=context)
message = _("Contract has been <b>opened</b>.")
self.message_post(cr, uid, ids, body=message, context=context)
self.message_post(cr, uid, ids, body=message, subtype="hr_timesheet_invoice.mt_account_renewed", context=context)
return True
def set_pending(self, cr, uid, ids, context=None):
self.write(cr, uid, ids, {'state': 'pending'}, context=context)
message = _("Contract has been set as <b>pending</b>.")
self.message_post(cr, uid, ids, body=message, context=context)
self.message_post(cr, uid, ids, body=message, subtype="hr_timesheet_invoice.mt_account_renew", context=context)
return True
account_analytic_account()

View File

@ -22,15 +22,35 @@
<field name="factor">20.0</field>
</record>
<!-- mail: subtypes -->
<record id="mt_account_closed" model="mail.message.subtype">
<field name="name">finished</field>
<!-- Analytic-account-related subtypes for messaging / Chatter -->
<record id="mt_account_renew" model="mail.message.subtype">
<field name="name">Contract to Renew</field>
<field name="res_model">account.analytic.account</field>
</record>
<record id="mt_account_canceled" model="mail.message.subtype">
<field name="name">canceled</field>
<record id="mt_account_closed" model="mail.message.subtype">
<field name="name">Contract Finished</field>
<field name="res_model">account.analytic.account</field>
</record>
<record id="mt_account_renewed" model="mail.message.subtype">
<field name="name">Contract Renewed</field>
<field name="res_model">account.analytic.account</field>
</record>
<!-- Salesteam-related subtypes for messaging / Chatter -->
<record id="mt_salesteam_renew" model="mail.message.subtype">
<field name="name">Contract to Renew</field>
<field name="res_model">crm.case.section</field>
<field name="default" eval="False"/>
</record>
<record id="mt_salesteam_finished" model="mail.message.subtype">
<field name="name">Contract Finished</field>
<field name="res_model">crm.case.section</field>
<field name="default" eval="False"/>
</record>
<record id="mt_salesteam_renewed" model="mail.message.subtype">
<field name="name">Contract Renewed</field>
<field name="res_model">crm.case.section</field>
<field name="default" eval="False"/>
</record>
</data>
</openerp>

View File

@ -27,6 +27,7 @@
<field name="priority">1000</field>
</record>
<!-- Discussion subtype for messaging / Chatter -->
<record id="mt_comment" model="mail.message.subtype">
<field name="name">Discussions</field>
</record>

View File

@ -952,6 +952,28 @@ class mail_thread(osv.AbstractModel):
self.check_access_rights(cr, uid, 'read')
return self.write(cr, SUPERUSER_ID, ids, {'message_follower_ids': [(3, pid) for pid in partner_ids]}, context=context)
def _subscribe_followers_subtype(self, cr, uid, ids, res_id, model, context=None):
""" TDE note: not the best way to do this, we could override _get_followers
of task, and perform a better mapping of subtypes than a mapping
based on names.
However we will keep this implementation, maybe to be refactored
in 7.1 of future versions. """
subtype_obj = self.pool.get('mail.message.subtype')
follower_obj = self.pool.get('mail.followers')
# create mapping
subtype_ids = subtype_obj.search(cr, uid, ['|', ('res_model', '=', False), ('res_model', '=', self._name)], context=context)
subtypes = subtype_obj.browse(cr, uid, subtype_ids, context=context)
# fetch subscriptions
follower_ids = follower_obj.search(cr, uid, [('res_model', '=', model), ('res_id', '=', res_id)], context=context)
# copy followers
for follower in follower_obj.browse(cr, uid, follower_ids, context=context):
if not follower.subtype_ids:
continue
subtype_names = [follower_subtype.name for follower_subtype in follower.subtype_ids]
subtype_ids = [subtype.id for subtype in subtypes if subtype.name in subtype_names]
self.message_subscribe(cr, uid, ids, [follower.partner_id.id],
subtype_ids=subtype_ids, context=context)
#------------------------------------------------------
# Thread state
#------------------------------------------------------

View File

@ -184,7 +184,6 @@ openerp_mail_followers = function(session, mail) {
/** Fetch subtypes, only if current user is follower */
fetch_subtypes: function () {
var subtype_list_ul = this.$('.oe_subtype_list').empty();
if (! this.message_is_follower) return;
var context = new session.web.CompoundContext(this.build_context(), {});
this.ds_model.call('message_get_subscription_data', [[this.view.datarecord.id], context]).then(this.proxy('display_subtypes'));
@ -193,14 +192,22 @@ openerp_mail_followers = function(session, mail) {
/** Display subtypes: {'name': default, followed} */
display_subtypes:function (data) {
var self = this;
var subtype_list_ul = this.$('.oe_subtype_list');
var subtype = [];
var subtype_list_ul = this.$('.oe_subtype_list').empty().hide();
subtype_list_ul.empty();
var records = data[this.view.datarecord.id || this.view.dataset.ids[0]].message_subtype_data;
_(records).each(function (record, record_name) {
record.name = record_name;
record.followed = record.followed || undefined;
$(session.web.qweb.render('mail.followers.subtype', {'record': record})).appendTo( self.$('.oe_subtype_list') );
subtype.push(record);
})
subtype.sort(function(a,b){return a.id - b.id});
_(subtype).each(function (record) {
$(session.web.qweb.render('mail.followers.subtype', {'record': record})).appendTo(subtype_list_ul);
});
if (subtype.length > 1) {
subtype_list_ul.show();
}
},
do_follow: function () {
@ -228,10 +235,12 @@ openerp_mail_followers = function(session, mail) {
checklist.push(parseInt($(record).data('id')));
}
});
var context = new session.web.CompoundContext(this.build_context(), {});
return this.ds_model.call('message_subscribe_users', [[this.view.datarecord.id], [this.session.uid], this.message_is_follower ? checklist : undefined, context])
.then(this.proxy('read_value'));
.then(this.proxy('read_value')).then(function(){
if(checklist.length == 0){
return self.do_unfollow();}
});
},
});
};

View File

@ -12,11 +12,12 @@
<span class="oe_unfollow">Unfollow</span>
<span class="oe_following">Following</span>
</button>
<t t-if="widget.comment">
<h5 class="oe_comment"><t t-raw="widget.comment"/></h5>
</t>
<div class="oe_subtype_list"></div>
</div>
<t t-if="widget.comment">
<h5 class="oe_comment"><t t-raw="widget.comment"/></h5>
</t>
<hr size="2"></hr>
<div class='oe_follower_title_box'>
<h4 class='oe_follower_title'>Followers</h4>
<a href='#' class="oe_invite">Invite others</a>

View File

@ -317,9 +317,7 @@ class project(osv.osv):
task_obj = self.pool.get('project.task')
task_ids = task_obj.search(cr, uid, [('project_id', 'in', ids), ('state', '!=', 'done')])
task_obj.case_cancel(cr, uid, task_ids, context=context)
self.write(cr, uid, ids, {'state':'cancelled'}, context=context)
self.set_cancel_send_note(cr, uid, ids, context=context)
return True
return self.write(cr, uid, ids, {'state':'cancelled'}, context=context)
def set_pending(self, cr, uid, ids, context=None):
self.write(cr, uid, ids, {'state':'pending'}, context=context)
@ -565,9 +563,6 @@ def Project():
def set_pending_send_note(self, cr, uid, ids, context=None):
return self.message_post(cr, uid, ids, body=_("Project is now <b>pending</b>."), context=context)
def set_cancel_send_note(self, cr, uid, ids, context=None):
return self.message_post(cr, uid, ids, body=_("Project has been <b>canceled</b>."), context=context)
def set_close_send_note(self, cr, uid, ids, context=None):
return self.message_post(cr, uid, ids, body=_("Project has been <b>closed</b>."), context=context)
@ -993,7 +988,6 @@ class task(base_stage, osv.osv):
self._check_child_task(cr, uid, ids, context=context)
for task in tasks:
self.case_set(cr, uid, [task.id], 'cancelled', {'remaining_hours': 0.0}, context=context)
self.case_cancel_send_note(cr, uid, [task.id], context=context)
return True
def do_open(self, cr, uid, ids, context=None):
@ -1085,11 +1079,13 @@ class task(base_stage, osv.osv):
def set_kanban_state_blocked(self, cr, uid, ids, context=None):
self.write(cr, uid, ids, {'kanban_state': 'blocked'}, context=context)
return False
self.case_block_send_note(cr, uid, ids, context=context)
return True
def set_kanban_state_normal(self, cr, uid, ids, context=None):
self.write(cr, uid, ids, {'kanban_state': 'normal'}, context=context)
return False
self.case_open_send_note(cr, uid, ids, context=context)
return True
def set_kanban_state_done(self, cr, uid, ids, context=None):
self.write(cr, uid, ids, {'kanban_state': 'done'}, context=context)
@ -1109,35 +1105,12 @@ class task(base_stage, osv.osv):
}, context=context)
return True
def _subscribe_project_followers_to_task(self, cr, uid, task_id, context=None):
""" TDE note: not the best way to do this, we could override _get_followers
of task, and perform a better mapping of subtypes than a mapping
based on names.
However we will keep this implementation, maybe to be refactored
in 7.1 of future versions. """
# task followers are project followers, with matching subtypes
task_record = self.browse(cr, uid, task_id, context=context)
subtype_obj = self.pool.get('mail.message.subtype')
follower_obj = self.pool.get('mail.followers')
if task_record.project_id:
# create mapping
task_subtype_ids = subtype_obj.search(cr, uid, ['|', ('res_model', '=', False), ('res_model', '=', self._name)], context=context)
task_subtypes = subtype_obj.browse(cr, uid, task_subtype_ids, context=context)
# fetch subscriptions
follower_ids = follower_obj.search(cr, uid, [('res_model', '=', 'project.project'), ('res_id', '=', task_record.project_id.id)], context=context)
# copy followers
for follower in follower_obj.browse(cr, uid, follower_ids, context=context):
if not follower.subtype_ids:
continue
project_subtype_names = [project_subtype.name for project_subtype in follower.subtype_ids]
task_subtype_ids = [task_subtype.id for task_subtype in task_subtypes if task_subtype.name in project_subtype_names]
self.message_subscribe(cr, uid, [task_id], [follower.partner_id.id],
subtype_ids=task_subtype_ids, context=context)
def create(self, cr, uid, vals, context=None):
task_id = super(task, self).create(cr, uid, vals, context=context)
# subscribe project followers to the task
self._subscribe_project_followers_to_task(cr, uid, task_id, context=context)
project_id = self.browse(cr, uid, task_id, context=context).project_id
if project_id:
# subscribe project followers to the task
self._subscribe_followers_subtype(cr, uid, [task_id], project_id, 'project.project', context=context)
self._store_history(cr, uid, [task_id], context=context)
return task_id
@ -1147,6 +1120,11 @@ class task(base_stage, osv.osv):
def write(self, cr, uid, ids, vals, context=None):
if isinstance(ids, (int, long)):
ids = [ids]
if vals.get('project_id'):
project_id = self.pool.get('project.project').browse(cr, uid, vals.get('project_id'), context=context)
if project_id:
vals.setdefault('message_follower_ids', [])
vals['message_follower_ids'] += [(6, 0,[follower.id]) for follower in project_id.message_follower_ids]
if vals and not 'kanban_state' in vals and 'stage_id' in vals:
new_stage = vals.get('stage_id')
vals_reset_kstate = dict(vals, kanban_state='normal')
@ -1165,8 +1143,7 @@ class task(base_stage, osv.osv):
# subscribe new project followers to the task
if vals.get('project_id'):
for id in ids:
self._subscribe_project_followers_to_task(cr, uid, id, context=context)
self._subscribe_followers_subtype(cr, uid, ids, vals.get('project_id'), 'project.project', context=context)
return result
def unlink(self, cr, uid, ids, context=None):
@ -1266,24 +1243,33 @@ class task(base_stage, osv.osv):
res = super(task, self).message_get_monitored_follower_fields(cr, uid, ids, context=context)
return res + ['user_id', 'manager_id']
def create_send_note(self, cr, uid, ids, context=None):
return self.message_post(cr, uid, ids, body=_("Task <b>created</b>."), subtype="project.mt_task_new", context=context)
def stage_set_send_note(self, cr, uid, ids, stage_id, context=None):
""" Override of the (void) default notification method. """
stage_name = self.pool.get('project.task.type').name_get(cr, uid, [stage_id], context=context)[0][1]
return self.message_post(cr, uid, ids, body=_("Stage changed to <b>%s</b>.") % (stage_name),
context=context)
def create_send_note(self, cr, uid, ids, context=None):
return self.message_post(cr, uid, ids, body=_("Task has been <b>created</b>."), context=context)
def case_open_send_note(self, cr, uid, ids, context=None):
return self.message_post(cr, uid, ids, body=_("Task <b>started</b>."), subtype="project.mt_task_started", context=context)
def case_close_send_note(self, cr, uid, ids, context=None):
return self.message_post(cr, uid, ids, body=_("Task <b>closed</b>."), subtype="project.mt_task_closed", context=context)
def case_block_send_note(self, cr, uid, ids, context=None):
return self.message_post(cr, uid, ids, body=_("Task <b>blocked</b>."), subtype="project.mt_task_blocked", context=context)
def case_draft_send_note(self, cr, uid, ids, context=None):
return self.message_post(cr, uid, ids, body=_('Task has been set as <b>draft</b>.'), context=context)
return self.message_post(cr, uid, ids, body=_('Task set as <b>draft</b>.'), context=context)
def do_delegation_send_note(self, cr, uid, ids, context=None):
for task in self.browse(cr, uid, ids, context=context):
msg = _('Task has been <b>delegated</b> to <em>%s</em>.') % (task.user_id.name)
self.message_post(cr, uid, [task.id], body=msg, context=context)
return True
def project_task_reevaluate(self, cr, uid, ids, context=None):
if self.pool.get('res.users').has_group(cr, uid, 'project.group_time_work_estimation_tasks'):
return {

View File

@ -78,39 +78,42 @@
<field name="fold" eval="True"/>
</record>
<!-- mail: subtypes -->
<record id="mt_project_new" model="mail.message.subtype">
<field name="name">New</field>
<!-- Project-related subtypes for messaging / Chatter -->
<record id="mt_project_task_new" model="mail.message.subtype">
<field name="name">Task Created</field>
<field name="res_model">project.project</field>
<field name="default" eval="False"/>
</record>
<record id="mt_project_closed" model="mail.message.subtype">
<field name="name">Closed</field>
<record id="mt_project_task_started" model="mail.message.subtype">
<field name="name">Task Started</field>
<field name="res_model">project.project</field>
<field name="default" eval="False"/>
</record>
<record id="mt_project_task_blocked" model="mail.message.subtype">
<field name="name">Task Blocked</field>
<field name="res_model">project.project</field>
</record>
<record id="mt_project_canceled" model="mail.message.subtype">
<field name="name">Canceled</field>
<record id="mt_project_task_closed" model="mail.message.subtype">
<field name="name">Task Done</field>
<field name="res_model">project.project</field>
</record>
<record id="mt_project_stage" model="mail.message.subtype">
<field name="name">Stage Changed</field>
<field name="res_model">project.project</field>
</record>
<!-- Task-related subtypes for messaging / Chatter -->
<record id="mt_task_new" model="mail.message.subtype">
<field name="name">New</field>
<field name="name">Task Created</field>
<field name="res_model">project.task</field>
<field name="default" eval="False"/>
</record>
<record id="mt_task_started" model="mail.message.subtype">
<field name="name">Task Started</field>
<field name="res_model">project.task</field>
<field name="default" eval="False"/>
</record>
<record id="mt_task_blocked" model="mail.message.subtype">
<field name="name">Task Blocked</field>
<field name="res_model">project.task</field>
</record>
<record id="mt_task_closed" model="mail.message.subtype">
<field name="name">Closed</field>
<field name="res_model">project.task</field>
</record>
<record id="mt_task_canceled" model="mail.message.subtype">
<field name="name">Canceled</field>
<field name="res_model">project.task</field>
</record>
<record id="mt_task_change" model="mail.message.subtype">
<field name="name">Stage Changed</field>
<field name="name">Task Done</field>
<field name="res_model">project.task</field>
</record>

View File

@ -115,7 +115,7 @@
</notebook>
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers" help="Follow this project to automatically follow all related tasks and issues." groups="base.group_user"/>
<field name="message_follower_ids" widget="mail_followers" help="Follow this project to automatically track the events associated to tasks and issues of this project." groups="base.group_user"/>
<field name="message_ids" widget="mail_thread"/>
</div>
</form>

View File

@ -233,6 +233,12 @@ class project_issue(base_stage, osv.osv):
When the case is over, the status is set to \'Done\'.\
If the case needs to be reviewed then the status is \
set to \'Pending\'.'),
'kanban_state': fields.selection([('normal', 'Normal'),('blocked', 'Blocked'),('done', 'Ready for next stage')], 'Kanban State',
help="A Issue's kanban state indicates special situations affecting it:\n"
" * Normal is the default situation\n"
" * Blocked indicates something is preventing the progress of this issue\n"
" * Ready for next stage indicates the issue is ready to be pulled to the next stage",
readonly=True, required=False),
'email_from': fields.char('Email', size=128, help="These people will receive email.", select=1),
'email_cc': fields.char('Watchers Emails', size=256, help="These email addresses will be added to the CC field of all inbound and outbound emails for this record before being sent. Separate multiple email addresses with a comma"),
'date_open': fields.datetime('Opened', readonly=True,select=True),
@ -279,6 +285,7 @@ class project_issue(base_stage, osv.osv):
'section_id': lambda s, cr, uid, c: s._get_default_section_id(cr, uid, c),
'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'crm.helpdesk', context=c),
'priority': crm.AVAILABLE_PRIORITIES[2][0],
'kanban_state': 'normal',
}
_group_by_full = {
@ -359,31 +366,6 @@ class project_issue(base_stage, osv.osv):
return super(project_issue, self).copy(cr, uid, id, default=default,
context=context)
def _subscribe_project_followers_to_issue(self, cr, uid, task_id, context=None):
""" TDE note: not the best way to do this, we could override _get_followers
of issue, and perform a better mapping of subtypes than a mapping
based on names.
However we will keep this implementation, maybe to be refactored
in 7.1 of future versions. """
# task followers are project followers, with matching subtypes
task_record = self.browse(cr, uid, task_id, context=context)
subtype_obj = self.pool.get('mail.message.subtype')
follower_obj = self.pool.get('mail.followers')
if task_record.project_id:
# create mapping
task_subtype_ids = subtype_obj.search(cr, uid, ['|', ('res_model', '=', False), ('res_model', '=', self._name)], context=context)
task_subtypes = subtype_obj.browse(cr, uid, task_subtype_ids, context=context)
# fetch subscriptions
follower_ids = follower_obj.search(cr, uid, [('res_model', '=', 'project.project'), ('res_id', '=', task_record.project_id.id)], context=context)
# copy followers
for follower in follower_obj.browse(cr, uid, follower_ids, context=context):
if not follower.subtype_ids:
continue
project_subtype_names = [project_subtype.name for project_subtype in follower.subtype_ids]
task_subtype_ids = [task_subtype.id for task_subtype in task_subtypes if task_subtype.name in project_subtype_names]
self.message_subscribe(cr, uid, [task_id], [follower.partner_id.id],
subtype_ids=task_subtype_ids, context=context)
def write(self, cr, uid, ids, vals, context=None):
#Update last action date every time the user change the stage, the state or send a new email
logged_fields = ['stage_id', 'state', 'message_ids']
@ -392,11 +374,14 @@ class project_issue(base_stage, osv.osv):
# subscribe new project followers to the issue
if vals.get('project_id'):
for id in ids:
self._subscribe_project_followers_to_issue(cr, uid, id, context=context)
return super(project_issue, self).write(cr, uid, ids, vals, context)
project_id = self.pool.get('project.project').browse(cr, uid, vals.get('project_id'), context=context)
vals.setdefault('message_follower_ids', [])
vals['message_follower_ids'] += [(6, 0,[follower.id]) for follower in project_id.message_follower_ids]
res = super(project_issue, self).write(cr, uid, ids, vals, context)
if vals.get('project_id'):
self._subscribe_followers_subtype(cr, uid, ids, vals.get('project_id'), 'project.project', context=context)
return res
def onchange_task_id(self, cr, uid, ids, task_id, context=None):
if not task_id:
return {'value': {}}
@ -413,8 +398,10 @@ class project_issue(base_stage, osv.osv):
def create(self, cr, uid, vals, context=None):
obj_id = super(project_issue, self).create(cr, uid, vals, context=context)
# subscribe project follower to the issue
self._subscribe_project_followers_to_issue(cr, uid, obj_id, context=context)
project_id = self.browse(cr, uid, obj_id, context=context).project_id
if project_id:
# subscribe project follower to the issue
self._subscribe_followers_subtype(cr, uid, [obj_id], project_id, 'project.project', context=context)
self.create_send_note(cr, uid, [obj_id], context=context)
return obj_id
@ -455,7 +442,6 @@ class project_issue(base_stage, osv.osv):
def case_cancel(self, cr, uid, ids, context=None):
""" Cancels case """
self.case_set(cr, uid, ids, 'cancelled', {'active': True}, context=context)
self.case_cancel_send_note(cr, uid, ids, context=context)
return True
def case_escalate(self, cr, uid, ids, context=None):
@ -536,7 +522,7 @@ class project_issue(base_stage, osv.osv):
def stage_set_send_note(self, cr, uid, ids, stage_id, context=None):
""" Override of the (void) default notification method. """
stage_name = self.pool.get('project.task.type').name_get(cr, uid, [stage_id], context=context)[0][1]
return self.message_post(cr, uid, ids, body= _("Stage changed to <b>%s</b>.") % (stage_name), subtype="mt_issue_new", context=context)
return self.message_post(cr, uid, ids, body=_("Stage changed to <b>%s</b>.") % (stage_name), context=context)
def case_get_note_msg_prefix(self, cr, uid, id, context=None):
""" Override of default prefix for notifications. """
@ -548,7 +534,10 @@ class project_issue(base_stage, osv.osv):
def create_send_note(self, cr, uid, ids, context=None):
message = _("Project issue <b>created</b>.")
return self.message_post(cr, uid, ids, body=message, subtype="mt_issue_new", context=context)
return self.message_post(cr, uid, ids, body=message, subtype="project_issue.mt_issue_new", context=context)
def case_open_send_note(self, cr, uid, ids, context=None):
return self.message_post(cr, uid, ids, body=_("Issue <b>started</b>."), subtype="project_issue.mt_issue_started", context=context)
def case_escalate_send_note(self, cr, uid, ids, context=None):
for obj in self.browse(cr, uid, ids, context=context):
@ -560,6 +549,25 @@ class project_issue(base_stage, osv.osv):
obj.message_post(body=message)
return True
def case_block_send_note(self, cr, uid, ids, context=None):
return self.message_post(cr, uid, ids, body=_("Issue <b>blocked</b>."), subtype="project_issue.mt_issue_blocked", context=context)
def case_close_send_note(self, cr, uid, ids, context=None):
return self.message_post(cr, uid, ids, body=_("Project issue <b>closed</b>."), subtype="project_issue.mt_issue_closed", context=context)
def set_kanban_state_blocked(self, cr, uid, ids, context=None):
self.write(cr, uid, ids, {'kanban_state': 'blocked'}, context=context)
self.case_block_send_note(cr, uid, ids, context=context)
return True
def set_kanban_state_normal(self, cr, uid, ids, context=None):
self.write(cr, uid, ids, {'kanban_state': 'normal'}, context=context)
self.case_open_send_note(cr, uid, ids, context=context)
return True
def set_kanban_state_done(self, cr, uid, ids, context=None):
self.write(cr, uid, ids, {'kanban_state': 'done'}, context=context)
return False
project_issue()
class project(osv.osv):

View File

@ -43,23 +43,46 @@ You can record issues, assign them to a responsible person, and keep track of th
Access all issues from the top Project menu, and access the issues of a specific project via the projects gallery view.</p>]]></field>
</record>
<!-- Mail subtypes -->
<record id="mail.mt_issue_new" model="mail.message.subtype">
<field name="name">New</field>
<!-- Issue-related subtypes for messaging / Chatter -->
<record id="mt_issue_new" model="mail.message.subtype">
<field name="name">Issue Created</field>
<field name="res_model">project.issue</field>
<field name="default" eval="False"/>
</record>
<record id="mt_issue_started" model="mail.message.subtype">
<field name="name">Issue Started</field>
<field name="res_model">project.issue</field>
<field name="default" eval="False"/>
</record>
<record id="mt_issue_blocked" model="mail.message.subtype">
<field name="name">Issue Blocked</field>
<field name="res_model">project.issue</field>
<field name="default" eval="False"/>
</record>
<record id="mt_issue_closed" model="mail.message.subtype">
<field name="name">Issue Closed</field>
<field name="res_model">project.issue</field>
</record>
<record id="mail.mt_issue_closed" model="mail.message.subtype">
<field name="name">Closed</field>
<field name="res_model">project.issue</field>
<!-- Project-related subtypes for messaging / Chatter -->
<record id="mt_project_issue_new" model="mail.message.subtype">
<field name="name">Issue Created</field>
<field name="res_model">project.project</field>
<field name="default" eval="False"/>
</record>
<record id="mail.mt_issue_canceled" model="mail.message.subtype">
<field name="name">Canceled</field>
<field name="res_model">project.issue</field>
<record id="mt_project_issue_started" model="mail.message.subtype">
<field name="name">Issue Started</field>
<field name="res_model">project.project</field>
<field name="default" eval="False"/>
</record>
<record id="mail.mt_issue_change" model="mail.message.subtype">
<field name="name">Stage Changed</field>
<field name="res_model">project.issue</field>
<record id="mt_project_issue_blocked" model="mail.message.subtype">
<field name="name">Issue Blocked</field>
<field name="res_model">project.project</field>
<field name="default" eval="False"/>
</record>
<record id="mt_project_issue_closed" model="mail.message.subtype">
<field name="name">Issue Closed</field>
<field name="res_model">project.project</field>
</record>
</data>
</openerp>

View File

@ -203,6 +203,7 @@
<field name="user_email"/>
<field name="user_id"/>
<field name="date_deadline"/>
<field name="kanban_state"/>
<templates>
<t t-name="kanban-tooltip">
<ul class="oe_kanban_tooltip">
@ -230,6 +231,9 @@
<field name="categ_ids"/>
<div class="oe_right">
<span class="oe_kanban_highlight" groups="base.group_user">
<a t-if="record.kanban_state.raw_value === 'normal'" type="object" string="In Progress" name="set_kanban_state_done" class="oe_kanban_status"> </a>
<a t-if="record.kanban_state.raw_value === 'done'" type="object" string="Ready for next stage" name="set_kanban_state_blocked" class="oe_kanban_status oe_kanban_status_green"> </a>
<a t-if="record.kanban_state.raw_value === 'blocked'" type="object" string="Blocked" name="set_kanban_state_normal" class="oe_kanban_status oe_kanban_status_red"> </a>
<t t-set="priority" t-value="record.priority.raw_value || 5"/>
<a type="object" name="set_priority" args="['3']" t-if="priority gt 3" title="Normal Priority">
<img src="/web/static/src/img/icons/star-off.png" width="16" height="16"/>

View File

@ -822,7 +822,7 @@ class purchase_order(osv.osv):
def confirm_send_note(self, cr, uid, ids, context=None):
for obj in self.browse(cr, uid, ids, context=context):
self.message_post(cr, uid, [obj.id], body=_("Quotation for <em>%s</em> <b>converted</b> to a Purchase Order of %s %s.") % (obj.partner_id.name, obj.amount_total, obj.pricelist_id.currency_id.symbol), context=context)
self.message_post(cr, uid, [obj.id], body=_("Quotation for <em>%s</em> <b>converted</b> to a Purchase Order of %s %s.") % (obj.partner_id.name, obj.amount_total, obj.pricelist_id.currency_id.symbol), subtype="purchase.mt_rfq_confirmed", context=context)
def shipment_send_note(self, cr, uid, ids, picking_id, context=None):
for order in self.browse(cr, uid, ids, context=context):

View File

@ -48,6 +48,18 @@
id="purchase_default_set"
model="ir.values"
name="set"/>
<!-- Purchase-related subtypes for messaging / Chatter -->
<record id="mt_rfq_confirmed" model="mail.message.subtype">
<field name="name">RFQ Confirmed</field>
<field name="res_model">purchase.order</field>
<field name="default" eval="False"/>
</record>
<record id="mt_rfq_approved" model="mail.message.subtype">
<field name="name">RFQ Approved</field>
<field name="res_model">purchase.order</field>
<field name="default" eval="False"/>
</record>
</data>
</openerp>

View File

@ -650,7 +650,7 @@ class sale_order(osv.osv):
def confirm_send_note(self, cr, uid, ids, context=None):
for obj in self.browse(cr, uid, ids, context=context):
self.message_post(cr, uid, [obj.id], body=_("Quotation for <em>%s</em> <b>converted</b> to Sale Order of %s %s.") % (obj.partner_id.name, obj.amount_total, obj.pricelist_id.currency_id.symbol), context=context)
self.message_post(cr, uid, [obj.id], body=_("Quotation for <em>%s</em> <b>converted</b> to Sale Order of %s %s.") % (obj.partner_id.name, obj.amount_total, obj.pricelist_id.currency_id.symbol), subtype="sale.mt_order_confirmed", context=context)
def cancel_send_note(self, cr, uid, ids, context=None):
for obj in self.browse(cr, uid, ids, context=context):

View File

@ -43,5 +43,28 @@
<field name="body"><![CDATA[<p>This application lets you create and send quotations and process your sales orders; from delivery to invoicing.</p>
<p>If you need to manage your sales pipeline (leads, opportunities, phonecalls), the <i>CRM</i> application may be useful. Use the Settings menu to install it.</p>]]></field>
</record>
<!-- Sale-related subtypes for messaging / Chatter -->
<record id="mt_quotation_sent" model="mail.message.subtype">
<field name="name">Quotation sent</field>
<field name="res_model">sale.order</field>
</record>
<record id="mt_order_confirmed" model="mail.message.subtype">
<field name="name">Sale Order Confirmed</field>
<field name="res_model">sale.order</field>
</record>
<!-- Salesteam-related subtypes for messaging / Chatter -->
<record id="mt_salesteam_sent" model="mail.message.subtype">
<field name="name">Quotation sent</field>
<field name="res_model">crm.case.section</field>
<field name="default" eval="False"/>
</record>
<record id="mt_salesteam_confirmed" model="mail.message.subtype">
<field name="name">Sale Order Confirmed</field>
<field name="res_model">crm.case.section</field>
<field name="default" eval="False"/>
</record>
</data>
</openerp>

View File

@ -33,16 +33,19 @@ class sale_order(osv.osv):
order = super(sale_order, self).create(cr, uid, vals, context=context)
section_id = self.browse(cr, uid, order, context=context).section_id
if section_id:
followers = [follow.id for follow in section_id.message_follower_ids]
self.message_subscribe(cr, uid, [order], followers, context=context)
# subscribe salesteam followers & subtypes to the sale order
self._subscribe_followers_subtype(cr, uid, [order], section_id, 'crm.case.section', context=context)
return order
def write(self, cr, uid, ids, vals, context=None):
if vals.get('section_id'):
section_id = self.pool.get('crm.case.section').browse(cr, uid, vals.get('section_id'), context=context)
if section_id:
vals['message_follower_ids'] = [(4, follower.id) for follower in section_id.message_follower_ids]
return super(sale_order, self).write(cr, uid, ids, vals, context=context)
vals['message_follower_ids'] = [(6, 0, [follower.id]) for follower in section_id.message_follower_ids]
res = super(sale_order, self).write(cr, uid, ids, vals, context=context)
# subscribe new salesteam followers & subtypes to the sale order
if vals.get('section_id'):
self._subscribe_followers_subtype(cr, uid, ids, vals.get('section_id'), 'crm.case.section', context=context)
return res
sale_order()