[NEW] module for campaiging using poweremail and crm - not ready to test functionally

bzr revid: dsh@tinyerp.com-20100514143602-7zvf7pefl6mvcij0
This commit is contained in:
DSH (Open ERP) 2010-05-14 20:06:02 +05:30
parent fbca09e243
commit 078271646a
5 changed files with 528 additions and 0 deletions

View File

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

View File

@ -0,0 +1,44 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
{
"name" : "",
"version" : "1.1",
"depends" : ["crm",
"document",
"poweremail" # need to get this module form the branch
# lp:poweremail
],
"author" : "Tiny",
"category": 'Generic Modules/Marketing',
"description": """
""",
'website': 'http://www.openerp.com',
'init_xml': [],
'update_xml': [
'marketing_campaign_view.xml',
],
'demo_xml': [],
'installable': True,
'active': False,
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,180 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import time
from datetime import datetime
from dateutil.relativedelta import relativedelta
from osv import fields, osv
_intervalTypes = {
'hours': lambda interval: relativedelta(hours=interval),
'days': lambda interval: relativedelta(days=interval),
'months': lambda interval: relativedelta(months=interval),
'years': lambda interval: relativedelta(years=interval),
}
class marketing_campaign(osv.osv): #{{{
_name = "marketing.campaign"
_description = "Marketing Campaigns"
_columns = {
'name': fields.char('Name', size=64),
'object_id': fields.many2one('ir.model', 'Objects'),
'mode':fields.selection([('test', 'Test'),
('test_realtime', 'Realtime Time'),
('manual', 'Manual'),
('active', 'Active')],
'Mode'),
'state': fields.selection([('draft', 'Draft'),
('running', 'Running'),
('done', 'Done'),
('cancelled', 'Cancelled'),],
'State',
readonly=True),
}
marketing_campaign()#}}}
class marketing_campaign_segment(osv.osv): #{{{
_name = "marketing.campaign.segment"
_description = "Marketing Campaign Segments"
_columns = {
'name': fields.char('Name', size=64),
'campaign_id': fields.many2one('marketing.campaign', 'Campaign'),
'object_id': fields.related('campaign_id','object_id',
type='many2one', relation='ir.model',
string='Object'),
'ir_filter_id':fields.many2one('ir.filters', 'Filter'),
'sync_last_date': fields.datetime('Date'),
'sync_mode':fields.selection([('create', 'Create'),
('write', 'Write')],
'Mode'),
'state': fields.selection([('draft', 'Draft'),
('running', 'Running'),
('done', 'Done'),
('cancelled', 'Cancelled')],
'State',
readonly=True),
'date_run': fields.datetime('Running'),
'date_done': fields.datetime('Done'),
}
marketing_campaign_segment()#}}}
class marketing_campaign_activity(osv.osv): #{{{
_name = "marketing.campaign.activity"
_description = "Marketing Campaign Activities"
_columns = {
'name': fields.char('Name', size=64),
'campaign_id': fields.many2one('marketing.campaign', 'Campaign'),
'object_id': fields.related('campaign_id','object_id',
type='many2one', relation='ir.model',
string='Object'),
'start': fields.boolean('Start'),
'condition': fields.text('Condition'),
'type':fields.selection([('email', 'E-mail'),
('paper', 'Paper'),
('action', 'Action'),
('subcampaign', 'Sub-Campaign')],
'Type'),
'email_template_id': fields.many2one('poweremail.templates','Email Template'),
'report_id': fields.many2one('ir.actions.report.xml', 'Reports'),
'report_directory_id': fields.many2one('document.directory', 'Directory'),
'server_action_id': fields.many2one('ir.actions.server', string='Action'),
'to_ids': fields.one2many('marketing.campaign.transition',
'activity_from_id',
'Next Activities'),
'subcampaign_id' :fields.many2one('marketing.campaign', 'Sub-Campaign'),
'subcampaign_segment_id' :fields.many2one('marketing.campaign.segment',
'Sub Campaign Segment'),
}
marketing_campaign_activity()#}}}
class marketing_campaign_transition(osv.osv): #{{{
_name = "marketing.campaign.transition"
_description = "Campaign Transitions"
_columns = {
'activity_from_id': fields.many2one('marketing.campaign.activity',
'Source Activity'),
'activity_to_id': fields.many2one('marketing.campaign.activity',
'Destination Activity'),
'interval_nbr': fields.integer('Interval No.'),
'interval_type': fields.selection([('hours', 'Hours'), ('days', 'Days'),
('months', 'Months'), ('years','Years')], 'Interval Type')
}
marketing_campaign_transition() #}}}
class marketing_campaign_workitem(osv.osv): #{{{
_name = "marketing.campaign.workitem"
_description = "Campaign Workitems"
_columns = {
'segment_id': fields.many2one('marketing.campaign.segment', 'Segment'),
'activity_id': fields.many2one('marketing.campaign.activity', 'Activity'),
'object_id': fields.related('segment_id', 'campaign_id', 'object_id',
type='many2one', relation='ir.model',
string='Object'),
'res_id': fields.integer('Results'),
'date': fields.datetime('Execution Date'),
'partner_id': fields.many2one('res.partner', 'Partner'),
'state': fields.selection([('todo', 'ToDo'), ('inprogress', 'In Progress'),
('exception', 'Exception'), ('done', 'Done'),
('cancelled', 'Cancelled')], 'State')
}
def process_chain(self, cr, uid, workitem_id, context={}):
workitem = self.browse(cr, uid, workitem_id)
to_ids = [to_ids.id for to_ids in workitem.activity_id.to_ids]
mct_obj = self.pool.get('marketing.campaign.transition')
process_to_id = mct_obj.search(cr,uid, [('id', 'in', to_ids),
('activity_from_id','=', 'activity_id')])
for mct_id in mct_obj.browse(cr, uid, process_to_id):
launch_date = datetime.datetime.now() + _intervalTypes[ \
mct_id.interval_type](mct_id.interval_nbr)
workitem_vals = {'segment_id': workitem.segment_id.id,
'activity_id': mct_id.activity_to_id.id,
'date': launch_date,
'partner_id': workitem.partner_id.id,
'state': 'todo',
}
self.create(cr, uid, workitem_vals)
def process(self, cr, uid, workitem_ids, context={}):
#for wi in self.browse(cr, uid, workitem_ids):
# if wi.state == 'todo'# we searched the wi which are in todo state then y v keep this filter again
return True
def process_all(self, cr, uid, context={}):
workitem_ids = self.search(cr, uid, [('type', '=', 'todo'),
('date','<=', time.strftime('%Y-%m-%d %H:%M:%S'))])
if workitem_ids:
self.parocess(cr, uid, workitem_ids, context)
marketing_campaign_workitem() #}}}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,18 @@
<?xml version="1.0" ?>
<openerp>
<data noupdate="1">
<!-- Cron -->
<record model="ir.cron" id="ir_cron_marketing_campaign_every_hour">
<field name="name">Check Workitem</field>
<field name="interval_number">60</field>
<field name="interval_type">minutes</field>
<field name="numbercall">-1</field>
<field name="doall" eval="False"/>
<field name="model" eval="'marketing.campaign.workitem'"/>
<field name="function" eval="'process_all'"/>
<field name="args" eval="'()'"/>
</record>
</data>
</openerp>

View File

@ -0,0 +1,261 @@
<?xml version="1.0"?>
<openerp>
<data>
<menuitem name="Direct Marketing" id="menu_marketing" parent="base.menu_base_partner"/>
<!--
======================
Marketing Campaign
======================
-->
<record model="ir.ui.view" id="view_marketing_campaign_form">
<field name="name">marketing.campaign.form</field>
<field name="model">marketing.campaign</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Campaign">
<group colspan="4">
<field name="name" select="1"/>
<field name="object_id" select="1"/>
<field name="mode"/>
</group>
<separator string="Status" colspan="4" />
<field name="state" nolabel = "1" colspan="4"/>
</form>
</field>
</record>
<record model="ir.ui.view" id="view_marketing_campaign_tree">
<field name="name">marketing.campaign.tree</field>
<field name="model">marketing.campaign</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="All Campaigns">
<field name="name" select="1"/>
<field name="object_id" select="1"/>
<field name="mode"/>
<field name="state"/>
</tree>
</field>
</record>
<!--record id="view_marketing_campaign_diagram" model="ir.ui.view">
<field name="name">marketing.campaign.diagram</field>
<field name="model">marketing.campaign</field>
<field name="type">diagram</field>
<field name="arch" type="xml">
<diagram string="Campaign Editor">
<node object="marketing.campaign.activity" shape="rectangle:type!='subcampaign'" bgcolor="gray:start==True">
<field name="name"/>
<field name="type"/>
<field name="start" invisible="1"/>
</node>
<arrow object="marketing.campaign.transition" source="activity_from_id" destination="activity_to_id">
<field name="activity_from_id"/>
<field name="activity_to_id"/>
</arrow>
</diagram>
</field>
</record-->
<record model="ir.actions.act_window" id="action_marketing_campaign_form">
<field name="name">All Campaigns</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">marketing.campaign</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form,diagram</field>
<field name="view_id" ref="view_marketing_campaign_tree"/>
</record>
<menuitem id="menu_marketing_campaign_form" parent="menu_marketing" action="action_marketing_campaign_form" sequence="20" />
<!--
======================
Marketing Segments
======================
-->
<record model="ir.ui.view" id="view_marketing_campaign_segment_form">
<field name="name">marketing.campaign.segment.form</field>
<field name="model">marketing.campaign.segment</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Segments">
<group colspan="4">
<field name="name" select="1"/>
<newline/>
<field name="campaign_id" select="1"/>
<field name="object_id" select="1"/>
<newline/>
<field name="ir_filter_id" select="1"/>
<newline/>
<field name="date_run"/>
<field name="date_done"/>
<separator string="Synchronization" colspan="4" />
<field name="sync_last_date"/>
<field name="sync_mode"/>
</group>
<separator string="Status" colspan="4" />
<field name="state" nolabel = "1" colspan="4"/>
</form>
</field>
</record>
<record model="ir.ui.view" id="view_marketing_campaign_segment_tree">
<field name="name">marketing.campaign.segment.tree</field>
<field name="model">marketing.campaign.segment</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="All Segments">
<field name="name" select="1"/>
<field name="campaign_id" select="1"/>
<field name="sync_last_date"/>
<field name="sync_mode"/>
<field name="state"/>
<field name="date_run"/>
<field name="date_done"/>
</tree>
</field>
</record>
<record model="ir.actions.act_window" id="action_marketing_campaign_segment_form">
<field name="name">All Segments</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">marketing.campaign.segment</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="view_marketing_campaign_segment_tree"/>
</record>
<menuitem id="menu_marketing_campaign_segment_form" parent="menu_marketing" action="action_marketing_campaign_segment_form" sequence="10" />
<!--
======================
Marketing Activities
======================
-->
<record model="ir.ui.view" id="view_marketing_campaign_activity_form">
<field name="name">marketing.campaign.activity.form</field>
<field name="model">marketing.campaign.activity</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Activities">
<field name="name" select="1" />
<field name="start"/>
<field name="campaign_id" select="1"/>
<field name="object_id"/>
<field name="condition" colspan="4"/>
<newline/>
<field name="type"/>
<group colspan="4" attrs="{'invisible':[('type','!=','email')]}" >
<field name="email_template_id" attrs="{'required':[('type','=','email')]}" />
</group>
<group colspan="4" attrs="{'invisible':[('type','!=','paper')]}" >
<field name="report_id" attrs="{'required':[('type','=','paper')]}" />
<field name="report_directory_id" attrs="{'required':[('type','=','paper')]}" />
</group>
<group colspan="4" attrs="{'invisible':[('type','!=','action')]}" >
<field name="server_action_id" attrs="{'required':[('type','=','action')]}" />
</group>
<group colspan="4" attrs="{'invisible':[('type','!=','subcampaign')]}" >
<field name="subcampaign_id" attrs="{'required':[('type','=','subcampaign')]}" />
<field name="subcampaign_segment_id" attrs="{'required':[('type','=','subcampaign')]}" />
</group>
<field name="to_ids" nolabel="1" colspan="4" mode="tree">
<tree string="All Transitions" editable="bottom">
<field name="activity_from_id"/>
<field name="activity_to_id" />
<field name="interval_nbr" />
<field name="interval_type"/>
</tree>
</field>
</form>
</field>
</record>
<record model="ir.ui.view" id="view_marketing_campaign_activity_tree">
<field name="name">marketing.campaign.activity.tree</field>
<field name="model">marketing.campaign.activity</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="All Activities">
<field name="name" select="1"/>
<field name="campaign_id" select="1"/>
<field name="start"/>
<field name="object_id"/>
<field name="condition"/>
<field name="type"/>
<field name="report_id"/>
<field name="to_ids"/>
<field name="subcampaign_id"/>
<field name="subcampaign_segment_id"/>
</tree>
</field>
</record>
<record model="ir.actions.act_window" id="action_marketing_campaign_activity_form">
<field name="name">All Activities</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">marketing.campaign.activity</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="view_marketing_campaign_activity_tree"/>
</record>
<!--
<menuitem id="menu_marketing_campaign_activity_form" parent="menu_marketing" action="action_marketing_campaign_activity_form" sequence="3" />-->
<!--
======================
Marketing Workitems
======================
-->
<record model="ir.ui.view" id="view_marketing_campaign_workitem_tree">
<field name="name">marketing.campaign.workitem.tree</field>
<field name="model">marketing.campaign.workitem</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="All Workitems">
<field name="segment_id"/>
<field name="activity_id" />
<field name="res_id" />
<field name="date"/>
<field name="state"/>
</tree>
</field>
</record>
<record model="ir.ui.view" id="view_marketing_campaign_workitem_form">
<field name="name">marketing.campaign.workitem.form</field>
<field name="model">marketing.campaign.workitem</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Workitem">
<field name="segment_id" select="1"/>
<field name="activity_id" select="1"/>
<field name="object_id"/>
<field name="res_id"/>
<field name="date" select="1"/>
<field name="partner_id" select="1"/>
<separator string="Status" colspan="4"/>
<field name="state" nolabel="1" colspan="4" readonly="True" select="1"/>
</form>
</field>
</record>
<record model="ir.actions.act_window" id="action_marketing_campaign_workitem">
<field name="name">All Workitems</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">marketing.campaign.workitem</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="view_marketing_campaign_workitem_tree"/>
</record>
<menuitem id="menu_action_marketing_campaign_workitem" parent="menu_marketing" action="action_marketing_campaign_workitem" sequence="30" groups="base.group_extended"/>
</data>
</openerp>