diff --git a/addons/marketing/marketing_view.xml b/addons/marketing/marketing_view.xml
index 78f5a742bb6..7d8a46a8a92 100644
--- a/addons/marketing/marketing_view.xml
+++ b/addons/marketing/marketing_view.xml
@@ -31,6 +31,7 @@
+
diff --git a/addons/marketing/marketing_wizard.py b/addons/marketing/marketing_wizard.py
index aee302283b2..8eb1d1a01f4 100644
--- a/addons/marketing/marketing_wizard.py
+++ b/addons/marketing/marketing_wizard.py
@@ -28,6 +28,8 @@ class marketing_installer(osv.osv_memory):
# Generic modules
'marketing_campaign':fields.boolean('Marketing Campaigns',
help="Helps you to manage marketing campaigns and automate actions and communication steps."),
+ 'marketing_campaign_mailchimp':fields.boolean('Mailchimp Integration',
+ help="This modules integrate mailchimp.com's service with OpenERP to automate mass mailings."),
'crm_profiling':fields.boolean('Profiling Tools',
help="Helps you to perform segmentation within partners and design questionaires.")
}
diff --git a/addons/marketing_campaign/marketing_campaign.py b/addons/marketing_campaign/marketing_campaign.py
index 3f29e03c968..a23bb0e42d1 100755
--- a/addons/marketing_campaign/marketing_campaign.py
+++ b/addons/marketing_campaign/marketing_campaign.py
@@ -25,7 +25,7 @@ from dateutil.relativedelta import relativedelta
from osv import fields, osv
import netsvc
-import tools
+import tools
_intervalTypes = {
'hours': lambda interval: relativedelta(hours=interval),
@@ -37,10 +37,10 @@ _intervalTypes = {
class marketing_campaign(osv.osv): #{{{
_name = "marketing.campaign"
_description = "Marketing Campaign"
-
+
_columns = {
'name': fields.char('Name', size=64, required=True),
- 'object_id': fields.many2one('ir.model', 'Objects', required=True,
+ 'object_id': fields.many2one('ir.model', 'Object', required=True,
help="Choose the Object on which you want \
this campaign to be run"),
'mode':fields.selection([('test', 'Test'),
@@ -52,17 +52,15 @@ class marketing_campaign(osv.osv): #{{{
('running', 'Running'),
('done', 'Done'),
('cancelled', 'Cancelled'),],
- 'State',),
- 'activity_ids': fields.one2many('marketing.campaign.activity',
+ 'State',),
+ 'activity_ids': fields.one2many('marketing.campaign.activity',
'campaign_id', 'Activities'),
'fixed_cost': fields.float('Fixed Cost', help="The fixed cost is cost\
- you required for the campaign"),
-
+ you required for the campaign"),
}
-
_defaults = {
'state': lambda *a: 'draft',
- 'mode': lambda *a: 'test',
+ 'mode': lambda *a: 'test',
}
def state_running_set(self, cr, uid, ids, *args):
@@ -79,16 +77,16 @@ class marketing_campaign(osv.osv): #{{{
('state', '=', 'draft')])
self.write(cr, uid, ids, {'state': 'running'})
return True
-
+
def state_done_set(self, cr, uid, ids, *args):
segment_ids = self.pool.get('marketing.campaign.segment').search(cr, uid,
[('campaign_id', 'in', ids),
('state', '=', 'running')])
if segment_ids :
- raise osv.except_osv("Error", "Camapign cannot be done before all segments are done")
+ raise osv.except_osv("Error", "Camapign cannot be done before all segments are done")
self.write(cr, uid, ids, {'state': 'done'})
return True
-
+
def state_cancel_set(self, cr, uid, ids, *args):
self.write(cr, uid, ids, {'state': 'cancelled'})
return True
@@ -100,7 +98,7 @@ class marketing_campaign_segment(osv.osv): #{{{
_columns = {
'name': fields.char('Name', size=64,required=True),
- 'campaign_id': fields.many2one('marketing.campaign', 'Campaign',
+ 'campaign_id': fields.many2one('marketing.campaign', 'Campaign',
required=True),
'object_id': fields.related('campaign_id','object_id',
type='many2one', relation='ir.model',
@@ -114,22 +112,22 @@ class marketing_campaign_segment(osv.osv): #{{{
('running', 'Running'),
('done', 'Done'),
('cancelled', 'Cancelled')],
- 'State',),
+ 'State',),
'date_run': fields.datetime('Running'),
'date_done': fields.datetime('Done'),
}
-
+
_defaults = {
'state': lambda *a: 'draft',
'sync_mode': lambda *a: 'create_date',
}
-
+
def state_running_set(self, cr, uid, ids, *args):
segment = self.browse(cr, uid, ids[0])
curr_date = time.strftime('%Y-%m-%d %H:%M:%S')
vals = {'state': 'running'}
if not segment.date_run:
- vals['date_run'] = time.strftime('%Y-%m-%d %H:%M:%S')
+ vals['date_run'] = time.strftime('%Y-%m-%d %H:%M:%S')
if not segment.sync_last_date:
vals['sync_last_date']=curr_date
if not segment.date_done:
@@ -137,9 +135,9 @@ class marketing_campaign_segment(osv.osv): #{{{
).strftime('%Y-%m-%d %H:%M:%S')
self.write(cr, uid, ids, vals)
return True
-
+
def state_done_set(self, cr, uid, ids, *args):
- date_done = self.browse(cr, uid, ids[0]).date_done
+ date_done = self.browse(cr, uid, ids[0]).date_done
if (date_done > time.strftime('%Y-%m-%d %H:%M:%S')):
raise osv.except_osv("Error", "Segment cannot be closed before end date")
@@ -147,21 +145,21 @@ class marketing_campaign_segment(osv.osv): #{{{
[('state', 'in', ['inprogress', 'todo']),
('segment_id', '=', ids[0])])
if wi_ids :
- raise osv.except_osv("Error", "Segment cannot be done before all workitems are processed")
+ raise osv.except_osv("Error", "Segment cannot be done before all workitems are processed")
self.write(cr, uid, ids, {'state': 'done'})
return True
-
+
def state_cancel_set(self, cr, uid, ids, *args):
self.write(cr, uid, ids, {'state': 'cancelled'})
return True
-
+
def process_segment(self, cr, uid, context={}):
segment_ids = self.search(cr, uid, [('state', '=', 'running')])
action_date = time.strftime('%Y-%m-%d %H:%M:%S')
last_action_date = (datetime.now() + _intervalTypes['days'](-1) \
).strftime('%Y-%m-%d %H:%M:%S')
for segment in self.browse(cr, uid, segment_ids):
- act_ids = self.pool.get('marketing.campaign.activity').search(cr,
+ act_ids = self.pool.get('marketing.campaign.activity').search(cr,
uid, [('start', '=', True),
('campaign_id', '=', segment.campaign_id.id)])
if (segment.sync_last_date and \
@@ -195,23 +193,23 @@ class marketing_campaign_activity(osv.osv): #{{{
_columns = {
'name': fields.char('Name', size=128, required=True),
- 'campaign_id': fields.many2one('marketing.campaign', 'Campaign',
+ 'campaign_id': fields.many2one('marketing.campaign', 'Campaign',
required = True, ondelete='cascade'),
'object_id': fields.related('campaign_id','object_id',
type='many2one', relation='ir.model',
string='Object'),
'start': fields.boolean('Start',help= "Its necessary to start activity \
before running campaign"),
- 'condition': fields.char('Condition', size=256, required=True,
+ 'condition': fields.char('Condition', size=256, required=True,
help="Condition that is to be tested before \
- action is executed"),
+ action is executed"),
'type': fields.selection([('email', 'E-mail'),
('paper', 'Paper'),
('action', 'Action'),
('subcampaign', 'Sub-Campaign')],
'Type', required=True),
'email_template_id': fields.many2one('email.template','Email Template'),
- 'report_id': fields.many2one('ir.actions.report.xml', 'Reports', ),
+ 'report_id': fields.many2one('ir.actions.report.xml', 'Reports', ),
'report_directory_id': fields.many2one('document.directory','Directory',
help="Folder is used to store the generated reports"),
'server_action_id': fields.many2one('ir.actions.server', string='Action',
@@ -222,7 +220,7 @@ class marketing_campaign_activity(osv.osv): #{{{
'Next Activities'),
'from_ids': fields.one2many('marketing.campaign.transition',
'activity_to_id',
- 'Previous Activities'),
+ 'Previous Activities'),
'subcampaign_id': fields.many2one('marketing.campaign', 'Sub-Campaign'),
'subcampaign_segment_id': fields.many2one('marketing.campaign.segment',
'Sub Campaign Segment'),
@@ -236,7 +234,7 @@ class marketing_campaign_activity(osv.osv): #{{{
'object_id' : lambda obj, cr, uid, context : context.get('object_id',False),
}
- def search(self, cr, uid, args, offset=0, limit=None, order=None,
+ def search(self, cr, uid, args, offset=0, limit=None, order=None,
context=None, count=False):
if context == None:
context = {}
@@ -247,14 +245,14 @@ class marketing_campaign_activity(osv.osv): #{{{
for activity in segment_obj.campaign_id.activity_ids:
act_ids.append(activity.id)
return act_ids
- return super(marketing_campaign_activity, self).search(cr, uid, args,
+ return super(marketing_campaign_activity, self).search(cr, uid, args,
offset, limit, order, context, count)
def process(self, cr, uid, act_id, wi_id, context={}):
activity = self.browse(cr, uid, act_id)
workitem_obj = self.pool.get('marketing.campaign.workitem')
workitem = workitem_obj.browse(cr, uid, wi_id)
-
+
if activity.type == 'paper' :
service = netsvc.LocalService('report.%s'%activity.report_id.report_name)
(report_data, format) = service.create(cr, uid, [], {}, {})
@@ -298,7 +296,7 @@ class marketing_campaign_activity(osv.osv): #{{{
server_obj = self.pool.get('ir.actions.server')
server_obj.run(cr, uid, [activity.server_action_id.id], context)
#???
- return True
+ return True
marketing_campaign_activity()#}}}
class marketing_campaign_transition(osv.osv): #{{{
@@ -309,10 +307,10 @@ class marketing_campaign_transition(osv.osv): #{{{
_columns = {
'activity_from_id': fields.many2one('marketing.campaign.activity',
'Source Activity'),
- 'activity_to_id': fields.many2one('marketing.campaign.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'),
+ 'interval_type': fields.selection([('hours', 'Hours'), ('days', 'Days'),
('months', 'Months'),
('years','Years')],'Interval Type')
}
@@ -323,32 +321,46 @@ class marketing_campaign_transition(osv.osv): #{{{
if context.has_key('type_id'):
value[context['type_id']] = context['activity_id']
return value
-
+
marketing_campaign_transition() #}}}
class marketing_campaign_workitem(osv.osv): #{{{
_name = "marketing.campaign.workitem"
_description = "Campaign Workitem"
+ def _res_name_get(self, cr, uid, ids, field_name, arg, context=None):
+ res = {}
+ for obj in self.browse(cr, uid, ids, context=context):
+ if obj.res_id:
+ try:
+ res[obj.id] = self.pool.get(obj.object_id.model).name_get(cr, uid, [obj.res_id], context=context)[0][1]
+ except:
+ res[obj.id] = '/'
+ else:
+ res[obj.id] = '/'
+ return res
+
_columns = {
'segment_id': fields.many2one('marketing.campaign.segment', 'Segment',
- required=True),
+ required=True),
'activity_id': fields.many2one('marketing.campaign.activity','Activity',
- required=True),
- 'object_id': fields.related('segment_id', 'campaign_id', 'object_id',
- type='many2one', relation='ir.model',
- string='Object'),
- 'res_id': fields.integer('Results'),
+ required=True),
+ 'campaign_id': fields.related('segment_id', 'campaign_id',
+ type='many2one', relation='marketing.campaign', string='Campaign', readonly=True),
+ 'object_id': fields.related('segment_id', 'campaign_id', 'object_id',
+ type='many2one', relation='ir.model', string='Object'),
+ 'res_id': fields.integer('Resource ID'),
+ 'res_name': fields.function(_res_name_get, method=True, string='Resource Name', type="char", size=64),
'date': fields.datetime('Execution Date'),
'partner_id': fields.many2one('res.partner', 'Partner',required=True),
- 'state': fields.selection([('todo', 'ToDo'), ('inprogress', 'In Progress'),
+ 'state': fields.selection([('todo', 'ToDo'), ('inprogress', 'In Progress'),
('exception', 'Exception'), ('done', 'Done'),
('cancelled', 'Cancelled')], 'State'),
'error_msg' : fields.text('Error Message')
- }
+ }
_defaults = {
- 'state': lambda *a: 'draft',
+ 'state': lambda *a: 'todo',
}
def process_chain(self, cr, uid, workitem_id, context={}):
@@ -369,11 +381,17 @@ class marketing_campaign_workitem(osv.osv): #{{{
'state': 'todo',
}
self.create(cr, uid, workitem_vals)
-
+
+ def button_cancel(self, cr, uid, workitem_ids, context={}):
+ for wi in self.browse(cr, uid, workitem_ids):
+ if wi.state in ('todo','exception'):
+ self.write(cr, uid, [wi.id], {'state':'cancelled'}, context=context)
+ return True
+
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
+ if wi.state == 'todo':# we searched the wi which are in todo state
+ #then y v keep this filter again
eval_context = {
'pool': self.pool,
'cr': cr,
@@ -390,45 +408,44 @@ class marketing_campaign_workitem(osv.osv): #{{{
if res :
self.write(cr, uid, wi.id, {'state': 'done'})
self.process_chain(cr, uid, wi.id, context)
- else :
+ else :
self.write(cr, uid, wi.id, {'state': 'exception',
'error_msg': res['error_msg']})
except Exception,e:
self.write(cr, uid, wi.id, {'state': 'exception'})
else :
self.write(cr, uid, wi.id, {'state': 'cancelled'})
-
+
return True
-
+
def process_all(self, cr, uid, context={}):
workitem_ids = self.search(cr, uid, [('state', '=', 'todo'),
('date','<=', time.strftime('%Y-%m-%d %H:%M:%S'))])
if workitem_ids:
self.process(cr, uid, workitem_ids, context)
-
-marketing_campaign_workitem() #}}}
+
+marketing_campaign_workitem() #}}}
class email_template(osv.osv):
_inherit = "email.template"
-
_defaults = {
'object_name': lambda obj, cr, uid, context: context.get('object_id',False),
}
-email_template()
+email_template()
class report_xml(osv.osv):
_inherit = 'ir.actions.report.xml'
-
+
def search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False):
if not context:
context = {}
if context and 'object_id' in context and context['object_id']:
- model = self.pool.get('ir.model').browse(cr, uid,
+ model = self.pool.get('ir.model').browse(cr, uid,
context['object_id']).model
args.append(('model', '=', model))
return super(report_xml, self).search(cr, uid, args, offset, limit, order, context, count)
-
-report_xml()
+
+report_xml()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/marketing_campaign/marketing_campaign_view.xml b/addons/marketing_campaign/marketing_campaign_view.xml
index 3e2d7330291..8f0e6dcfcd6 100755
--- a/addons/marketing_campaign/marketing_campaign_view.xml
+++ b/addons/marketing_campaign/marketing_campaign_view.xml
@@ -14,75 +14,67 @@
form
@@ -122,13 +113,13 @@
-
-
+
+
-
-
+
+
@@ -183,21 +174,23 @@
form
@@ -374,11 +361,12 @@
-
-
-
+
+
+
+
@@ -389,14 +377,31 @@
form
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+