[MERGE] CRM Improvement: _inhertis from mailgate.Thread

bzr revid: hmo@hmo-20100521102600-xvfwskufugexn5wv
This commit is contained in:
hmo 2010-05-21 15:56:00 +05:30
commit 734da01824
49 changed files with 1250 additions and 1270 deletions

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
##############################################################################
#
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
@ -15,34 +15,35 @@
# 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/>.
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
{
"name" : "Basic Calendar Functionality",
"version" : "1.0",
"depends" : ["base"],
"name" : "Basic Calendar Functionality",
"version" : "1.0",
"depends" : ["base"],
'description': """Full featured calendar system that support:
- Alerts (create requests)
- Recurring events (*)
- Invitations to others people""",
"author" : "Tiny",
'category': 'Generic Modules/Others',
'website': 'http://www.openerp.com',
- Invitations to others people""",
"author" : "Tiny",
'category': 'Generic Modules/Others',
'website': 'http://www.openerp.com',
"init_xml" : [
'base_calendar_data.xml'
],
"demo_xml" : [],
],
"demo_xml" : [],
"update_xml" : [
'security/ir.model.access.csv',
'wizard/calendar_event_edit_all_view.xml',
'wizard/base_calendar_invite_attendee_view.xml',
'wizard/calendar_event_edit_all_view.xml',
'wizard/base_calendar_invite_attendee_view.xml',
'wizard/base_calendar_set_exrule_view.xml',
'base_calendar_view.xml'
],
# "test" : ['test/base_calendar_test.yml'],
"installable" : True,
"active" : False,
],
# "test" : ['test/base_calendar_test.yml'],
"installable" : True,
"active" : False,
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!-- Attendee form view-->
<record id="base_calendar_attendee_form_view" model="ir.ui.view">
<field name="name">calendar.attendee.form</field>
@ -65,6 +67,8 @@
</form>
</field>
</record>
<!-- Attendee tree view-->
<record id="base_calendar_attendee_tree_view" model="ir.ui.view">
<field name="name">calendar.attendee.tree</field>
@ -77,10 +81,14 @@
<field name="partner_address_id" string="Contact" />
<field name="role" />
<field name="state" />
<field name="cutype" invisible="1"/>
<field name="rsvp" invisible="1"/>
</tree>
</field>
</record>
<!-- Attendee search view-->
<record id="base_calendar_attendee_search_view" model="ir.ui.view">
<field name="name">calendar.attendee.search</field>
<field name="model">calendar.attendee</field>
@ -99,11 +107,26 @@
<separator orientation="vertical"/>
<field name="cutype" string="Invitation type" select="1"/>
<field name="event_date" select="1"/>
<newline/>
<group expand="0" string="Group By..." colspan="16">
<filter string="Type" icon="terp-project" help="Invitation Type"
domain="[]" context="{'group_by':'cutype'}" />
<filter string="Role" icon="terp-project"
domain="[]" context="{'group_by':'role'}" />
<filter string="Required Reply" icon="terp-crm"
domain="[]" context="{'group_by':'rsvp'}" />
<separator orientation="vertical" />
<filter string="User" icon="terp-partner" domain="[]"
context="{'group_by':'user_id'}" />
<filter string="Contact" icon="terp-partner" domain="[]"
context="{'group_by':'partner_address_id'}" />
</group>
</search>
</field>
</record>
<!-- Action for attendee view-->
<record id="action_view_attendee_form" model="ir.actions.act_window">
<field name="name">Event Invitations</field>
<field name="type">ir.actions.act_window</field>
@ -115,10 +138,12 @@
</record>
<!-- Calenadar's menu -->
<menuitem id="base.menu_calendar_configuration" name="Calendar"
parent="base.menu_base_config" sequence="10" />
<!-- Invitation menu -->
<menuitem id="menu_attendee_invitations"
name="Event Invitations" parent="base.menu_calendar_configuration"
sequence="10" action="action_view_attendee_form" />
@ -138,9 +163,6 @@
<field name="trigger_interval" select="1" />
<field name="trigger_occurs" select="1" />
<field name="trigger_related" select="1" />
<separator string="" colspan="4" />
<field name="duration" />
<field name="repeat" />
</form>
</field>
</record>
@ -162,7 +184,8 @@
</field>
</record>
<!-- Action for alarms view-->
<record id="action_res_alarm_view" model="ir.actions.act_window">
<field name="name">Available Alarms</field>
<field name="type">ir.actions.act_window</field>
@ -170,6 +193,8 @@
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
</record>
<!-- Menu for Alarms-->
<menuitem id="menu_crm_meeting_avail_alarm"
groups="base.group_extended"
@ -405,6 +430,7 @@
</record>
<!-- Event menu -->
<menuitem id="menu_events"
name="Events" parent="base.menu_calendar_configuration"
sequence="5" action="action_view_event" />

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
##############################################################################
#
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
#
@ -15,12 +15,13 @@
# 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/>.
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import calendar_event_edit_all
import base_calendar_invite_attendee
import base_calendar_set_exrule
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -13,37 +13,38 @@
<field name="type" />
<field name="send_mail" />
<newline />
<group col="1" colspan="4"
<group col="2" colspan="6"
attrs="{'invisible': [('type', '!=', 'external')]}">
<field name="email" colspan="4"
attrs="{'required': [('type', '=', 'external')]}" />
</group>
<group col="1" colspan="4"
<group col="2" colspan="6"
attrs="{'invisible': [('type', '!=', 'internal')]}">
<separator string="Users" colspan="4" />
<field name="user_ids" select="1" colspan="4"
nolabel="1" />
<newline />
</group>
<group col="2" colspan="4"
<group col="2" colspan="6"
attrs="{'invisible': [('type', '!=', 'partner')]}">
<field name="partner_id" colspan="2"
on_change="onchange_partner_id(partner_id)"
attrs="{'required': [('type', '=', 'partner')]}" />
<newline />
<separator string="Partner Contacts"
colspan="4" />
colspan="6" />
<field name="contact_ids" select="1" colspan="4"
nolabel="1" domain="[('partner_id', '=', partner_id)]"
attrs="{'readonly': [('type', '!=', 'partner')]}" />
</group>
<newline />
<separator string="" colspan="6" />
<label string="" colspan="2" />
<group col="4" colspan="4">
<button icon='gtk-cancel' special="cancel"
string="Cancel" />
<button name="do_invite" string="Invite"
type="object" icon="gtk-ok" />
</group>
</form>
</field>
</record>

View File

@ -0,0 +1,162 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 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 base_calendar import base_calendar
from osv import fields, osv
from tools.translate import _
import tools
import mx.DateTime
import re
months = {
1: "January", 2: "February", 3: "March", 4: "April", \
5: "May", 6: "June", 7: "July", 8: "August", 9: "September", \
10: "October", 11: "November", 12: "December"
}
class base_calendar_set_exrule(osv.osv_memory):
"""
Set Exrule.
"""
_name = "base.calendar.set.exrule"
_description = "Set Exrule"
_columns = {
'freq': fields.selection([('None', 'No Repeat'), \
('secondly', 'Secondly'), \
('minutely', 'Minutely'), \
('hourly', 'Hourly'), \
('daily', 'Daily'), \
('weekly', 'Weekly'), \
('monthly', 'Monthly'), \
('yearly', 'Yearly')], 'Frequency',required=True),
'interval': fields.integer('Interval'),
'count': fields.integer('Count'),
'mo': fields.boolean('Mon'),
'tu': fields.boolean('Tue'),
'we': fields.boolean('Wed'),
'th': fields.boolean('Thu'),
'fr': fields.boolean('Fri'),
'sa': fields.boolean('Sat'),
'su': fields.boolean('Sun'),
'select1': fields.selection([('date', 'Date of month'), \
('day', 'Day of month')], 'Option'),
'day': fields.integer('Date of month'),
'week_list': fields.selection([('MO', 'Monday'), ('TU', 'Tuesday'), \
('WE', 'Wednesday'), ('TH', 'Thursday'), \
('FR', 'Friday'), ('SA', 'Saturday'), \
('SU', 'Sunday')], 'Weekday'),
'byday': fields.selection([('1', 'First'), ('2', 'Second'), \
('3', 'Third'), ('4', 'Fourth'), \
('5', 'Fifth'), ('-1', 'Last')], 'By day'),
'month_list': fields.selection(months.items(),'Month'),
'end_date': fields.date('Repeat Until'),
}
def view_init(self, cr, uid, fields, context=None):
"""
This function checks for precondition before wizard executes
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param fields: List of fields for default value
@param context: A standard dictionary for contextual values
"""
crm_obj = self.pool.get('crm.meeting')
for meeting in crm_obj.browse(cr, uid, context.get('active_ids', [])):
if not meeting.rrule:
raise osv.except_osv(_("Warning !"), _("Please Apply Recurrency after Apply Exception Rule"))
return False
def compute_exrule_string(self, cr, uid, ids, context=None):
"""
Compute rule string.
@param self: the object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param datas: dictionary of freq and interval value.
@return: string value which compute FREQILY;INTERVAL
"""
weekdays = ['mo', 'tu', 'we', 'th', 'fr', 'sa', 'su']
weekstring = ''
monthstring = ''
yearstring = ''
for datas in self.read(cr, uid, ids, context=context):
freq = datas.get('freq')
if freq == 'None':
return ''
interval_srting = datas.get('interval') and (';INTERVAL=' + str(datas.get('interval'))) or ''
if freq == 'weekly':
byday = map(lambda x: x.upper(), filter(lambda x: datas.get(x) and x in weekdays, datas))
if byday:
weekstring = ';BYDAY=' + ','.join(byday)
elif freq == 'monthly':
if datas.get('select1')=='date' and (datas.get('day') < 1 or datas.get('day') > 31):
raise osv.except_osv(_('Error!'), ("Please select proper Day of month"))
if datas.get('select1')=='day':
monthstring = ';BYDAY=' + datas.get('byday') + datas.get('week_list')
elif datas.get('select1')=='date':
monthstring = ';BYMONTHDAY=' + str(datas.get('day'))
elif freq == 'yearly':
if datas.get('select1')=='date' and (datas.get('day') < 1 or datas.get('day') > 31):
raise osv.except_osv(_('Error!'), ("Please select proper Day of month"))
bymonth = ';BYMONTH=' + str(datas.get('month_list'))
if datas.get('select1')=='day':
bystring = ';BYDAY=' + datas.get('byday') + datas.get('week_list')
elif datas.get('select1')=='date':
bystring = ';BYMONTHDAY=' + str(datas.get('day'))
yearstring = bymonth + bystring
if datas.get('end_date'):
datas['end_date'] = ''.join((re.compile('\d')).findall(datas.get('end_date'))) + '235959Z'
enddate = (datas.get('count') and (';COUNT=' + str(datas.get('count'))) or '') +\
((datas.get('end_date') and (';UNTIL=' + datas.get('end_date'))) or '')
exrule_string = 'FREQ=' + freq.upper() + weekstring + interval_srting \
+ enddate + monthstring + yearstring
ex_id = base_calendar.base_calendar_id2real_id(context['active_id'])
model = context.get('model', False)
model_obj = self.pool.get(model)
exrule_value = model_obj.write(cr, uid,ex_id,{
'exrule': exrule_string,
})
return {}
_defaults = {
'freq': lambda *x: 'None',
'select1': lambda *x: 'date',
'interval': lambda *x: 1,
}
base_calendar_set_exrule()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_base_calendar_set_exrule" model="ir.ui.view">
<field name="name">base.calendar.set.exrule.form</field>
<field name="model">base.calendar.set.exrule</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Set Exrule">
<separator string="Select data for ExRule" colspan="8"/>
<group col="8" colspan="6">
<field name="freq" />
<field name="interval" />
<field name="count" />
<field name="end_date" />
</group>
<group col="8" colspan="8" name="Select weekdays"
attrs="{'invisible' : [('freq','!=','weekly')]}">
<field name="mo" colspan="1" />
<field name="tu" colspan="1" />
<field name="we" colspan="1" />
<field name="th" colspan="1" />
<field name="fr" colspan="1" />
<field name="sa" colspan="1" />
<field name="su" colspan="1" />
<newline />
</group>
<group col="8" colspan="6"
attrs="{'invisible' : [('freq','!=','monthly'), ('freq','!=','yearly')]}">
<group col="2" colspan="1">
<field name="select1" />
</group>
<group col="2" colspan="1"
attrs="{'invisible' : [('select1','=','day')]}">
<field name="day"
attrs="{'required' : [('select1','=','date')]}"/>
</group>
<group col="3" colspan="1"
attrs="{'invisible' : [('select1','=','date')]}">
<field name="byday" string="The"
attrs="{'required' : [('select1','=','day')]}"/>
<field name="week_list" nolabel="1"
attrs="{'required' : [('select1','=','day')]}"/>
</group>
<group col="1" colspan="1"
attrs="{'invisible' : [('freq','!=','yearly')]}">
<field name="month_list" string="of"
colspan="1"
attrs="{'required' : [('freq','=','yearly')]}"/>
</group>
</group>
<group colspan="4" col="6">
<button icon="gtk-cancel" special="cancel" string="Cancel"/>
<button icon="gtk-ok" string="ok" name="compute_exrule_string" type="object"/>
</group>
</form>
</field>
</record>
<record id="action_base_calendar_set_exrule" model="ir.actions.act_window">
<field name="name">Set Exrule</field>
<field name="res_model">base.calendar.set.exrule</field>
<field name="view_type">form</field>
<field name="view_mode">form,tree</field>
<field name="target">new</field>
</record>
</data>
</openerp>

View File

@ -212,8 +212,8 @@ class res_partner_job(osv.osv):
'name': fields.related('address_id', 'partner_id', type='many2one',\
relation='res.partner', string='Partner', help="You may\
enter Address first,Partner will be linked automatically if any."),
'address_id': fields.many2one('res.partner.address', 'Address', domain=[('partner_id', '=', name)], \
help='Address which is linked to the Partner'),
'address_id': fields.many2one('res.partner.address', 'Address', \
help='Address which is linked to the Partner'), # TO Correct: domain=[('partner_id', '=', name)]
'contact_id': fields.many2one('res.partner.contact','Contact', required=True, ondelete='cascade'),
'function_id': fields.many2one('res.partner.function','Partner Function', \
help="Function of this contact with this partner"),

View File

@ -21,9 +21,9 @@
{
'name': 'Customer & Supplier Relationship Management',
'version': '1.0',
'category': 'Generic Modules/CRM & SRM',
'name': 'Customer & Supplier Relationship Management',
'version': '1.0',
'category': 'Generic Modules/CRM & SRM',
'description': """The generic Open ERP Customer Relationship Management
system enables a group of people to intelligently and efficiently manage
leads, opportunities, meeting, phonecall etc.
@ -41,70 +41,70 @@ appropriate staff, and making sure all future correspondence gets to the right
place.
The CRM module has a email gateway for the synchronisation interface
between mails and Open ERP.""",
'author': 'Tiny',
'website': 'http://www.openerp.com',
between mails and Open ERP.""",
'author': 'Tiny',
'website': 'http://www.openerp.com',
'depends': [
'base',
'base_action_rule',
'process',
'mail_gateway',
'base_calendar',
'resource',
],
'base',
'base_action_rule',
'process',
'mail_gateway',
'base_calendar',
'resource',
],
'init_xml': [
'crm_data.xml',
'crm_meeting_data.xml',
'crm_lead_data.xml',
'crm_meeting_data.xml',
'crm_opportunity_data.xml',
'crm_phonecall_data.xml',
],
'crm_data.xml',
'crm_meeting_data.xml',
'crm_lead_data.xml',
'crm_meeting_data.xml',
'crm_opportunity_data.xml',
'crm_phonecall_data.xml',
],
'update_xml': [
'wizard/crm_lead_to_partner_view.xml',
'wizard/crm_lead_to_opportunity_view.xml',
'wizard/crm_lead_to_partner_view.xml',
'wizard/crm_lead_to_opportunity_view.xml',
'wizard/crm_phonecall_to_phonecall_view.xml',
'wizard/crm_phonecall_to_partner_view.xml',
'wizard/crm_phonecall_to_opportunity_view.xml',
'wizard/crm_phonecall_to_phonecall_view.xml',
'wizard/crm_phonecall_to_partner_view.xml',
'wizard/crm_phonecall_to_opportunity_view.xml',
'wizard/crm_opportunity_to_phonecall_view.xml',
'wizard/crm_partner_to_opportunity_view.xml',
'wizard/crm_opportunity_to_phonecall_view.xml',
'wizard/crm_partner_to_opportunity_view.xml',
'wizard/crm_forward_to_partner_view.xml',
'wizard/crm_send_email_view.xml',
'crm_view.xml',
'wizard/crm_forward_to_partner_view.xml',
'wizard/crm_send_email_view.xml',
'crm_view.xml',
'crm_action_rule_view.xml',
'crm_lead_view.xml',
'crm_lead_menu.xml',
'crm_meeting_view.xml',
'crm_meeting_menu.xml',
'crm_phonecall_view.xml',
'crm_phonecall_menu.xml',
'crm_opportunity_view.xml',
'crm_opportunity_menu.xml',
'security/crm_security.xml',
'security/ir.model.access.csv',
'crm_action_rule_view.xml',
'crm_lead_view.xml',
'crm_lead_menu.xml',
'report/crm_lead_report_view.xml',
'report/crm_phonecall_report_view.xml',
'crm_meeting_view.xml',
'crm_meeting_menu.xml',
'process/crm_configuration_process.xml',
'crm_phonecall_view.xml',
'crm_phonecall_menu.xml',
'crm_opportunity_view.xml',
'crm_opportunity_menu.xml',
'security/crm_security.xml',
'security/ir.model.access.csv',
'report/crm_lead_report_view.xml',
'report/crm_phonecall_report_view.xml',
'process/crm_configuration_process.xml',
'crm_installer_view.xml'
],
],
'demo_xml': [
'crm_demo.xml',
'crm_lead_demo.xml',
'crm_meeting_demo.xml',
'crm_opportunity_demo.xml',
'crm_demo.xml',
'crm_lead_demo.xml',
'crm_meeting_demo.xml',
'crm_opportunity_demo.xml',
'crm_phonecall_demo.xml'
],
],
'test': [
# 'test/test_crm_lead.yml',
# 'test/test_crm_meeting.yml',
@ -113,6 +113,6 @@ between mails and Open ERP.""",
],
'installable': True,
'active': False,
'certificate': '0079056041421',
'certificate': '0079056041421',
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -202,7 +202,11 @@ class crm_case(object):
return {'value': {'email_from': False}}
address = self.pool.get('res.partner.address').browse(cr, uid, add)
return {'value': {'email_from': address.email}}
def _history(self, cr, uid, cases, keyword, history=False, email=False, details=None, email_from=False, message_id=False, context={}):
mailgate_pool = self.pool.get('mailgate.thread')
return mailgate_pool._history(cr, uid, cases, keyword, history=history, email=email, details=details, email_from=email_from, message_id=message_id, context=context)
def case_open(self, cr, uid, ids, *args):
"""Opens Case
@param self: The object pointer
@ -311,6 +315,107 @@ class crm_case(object):
self._action(cr, uid, cases, 'draft')
return True
def remind_partner(self, cr, uid, ids, context={}, attach=False):
"""
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of Remind Partner's IDs
@param context: A standard dictionary for contextual values
"""
return self.remind_user(cr, uid, ids, context, attach,
destination=False)
def remind_user(self, cr, uid, ids, context={}, attach=False,destination=True):
"""
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of Remind user's IDs
@param context: A standard dictionary for contextual values
"""
for case in self.browse(cr, uid, ids):
if not case.section_id.reply_to:
raise osv.except_osv(_('Error!'), ("Reply To is not specified in the sales team"))
if not case.email_from:
raise osv.except_osv(_('Error!'), ("Partner Email is not specified in Case"))
if case.section_id.reply_to and case.email_from:
src = case.email_from
dest = case.section_id.reply_to
body = ""
body = case.email_last or case.description
if not destination:
src, dest = dest, src
if body and case.user_id.signature:
body += '\n\n%s' % (case.user_id.signature)
body = self.format_body(body)
dest = [dest]
attach_to_send = None
if attach:
attach_ids = self.pool.get('ir.attachment').search(cr, uid, [('res_model', '=', 'mailgate.thread'), ('res_id', '=', case.id)])
attach_to_send = self.pool.get('ir.attachment').read(cr, uid, attach_ids, ['datas_fname','datas'])
attach_to_send = map(lambda x: (x['datas_fname'], base64.decodestring(x['datas'])), attach_to_send)
# Send an email
flag = tools.email_send(
src,
dest,
"Reminder: [%s] %s" % (str(case.id), case.name, ),
body,
reply_to=case.section_id.reply_to,
openobject_id=str(case.id),
attach=attach_to_send
)
self._history(cr, uid, [case], _('Send'), history=True, email=dest, details=body, email_from=src)
#if flag:
# raise osv.except_osv(_('Email!'),("Email Successfully Sent"))
#else:
# raise osv.except_osv(_('Email Fail!'),("Email is not sent successfully"))
return True
def _check(self, cr, uid, ids=False, context={}):
"""
Function called by the scheduler to process cases for date actions
Only works on not done and cancelled cases
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param context: A standard dictionary for contextual values
"""
cr.execute('select * from crm_case \
where (date_action_last<%s or date_action_last is null) \
and (date_action_next<=%s or date_action_next is null) \
and state not in (\'cancel\',\'done\')',
(time.strftime("%Y-%m-%d %H:%M:%S"),
time.strftime('%Y-%m-%d %H:%M:%S')))
ids2 = map(lambda x: x[0], cr.fetchall() or [])
cases = self.browse(cr, uid, ids2, context)
return self._action(cr, uid, cases, False, context=context)
def _action(self, cr, uid, cases, state_to, scrit=None, context={}):
if not context:
context = {}
context['state_to'] = state_to
rule_obj = self.pool.get('base.action.rule')
model_obj = self.pool.get('ir.model')
model_ids = model_obj.search(cr, uid, [('model','=',self._name)])
rule_ids = rule_obj.search(cr, uid, [('name','=',model_ids[0])])
return rule_obj._action(cr, uid, rule_ids, cases, scrit=scrit, context=context)
def format_body(self, body):
return self.pool.get('base.action.rule').format_body(body)
def format_mail(self, obj, body):
return self.pool.get('base.action.rule').format_mail(obj, body)
class crm_case_section(osv.osv):
"""Sales Team"""
@ -506,62 +611,6 @@ def _links_get(self, cr, uid, context=None):
res = obj.read(cr, uid, ids, ['object', 'name'], context)
return [(r['object'], r['name']) for r in res]
class crm_case_log(osv.osv):
""" Case Communication History """
_name = "crm.case.log"
_description = "Case Communication History"
_order = "id desc"
_columns = {
'name': fields.char('Status', size=64),
'date': fields.datetime('Date'),
'section_id': fields.many2one('crm.case.section', 'Sales Team'),
'user_id': fields.many2one('res.users', 'User Responsible', readonly=True),
'model_id': fields.many2one('ir.model', "Model"),
'res_id': fields.integer('Resource ID'),
}
_defaults = {
'date': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
}
crm_case_log()
class crm_case_history(osv.osv):
"""Case history"""
_name = "crm.case.history"
_description = "Case history"
_order = "id desc"
_inherits = {'crm.case.log': "log_id"}
def _note_get(self, cursor, user, ids, name, arg, context=None):
""" Gives case History Description
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of case Historys IDs
@param context: A standard dictionary for contextual values
"""
res = {}
for hist in self.browse(cursor, user, ids, context or {}):
res[hist.id] = (hist.email_from or '/') + ' (' + str(hist.date) + ')\n'
res[hist.id] += (hist.description or '')
return res
_columns = {
'description': fields.text('Description'),
'note': fields.function(_note_get, method=True, string="Description", type="text"),
'email_to': fields.char('Email To', size=84),
'email_from' : fields.char('Email From', size=84),
'log_id': fields.many2one('crm.case.log','Log',ondelete='cascade'),
'message_id': fields.char('Message Id', size=1024, readonly=True, help="Message Id on Email Server.", select=True),
}
crm_case_history()
class users(osv.osv):
_inherit = 'res.users'
_description = "Users"

View File

@ -34,138 +34,24 @@ from osv.orm import except_orm
import crm
class case(osv.osv):
""" Case """
_inherit = 'mailgate.thread'
_description = 'case'
_columns = {
'date_action_last': fields.datetime('Last Action', readonly=1),
'date_action_next': fields.datetime('Next Action', readonly=1),
}
def remind_partner(self, cr, uid, ids, context={}, attach=False):
"""
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of Remind Partner's IDs
@param context: A standard dictionary for contextual values
"""
return self.remind_user(cr, uid, ids, context, attach,
destination=False)
def remind_user(self, cr, uid, ids, context={}, attach=False,destination=True):
"""
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of Remind user's IDs
@param context: A standard dictionary for contextual values
"""
for case in self.browse(cr, uid, ids):
if not case.section_id.reply_to:
raise osv.except_osv(_('Error!'), ("Reply To is not specified in the sales team"))
if not case.email_from:
raise osv.except_osv(_('Error!'), ("Partner Email is not specified in Case"))
if case.section_id.reply_to and case.email_from:
src = case.email_from
dest = case.section_id.reply_to
body = ""
body = case.email_last or case.description
if not destination:
src, dest = dest, src
if body and case.user_id.signature:
body += '\n\n%s' % (case.user_id.signature)
body = self.format_body(body)
dest = [dest]
attach_to_send = None
if attach:
attach_ids = self.pool.get('ir.attachment').search(cr, uid, [('res_model', '=', 'mailgate.thread'), ('res_id', '=', case.id)])
attach_to_send = self.pool.get('ir.attachment').read(cr, uid, attach_ids, ['datas_fname','datas'])
attach_to_send = map(lambda x: (x['datas_fname'], base64.decodestring(x['datas'])), attach_to_send)
# Send an email
flag = tools.email_send(
src,
dest,
"Reminder: [%s] %s" % (str(case.id), case.name, ),
body,
reply_to=case.section_id.reply_to,
openobject_id=str(case.id),
attach=attach_to_send
)
self._history(cr, uid, [case], _('Send'), history=True, email=dest, details=body, email_from=src)
#if flag:
# raise osv.except_osv(_('Email!'),("Email Successfully Sent"))
#else:
# raise osv.except_osv(_('Email Fail!'),("Email is not sent successfully"))
return True
def _check(self, cr, uid, ids=False, context={}):
"""
Function called by the scheduler to process cases for date actions
Only works on not done and cancelled cases
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param context: A standard dictionary for contextual values
"""
cr.execute('select * from crm_case \
where (date_action_last<%s or date_action_last is null) \
and (date_action_next<=%s or date_action_next is null) \
and state not in (\'cancel\',\'done\')',
(time.strftime("%Y-%m-%d %H:%M:%S"),
time.strftime('%Y-%m-%d %H:%M:%S')))
ids2 = map(lambda x: x[0], cr.fetchall() or [])
cases = self.browse(cr, uid, ids2, context)
return self._action(cr, uid, cases, False, context=context)
def _action(self, cr, uid, cases, state_to, scrit=None, context={}):
if not context:
context = {}
context['state_to'] = state_to
rule_obj = self.pool.get('base.action.rule')
model_obj = self.pool.get('ir.model')
model_ids = model_obj.search(cr, uid, [('model','=',self._name)])
rule_ids = rule_obj.search(cr, uid, [('name','=',model_ids[0])])
return rule_obj._action(cr, uid, rule_ids, cases, scrit=scrit, context=context)
def format_body(self, body):
return self.pool.get('base.action.rule').format_body(body)
def format_mail(self, obj, body):
return self.pool.get('base.action.rule').format_mail(obj, body)
case()
class base_action_rule(osv.osv):
""" Base Action Rule """
_inherit = 'base.action.rule'
_description = 'Action Rules'
_columns = {
'trg_section_id': fields.many2one('crm.case.section', 'Sales Team'),
'trg_max_history': fields.integer('Maximum Communication History'),
'trg_categ_id': fields.many2one('crm.case.categ', 'Category'),
'regex_history' : fields.char('Regular Expression on Case History', size=128),
'act_section_id': fields.many2one('crm.case.section', 'Set Team to'),
'act_categ_id': fields.many2one('crm.case.categ', 'Set Category to'),
'act_mail_to_partner': fields.boolean('Mail to partner',help="Check \
this if you want the rule to send an email to the partner."),
'trg_section_id': fields.many2one('crm.case.section', 'Sales Team'),
'trg_max_history': fields.integer('Maximum Communication History'),
'trg_categ_id': fields.many2one('crm.case.categ', 'Category'),
'regex_history' : fields.char('Regular Expression on Case History', size=128),
'act_section_id': fields.many2one('crm.case.section', 'Set Team to'),
'act_categ_id': fields.many2one('crm.case.categ', 'Set Category to'),
'act_mail_to_partner': fields.boolean('Mail to Partner', help="Check \
this if you want the rule to send an email to the partner."),
}
def email_send(self, cr, uid, obj, emails, body, emailfrom=tools.config.get('email_from',False), context={}):
def email_send(self, cr, uid, obj, emails, body, emailfrom=tools.config.get('email_from', False), context={}):
body = self.format_mail(obj, body)
if not emailfrom:
if hasattr(obj, 'user_id') and obj.user_id and obj.user_id.address_id and obj.user_id.address_id.email:
@ -178,7 +64,7 @@ this if you want the rule to send an email to the partner."),
else:
reply_to = emailfrom
if not emailfrom:
raise osv.except_osv(_('Error!'),
raise osv.except_osv(_('Error!'),
_("No E-Mail ID Found for your Company address!"))
return tools.email_send(emailfrom, emails, name, body, reply_to=reply_to, openobject_id=str(obj.id))
@ -253,7 +139,7 @@ this if you want the rule to send an email to the partner."),
@param context: A standard dictionary for contextual values """
res = super(base_action_rule, self).state_get(cr, uid, context=context)
return res + [('escalate','Escalate')] + crm.AVAILABLE_STATES
return res + [('escalate', 'Escalate')] + crm.AVAILABLE_STATES
def priority_get(self, cr, uid, context={}):

View File

@ -34,7 +34,8 @@ class crm_lead(osv.osv, crm_case):
_name = "crm.lead"
_description = "Lead"
_order = "priority, id desc"
_inherit = ['res.partner.address', 'mailgate.thread']
_inherit = ['res.partner.address']
_inherits = {'mailgate.thread': 'thread_id'}
def _compute_day(self, cr, uid, ids, fields, args, context={}):
"""
@ -74,7 +75,7 @@ class crm_lead(osv.osv, crm_case):
duration = float(ans.days)
if lead.section_id and lead.section_id.resource_calendar_id:
duration = float(ans.days) * 24
duration = float(ans.days) * 24
new_dates = cal_obj.interval_get(cr,
uid,
lead.section_id.resource_calendar_id and lead.section_id.resource_calendar_id.id or False,
@ -95,18 +96,23 @@ class crm_lead(osv.osv, crm_case):
_columns = {
# From crm.case
'email_from': fields.char('Email', size=128, help="These people will receive email."),
'name': fields.char('Name', size=64),
'active': fields.boolean('Active', required=False),
'date_action_last': fields.datetime('Last Action', readonly=1),
'date_action_next': fields.datetime('Next Action', readonly=1),
'email_from': fields.char('Email', size=128, help="These people will receive email."),
'section_id': fields.many2one('crm.case.section', 'Sales Team', \
select=True, help='Sales team to which Case belongs to.\
Define Responsible user and Email account for mail gateway.'),
Define Responsible user and Email account for mail gateway.'),
'create_date': fields.datetime('Creation Date' , readonly=True),
'email_cc': fields.text('Watchers Emails', size=252 , help="These \
people will receive a copy of the future communication between partner \
and users by email"),
'description': fields.text('Notes'),
'write_date': fields.datetime('Update Date' , readonly=True),
'description': fields.text('Description'),
'write_date': fields.datetime('Update Date' , readonly=True),
# Lead fields
# Lead fields
'thread_id': fields.many2one('mailgate.thread', 'Thread', required=False),
'categ_id': fields.many2one('crm.case.categ', 'Lead Source', \
domain="[('section_id','=',section_id),\
('object_id.model', '=', 'crm.lead')]"),
@ -117,22 +123,22 @@ and users by email"),
'type':fields.selection([
('lead','Lead'),
('opportunity','Opportunity'),
],'Type', help="Type is used to separate Leads and Opportunities"),
],'Type', help="Type is used to separate Leads and Opportunities"),
'priority': fields.selection(crm.AVAILABLE_PRIORITIES, 'Priority'),
'date_closed': fields.datetime('Closed', readonly=True),
'stage_id': fields.many2one('crm.case.stage', 'Stage', \
domain="[('section_id','=',section_id),\
('object_id.model', '=', 'crm.lead')]"),
'user_id': fields.many2one('res.users', 'Salesman'),
'user_id': fields.many2one('res.users', 'Salesman',help='By Default Salesman is Administrator when create New User'),
'referred': fields.char('Referred By', size=64),
'date_open': fields.datetime('Opened', readonly=True),
'day_open': fields.function(_compute_day, string='Days to Open', \
method=True, multi='day_open', type="float", store=True),
'day_close': fields.function(_compute_day, string='Days to Close', \
method=True, multi='day_close', type="float", store=True),
'function_name': fields.char('Function', size=64),
'state': fields.selection(crm.AVAILABLE_STATES, 'State', size=16, readonly=True,
'function_name': fields.char('Function', size=64),
'state': fields.selection(crm.AVAILABLE_STATES, 'State', size=16, readonly=True,
help='The state is set to \'Draft\', when a case is created.\
\nIf the case is in progress the state is set to \'Open\'.\
\nWhen the case is over, the state is set to \'Done\'.\
@ -140,15 +146,15 @@ and users by email"),
}
_defaults = {
'active': lambda *a: 1,
'user_id': crm_case._get_default_user,
'email_from': crm_case._get_default_email,
'state': lambda *a: 'draft',
'section_id': crm_case._get_section,
'active': lambda *a: 1,
'user_id': crm_case._get_default_user,
'email_from': crm_case._get_default_email,
'state': lambda *a: 'draft',
'section_id': crm_case._get_section,
'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'crm.lead', context=c),
'priority': lambda *a: crm.AVAILABLE_PRIORITIES[2][0],
}
def case_open(self, cr, uid, ids, *args):
"""Overrides cancel for crm_case for setting Open Date
@param self: The object pointer
@ -160,7 +166,7 @@ and users by email"),
res = super(crm_lead, self).case_open(cr, uid, ids, *args)
self.write(cr, uid, ids, {'date_open': time.strftime('%Y-%m-%d %H:%M:%S')})
return res
def case_close(self, cr, uid, ids, *args):
"""Overrides close for crm_case for setting close date
@param self: The object pointer

View File

@ -10,7 +10,7 @@
<field name="view_id" ref="crm_case_tree_view_leads"/>
<field name="context">{"search_default_user_id":uid,'search_default_current':1}</field>
<field name="search_view_id" ref="crm.view_crm_case_leads_filter"/>
<field name="context">{'search_default_current':1}</field>
<field name="context">{'search_default_current':1, 'default_type': 'lead'}</field>
</record>
<record model="ir.actions.act_window.view" id="action_crm_tag_tree_view_leads_all">

View File

@ -47,9 +47,8 @@
name="convert_opportunity"
string="Convert"
help="Convert to Opportunity"
icon="gtk-index"
type="object"
attrs="{'invisible':[('opportunity_id','!=',False)]}"/>
icon="gtk-index"
type="object"/>
<newline />
<field name="section_id" colspan="1"
widget="selection" />
@ -176,7 +175,7 @@
<field name="email_to"/>
<field name="description"/>
</tree>
</field>
</field>
<button colspan="2" string="Send New Email"
name="%(action_crm_send_mail)d"
context="{'mail':'new', 'model': 'crm.lead'}"

View File

@ -43,7 +43,8 @@ class crm_meeting(osv.osv, crm_case):
_name = 'crm.meeting'
_description = "Meeting"
_order = "id desc"
_inherit = ["mailgate.thread", "calendar.event"]
_inherit = ["calendar.event"]
_inherits = {'mailgate.thread': 'thread_id'}
_columns = {
# From crm.case
@ -58,6 +59,7 @@ class crm_meeting(osv.osv, crm_case):
'id': fields.integer('ID'),
# Meeting fields
'thread_id': fields.many2one('mailgate.thread', 'Thread', required=False),
'categ_id': fields.many2one('crm.case.categ', 'Meeting Type', \
domain="[('object_id.model', '=', 'crm.meeting')]", \
),
@ -157,6 +159,22 @@ class calendar_attendee(osv.osv):
calendar_attendee()
class res_users(osv.osv):
_name = 'res.users'
_inherit = 'res.users'
def create(self, cr, uid, data, context={}):
user_id = super(res_users, self).create(cr, uid, data, context)
data_obj = self.pool.get('ir.model.data')
data_id = data_obj._get_id(cr, uid, 'crm', 'ir_ui_view_sc_calendar0')
view_id = data_obj.browse(cr, uid, data_id, context=context).res_id
copy_id = self.pool.get('ir.ui.view_sc').copy(cr, uid, view_id, default = {
'user_id': user_id}, context=context)
return user_id
res_users()
class res_partner(osv.osv):
""" Inherits partner and adds meetings information in the partner form """
_inherit = 'res.partner'

View File

@ -110,7 +110,8 @@
<menuitem id="menu_attendee_invitations"
name="Meeting Invitations" parent="crm.menu_meeting_sale"
sequence="10" action="action_view_attendee_form" />
sequence="10" action="action_view_attendee_form"
groups="base.group_extended" />
</data>
</openerp>

View File

@ -24,18 +24,18 @@
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Meetings">
<group col="6" colspan="4">
<group col="6" colspan="4">
<field name="name" select="1" string="Summary"
colspan="2" />
required="1" colspan="2" />
<field name="categ_id" widget="selection"
string="Meeting Type"
groups="base.group_extended"
domain="[('object_id.model', '=', 'crm.meeting')]" />
<field name="allday" colspan="2" on_change="onchange_allday(allday)" />
<field name="date" string="Start Date" required="1"
on_change="onchange_dates(date,duration,False)" />
<field name="allday" colspan="2" on_change="onchange_allday(allday)" />
<field name="date" string="Start Date" required="1"
on_change="onchange_dates(date,duration,False,allday)" />
<field name="duration" widget="float_time"
on_change="onchange_dates(date,duration,False)" />
on_change="onchange_dates(date,duration,False,allday)" />
<field name="date_deadline" string="End Date"
required="1"
on_change="onchange_dates(date,False,date_deadline)" />
@ -50,6 +50,10 @@
attrs="{'invisible':[('rrule_type','in', ('none', False))]}"
name="open_meeting" icon="gtk-edit"
type="object" />
<button string="ExRule"
name="%(base_calendar.action_base_calendar_set_exrule)d" icon="gtk-zoom-out" type="action"
context="{'model' : 'crm.meeting'}"
attrs="{'invisible':[('rrule_type','in', ('none', False))]}"/>
</group>
</group>
<group col="4" colspan="4" name="rrule" attrs="{'invisible': [('rrule_type','!=','custom')]}">
@ -213,7 +217,6 @@
<field name="partner_id" string="Partner" />
<field name="date" string="Meeting Date" />
<field name="duration" />
<field name="user_id" />
<field name="state"/>
</tree>
</field>
@ -320,7 +323,7 @@
</field>
</field>
</record>
<!-- Partners inherited form -->
<record id="view_meeting_partner_info_form" model="ir.ui.view">

View File

@ -2,16 +2,6 @@
<openerp>
<data noupdate="1">
<act_window
id="act_crm_opportunity_crm_meeting_new"
name="Meetings"
res_model="crm.meeting"
src_model="crm.lead"
view_mode="tree,form,calendar,"
context="{'default_duration': 4.0, 'default_opportunity_id': active_id}"
domain="[('user_id','=',uid), ('opportunity_id', '=', active_id)]"
view_type="form"/>
<act_window
id="act_crm_opportunity_crm_phonecall_new"
name="Phone calls"
@ -22,12 +12,22 @@
domain="[('user_id','=',uid),('opportunity_id', '=', active_id)]"
view_type="form"/>
<act_window
id="act_crm_opportunity_crm_meeting_new"
name="Meetings"
res_model="crm.meeting"
src_model="crm.lead"
view_mode="tree,form,calendar,"
context="{'default_duration': 4.0, 'default_opportunity_id': active_id}"
domain="[('user_id','=',uid), ('opportunity_id', '=', active_id)]"
view_type="form"/>
<record model="ir.actions.act_window" id="crm_case_category_act_oppor11">
<field name="name">Opportunities</field>
<field name="res_model">crm.lead</field>
<field name="view_mode">tree,form,graph</field>
<field name="domain">[('type','=','opportunity')]</field>
<field name="context">{'search_default_current':1}</field>
<field name="context">{'search_default_current':1, 'default_type': 'opportunity'}</field>
<field name="view_id" ref="crm_case_tree_view_oppor"/>
<field name="context">{"search_default_user_id":uid}</field>
<field name="search_view_id" ref="crm.view_crm_case_opportunities_filter"/>

View File

@ -56,7 +56,7 @@
<field name="arch" type="xml">
<form string="Opportunities">
<group colspan="4" col="7">
<field name="name" string="Opportunity"/>
<field name="name" required="1" string="Opportunity"/>
<label string="Stage:" align="1.0"/>
<group colspan="1" col="4">
<field name="stage_id" nolabel="1"
@ -217,7 +217,7 @@
<field name="name" string="Opportunity"/>
<field name="partner_id"/>
<field name="stage_id"/>
<field name="categ_id" invisible="1"/>
<field name="categ_id" invisible="1" groups="base.group_extended"/>
<button name="stage_previous" string="Previous"
states="open,pending" type="object" icon="gtk-go-back" />
<button name="stage_next" string="Next"
@ -292,7 +292,11 @@
<field name="name" string="Opportunity"/>
<field name="user_id" widget="selection">
<filter icon="terp-partner"
domain="[('user_id','=', False)]"
domain="[('user_id','=',uid)]"
help="My Opportunities" default="1"
/>
<filter icon="terp-partner"
domain="[('user_id','=', uid)]"
help="Unassigned Opportunities" />
</field>
<field name="section_id"
@ -312,8 +316,6 @@
domain="[]" context="{'group_by':'categ_id'}" />
<separator orientation="vertical" />
<filter string="Partner" icon="terp-crm" domain="[]"
context="{'group_by':'partner_id'}" />
<filter string="Salesman" icon="terp-crm"
domain="[('user_id','=',uid)]" context="{'group_by':'user_id'}" />
<separator orientation="vertical" />

View File

@ -31,10 +31,13 @@ class crm_phonecall(osv.osv, crm_case):
_name = "crm.phonecall"
_description = "Phonecall"
_order = "id desc"
_inherit = 'mailgate.thread'
_inherits = {'mailgate.thread': 'thread_id'}
_columns = {
# From crm.case
'name': fields.char('Name', size=64),
'active': fields.boolean('Active', required=False),
'thread_id': fields.many2one('mailgate.thread', 'Thread', required=False),
'section_id': fields.many2one('crm.case.section', 'Sales Team', \
select=True, help='Sales team to which Case belongs to.\
Define Responsible user and Email account for mail gateway.'),

View File

@ -10,6 +10,7 @@
view_mode="calendar,tree,form"
context="{'default_partner_id': active_id, 'default_duration': 1.0}"
domain="[('partner_id', '=', active_id)]"
groups="base.group_extended"
/>
<!-- PHONE CALLS (menu) -->

View File

@ -16,30 +16,29 @@
<field name="arch" type="xml">
<form string="Sales Team">
<group col="6" colspan="4">
<field name="name" select="1" colspan="4"/>
<field name="name" select="1" colspan="2"/>
<field name="parent_id" select="2" widget="selection"/>
<field name="code" select="1"/>
<field name="resource_calendar_id" select="2"/>
<newline/>
<field name="user_id" select="2"/>
<field name="resource_calendar_id" select="2" widget="selection"/>
<field name="active" select="2"/>
</group>
<notebook colspan="4">
<page string="Sales Team">
<group col="2" colspan="1">
<separator string="Responsible" colspan="2"/>
<field name="parent_id" select="2" widget="selection"/>
<field name="user_id" select="2"/>
</group>
<group col="2" colspan="1">
<separator string="Contact Information" colspan="2"/>
<separator string="Mailgateway" colspan="2"/>
<field name="reply_to" select="2"/>
</group>
<group col="2" colspan="1">
<separator string="Sales Team Property" colspan="2"/>
<field name="active" select="2"/>
<separator string="Configuration" colspan="2"/>
<field name="allow_unlink" select="2"/>
</group>
<separator string="Members List" colspan="4"/>
<separator string="Team Members" colspan="4"/>
<field name="member_ids" nolabel="1" colspan="4"/>
</page><page string="Notes">
<field name="note" colspan="4" nolabel="1"/>
</page>
<page string="Notes">
<field name="note" select="1" colspan="4" nolabel="1"/>
</page>
</notebook>
</form>
@ -120,7 +119,6 @@
<menuitem id="menu_crm_case_stage" name="Stages" parent="base.menu_crm_configuration" groups="base.group_extended"/>
<!-- Case Categories Form View -->
<record id="crm_case_categ-view" model="ir.ui.view">
@ -234,313 +232,6 @@
</field>
</record>
<!--Case History Tree View -->
<record id="crm_case_history_tree-view" model="ir.ui.view">
<field name="name">crm.case.history.tree</field>
<field name="model">crm.case.history</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Case History">
<field name="date"/>
<field name="name"/>
<field name="user_id"/>
<!--
<field name="som"/>
<field name="canal_id"/>
-->
</tree>
</field>
</record>
<!-- Case Calendar View -->
<record id="crm_case_calendar-view" model="ir.ui.view">
<field name="name">crm.case.calendar</field>
<field name="model">mailgate.thread</field>
<field name="type">calendar</field>
<field name="arch" type="xml">
<calendar color="user_id" date_start="create_date"
date_stop="date_deadline" day_length="12"
string="Cases">
<field name="name" />
<field name="partner_id" />
<field name="state" />
</calendar>
</field>
</record>
<!-- Case Tree View -->
<record id="crm_case_tree-view" model="ir.ui.view">
<field name="name">crm.case.tree</field>
<field name="model">mailgate.thread</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree colors="red:date_deadline&lt;current_date and state=='open';black:state in ('draft', 'cancel','done','pending')" string="Cases">
<field name="id"/>
<field name="section_id"/>
<field name="create_date"/>
<field name="date_deadline"/>
<field name="name"/>
<field name="partner_id"/>
<field name="user_id"/>
<field name="state"/>
<button name="case_close"
states="open,draft,pending" string="Close"
type="object" icon="gtk-close" />
<button name="case_open" states="draft,pending"
string="Open" type="object" icon="gtk-go-forward" />
<button name="case_cancel"
states="draft,open,pending" string="Cancel"
type="object" icon="gtk-cancel" />
<button name="case_pending" states="draft,open"
string="Pending" type="object"
icon="gtk-media-pause" />
<button name="case_escalate"
states="open,draft,pending" string="Escalate"
groups="base.group_extended"
type="object" icon="gtk-go-up" />
<button name="case_reset" states="done,cancel"
string="Reset to Draft" type="object"
icon="gtk-convert" />
</tree>
</field>
</record>
<!-- Case Form View -->
<record id="crm_case-view" model="ir.ui.view">
<field name="name">crm.case.form</field>
<field name="model">mailgate.thread</field>
<field name="type">form</field>
<field name="priority" eval="1"/>
<field name="arch" type="xml">
<form string="Cases">
<field colspan="4" name="name" select="1"/>
<field colspan="2" name="section_id" widget="selection"/>
<field name="create_date" select="1"/>
<field name="date_deadline"/>
<newline />
<notebook colspan="4">
<page string="General">
<group col="8" colspan="4">
<field colspan="4" name="partner_id"
on_change="onchange_partner_id(partner_id, email_from)"
select="1" />
<field colspan="3"
name="partner_address_id"
on_change="onchange_partner_address_id(partner_address_id, email_from)"
/>
<newline />
<field colspan="3" name="email_from"
/>
<button name="remind_partner"
states="open,pending"
string="Send Reminder" type="object"
icon="gtk-go-forward" />
<field name="user_id" select="1" />
<button name="remind_user"
states="open,pending"
string="Send Reminder" type="object"
icon="gtk-go-forward" />
</group>
<separator colspan="4" string="Description"/>
<field name="description" colspan="4" nolabel="1"/>
<separator colspan="4"/>
<group col="8" colspan="4">
<field name="state" select="1"/>
<button name="case_close"
states="open,draft,pending"
string="Close" type="object"
icon="gtk-close" />
<button name="case_open"
states="draft,pending" string="Open"
type="object" icon="gtk-go-forward" />
<button name="case_cancel"
states="draft,open,pending"
string="Cancel" type="object"
icon="gtk-cancel" />
<button name="case_pending"
states="draft,open" string="Pending"
type="object" icon="gtk-media-pause" />
<button name="case_escalate"
states="open,draft,pending"
string="Escalate" type="object"
groups="base.group_extended"
icon="gtk-go-up" />
<button name="case_reset"
states="done,cancel"
string="Reset to Draft" type="object"
icon="gtk-convert" />
</group>
</page>
<page string="History" groups="base.group_extended">
<field name="id" select="1"/>
<field name="active"/>
<separator colspan="4" string="Dates"/>
<field name="create_date"/>
<field colspan="4" name="log_ids" nolabel="1">
<form string="Actions">
<separator colspan="4" string="Action Information"/>
<field colspan="4" name="name"/>
<field name="date"/>
<field name="user_id"/>
</form>
</field>
</page>
<page string="Emails" groups="base.group_extended">
<group colspan="4">
<field colspan="4" name="email_cc" string="CC"/>
</group>
<field name="message_ids" colspan="4" nolabel="1" mode="form,tree">
<form string="Communication history">
<group col="6" colspan="4">
<field name="date"/>
<field name="email_to"/>
<field name="email_from"/>
</group>
<newline/>
<field name="description" colspan="4" nolabel="1"/>
<button colspan="4"
string="Reply to Last Email"
name="%(action_crm_send_mail)d"
context="{'mail':'reply', 'model': 'crm.case'}"
icon="gtk-undo" type="action" />
</form>
<tree string="Communication history">
<field name="description"/>
<field name="email_to"/>
<field name="date"/>
</tree>
</field>
<button colspan="4" string="Send New Email"
name="%(action_crm_send_mail)d"
context="{'mail':'new', 'model': 'crm.case'}"
icon="gtk-go-forward" type="action" />
</page>
</notebook>
</form>
</field>
</record>
<!-- Case Search View -->
<record id="view_crm_case_filter" model="ir.ui.view">
<field name="name">crm.case.select</field>
<field name="model">mailgate.thread</field>
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Search Case">
<group col='6' colspan='4'>
<field name="state" select="1">
<filter icon="gtk-new"
domain="[('state','in',('draft', 'open'))]"
help="Current Cases" />
<filter icon="gtk-yes"
domain="[('state','=','open')]" help="Open Cases" />
<filter icon="gtk-media-pause"
domain="[('state','=','pending')]"
help="Pending Cases" />
</field>
<separator orientation="vertical" />
<field name="name" select='1' />
<field name="user_id" select="1"
widget="selection" />
</group>
<field name="section_id"
default="context.get('section_id', False)" select="1"
widget="selection"/>
</search>
</field>
</record>
<record id="crm_case_categ0-act" model="ir.actions.act_window">
<field name="name">Cases</field>
<field name="res_model">mailgate.thread</field>
<field name="view_type">form</field>
<field name="view_id" ref="crm_case_tree-view"/>
<field name="context">{"search_default_user_id":uid}</field>
<field name="search_view_id" ref="view_crm_case_filter"/>
</record>
<record id="crm_case_categ0-act_open" model="ir.actions.act_window">
<field name="name">Open Cases</field>
<field name="res_model">mailgate.thread</field>
<field name="view_type">form</field>
<field name="domain">
[('state','&lt;&gt;','done'),('state','&lt;&gt;','cancel'),('state','&lt;&gt;','pending')]
</field>
<field name="search_view_id" ref="view_crm_case_filter"/>
</record>
<record id="crm_case_section_open_act" model="ir.actions.act_window">
<field name="name">Cases</field>
<field name="res_model">mailgate.thread</field>
<field name="domain">[('section_id','child_of',[active_id])]</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form,calendar</field>
</record>
<record id="ir_open_section_case" model="ir.values">
<field eval="'tree_but_open'" name="key2"/>
<field eval="'crm.case.section'" name="model"/>
<field name="name">Open Cases</field>
<field eval="'ir.actions.act_window,%d'%crm_case_section_open_act" name="value"/>
<field eval="True" name="object"/>
</record>
<!--Case History Form View -->
<record id="crm_case_history-view" model="ir.ui.view">
<field name="name">crm.case.history.form</field>
<field name="model">crm.case.history</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Cases">
<separator colspan="4" string="Case Description"/>
<field colspan="4" name="name" select="1"/>
<field name="date" select="1"/>
<field name="user_id" select="1"/>
<field name="model_id"/>
<field name="res_id"/>
<field name="som"/>
<field name="canal_id"/>
<field colspan="4" name="description"/>
</form>
</field>
</record>
<!--Case History Search View -->
<record id="crm_case_history_search" model="ir.ui.view">
<field name="name">crm.case.history.select</field>
<field name="model">crm.case.history</field>
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Search Histories">
<group col="6" colspan="2">
<field name="date" select="1"/>
<field name="user_id" select="1" widget="selection"/>
<field name="section_id"
default="context.get('section_id', False)"
select="1" widget="selection"/>
</group>
</search>
</field>
</record>
<!--Case History Action -->
<record id="crm_case_history-act" model="ir.actions.act_window">
<field name="name">Histories</field>
<field name="res_model">crm.case.history</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="crm_case_history_tree-view"/>
<field name="context">{"search_default_user_id":uid}</field>
<field name="search_view_id" ref="crm_case_history_search"/>
</record>
<!-- Segmentation line Tree View -->

View File

@ -6,12 +6,8 @@
"access_crm_meeting","crm.meeting","model_crm_meeting","crm.group_crm_manager",1,1,1,1
"access_crm_lead","crm.lead","model_crm_lead","crm.group_crm_manager",1,1,1,1
"access_crm_phonecall","crm.phonecall","model_crm_phonecall","crm.group_crm_manager",1,1,1,1
"access_crm_case_log","crm.case.log","model_crm_case_log","crm.group_crm_user",1,1,1,1
"access_crm_case_history","crm.case.history","model_crm_case_history","crm.group_crm_user",1,1,1,1
"o","crm.case.section.manager","model_crm_case_section","crm.group_crm_manager",1,1,1,1
"access_crm_case_section_manager","crm.case.section.manager","model_crm_case_section","crm.group_crm_manager",1,1,1,1
"access_crm_case_categ_manager","crm.case.categ.manager","model_crm_case_categ","crm.group_crm_manager",1,1,1,1
"access_crm_case_log_manager","crm.case.log manager","model_crm_case_log","crm.group_crm_manager",1,1,1,1
"access_crm_case_history_manager","crm.case.history manager","model_crm_case_history","crm.group_crm_manager",1,1,1,1
"access_crm_case_stage","crm.case.stage","model_crm_case_stage","crm.group_crm_user",1,0,0,0
"access_crm_case_stage_manager","crm.case.stage","model_crm_case_stage","crm.group_crm_manager",1,1,1,1
"access_crm_case_resource_type_user","crm_case_resource_type user","model_crm_case_resource_type","crm.group_crm_user",1,0,0,0

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
6 access_crm_meeting crm.meeting model_crm_meeting crm.group_crm_manager 1 1 1 1
7 access_crm_lead crm.lead model_crm_lead crm.group_crm_manager 1 1 1 1
8 access_crm_phonecall crm.phonecall model_crm_phonecall crm.group_crm_manager 1 1 1 1
9 access_crm_case_log access_crm_case_section_manager crm.case.log crm.case.section.manager model_crm_case_log model_crm_case_section crm.group_crm_user crm.group_crm_manager 1 1 1 1
access_crm_case_history crm.case.history model_crm_case_history crm.group_crm_user 1 1 1 1
o crm.case.section.manager model_crm_case_section crm.group_crm_manager 1 1 1 1
10 access_crm_case_categ_manager crm.case.categ.manager model_crm_case_categ crm.group_crm_manager 1 1 1 1
access_crm_case_log_manager crm.case.log manager model_crm_case_log crm.group_crm_manager 1 1 1 1
access_crm_case_history_manager crm.case.history manager model_crm_case_history crm.group_crm_manager 1 1 1 1
11 access_crm_case_stage crm.case.stage model_crm_case_stage crm.group_crm_user 1 0 0 0
12 access_crm_case_stage_manager crm.case.stage model_crm_case_stage crm.group_crm_manager 1 1 1 1
13 access_crm_case_resource_type_user crm_case_resource_type user model_crm_case_resource_type crm.group_crm_user 1 0 0 0

View File

@ -16,7 +16,6 @@
login: user_crm
name: user_crm
password: user_crm
- |
I start by creating a new lead "New Customer" and I provide an address to this
@ -25,7 +24,7 @@
!record {model: crm.lead, id: crm_lead_newcustomer0}:
email_from: info@mycustomer.com
name: New Customer
partner_name: Sandip zala
partner_name: Capegemini
phone: (855) 924-4364
mobile: (333) 715-1450
section_id: crm.section_sales_department
@ -41,6 +40,11 @@
-
!python {model: crm.lead}: |
self.case_open(cr, uid, [ref("crm_lead_newcustomer0")])
- |
I check that lead is now in 'open' state.
-
!assert {model: crm.lead, id: crm_lead_newcustomer0, string: Lead in open state}:
- state == "open"
- |
As the lead seems to be a real business opportunity, I will convert it to a
@ -49,8 +53,8 @@
-
!python {model: crm.lead}: |
lead = self.browse(cr, uid, ref('crm_lead_newcustomer0'))
if not lead.partner_id:
self.convert_opportunity(cr, uid, [ref("crm_lead_newcustomer0")], {'active_ids': [ref("crm_lead_newcustomer0")]})
action = self.convert_opportunity(cr, uid, [ref("crm_lead_newcustomer0")], {'active_ids': [ref("crm_lead_newcustomer0")]})
assert action['res_model'] == 'crm.lead2opportunity.partner'
-
|
Now, select "create a new partner" option in this wizard.
@ -66,7 +70,7 @@
Now, I give value to this wizard field.
-
!record {model: crm.lead2opportunity, id: crm_lead2opportunity_stonage_0}:
name: Sandip zala
name: Capegemini
planned_revenue: 0.00
probability: 0.00
-
@ -79,8 +83,8 @@
I can check that a lead and a business opportunity is now assigned to this
lead.
-
# !python {model: crm.lead, id: crm_lead_newcustomer0}:
# - opportunity_id.id != False
# !python {model: crm.lead, id: crm_lead_newcustomer0}:
# - opportunity_id == False
- |
I check that the partner associated to this lead as the same country, phone number
@ -109,4 +113,4 @@
- |
I Reply to last Email to lead with some document attached.and check that communication history generated or not.

View File

@ -4,44 +4,55 @@
!record {model: crm.phonecall, id: crm_phonecall_interviewcall0}:
date: '2010-04-21 18:59:00'
name: Interview call
partner_address_id: base.res_partner_address_1
partner_id: base.res_partner_9
partner_mobile: (+32)2 211 34 83
section_id: crm.section_sales_department
- |
Now , I select partner by click on "Create a Partner" button.
-
!record {model: crm.phonecall2partner, id: crm_phonecall2partner_1}:
action: exist
partner_id: base.res_partner_9
-
Now, click on "Continue" button of this wizard.
-
!python {model: crm.phonecall2partner}: |
self.make_partner(cr, uid, [ref("crm_phonecall2partner_1")], {"active_ids": [ref("crm_phonecall_interviewcall0")]})
- |
As the success of phonecall seems to be a real business opportunity, I will convert
it to opportunity by clicking on the "Convert to Opportunity" button.
-
!record {model: crm.phonecall2opportunity, id: crm_phonecall2opportunity_interviewcall0}:
name: Interview call
partner_id: base.res_partner_9
planned_revenue: 0.0
probability: 0.0
-
Now, I click on "Convert" button of this wizard.
-
# !python {model: crm.phonecall2opportunity}: |
# self.action_apply(cr, uid, [1], {'active_id': ref('crm_phonecall_interviewcall0')})
!python {model: crm.phonecall2opportunity}: |
self.action_apply(cr, uid, [ref("crm_phonecall2opportunity_interviewcall0")], {"active_id": ref("crm_phonecall_interviewcall0")})
-
# This is not working, find a way to do that in YAML
- |
I can see that a business opportunity is now assigned to this phonecall
- |
I check that the partner associated to this as the same country, phone number
and name than the phonecall.
- |
In order to avoid the duplication of similar partner, OpenERP should be able to
detect if the partner exists or if it should be created from the phonecall during the
conversion.
- |
In order to test this, I log as the user "user_crm2"
- |
Then, I create the same phonecall than the preceeding one but I change the name
of the phonecall. But this customer keeps the same email.
- |
This time OpenERP should detect that this customer already exists in the
partner base and I check that in the wizard, proposes me to link to this existing
partner instead of creating another one.
- |
I confirm the conversion wizard.
-
!assert {model: crm.phonecall, id: crm_phonecall_interviewcall0}:
- opportunity_id == True
- |
And I check that the phonecall and the newly created business opportunity is linked
to the partner
to same partner
-
!python {model: crm.phonecall}: |
xid= ref('crm_phonecall_interviewcall0')
obj_phonecall = self.browse(cr, uid, xid)
ids = self.pool.get('crm.lead').search(cr, uid, [('name', '=', obj_phonecall.opportunity_id.name)])
obj_opp = self.pool.get('crm.lead').browse(cr, uid, ids)[0]
assert obj_phonecall.partner_id == obj_opp.partner_id
- |
I schedule Meeting on this current phonecall by clicking on "schedule
Meeting"

View File

@ -176,7 +176,6 @@ class crm_lead_forward_to_partner(osv.osv_memory):
this = self.browse(cr, uid, ids[0], context=context)
hist_obj = self.pool.get('crm.case.history')
smtp_pool = self.pool.get('email.smtpclient')
case_pool = self.pool.get(model)
case = case_pool.browse(cr, uid, res_id, context=context)

View File

@ -57,7 +57,6 @@ class crm_lead2opportunity(osv.osv_memory):
lead_obj = self.pool.get('crm.lead')
data_obj = self.pool.get('ir.model.data')
history_obj = self.pool.get('crm.case.history')
model_obj = self.pool.get('ir.model')
# Get Opportunity views

View File

@ -42,12 +42,15 @@
</record>
<!-- Lead to Partner wizard -->
<act_window id="action_crm_lead2partner"
key2="client_action_multi" name="Create a Partner"
res_model="crm.lead2partner" src_model="crm.lead"
view_id="view_crm_lead2partner_create"
view_mode="form" target="new" view_type="form" />
<record id="action_crm_lead2partner" model="ir.actions.act_window">
<field name="name">Create a Partner</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">crm.lead2partner</field>
<field name="view_type">form</field>
<field name="view_id" ref="view_crm_lead2partner_create"/>
<field name="target">new</field>
</record>
</data>
</openerp>

View File

@ -39,7 +39,8 @@
key2="client_action_multi" name="Create Opportunity"
res_model="crm.partner2opportunity" src_model="res.partner"
view_id="view_crm_lead2partner_create"
view_mode="form" target="new" view_type="form" />
view_mode="form" target="new" view_type="form"
groups="base.group_extended"/>
</data>
</openerp>

View File

@ -43,11 +43,15 @@
<!-- Phonecall to Partner wizard -->
<act_window id="action_crm_phonecall2partner"
key2="client_action_multi" name="Create a Partner"
res_model="crm.phonecall2partner" src_model="crm.phonecall"
view_id="view_crm_phonecall2partner_create"
view_mode="form" target="new" view_type="form" />
<record id="action_crm_phonecall2partner" model="ir.actions.act_window">
<field name="name">Create a Partner</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">crm.phonecall2partner</field>
<field name="view_type">form</field>
<field name="view_id" ref="view_crm_phonecall2partner_create"/>
<field name="target">new</field>
</record>
</data>
</openerp>

View File

@ -98,7 +98,9 @@ class crm_send_new_email(osv.osv_memory):
message_id = hist.message_id
model = hist.model_id.model
model_pool = self.pool.get(model)
case = model_pool.browse(cr, uid, hist.res_id)
res_ids = model_pool.search(cr, uid, [('thread_id','=', hist.thread_id.id)])
res_id = res_ids and res_ids[0] or False
case = model_pool.browse(cr, uid, res_id)
emails = [obj.email_to] + (obj.email_cc or '').split(',')
emails = filter(None, emails)
body = obj.text
@ -197,7 +199,9 @@ class crm_send_new_email(osv.osv_memory):
return {}
model_pool = self.pool.get(model)
case = model_pool.browse(cr, uid, hist.res_id)
res_ids = model_pool.search(cr, uid, [('thread_id','=', hist.thread_id.id)])
res_id = res_ids and res_ids[0] or False
case = model_pool.browse(cr, uid, res_id)
if 'email_to' in fields:
res.update({'email_to': case.email_from or hist.email_from or False})
if 'email_from' in fields:

View File

@ -29,10 +29,15 @@ class crm_claim(osv.osv, crm.crm_case):
_name = "crm.claim"
_description = "Claim Cases"
_order = "id desc"
_inherit = 'mailgate.thread'
_inherits = {'mailgate.thread': 'thread_id'}
_columns = {
'thread_id': fields.many2one('mailgate.thread', 'Thread', required=False),
'id': fields.integer('ID', readonly=True),
'name': fields.char('Name', size=128, required=True),
'active': fields.boolean('Active', required=False),
'date_action_last': fields.datetime('Last Action', readonly=1),
'date_action_next': fields.datetime('Next Action', readonly=1),
'description': fields.text('Description'),
'create_date': fields.datetime('Creation Date' , readonly=True),
'write_date': fields.datetime('Update Date' , readonly=True),

View File

@ -28,11 +28,15 @@ class crm_fundraising(osv.osv, crm.crm_case):
_name = "crm.fundraising"
_description = "Fund Raising Cases"
_order = "id desc"
_inherit ='mailgate.thread'
_inherits = {'mailgate.thread': 'thread_id'}
_columns = {
'thread_id': fields.many2one('mailgate.thread', 'Thread', required=False),
'id': fields.integer('ID'),
'name': fields.char('Name', size=128, required=True),
'name': fields.char('Name', size=128, required=True),
'active': fields.boolean('Active', required=False),
'date_action_last': fields.datetime('Last Action', readonly=1),
'date_action_next': fields.datetime('Next Action', readonly=1),
'description': fields.text('Description'),
'create_date': fields.datetime('Creation Date' , readonly=True),
'write_date': fields.datetime('Update Date' , readonly=True),

View File

@ -28,11 +28,15 @@ class crm_helpdesk(osv.osv, crm.crm_case):
_name = "crm.helpdesk"
_description = "Helpdesk Cases"
_order = "id desc"
_inherit = 'mailgate.thread'
_inherits = {'mailgate.thread': 'thread_id'}
_columns = {
'thread_id': fields.many2one('mailgate.thread', 'Thread', required=False),
'id': fields.integer('ID', readonly=True),
'name': fields.char('Name', size=128, required=True),
'active': fields.boolean('Active', required=False),
'date_action_last': fields.datetime('Last Action', readonly=1),
'date_action_next': fields.datetime('Next Action', readonly=1),
'description': fields.text('Description'),
'create_date': fields.datetime('Creation Date' , readonly=True),
'write_date': fields.datetime('Update Date' , readonly=True),

View File

@ -23,32 +23,32 @@
<record model="document.directory.ics.fields" id="dir_field1">
<field name="name">dtstart</field>
<field name="field_id" ref="crm.field_crm_case_create_date"/>
<field name="field_id" ref="crm.field_crm_meeting_create_date"/>
<field name="content_id" ref="dir_content_calendar"/>
</record>
<record model="document.directory.ics.fields" id="dir_field6">
<field name="name">dtend</field>
<field name="field_id" ref="crm.field_crm_case_date_deadline"/>
<field name="field_id" ref="crm.field_crm_meeting_date_deadline"/>
<field name="content_id" ref="dir_content_calendar"/>
</record>
<record model="document.directory.ics.fields" id="dir_field2">
<field name="name">summary</field>
<field name="field_id" ref="crm.field_crm_case_name"/>
<field name="field_id" ref="crm.field_crm_meeting_name"/>
<field name="content_id" ref="dir_content_calendar"/>
</record>
<record model="document.directory.ics.fields" id="dir_field3">
<field name="name">uid</field>
<field name="field_id" ref="field_crm_case_code"/>
<field name="field_id" ref="field_crm_meeting_code"/>
<field name="content_id" ref="dir_content_calendar"/>
</record>
<record model="document.directory.ics.fields" id="dir_field4">
<field name="name">description</field>
<field name="field_id" ref="crm.field_crm_case_description"/>
<field name="field_id" ref="crm.field_crm_meeting_description"/>
<field name="content_id" ref="dir_content_calendar"/>
</record>
<record model="document.directory.ics.fields" id="dir_field5">
<field name="name">url</field>
<field name="field_id" ref="crm.field_crm_case_email_from"/>
<field name="field_id" ref="crm.field_crm_meeting_email_from"/>
<field name="content_id" ref="dir_content_calendar"/>
</record>

View File

@ -45,7 +45,7 @@
<field name="type">form</field>
<field name="inherit_id" ref="crm.crm_case_form_view_meet"/>
<field name="arch" type="xml">
<field name="priority" position="after">
<field name="show_as" position="after">
<field name="code"/>
</field>
</field>

View File

@ -27,23 +27,12 @@ import tools
from tools.translate import _
from crm import crm
class crm_case_log(osv.osv):
_inherit = 'crm.case.log'
_description = 'crm.case.log'
def create(self, cr, uid, vals, *args, **kwargs):
if not 'name' in vals:
vals['name']='Historize'
return super(osv.osv,self).create(cr, uid, vals, *args, **kwargs)
_defaults = {
'user_id': lambda self,cr,uid,context: uid,
}
crm_case_log()
class event_type(osv.osv):
_name = 'event.type'
_description= 'Event type'
_columns = {
'name': fields.char('Event type', size=64, required=True),
'name': fields.char('Event type', size=64, required=True),
}
event_type()
@ -54,58 +43,53 @@ class event(osv.osv):
_order = 'date_begin'
def copy(self, cr, uid, id, default=None, context=None):
return super(event, self).copy(cr, uid,id, default={'code': self.pool.get('ir.sequence').get(cr, uid, 'event.event'),'state':'draft'})
return super(event, self).copy(cr, uid, id, default={'code': self.pool.get('ir.sequence').get(cr, uid, 'event.event'), 'state': 'draft'})
def button_draft(self, cr, uid, ids, context={}):
return self.write(cr, uid, ids, {'state':'draft'})
return self.write(cr, uid, ids, {'state': 'draft'})
def button_cancel(self, cr, uid, ids, context={}):
return self.write(cr, uid, ids, {'state':'cancel'})
return self.write(cr, uid, ids, {'state': 'cancel'})
def button_done(self, cr, uid, ids, context={}):
return self.write(cr, uid, ids, {'state':'done'})
return self.write(cr, uid, ids, {'state': 'done'})
def button_confirm(self, cr, uid, ids, context={}):
for eve in self.browse(cr, uid, ids):
if eve.mail_auto_confirm:
#send reminder that will confirm the event for all the people that were already confirmed
reg_ids = self.pool.get('event.registration').search(cr, uid, [('event_id','=',eve.id),('state','not in',['draft','cancel'])])
reg_ids = self.pool.get('event.registration').search(cr, uid, [('event_id', '=', eve.id), ('state', 'not in', ['draft', 'cancel'])])
if reg_ids:
self.pool.get('event.registration').mail_user_confirm(cr, uid, reg_ids)
return self.write(cr, uid, ids, {'state':'confirm'})
return self.write(cr, uid, ids, {'state': 'confirm'})
def _get_register(self, cr, uid, ids, name, args, context=None):
res={}
for event in self.browse(cr, uid, ids, context):
query = """select sum(nb_register) from crm_case c left join crm_case_section s on (c.section_id=s.id) right join event_event e on (e.section_id=s.id) right join event_registration r on (r.case_id=c.id) where e.section_id = %s and c.state in ('open','done')"""
cr.execute(query,(event.section_id.id,))
res[event.id] = {}
state = 'draft'
if name[0] == 'register_current':
state = 'open'
query = """SELECT sum(r.nb_register)
from event_registration r
where state=%s and event_id=%s"""
cr.execute(query, (state, event.id, ))
res2 = cr.fetchone()
if res2 and res2[0]:
res[event.id] = res2[0]
res[event.id][name[0]] = res2[0]
else:
res[event.id] = 0
res[event.id][name[0]] = 0
return res
def _get_prospect(self, cr, uid, ids, name, args, context=None):
res={}
for event in self.browse(cr, uid, ids, context):
query = """select sum(nb_register) from crm_case c left join crm_case_section s on (c.section_id=s.id) right join event_event e on (e.section_id=s.id) right join event_registration r on (r.case_id=c.id) where e.section_id = %s and c.state = 'draft'"""
cr.execute(query,(event.section_id.id,))
res2 = cr.fetchone()
if res2 and res2[0]:
res[event.id] = res2[0]
else:
res[event.id] = 0
return res
def write(self, cr, uid, ids,vals, *args, **kwargs):
res = super(event,self).write(cr, uid, ids,vals, *args, **kwargs)
def write(self, cr, uid, ids, vals, *args, **kwargs):
res = super(event, self).write(cr, uid, ids, vals, *args, **kwargs)
if 'date_begin' in vals and vals['date_begin']:
for eve in self.browse(cr, uid, ids):
#change the deadlines of the registration linked to this event
reg_ids = self.pool.get('event.registration').search(cr, uid, [('event_id','=',eve.id)])
reg_ids = self.pool.get('event.registration').search(cr, uid, [('event_id', '=', eve.id)])
if reg_ids:
self.pool.get('event.registration').write(cr, uid, reg_ids, {'date_deadline':vals['date_begin']})
self.pool.get('event.registration').write(cr, uid, reg_ids, {'date_deadline': vals['date_begin']})
#change the description of the registration linked to this event
if 'mail_auto_confirm' in vals:
@ -117,36 +101,36 @@ class event(osv.osv):
vals['mail_confirm']=False
if 'mail_confirm' in vals:
for eve in self.browse(cr, uid, ids):
reg_ids = self.pool.get('event.registration').search(cr, uid, [('event_id','=',eve.id)])
reg_ids = self.pool.get('event.registration').search(cr, uid, [('event_id', '=', eve.id)])
if reg_ids:
self.pool.get('event.registration').write(cr, uid, reg_ids, {'description':vals['mail_confirm']})
self.pool.get('event.registration').write(cr, uid, reg_ids, {'description': vals['mail_confirm']})
return res
_columns = {
'type': fields.many2one('event.type', 'Type'),
'section_id': fields.many2one('crm.case.section', 'Case section', required=True),
'register_max': fields.integer('Maximum Registrations'),
'register_min': fields.integer('Minimum Registrations'),
'register_current': fields.function(_get_register, method=True, string='Confirmed Registrations'),
'register_prospect': fields.function(_get_prospect, method=True, string='Unconfirmed Registrations'),
'date_begin': fields.datetime('Beginning date', required=True),
'date_end': fields.datetime('Ending date', required=True),
'state': fields.selection([('draft','Draft'),('confirm','Confirmed'),('done','Done'),('cancel','Cancelled')], 'State', readonly=True, required=True,
'type': fields.many2one('event.type', 'Type'),
'section_id': fields.many2one('crm.case.section', 'Case section', required=True),
'register_max': fields.integer('Maximum Registrations'),
'register_min': fields.integer('Minimum Registrations'),
'register_current': fields.function(_get_register, method=True, string='Confirmed Registrations', multi='register_current'),
'register_prospect': fields.function(_get_register, method=True, string='Unconfirmed Registrations', multi='register_prospect'),
'date_begin': fields.datetime('Beginning date', required=True),
'date_end': fields.datetime('Ending date', required=True),
'state': fields.selection([('draft', 'Draft'), ('confirm', 'Confirmed'), ('done', 'Done'), ('cancel', 'Cancelled')], 'State', readonly=True, required=True,
help='If event is created, the state is \'Draft\'.\n If event is confirmed for the particular dates the state is set to \'Confirmed\'.\
\nIf the event is over, the state is set to \'Done\'.\n If event is cancelled the state is set to \'Cancelled\'.'),
'mail_auto_registr':fields.boolean('Mail Auto Register',help='Check this box if you want to use the automatic mailing for new registration'),
'mail_auto_confirm':fields.boolean('Mail Auto Confirm',help='Check this box if you want ot use the automatic confirmation emailing or the reminder'),
'mail_registr':fields.text('Registration Email',help='This email will be sent when someone subscribes to the event.'),
'mail_confirm': fields.text('Confirmation Email', help="This email will be sent when the event gets confimed or when someone subscribes to a confirmed event. This is also the email sent to remind someone about the event."),
'product_id':fields.many2one('product.product','Product', required=True),
\nIf the event is over, the state is set to \'Done\'.\n If event is cancelled the state is set to \'Cancelled\'.'),
'mail_auto_registr': fields.boolean('Mail Auto Register', help='Check this box if you want to use the automatic mailing for new registration'),
'mail_auto_confirm': fields.boolean('Mail Auto Confirm', help='Check this box if you want ot use the automatic confirmation emailing or the reminder'),
'mail_registr': fields.text('Registration Email', help='This email will be sent when someone subscribes to the event.'),
'mail_confirm': fields.text('Confirmation Email', help="This email will be sent when the event gets confimed or when someone subscribes to a confirmed event. This is also the email sent to remind someone about the event."),
'product_id': fields.many2one('product.product', 'Product', required=True),
}
_defaults = {
'state': lambda *args: 'draft',
'code': lambda obj, cr, uid, context: obj.pool.get('ir.sequence').get(cr, uid, 'event.event'),
'user_id': lambda self,cr,uid,ctx: uid,
'state': lambda *args: 'draft',
'code': lambda obj, cr, uid, context: obj.pool.get('ir.sequence').get(cr, uid, 'event.event'),
'user_id': lambda self, cr, uid, ctx: uid,
}
event()
class event_registration(osv.osv):
@ -156,48 +140,45 @@ class event_registration(osv.osv):
current_registration = self.browse(cr, uid, [ids[0]])[0]
total_confirmed = current_registration.event_id.register_current + current_registration.nb_register
if total_confirmed <= current_registration.event_id.register_max or current_registration.event_id.register_max == 0:
self.write(cr, uid, [ids[0]], {'state':'open'}, context=context)
self.write(cr, uid, [ids[0]], {'state': 'open'}, context=context)
self._history(cr, uid, [ids[0]], 'Open', history=True)
self.mail_user(cr, uid, [ids[0]])
return True
else:
model_data_ids = mod_obj.search(cr,uid,[('model','=','ir.ui.view'),('name','=','view_event_confirm_registration')], context=context)
model_data_ids = mod_obj.search(cr, uid, [('model', '=', 'ir.ui.view'), ('name', '=', 'view_event_confirm_registration')], context=context)
resource_id = mod_obj.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id']
context.update({'reg_id': ids[0]})
return {
'name': _('Confirm Registration'),
'context': context,
'view_type': 'form',
'view_mode': 'tree,form',
'res_model': 'event.confirm.registration',
'views': [(resource_id,'form')],
'type': 'ir.actions.act_window',
'target': 'new',
'name': _('Confirm Registration'),
'context': context,
'view_type': 'form',
'view_mode': 'tree,form',
'res_model': 'event.confirm.registration',
'views': [(resource_id, 'form')],
'type': 'ir.actions.act_window',
'target': 'new',
'nodestroy': True
}
def _history(self, cr, uid,ids,keyword, history=False, email=False, context={}):
def _history(self, cr, uid, ids, keyword, history=False, email=False, context={}):
for case in self.browse(cr, uid, ids):
if not case.case_id:
return True
data = {
'name': keyword,
'som': case.som.id,
'canal_id': case.canal_id.id,
'user_id': uid,
'case_id': case.case_id.id
'name': keyword,
'som': case.som.id,
'canal_id': case.canal_id.id,
'user_id': uid,
}
obj = self.pool.get('crm.case.log')
obj.create(cr, uid, data, context)
obj = self.pool.get('mailgate.message')
obj.create(cr, uid, data, context=context)
return True
def button_reg_close(self, cr, uid, ids, *args):
self.write(cr, uid, ids, {'state':'done',})
self.write(cr, uid, ids, {'state': 'done', })
self._history(cr, uid, ids, 'Done', history=True)
return True
def button_reg_cancel(self, cr, uid, ids, *args):
self.write(cr, uid, ids, {'state':'cancel',})
self.write(cr, uid, ids, {'state': 'cancel', })
self._history(cr, uid, ids, 'Cancel', history=True)
return True
@ -207,7 +188,7 @@ class event_registration(osv.osv):
args[0]['date_deadline']= event.date_begin
args[0]['description']= event.mail_confirm
res = super(event_registration, self).create(cr, uid, *args, **argv)
self._history(cr, uid,[res], 'Created', history=True)
self._history(cr, uid, [res], 'Created', history=True)
return res
def write(self, cr, uid, *args, **argv):
@ -228,7 +209,7 @@ class event_registration(osv.osv):
if reg_id.email_cc:
dest += [reg_id.email_cc]
if dest and src:
tools.email_send(src, dest,'Auto Confirmation: '+'['+str(reg_id.id)+']'+' '+reg_id.name, reg_id.event_id.mail_confirm, openobject_id = str(reg_id.case_id.id))
tools.email_send(src, dest, 'Auto Confirmation: '+'['+str(reg_id.id)+']'+' '+reg_id.name, reg_id.event_id.mail_confirm, openobject_id = str(reg_id.id))
if not src:
raise osv.except_osv(_('Error!'), _('You must define a reply-to address in order to mail the participant. You can do this in the Mailing tab of your event. Note that this is also the place where you can configure your event to not send emails automaticly while registering'))
return False
@ -244,49 +225,50 @@ class event_registration(osv.osv):
dest += [reg_id.email_cc]
if reg_id.event_id.mail_auto_confirm or reg_id.event_id.mail_auto_registr:
if dest and src:
if reg_id.event_id.state in ['draft', 'fixed', 'open','confirm','running'] and reg_id.event_id.mail_auto_registr:
tools.email_send(src, dest,'Auto Registration: '+'['+str(reg_id.id)+']'+' '+reg_id.name, reg_id.event_id.mail_registr, openobject_id = str(reg_id.case_id.id))
if (reg_id.event_id.state in ['confirm','running']) and reg_id.event_id.mail_auto_confirm:
tools.email_send(src, dest,'Auto Confirmation: '+'['+str(reg_id.id)+']'+' '+reg_id.name, reg_id.event_id.mail_confirm, openobject_id = str(reg_id.case_id.id))
if reg_id.event_id.state in ['draft', 'fixed', 'open', 'confirm', 'running'] and reg_id.event_id.mail_auto_registr:
tools.email_send(src, dest, 'Auto Registration: '+'['+str(reg_id.id)+']'+' '+reg_id.name, reg_id.event_id.mail_registr, openobject_id = str(reg_id.id))
if (reg_id.event_id.state in ['confirm', 'running']) and reg_id.event_id.mail_auto_confirm:
tools.email_send(src, dest, 'Auto Confirmation: '+'['+str(reg_id.id)+']'+' '+reg_id.name, reg_id.event_id.mail_confirm, openobject_id = str(reg_id.id))
if not src:
raise osv.except_osv(_('Error!'), _('You must define a reply-to address in order to mail the participant. You can do this in the Mailing tab of your event. Note that this is also the place where you can configure your event to not send emails automaticly while registering'))
return False
def _create_invoice_lines(self, cr, uid, ids, vals):
return self.pool.get('account.invoice.line').create(cr, uid,vals )
return self.pool.get('account.invoice.line').create(cr, uid, vals)
_name= 'event.registration'
_description = 'Event Registration'
_inherits = {'crm.case': 'case_id'}
_inherit = 'crm.meeting'
_columns = {
'case_id':fields.many2one('crm.case','Case'),
'nb_register': fields.integer('Number of Registration', readonly=True, states={'draft':[('readonly',False)]}),
'event_id':fields.many2one('event.event', 'Event Related', required=True),
"partner_invoice_id":fields.many2one('res.partner', 'Partner Invoiced'),
"contact_id":fields.many2one('res.partner.contact', 'Partner Contact'), #TODO: filter only the contacts that have a function into the selected partner_id
"unit_price": fields.float('Unit Price'),
"badge_title":fields.char('Badge Title',size=128),
"badge_name":fields.char('Badge Name',size=128),
"badge_partner":fields.char('Badge Partner',size=128),
"invoice_label":fields.char("Label Invoice",size=128,required=True),
"tobe_invoiced":fields.boolean("To be Invoiced"),
"invoice_id":fields.many2one("account.invoice","Invoice"),
'date_closed': fields.datetime('Closed', readonly=True),
'ref' : fields.reference('Reference', selection=crm._links_get, size=128),
'ref2' : fields.reference('Reference 2', selection=crm._links_get, size=128),
'categ_id': fields.many2one('crm.case.categ','Category', domain="[('section_id','=',section_id)]"),
'canal_id': fields.many2one('res.partner.canal', 'Channel',help="The channels represent the different communication modes available with the customer." \
" With each commercial opportunity, you can indicate the canall which is this opportunity source."),
'email_cc': fields.text('Watchers Emails', size=252 , help="These \
people will receive a copy of the future communication between partner \
and users by email"),
'nb_register': fields.integer('Number of Registration', readonly=True, states={'draft': [('readonly', False)]}),
'event_id': fields.many2one('event.event', 'Event Related', required=True),
"partner_invoice_id": fields.many2one('res.partner', 'Partner Invoiced'),
"contact_id": fields.many2one('res.partner.contact', 'Partner Contact'), #TODO: filter only the contacts that have a function into the selected partner_id
"unit_price": fields.float('Unit Price'),
"badge_title": fields.char('Badge Title', size=128),
"badge_name": fields.char('Badge Name', size=128),
"badge_partner": fields.char('Badge Partner', size=128),
"invoice_label": fields.char("Label Invoice", size=128, required=True),
"tobe_invoiced": fields.boolean("To be Invoiced"),
"invoice_id": fields.many2one("account.invoice", "Invoice"),
'date_closed': fields.datetime('Closed', readonly=True),
'ref': fields.reference('Reference', selection=crm._links_get, size=128),
'ref2': fields.reference('Reference 2', selection=crm._links_get, size=128),
'canal_id': fields.many2one('res.partner.canal', 'Channel', help="The channels represent the different communication modes available with the customer." \
" With each commercial opportunity, you can indicate the canall which is this opportunity source."),
'som': fields.many2one('res.partner.som', 'State of Mind', help="The minds states allow to define a value scale which represents" \
"the partner mentality in relation to our services.The scale has" \
"to be created with a factor for each level from 0 (Very dissatisfied) to 10 (Extremely satisfied)."),
"to be created with a factor for each level from 0 (Very dissatisfied) to 10 (Extremely satisfied)."),
}
_defaults = {
'nb_register': lambda *a: 1,
'tobe_invoiced' : lambda *a: True,
'name': lambda *a: 'Registration',
'state': lambda *b: 'draft'
'nb_register': lambda *a: 1,
'tobe_invoiced': lambda *a: True,
'name': lambda *a: 'Registration',
}
def onchange_badge_name(self, cr, uid, ids, badge_name):
@ -294,7 +276,7 @@ class event_registration(osv.osv):
if not badge_name:
return data
data['name'] = 'Registration: ' + badge_name
return {'value':data}
return {'value': data}
def onchange_contact_id(self, cr, uid, ids, contact, partner):
data ={}
@ -304,109 +286,76 @@ class event_registration(osv.osv):
data['badge_name'] = contact_id.name
data['badge_title'] = contact_id.title
if partner:
partner_addresses = self.pool.get('res.partner.address').search(cr, uid, [('partner_id','=',partner)])
job_ids = self.pool.get('res.partner.job').search(cr, uid, [('contact_id','=',contact),('address_id','in',partner_addresses)])
partner_addresses = self.pool.get('res.partner.address').search(cr, uid, [('partner_id', '=', partner)])
job_ids = self.pool.get('res.partner.job').search(cr, uid, [('contact_id', '=', contact), ('address_id', 'in', partner_addresses)])
if job_ids:
data['email_from'] = self.pool.get('res.partner.job').browse(cr, uid, job_ids[0]).email
d = self.onchange_badge_name(cr, uid, ids,data['badge_name'])
d = self.onchange_badge_name(cr, uid, ids, data['badge_name'])
data.update(d['value'])
return {'value':data}
return {'value': data}
def onchange_event(self, cr, uid, ids, event_id, partner_invoice_id):
context={}
if not event_id:
return {'value':{'unit_price' : False ,'invoice_label' : False }}
data_event = self.pool.get('event.event').browse(cr,uid,event_id)
return {'value': {'unit_price': False , 'invoice_label': False }}
data_event = self.pool.get('event.event').browse(cr, uid, event_id)
if data_event.product_id:
if not partner_invoice_id:
unit_price=self.pool.get('product.product').price_get(cr, uid, [data_event.product_id.id],context=context)[data_event.product_id.id]
return {'value':{'unit_price' : unit_price , 'invoice_label' : data_event.product_id.name}}
data_partner = self.pool.get('res.partner').browse(cr,uid,partner_invoice_id)
context.update({'partner_id':data_partner})
unit_price = self.pool.get('product.product')._product_price(cr, uid, [data_event.product_id.id], False, False, {'pricelist':data_partner.property_product_pricelist.id})[data_event.product_id.id]
return {'value':{'unit_price' :unit_price , 'invoice_label' : data_event.product_id.name}}
return {'value':{'unit_price' : False,'invoice_label' : False}}
unit_price=self.pool.get('product.product').price_get(cr, uid, [data_event.product_id.id], context=context)[data_event.product_id.id]
return {'value': {'unit_price': unit_price , 'invoice_label': data_event.product_id.name}}
data_partner = self.pool.get('res.partner').browse(cr, uid, partner_invoice_id)
context.update({'partner_id': data_partner})
unit_price = self.pool.get('product.product')._product_price(cr, uid, [data_event.product_id.id], False, False, {'pricelist': data_partner.property_product_pricelist.id})[data_event.product_id.id]
return {'value': {'unit_price': unit_price , 'invoice_label': data_event.product_id.name}}
return {'value': {'unit_price': False, 'invoice_label': False}}
def onchange_partner_id(self, cr, uid, ids, part, event_id, email=False):
data={}
data['badge_partner'] = data['contact_id'] = data['partner_invoice_id'] = data['email_from'] = data['badge_title'] = data['badge_name'] = False
if not part:
return {'value':data}
return {'value': data}
data['partner_invoice_id']=part
# this calls onchange_partner_invoice_id
d = self.onchange_partner_invoice_id(cr, uid, ids, event_id,part)
d = self.onchange_partner_invoice_id(cr, uid, ids, event_id, part)
# this updates the dictionary
data.update(d['value'])
addr = self.pool.get('res.partner').address_get(cr, uid, [part])
if addr:
if addr.has_key('default'):
job_ids = self.pool.get('res.partner.job').search(cr, uid, [('address_id','=',addr['default'])])
job_ids = self.pool.get('res.partner.job').search(cr, uid, [('address_id', '=', addr['default'])])
if job_ids:
data['contact_id'] = self.pool.get('res.partner.job').browse(cr, uid, job_ids[0]).contact_id.id
d = self.onchange_contact_id(cr, uid, ids, data['contact_id'],part)
d = self.onchange_contact_id(cr, uid, ids, data['contact_id'], part)
data.update(d['value'])
partner_data = self.pool.get('res.partner').browse(cr, uid, part)
data['badge_partner'] = partner_data.name
return {'value':data}
return {'value': data}
def onchange_partner_invoice_id(self, cr, uid, ids, event_id, partner_invoice_id):
data={}
context={}
data['unit_price']=False
if not event_id:
return {'value':data}
data_event = self.pool.get('event.event').browse(cr,uid,event_id)
return {'value': data}
data_event = self.pool.get('event.event').browse(cr, uid, event_id)
if data_event.product_id:
if not partner_invoice_id:
data['unit_price']=self.pool.get('product.product').price_get(cr, uid, [data_event.product_id.id],context=context)[data_event.product_id.id]
return {'value':data}
data_partner = self.pool.get('res.partner').browse(cr,uid,partner_invoice_id)
context.update({'partner_id':data_partner})
data['unit_price'] = self.pool.get('product.product')._product_price(cr, uid, [data_event.product_id.id], False, False, {'pricelist':data_partner.property_product_pricelist.id})[data_event.product_id.id]
return {'value':data}
return {'value':data}
data['unit_price']=self.pool.get('product.product').price_get(cr, uid, [data_event.product_id.id], context=context)[data_event.product_id.id]
return {'value': data}
data_partner = self.pool.get('res.partner').browse(cr, uid, partner_invoice_id)
context.update({'partner_id': data_partner})
data['unit_price'] = self.pool.get('product.product')._product_price(cr, uid, [data_event.product_id.id], False, False, {'pricelist': data_partner.property_product_pricelist.id})[data_event.product_id.id]
return {'value': data}
return {'value': data}
def onchange_categ_id(self, cr, uid, ids, categ, context={}):
if not categ:
return {'value':{}}
return {'value': {}}
cat = self.pool.get('crm.case.categ').browse(cr, uid, categ, context).probability
return {'value':{'probability':cat}}
def _map_ids(self,method,cr, uid, ids, *args, **argv):
case_data = self.browse(cr,uid,ids)
new_ids=[]
for case in case_data:
if case.case_id:
new_ids.append(case.case_id.id)
return getattr(self.pool.get('crm.case'),method)(cr, uid, new_ids, *args, **argv)
def case_close(self,cr, uid, ids, *args, **argv):
return self._map_ids('case_close',cr,uid,ids,*args,**argv)
def case_escalate(self,cr, uid, ids, *args, **argv):
return self._map_ids('case_escalate',cr,uid,ids,*args,**argv)
def case_open(self,cr, uid, ids, *args, **argv):
return self._map_ids('case_open',cr,uid,ids,*args,**argv)
def case_cancel(self,cr, uid, ids, *args, **argv):
return self._map_ids('case_cancel',cr,uid,ids,*args,**argv)
def case_pending(self,cr, uid, ids, *args, **argv):
return self._map_ids('case_pending',cr,uid,ids,*args,**argv)
def case_reset(self,cr, uid, ids, *args, **argv):
return self._map_ids('case_reset',cr,uid,ids,*args,**argv)
def case_log(self,cr, uid, ids, *args, **argv):
return self._map_ids('case_log',cr,uid,ids,*args,**argv)
def case_log_reply(self,cr, uid, ids, *args, **argv):
return self._map_ids('case_log_reply',cr,uid,ids,*args,**argv)
def add_reply(self,cr, uid, ids, *args, **argv):
return self._map_ids('add_reply',cr,uid,ids,*args,**argv)
def remind_partner(self,cr, uid, ids, *args, **argv):
return self._map_ids('remind_partner',cr,uid,ids,*args,**argv)
def remind_user(self,cr, uid, ids, *args, **argv):
return self._map_ids('remind_user',cr,uid,ids,*args,**argv)
return {'value': {'probability': cat}}
event_registration()
@ -417,12 +366,12 @@ class report_event_registration(osv.osv):
_description = "Events on registrations"
_auto = False
_columns = {
'name': fields.char('Event',size=20),
'date_begin': fields.datetime('Beginning date', required=True),
'date_end': fields.datetime('Ending date', required=True),
'draft_state': fields.integer('Draft Registration',size=20),
'confirm_state': fields.integer('Confirm Registration',size=20),
'register_max': fields.integer('Maximum Registrations'),
'name': fields.char('Event', size=20),
'date_begin': fields.datetime('Beginning date', required=True),
'date_end': fields.datetime('Ending date', required=True),
'draft_state': fields.integer('Draft Registration', size=20),
'confirm_state': fields.integer('Confirm Registration', size=20),
'register_max': fields.integer('Maximum Registrations'),
}
def init(self, cr):
cr.execute("""
@ -432,8 +381,8 @@ class report_event_registration(osv.osv):
c.name as name,
e.date_begin as date_begin,
e.date_end as date_end,
(SELECT sum(nb_register) FROM event_registration x , crm_case c WHERE x.case_id=c.id and c.section_id=e.section_id and state in ('draft')) as draft_state,
(SELECT sum(nb_register) FROM event_registration x , crm_case c WHERE x.case_id=c.id and c.section_id=e.section_id and state in ('open')) as confirm_state,
(SELECT sum(c.nb_register) FROM event_registration c WHERE c.section_id=e.section_id and state in ('draft')) as draft_state,
(SELECT sum(c.nb_register) FROM event_registration c WHERE c.section_id=e.section_id and state in ('open')) as confirm_state,
e.register_max as register_max
from
event_event e,crm_case_section c
@ -448,19 +397,21 @@ class report_event_type_registration(osv.osv):
_description = "Event type on registration"
_auto = False
_columns = {
'name': fields.char('Event Type',size=20),
'nbevent':fields.integer('Number Of Events'),
'draft_state': fields.integer('Draft Registrations',size=20),
'confirm_state': fields.integer('Confirm Registrations',size=20),
'name': fields.char('Event Type', size=20),
'nbevent': fields.integer('Number Of Events'),
'draft_state': fields.integer('Draft Registrations', size=20),
'confirm_state': fields.integer('Confirm Registrations', size=20),
}
def init(self, cr):
cr.execute("""
create or replace view report_event_type_registration as (
select
count(t.id) as id,
t.name as name,
(select sum(nb_register) from event_registration r , crm_case c , event_event e where c.section_id=e.section_id and r.case_id=c.id and c.state='draft' and e.type=t.id ) as draft_state ,
(select sum(nb_register) from event_registration r , crm_case c , event_event e where c.section_id=e.section_id and r.case_id=c.id and c.state='open' and e.type=t.id ) as confirm_state,
(select sum(c.nb_register) from event_registration c, event_event e where c.section_id=e.section_id and c.state='draft' and e.type=t.id ) as draft_state ,
(select sum(c.nb_register) from event_registration c, event_event e where c.section_id=e.section_id and c.state='open' and e.type=t.id ) as confirm_state,
count(t.id) as nbevent
from
event_event e

View File

@ -33,8 +33,8 @@
<field name="res_model">event.type</field>
<field name="view_type">form</field>
</record>
<menuitem name="Configuration" id="menu_event_config" parent="menu_marketing_event_main" sequence="30"/>
<menuitem name="Types of Events" id="menu_event_type" action="action_event_type" parent="menu_event_config"/>
<menuitem name="Configuration" id="menu_event_config" parent="menu_marketing_event_main" sequence="30" groups="base.group_extended"/>
<menuitem name="Types of Events" id="menu_event_type" action="action_event_type" parent="menu_event_config" groups="base.group_extended,crm.group_crm_manager"/>
<!-- The base section for all events -->
@ -221,23 +221,26 @@
<field name="ref2" colspan="4"/>
</page>
<page string="History">
<field name="history_line" colspan="4" nolabel="1" mode="tree,form">
<form string="Communication history">
<field name="date"/>
<field name="som"/>
<newline/>
<field name="canal_id"/>
<field name="email"/>
<newline/>
<field name="description" colspan="4"/>
</form>
<tree string="Communication history">
<field name="date"/>
<field name="description"/>
<field name="som"/>
<field name="user_id"/>
<field name="canal_id"/>
</tree>
<field name="message_ids" colspan="4" nolabel="1" mode="tree,form">
<form string="Communication history">
<group col="6" colspan="4">
<field name="date"/>
<field name="email_to"/>
<field name="email_from"/>
</group>
<newline/>
<field name="description" colspan="4" nolabel="1"/>
<button colspan="4"
string="Reply to Last Email"
name="%(crm.action_crm_send_mail)d"
context="{'mail':'reply', 'model': 'crm.lead'}"
icon="gtk-undo" type="action" />
</form>
<tree string="Communication history">
<field name="description"/>
<field name="email_to"/>
<field name="date"/>
</tree>
</field>
<field name="log_ids" nolabel="1" colspan="4" mode="tree,form" readonly="1">
<tree string="Actions">

View File

@ -2,11 +2,11 @@
<openerp>
<data>
<record id="menu_event_config" model="ir.ui.menu">
<field name="groups_id" eval="[(6,0,[ref('crm.group_crm_manager')])]"/>
<field name="groups_id" eval="[(6,0,[ref('crm.group_crm_manager'), ref('base.group_extended')])]"/>
</record>
<record id="menu_report_event" model="ir.ui.menu">
<field name="groups_id" eval="[(6,0,[ref('crm.group_crm_manager')])]"/>
<field name="groups_id" eval="[(6,0,[ref('crm.group_crm_manager'), ref('base.group_extended')])]"/>
</record>
</data>
</openerp>

View File

@ -27,21 +27,23 @@ class event_confirm_registration(osv.osv_memory):
"""
_name = "event.confirm.registration"
_description = "Event Registraion"
_columns = {
'msg': fields.text('Message', readonly=True),
'msg': fields.text('Message', readonly=True),
}
_defaults={
'msg':lambda *a:'The event limit is reached. What do you want to do?'
'msg':lambda *a:'The event limit is reached. What do you want to do?'
}
def confirm(self, cr, uid, ids, context):
registration_obj = self.pool.get('event.registration')
reg_id = context.get('reg_id', False) or context.get('active_id', False)
if reg_id:
registration_obj.write(cr, uid, [reg_id], {'state':'open',})
registration_obj.write(cr, uid, [reg_id], {'state':'open', })
registration_obj._history(cr, uid, [reg_id], 'Open', history=True)
registration_obj.mail_user(cr,uid,[reg_id])
registration_obj.mail_user(cr, uid, [reg_id])
return {}
event_confirm_registration()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -36,10 +36,8 @@ class event_registration_list(osv.osv_memory):
'type': 'ir.actions.act_window'
}
cr.execute('SELECT section_id FROM event_event WHERE id = %s', (context['active_id'],))
res = cr.fetchone()
return {
'domain': [('section_id', '=', res[0])],
'domain': [('section_id', '=', context['active_id'])],
'name': 'Event Registrations',
'view_type': 'form',
'view_mode': 'tree,form',

View File

@ -57,11 +57,13 @@ class hr_applicant(osv.osv, crm.crm_case):
_name = "hr.applicant"
_description = "Applicant"
_order = "id desc"
_inherit ='mailgate.thread'
_inherits = {'mailgate.thread': 'thread_id'}
_columns = {
'active': fields.boolean('Active', help="If the active field is set to false, it will allow you to hide the case without removing it."),
'description': fields.text('Description'),
'thread_id': fields.many2one('mailgate.thread', 'Thread', required=False),
'name': fields.char('Name', size=128, required=True),
'active': fields.boolean('Active', help="If the active field is set to false, it will allow you to hide the case without removing it."),
'description': fields.text('Description'),
'section_id': fields.many2one('crm.case.section', 'Sales Team', \
select=True, help='Sales team to which Case belongs to.\
Define Responsible user and Email account for mail gateway.'),
@ -103,6 +105,16 @@ class hr_applicant(osv.osv, crm.crm_case):
'survey' : fields.related('job_id', 'survey_id', type='many2one', relation='survey', string='Survey'),
'response' : fields.integer("Response"),
}
_defaults = {
'active': lambda *a: 1,
'user_id': crm.crm_case._get_default_user,
'email_from': crm.crm_case. _get_default_email,
'state': lambda *a: 'draft',
'section_id': crm.crm_case. _get_section,
'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'crm.helpdesk', context=c),
'priority': lambda *a: crm.AVAILABLE_PRIORITIES[2][0],
}
def onchange_job(self,cr, uid, ids, job, context={}):
result = {}

View File

@ -10,7 +10,7 @@
<field name="date" invisible="1"/>
<field name="user_id" invisible="1"/>
<field name="job_id" invisible="1"/>
<field name="stage_id" invisible="1" widget="selection"/>
<field name="stage_id" invisible="1" />
<field name="department_id" invisible="1"/>
<field name="type_id" invisible="1"/>
<field name="partner_id" invisible="1"/>

View File

@ -32,7 +32,7 @@
* Easy Integration with any Module""",
'author': 'Tiny',
'website': 'http://www.openerp.com',
'depends': ['base','fetchmail'],
'depends': ['base'],
'init_xml': [],
'update_xml': [
"mail_gateway_view.xml"

View File

@ -22,60 +22,38 @@
from osv import osv, fields
import time
class one2many_domain(fields.one2many):
def set(self, cr, obj, id, field, values, user=None, context=None):
if not values:
return
return super(one2many_domain, self).set(cr, obj, id, field, values,
user=user, context=context)
def get(self, cr, obj, ids, name, user=None, offset=0, context=None, values=None):
if not context:
context = {}
res = {}
msg_obj = obj.pool.get('mailgate.message')
for thread in obj.browse(cr, user, ids, context=context):
final = msg_obj.search(cr, user, self._domain + [('thread_id', '=', thread.id)], context=context)
res[thread.id] = final
return res
class mailgate_thread(osv.osv):
'''
Mailgateway Thread
'''
_name = 'mailgate.thread'
_description = 'Mailgateway Thread'
def _get_log_ids(self, cr, uid, ids, field_names, arg, context=None):
"""Gets id for case log from history of particular case
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param ids: List of Case IDs
@param context: A standard dictionary for contextual values
@return:Dictionary of History Ids
"""
if not context:
context = {}
result = {}
domain = []
history_obj = False
model_obj = self.pool.get('ir.model')
history_obj = self.pool.get('mailgate.message')
if 'message_ids' in field_names:
name = 'message_ids'
domain += [('email_to', '!=', False)]
if 'log_ids' in field_names:
name = 'log_ids'
domain += [('email_to', '=', False)]
model_ids = model_obj.search(cr, uid, [('model', '=', self._name)])
domain += [('model_id', '=', model_ids[0])]
for case in self.browse(cr, uid, ids, context):
domain1 = domain + [('res_id', '=', case.id)]
history_ids = history_obj.search(cr, uid, domain1, context=context)
if history_ids:
result[case.id] = {name: history_ids}
else:
result[case.id] = {name: []}
return result
_rec_name = 'thread'
_columns = {
'name':fields.char('Name', size=64),
'active': fields.boolean('Active'),
'message_ids': fields.function(_get_log_ids, method=True, type='one2many', \
multi="message_ids", relation="mailgate.message", string="Messages"),
'log_ids': fields.function(_get_log_ids, method=True, type='one2many', \
multi="log_ids", relation="mailgate.message", string="Logs"),
}
'thread': fields.char('Thread', size=32, required=False),
'message_ids': one2many_domain('mailgate.message', 'thread_id', 'Messages', domain=[('history', '=', True)], required=False),
'log_ids': one2many_domain('mailgate.message', 'thread_id', 'Logs', domain=[('history', '=', False)], required=False),
}
def __history(self, cr, uid, cases, keyword, history=False, email=False, details=None, email_from=False, message_id=False, context={}):
"""
@param self: The object pointer
@ -89,7 +67,6 @@ class mailgate_thread(osv.osv):
@param context: A standard dictionary for contextual values"""
if not context:
context = {}
# The mailgate sends the ids of the cases and not the object list
if all(isinstance(case_id, (int, long)) for case_id in cases) and context.get('model'):
cases = self.pool.get(context['model']).browse(cr, uid, cases, context=context)
@ -102,21 +79,19 @@ class mailgate_thread(osv.osv):
data = {
'name': keyword,
'user_id': uid,
'date': time.strftime('%Y-%m-%d %H:%M:%S'),
'model_id' : model_ids and model_ids[0] or False,
'res_id': case.id,
'section_id': case.section_id.id,
'message_id':message_id
'date': time.strftime('%Y-%m-%d %H:%M:%S'),
'thread_id': case.thread_id.id,
'message_id': message_id
}
if history:
data['history'] = True
data['description'] = details or case.description
data['email_to'] = email or \
(case.section_id and case.section_id.reply_to) or \
(case.user_id and case.user_id.address_id and \
case.user_id.address_id.email) or tools.config.get('email_from', False)
data['email_from'] = email_from or \
(case.section_id and case.section_id.reply_to) or \
(case.user_id and case.user_id.address_id and \
case.user_id.address_id.email) or tools.config.get('email_from', False)
res = obj.create(cr, uid, data, context)
@ -138,10 +113,10 @@ class mailgate_message(osv.osv):
_columns = {
'name':fields.char('Message', size=64),
'model_id': fields.many2one('ir.model', 'Model'),
'thread_id':fields.many2one('mailgate.thread', 'Thread'),
'date': fields.datetime('Date'),
'model_id': fields.many2one('ir.model', "Model"),
'res_id': fields.integer('Resource ID'),
'history': fields.boolean('Is History?', required=False),
'user_id': fields.many2one('res.users', 'User Responsible', readonly=True),
'message': fields.text('Description'),
'email_from': fields.char('Email From', size=84),

View File

@ -9,9 +9,8 @@
<form string="maligate message">
<field name="name" />
<field name="date" />
<field name="model_id" />
<field name="res_id" />
<field name="user_id" />
<field name="history" />
<field name="message_id" />
<notebook colspan="4">
<page>
@ -51,20 +50,19 @@
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Mailgateway Thread">
<field name="name" select="1"/>
<separator string="Messages" colspan="4"/>
<field name="message_ids" nolabel="1" colspan="4">
<tree string="Mailgateway Message">
<field name="thread" select="1"/>
<separator string="Logs" colspan="4"/>
<field name="log_ids" nolabel="1" colspan="4" domain="[('history', '=', True)]">
<tree string="Mailgateway Logs">
<field name="name" select="1" />
<field name="date" />
</tree>
<form string="Maligate Message">
<form string="Maligate Logs">
<field name="name" />
<field name="date" />
<field name="model_id" />
<field name="res_id" />
<field name="user_id" />
<field name="message_id" />
<field name="history" />
<notebook colspan="4">
<page string="Email Details">
<group col="4" colspan="4">
@ -82,6 +80,35 @@
</notebook>
</form>
</field>
<separator string="Histories" colspan="4"/>
<field name="message_ids" nolabel="1" colspan="4" domain="[('history', '=', True)]">
<tree string="Mailgateway Histories">
<field name="name" select="1" />
<field name="date" />
</tree>
<form string="Maligate Histories">
<field name="name" />
<field name="date" />
<field name="user_id" />
<field name="message_id" />
<field name="history" />
<notebook colspan="4">
<page string="Email Details">
<group col="4" colspan="4">
<separator string="Email Details" colspan="4"/>
<field name="email_from" />
<field name="email_to" />
<field name="email_cc" />
<field name="email_bcc" />
</group>
</page>
<page string="Attachments">
<separator string="Attachments" colspan="4"/>
<field name="attachment_ids" nolabel="1" colspan="4" />
</page>
</notebook>
</form>
</field>
</form>
</field>
</record>
@ -92,7 +119,7 @@
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Mailgateway Thread">
<field name="name" select="1" />
<field name="thread" select="1" />
<field name="message_ids" />
</tree>
</field>
@ -120,12 +147,12 @@
</record>
<menuitem id="base.menu_crm_configuration" name="Cases"
<!-- <menuitem id="base.menu_crm_configuration" name="Cases"
parent="base.menu_base_config" sequence="0"/>
<menuitem id="menu_mailgate_thread" name="Mailgateway Threads" action="action_view_mailgate_thread"
parent="base.menu_crm_configuration" sequence="20"/>
-->
</data>
</openerp>

View File

@ -0,0 +1,3 @@
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
"mail_gateway_mailgate_message","mail_gateway.mailgate.message","model_mailgate_message","base.group_user",1,1,1,1
"mail_gateway_mailgate_thread","mail_gateway.mailgate.thread","model_mailgate_thread","base.group_user",1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 mail_gateway_mailgate_message mail_gateway.mailgate.message model_mailgate_message base.group_user 1 1 1 1
3 mail_gateway_mailgate_thread mail_gateway.mailgate.thread model_mailgate_thread base.group_user 1 1 1 1

View File

@ -36,7 +36,7 @@ class project_issue(osv.osv, crm.crm_case):
_name = "project.issue"
_description = "Project Issue"
_order = "priority, id desc"
_inherit = 'mailgate.thread'
_inherits = {'mailgate.thread': 'thread_id'}
def case_open(self, cr, uid, ids, *args):
"""
@ -110,6 +110,10 @@ class project_issue(osv.osv, crm.crm_case):
return res
_columns = {
'thread_id': fields.many2one('mailgate.thread', 'Thread', required=False),
'id': fields.integer('ID'),
'name': fields.char('Name', size=128, required=True),
'active': fields.boolean('Active', required=False),
'create_date': fields.datetime('Creation Date' , readonly=True),
'write_date': fields.datetime('Update Date' , readonly=True),
'date_deadline': fields.date('Deadline'),
@ -164,13 +168,26 @@ class project_issue(osv.osv, crm.crm_case):
method=True, multi='day_close', type="float", store=True),
'assigned_to' : fields.many2one('res.users', 'Assigned to'),
}
def _get_project(self, cr, uid, context):
user = self.pool.get('res.users').browse(cr,uid,uid, context=context)
if user.context_project_id:
return user.context_project_id.id
return False
_defaults = {
'active': lambda *a: 1,
'user_id': crm.crm_case._get_default_user,
'partner_id': crm.crm_case._get_default_partner,
'partner_address_id': crm.crm_case._get_default_partner_address,
'email_from': crm.crm_case. _get_default_email,
'state': lambda *a: 'draft',
'section_id': crm.crm_case. _get_section,
'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'crm.helpdesk', context=c),
'priority': lambda *a: crm.AVAILABLE_PRIORITIES[2][0],
'project_id':_get_project,
}
def convert_issue_task(self, cr, uid, ids, context=None):
case_obj = self.pool.get('project.issue')
data_obj = self.pool.get('ir.model.data')
@ -249,9 +266,5 @@ class project_issue(osv.osv, crm.crm_case):
return {'value':{}}
return {'value':{}}
_defaults = {
'project_id':_get_project,
}
project_issue()

View File

@ -22,7 +22,7 @@
<field eval="&quot;Bug in Accounts module&quot;" name="name"/>
<field eval="&quot;agr@agrolait.com&quot;" name="email_from"/>
</record>
<record id="crm_case_log_takecorrectiveactions0" model="crm.case.log">
<record id="crm_case_log_takecorrectiveactions0" model="mailgate.message">
<field eval="time.strftime('%Y-%m-08')" name="date"/>
<field name="case_id" ref="crm_case_buginaccountsmodule0"/>
<field name="som" ref="base.som_normal"/>