diff --git a/addons/base_action_rule/base_action_rule.py b/addons/base_action_rule/base_action_rule.py
index df2d43d3a53..77446c633ee 100644
--- a/addons/base_action_rule/base_action_rule.py
+++ b/addons/base_action_rule/base_action_rule.py
@@ -33,20 +33,99 @@ class base_action_rule(osv.osv):
_name = 'base.action.rule'
_description = 'Action Rules'
+
+ def _state_get(self, cr, uid, context={}):
+ """ Get State
+ @param self: The object pointer
+ @param cr: the current row, from the database cursor,
+ @param uid: the current user’s ID for security checks,
+ @param context: A standard dictionary for contextual values """
+ return self.state_get(cr, uid, context=context)
+
+
+ def state_get(self, cr, uid, context={}):
+ """ Get State
+ @param self: The object pointer
+ @param cr: the current row, from the database cursor,
+ @param uid: the current user’s ID for security checks,
+ @param context: A standard dictionary for contextual values """
+
+ return [('','')]
+
_columns = {
'name': fields.many2one('ir.model', 'Model', required=True),
'max_level': fields.integer('Max Level', help='Specifies maximum level.'),
- 'rule_lines': fields.one2many('base.action.rule.line','rule_id','Rule Lines'),
'create_date': fields.datetime('Create Date', readonly=1),
- 'active': fields.boolean('Active')
+ 'active': fields.boolean('Active', help="If the active field is set to true,\
+ it will allow you to hide the rule without removing it."),
+ 'sequence': fields.integer('Sequence', help="Gives the sequence order when\
+ displaying a list of rules."),
+ 'trg_date_type': fields.selection([
+ ('none','None'),
+ ('create','Creation Date'),
+ ('action_last','Last Action Date'),
+ ('date','Date'),
+ ('deadline', 'Deadline'),
+ ], 'Trigger Date', size=16),
+ 'trg_date_range': fields.integer('Delay after trigger date',help="Delay After Trigger Date,\
+ specifies you can put a negative number " \
+ "if you need a delay before the trigger date, like sending a reminder 15 minutes before a meeting."),
+ 'trg_date_range_type': fields.selection([('minutes', 'Minutes'),('hour','Hours'),\
+ ('day','Days'),('month','Months')], 'Delay type'),
+
+
+ 'trg_user_id': fields.many2one('res.users', 'Responsible'),
+
+ 'trg_partner_id': fields.many2one('res.partner', 'Partner'),
+ 'trg_partner_categ_id': fields.many2one('res.partner.category', 'Partner Category'),
+ 'trg_state_from': fields.selection(_state_get, 'State', size=16),
+ 'trg_state_to': fields.selection(_state_get, 'Button Pressed', size=16),
+
+ 'act_method': fields.char('Call Object Method', size=64),
+ 'act_user_id': fields.many2one('res.users', 'Set responsible to'),
+ 'act_state': fields.selection(_state_get, 'Set state to', size=16),
+ 'act_email_cc': fields.char('Add watchers (Cc)', size=250, help="These people\
+ will receive a copy of the future communication between partner and users by email"),
+
+ 'act_remind_partner': fields.boolean('Remind Partner', help="Check this if\
+ you want the rule to send a reminder by email to the partner."),
+ 'act_remind_user': fields.boolean('Remind responsible', help="Check this if \
+ you want the rule to send a reminder by email to the user."),
+ 'act_reply_to': fields.char('Reply-To', size=64),
+ 'act_remind_attach': fields.boolean('Remind with attachment', help="Check this if\
+ you want that all documents attached to the object be attached \
+ to the reminder email sent."),
+
+ 'act_mail_to_user': fields.boolean('Mail to responsible',help="Check this if \
+ you want the rule to send an email to the responsible person."),
+ 'act_mail_to_watchers': fields.boolean('Mail to watchers (CC)',help="Check this\
+ if you want the rule to mark CC(mail to any other person\
+ defined in actions)."),
+ 'act_mail_to_email': fields.char('Mail to these emails', size=128,help="Email-id \
+ of the persons whom mail is to be sent"),
+ 'act_mail_body': fields.text('Mail body',help="Content of mail"),
+ 'regex_name': fields.char('Regular Expression on Model Name', size=128),
+ 'server_action_id': fields.many2one('ir.actions.server','Server Action',help="Describes the\
+ action name." \
+ "eg:on which object which action to be taken on basis of which condition"),
+ 'domain':fields.char('Domain', size=124, required=False, readonly=False),
}
_defaults = {
'active': lambda *a: True,
'max_level': lambda *a: 15,
+ 'trg_date_type': lambda *a: 'none',
+ 'trg_date_range_type': lambda *a: 'day',
+ 'act_mail_to_user': lambda *a: 0,
+ 'act_remind_partner': lambda *a: 0,
+ 'act_remind_user': lambda *a: 0,
+ 'act_mail_to_watchers': lambda *a: 0,
+ 'domain': lambda *a: '[]'
}
-
+
+ _order = 'sequence'
+
def format_body(self, body):
""" Foramat Action rule's body
@param self: The object pointer """
@@ -56,7 +135,6 @@ class base_action_rule(osv.osv):
def format_mail(self, obj, body):
""" Foramat Mail
@param self: The object pointer """
-
data = {
'object_id': obj.id,
'object_subject': hasattr(obj, 'name') and obj.name or False,
@@ -105,6 +183,10 @@ class base_action_rule(osv.osv):
@param context: A standard dictionary for contextual values """
ok = True
+ if eval(action.domain):
+ obj_ids = obj._table.search(cr, uid, eval(action.domain), context=context)
+ if not obj.id in obj_ids:
+ ok = False
if hasattr(obj, 'user_id'):
ok = ok and (not action.trg_user_id.id or action.trg_user_id.id==obj.user_id.id)
if hasattr(obj, 'partner_id'):
@@ -122,10 +204,6 @@ class base_action_rule(osv.osv):
if state_to:
ok = ok and (not action.trg_state_to or action.trg_state_to==state_to)
- if hasattr(obj, 'priority'):
- ok = ok and (not action.trg_priority_from or action.trg_priority_from>=obj.priority)
- ok = ok and (not action.trg_priority_to or action.trg_priority_to<=obj.priority)
-
reg_name = action.regex_name
result_name = True
if reg_name:
@@ -163,10 +241,6 @@ class base_action_rule(osv.osv):
obj.categ_id = action.act_categ_id
write['categ_id'] = action.act_categ_id.id
- if hasattr(obj, 'priority') and action.act_priority:
- obj.priority = action.act_priority
- write['priority'] = action.act_priority
-
model_obj.write(cr, uid, [obj.id], write, context)
if hasattr(model_obj, 'remind_user') and action.act_remind_user:
@@ -198,178 +272,59 @@ class base_action_rule(osv.osv):
@param ids: List of Basic Action Rule’s IDs,
@param objects: pass objects
@param context: A standard dictionary for contextual values """
-
if not scrit:
scrit = []
- rule_line_obj = self.pool.get('base.action.rule.line')
- for rule in self.browse(cr, uid, ids):
- level = rule.max_level
+ cr.execute("select id from base_action_rule order by sequence")
+ rule_ids = map(lambda x: x[0], cr.fetchall())
+ for action in self.browse(cr, uid, rule_ids):
+ level = action.max_level
if not level:
break
- newactions = []
- scrit += [('rule_id','=',rule.id)]
- line_ids = rule_line_obj.search(cr, uid, scrit)
- actions = rule_line_obj.browse(cr, uid, line_ids, context=context)
- model_obj = self.pool.get(rule.name.model)
+ model_obj = self.pool.get(action.name.model)
for obj in objects:
- for action in actions:
- ok = self.do_check(cr, uid, action, obj, context=context)
- if not ok:
- continue
+ ok = self.do_check(cr, uid, action, obj, context=context)
+ if not ok:
+ continue
- base = False
- if hasattr(obj, 'create_date') and action.trg_date_type=='create':
- base = mx.DateTime.strptime(obj.create_date[:19], '%Y-%m-%d %H:%M:%S')
- elif hasattr(obj, 'create_date') and action.trg_date_type=='action_last':
- if hasattr(obj, 'date_action_last') and obj.date_action_last:
- base = mx.DateTime.strptime(obj.date_action_last, '%Y-%m-%d %H:%M:%S')
- else:
- base = mx.DateTime.strptime(obj.create_date[:19], '%Y-%m-%d %H:%M:%S')
- elif hasattr(obj, 'date_deadline') and action.trg_date_type=='deadline' \
- and obj.date_deadline:
- base = mx.DateTime.strptime(obj.date_deadline, '%Y-%m-%d %H:%M:%S')
- elif hasattr(obj, 'date') and action.trg_date_type=='date' and obj.date:
- base = mx.DateTime.strptime(obj.date, '%Y-%m-%d %H:%M:%S')
- if base:
- fnct = {
- 'minutes': lambda interval: mx.DateTime.RelativeDateTime(minutes=interval),
- 'day': lambda interval: mx.DateTime.RelativeDateTime(days=interval),
- 'hour': lambda interval: mx.DateTime.RelativeDateTime(hours=interval),
- 'month': lambda interval: mx.DateTime.RelativeDateTime(months=interval),
- }
- d = base + fnct[action.trg_date_range_type](action.trg_date_range)
- dt = d.strftime('%Y-%m-%d %H:%M:%S')
- ok = False
- if hasattr(obj, 'date_action_last') and hasattr(obj, 'date_action_next'):
- ok = (dt <= time.strftime('%Y-%m-%d %H:%M:%S')) and \
- ((not obj.date_action_next) or \
- (dt >= obj.date_action_next and \
- obj.date_action_last < obj.date_action_next))
- if not ok:
- if not obj.date_action_next or dt < obj.date_action_next:
- obj.date_action_next = dt
- model_obj.write(cr, uid, [obj.id], {'date_action_next': dt}, context)
+ base = False
+ if hasattr(obj, 'create_date') and action.trg_date_type=='create':
+ base = mx.DateTime.strptime(obj.create_date[:19], '%Y-%m-%d %H:%M:%S')
+ elif hasattr(obj, 'create_date') and action.trg_date_type=='action_last':
+ if hasattr(obj, 'date_action_last') and obj.date_action_last:
+ base = mx.DateTime.strptime(obj.date_action_last, '%Y-%m-%d %H:%M:%S')
else:
- ok = action.trg_date_type=='none'
-
- if ok:
- self.do_action(cr, uid, action, model_obj, obj, context)
- break
+ base = mx.DateTime.strptime(obj.create_date[:19], '%Y-%m-%d %H:%M:%S')
+ elif hasattr(obj, 'date_deadline') and action.trg_date_type=='deadline' \
+ and obj.date_deadline:
+ base = mx.DateTime.strptime(obj.date_deadline, '%Y-%m-%d %H:%M:%S')
+ elif hasattr(obj, 'date') and action.trg_date_type=='date' and obj.date:
+ base = mx.DateTime.strptime(obj.date, '%Y-%m-%d %H:%M:%S')
+ if base:
+ fnct = {
+ 'minutes': lambda interval: mx.DateTime.RelativeDateTime(minutes=interval),
+ 'day': lambda interval: mx.DateTime.RelativeDateTime(days=interval),
+ 'hour': lambda interval: mx.DateTime.RelativeDateTime(hours=interval),
+ 'month': lambda interval: mx.DateTime.RelativeDateTime(months=interval),
+ }
+ d = base + fnct[action.trg_date_range_type](action.trg_date_range)
+ dt = d.strftime('%Y-%m-%d %H:%M:%S')
+ ok = False
+ if hasattr(obj, 'date_action_last') and hasattr(obj, 'date_action_next'):
+ ok = (dt <= time.strftime('%Y-%m-%d %H:%M:%S')) and \
+ ((not obj.date_action_next) or \
+ (dt >= obj.date_action_next and \
+ obj.date_action_last < obj.date_action_next))
+ if not ok:
+ if not obj.date_action_next or dt < obj.date_action_next:
+ obj.date_action_next = dt
+ model_obj.write(cr, uid, [obj.id], {'date_action_next': dt}, context)
+ else:
+ ok = action.trg_date_type=='none'
+ if ok:
+ self.do_action(cr, uid, action, model_obj, obj, context)
+ break
level -= 1
return True
-base_action_rule()
-
-class base_action_rule_line(osv.osv):
- _name = 'base.action.rule.line'
- _description = 'Action Rule Lines'
-
- def _state_get(self, cr, uid, context={}):
- """ Get State
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param context: A standard dictionary for contextual values """
-
- return self.state_get(cr, uid, context=context)
- def _priority_get(self, cr, uid, context={}):
- """ Get Priority
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param context: A standard dictionary for contextual values """
-
- return self.priority_get(cr, uid, context=context)
-
- def state_get(self, cr, uid, context={}):
- """ Get State
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param context: A standard dictionary for contextual values """
-
- return [('','')]
- def priority_get(self, cr, uid, context={}):
- """ Get Priority
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param context: A standard dictionary for contextual values """
-
- return [('','')]
-
- _columns = {
- 'name': fields.char('Rule Name',size=64, required=True),
- 'rule_id': fields.many2one('base.action.rule','Rule'),
- 'active': fields.boolean('Active', help="If the active field is set to true,\
- it will allow you to hide the rule without removing it."),
- 'sequence': fields.integer('Sequence', help="Gives the sequence order when\
- displaying a list of rules."),
-
- 'trg_date_type': fields.selection([
- ('none','None'),
- ('create','Creation Date'),
- ('action_last','Last Action Date'),
- ('date','Date'),
- ('deadline', 'Deadline'),
- ], 'Trigger Date', size=16),
- 'trg_date_range': fields.integer('Delay after trigger date',help="Delay After Trigger Date,\
- specifies you can put a negative number " \
- "if you need a delay before the trigger date, like sending a reminder 15 minutes before a meeting."),
- 'trg_date_range_type': fields.selection([('minutes', 'Minutes'),('hour','Hours'),\
- ('day','Days'),('month','Months')], 'Delay type'),
-
-
- 'trg_user_id': fields.many2one('res.users', 'Responsible'),
-
- 'trg_partner_id': fields.many2one('res.partner', 'Partner'),
- 'trg_partner_categ_id': fields.many2one('res.partner.category', 'Partner Category'),
- 'trg_state_from': fields.selection(_state_get, 'State', size=16),
- 'trg_state_to': fields.selection(_state_get, 'Button Pressed', size=16),
- 'trg_priority_from': fields.selection(_priority_get, 'Minimum Priority'),
- 'trg_priority_to': fields.selection(_priority_get, 'Maximum Priority'),
-
- 'act_method': fields.char('Call Object Method', size=64),
- 'act_user_id': fields.many2one('res.users', 'Set responsible to'),
- 'act_state': fields.selection(_state_get, 'Set state to', size=16),
- 'act_priority': fields.selection(_priority_get, 'Set priority to'),
- 'act_email_cc': fields.char('Add watchers (Cc)', size=250, help="These people\
- will receive a copy of the future communication between partner and users by email"),
-
- 'act_remind_partner': fields.boolean('Remind Partner', help="Check this if\
- you want the rule to send a reminder by email to the partner."),
- 'act_remind_user': fields.boolean('Remind responsible', help="Check this if \
- you want the rule to send a reminder by email to the user."),
- 'act_reply_to': fields.char('Reply-To', size=64),
- 'act_remind_attach': fields.boolean('Remind with attachment', help="Check this if\
- you want that all documents attached to the object be attached \
- to the reminder email sent."),
-
- 'act_mail_to_user': fields.boolean('Mail to responsible',help="Check this if \
- you want the rule to send an email to the responsible person."),
- 'act_mail_to_watchers': fields.boolean('Mail to watchers (CC)',help="Check this\
- if you want the rule to mark CC(mail to any other person\
- defined in actions)."),
- 'act_mail_to_email': fields.char('Mail to these emails', size=128,help="Email-id \
- of the persons whom mail is to be sent"),
- 'act_mail_body': fields.text('Mail body',help="Content of mail"),
- 'regex_name': fields.char('Regular Expression on Model Name', size=128),
- 'server_action_id': fields.many2one('ir.actions.server','Server Action',help="Describes the\
- action name." \
- "eg:on which object which action to be taken on basis of which condition"),
- }
-
- _defaults = {
- 'active': lambda *a: 1,
- 'trg_date_type': lambda *a: 'none',
- 'trg_date_range_type': lambda *a: 'day',
- 'act_mail_to_user': lambda *a: 0,
- 'act_remind_partner': lambda *a: 0,
- 'act_remind_user': lambda *a: 0,
- 'act_mail_to_watchers': lambda *a: 0,
- }
-
- _order = 'sequence'
-
def _check_mail(self, cr, uid, ids, context=None):
""" Check Mail
@@ -393,6 +348,6 @@ class base_action_rule_line(osv.osv):
(_check_mail, 'Error: The mail is not well formated', ['act_mail_body']),
]
-base_action_rule_line()
+base_action_rule()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/base_action_rule/base_action_rule_view.xml b/addons/base_action_rule/base_action_rule_view.xml
index 09bbb2e2f5f..f7a476fd09e 100644
--- a/addons/base_action_rule/base_action_rule_view.xml
+++ b/addons/base_action_rule/base_action_rule_view.xml
@@ -16,52 +16,9 @@
-
-
-
-
-
-
- base.action.rule.tree
- base.action.rule
- tree
-
-
-
-
-
-
-
-
-
-
-
-
- Action Rules
- base.action.rule
- form
- tree,form
-
-
-
-
-
-
-
- base.action.rule.line.form
- base.action.rule.line
- form
-
-
-
+
-
+
-
- base.action.rule.line.tree
- base.action.rule.line
+
+ base.action.rule.tree
+ base.action.ruletree
-
-
-
+
+
+
+
+
+
+
+
+
+
+ Action Rules
+ base.action.rule
+ form
+ tree,form
+
-
+
+
diff --git a/addons/base_action_rule/security/ir.model.access.csv b/addons/base_action_rule/security/ir.model.access.csv
index 982dfdebfb5..99e4fc07c4b 100644
--- a/addons/base_action_rule/security/ir.model.access.csv
+++ b/addons/base_action_rule/security/ir.model.access.csv
@@ -1,3 +1,2 @@
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
"access_base_action_rule","base.action.rule","model_base_action_rule",,1,1,1,1
-"access_base_action_rule_line","base.action.rule.line","model_base_action_rule_line",,1,1,1,1
diff --git a/addons/base_calendar/base_calendar.py b/addons/base_calendar/base_calendar.py
index f4f1e68a269..372218b8088 100644
--- a/addons/base_calendar/base_calendar.py
+++ b/addons/base_calendar/base_calendar.py
@@ -29,6 +29,7 @@ import pytz
import re
import time
import tools
+from caldav import caldav
months = {
1: "January", 2: "February", 3: "March", 4: "April", \
@@ -1213,7 +1214,52 @@ e.g.: Every other month on the last Sunday of the month for 10 occurrences:\
if isinstance(select, (str, int, long)):
return ids and ids[0] or False
return ids
-
+
+ def check_import(self, cr, uid, vals, context={}):
+ """
+ @param self: The object pointer
+ @param cr: the current row, from the database cursor,
+ @param uid: the current user’s ID for security checks,
+ @param vals: Get Values
+ @param context: A standard dictionary for contextual values
+ """
+ ids = []
+ model_obj = self.pool.get(context.get('model'))
+ recur_pool = {}
+ try:
+ for val in vals:
+ exists, r_id = caldav.uid2openobjectid(cr, val['id'], context.get('model'), \
+ val.get('recurrent_id'))
+ if val.has_key('create_date'): val.pop('create_date')
+ u_id = val.get('id', None)
+ val.pop('id')
+ if exists and r_id:
+ val.update({'recurrent_uid': exists})
+ model_obj.write(cr, uid, [r_id], val)
+ ids.append(r_id)
+ elif exists:
+ # Compute value of duration
+ if 'date_deadline' in val and 'duration' not in val:
+ start = datetime.strptime(val['date'], '%Y-%m-%d %H:%M:%S')
+ end = datetime.strptime(val['date_deadline'], '%Y-%m-%d %H:%M:%S')
+ diff = end - start
+ val['duration'] = (diff.seconds/float(86400) + diff.days) * 24
+ model_obj.write(cr, uid, [exists], val)
+ ids.append(exists)
+ else:
+ if u_id in recur_pool and val.get('recurrent_id'):
+ val.update({'recurrent_uid': recur_pool[u_id]})
+ revent_id = model_obj.create(cr, uid, val)
+ ids.append(revent_id)
+ else:
+ event_id = model_obj.create(cr, uid, val)
+ recur_pool[u_id] = event_id
+ ids.append(event_id)
+ except Exception, e:
+ raise osv.except_osv(('Error !'), (str(e)))
+ return ids
+
+
def compute_rule_string(self, cr, uid, datas, context=None, *args):
"""
Compute rule string.
diff --git a/addons/base_calendar/base_calendar_view.xml b/addons/base_calendar/base_calendar_view.xml
index 2a48c0be32f..d9acae67a9e 100755
--- a/addons/base_calendar/base_calendar_view.xml
+++ b/addons/base_calendar/base_calendar_view.xml
@@ -190,7 +190,7 @@
+ on_change="onchange_dates(date,duration,False,allday)" attrs="{'invisible': [('allday', '=', True)]}"/>
diff --git a/addons/crm/__init__.py b/addons/crm/__init__.py
index 4931c46b328..e4b80da6ff2 100644
--- a/addons/crm/__init__.py
+++ b/addons/crm/__init__.py
@@ -24,8 +24,9 @@ import crm_mailgate
import crm_action_rule
import crm_segmentation
import crm_meeting
+import crm_opportunity
+import crm_lead
import crm_phonecall
-import crm_claim
import crm_fundraising
import crm_helpdesk
@@ -34,6 +35,5 @@ import wizard
-
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/crm/__openerp__.py b/addons/crm/__openerp__.py
index 9c5702c800b..ecf7d33261b 100644
--- a/addons/crm/__openerp__.py
+++ b/addons/crm/__openerp__.py
@@ -26,7 +26,7 @@
'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, claims, meeting, phonecall etc.
+leads, opportunities, meeting, phonecall etc.
It manages key tasks such as communication, identification, prioritization,
assignment, resolution and notification.
@@ -54,33 +54,61 @@ between mails and Open ERP.""",
],
'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',
],
'update_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_opportunity_to_phonecall_view.xml',
+ 'wizard/crm_partner_to_opportunity_view.xml',
+
'wizard/crm_send_email_view.xml',
'wizard/crm_email_add_cc_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',
'report/crm_report_view.xml',
-
+ 'report/crm_lead_report_view.xml',
+ 'report/crm_opportunity_report_view.xml' ,
+ 'report/crm_phonecall_report_view.xml',
+
'process/crm_configuration_process.xml',
],
'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_opportunity.yml',
-# 'test/test_crm_phonecall.yml',
-# 'test/test_crm_fund.yml',
-# 'test/test_crm_claim.yml',
-# 'test/test_crm_helpdesk.yml',
-# 'test/test_crm_meeting.yml',
-# ],
+ 'test': [
+ 'test/test_crm_meeting.yml',
+ 'test/test_crm_lead.yml',
+ 'test/test_crm_opportunity.yml',
+ 'test/test_crm_phonecall.yml',
+ ],
'installable': True,
'active': False,
'certificate': '0079056041421',
diff --git a/addons/crm/crm_action_rule.py b/addons/crm/crm_action_rule.py
index 718b12bb9c3..53062f4045b 100644
--- a/addons/crm/crm_action_rule.py
+++ b/addons/crm/crm_action_rule.py
@@ -152,6 +152,18 @@ 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."),
+ }
+
def email_send(self, cr, uid, obj, emails, body, emailfrom=tools.config.get('email_from',False), context={}):
body = self.format_mail(obj, body)
@@ -168,6 +180,17 @@ class base_action_rule(osv.osv):
if not emailfrom:
raise osv.except_osv(_('Error!'),
_("No E-Mail ID Found for your Company address!"))
+ if hasattr(obj, 'section_id'):
+ smtp_pool = self.pool.get('email.smtpclient')
+ if obj.section_id and obj.section_id.server_id:
+ flag = smtp_pool.send_email(
+ cr=cr,
+ uid=uid,
+ server_id=obj.section_id.server_id.id,
+ emailto=emails,
+ subject=name,
+ body="
%s
" % body,
+ )
return tools.email_send(emailfrom, emails, name, body, reply_to=reply_to, openobject_id=str(obj.id))
def do_check(self, cr, uid, action, obj, context={}):
@@ -207,7 +230,7 @@ class base_action_rule(osv.osv):
res = super(base_action_rule, self).do_action(cr, uid, action, model_obj, obj, context=context)
write = {}
- if hasattr(action, act_section_id) and action.act_section_id:
+ if hasattr(action, 'act_section_id') and action.act_section_id:
obj.section_id = action.act_section_id
write['section_id'] = action.act_section_id.id
@@ -231,13 +254,6 @@ class base_action_rule(osv.osv):
return True
-base_action_rule()
-
-class base_action_rule_line(osv.osv):
- """ Base Action Rule Line """
- _inherit = 'base.action.rule.line'
- _description = 'Base Action Rule Line'
-
def state_get(self, cr, uid, context={}):
"""@param self: The object pointer
@@ -245,28 +261,8 @@ class base_action_rule_line(osv.osv):
@param uid: the current user’s ID for security checks,
@param context: A standard dictionary for contextual values """
- res = super(base_action_rule_line, self).state_get(cr, uid, context=context)
- return res + [('escalate','Escalate')] + crm.AVAILABLE_STATES
+ res = super(base_action_rule, self).state_get(cr, uid, context=context)
+ return res + [('escalate', 'Escalate')] + crm.AVAILABLE_STATES
- def priority_get(self, cr, uid, context={}):
- """@param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param context: A standard dictionary for contextual values """
-
- res = super(base_action_rule_line, self).priority_get(cr, uid, context=context)
- return res + crm.AVAILABLE_PRIORITIES
-
- _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."),
- }
-
-base_action_rule_line()
+base_action_rule()
diff --git a/addons/crm/crm_action_rule_view.xml b/addons/crm/crm_action_rule_view.xml
index 78767a2f795..6211714232c 100644
--- a/addons/crm/crm_action_rule_view.xml
+++ b/addons/crm/crm_action_rule_view.xml
@@ -3,9 +3,9 @@
- base.action.rule.line.form.inherit
- base.action.rule.line
-
+ base.action.rule.form.inherit
+ base.action.rule
+ form
@@ -19,9 +19,9 @@
- base.action.rule.line.form2.inherit
- base.action.rule.line
-
+ base.action.rule.form2.inherit
+ base.action.rule
+ form
@@ -35,9 +35,9 @@
- base.action.rule.line.form3.inherit
- base.action.rule.line
-
+ base.action.rule.form3.inherit
+ base.action.rule
+ form
diff --git a/addons/crm/crm_lead.py.moved b/addons/crm/crm_lead.py.moved
new file mode 100644
index 00000000000..9c4c38875c5
--- /dev/null
+++ b/addons/crm/crm_lead.py.moved
@@ -0,0 +1,198 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2010 Tiny SPRL ().
+#
+# 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 .
+#
+##############################################################################
+
+from osv import fields, osv, orm
+from datetime import datetime, timedelta
+import crm
+import math
+import time
+import mx.DateTime
+from tools.translate import _
+
+class crm_lead(osv.osv):
+ """ CRM Lead Case """
+
+ _name = "crm.lead"
+ _description = "Leads Cases"
+ _order = "priority, id desc"
+ _inherit = ['res.partner.address', 'crm.case']
+
+ def case_open(self, cr, uid, ids, *args):
+ """
+ @param self: The object pointer
+ @param cr: the current row, from the database cursor,
+ @param uid: the current user’s ID for security checks,
+ @param ids: List of case's Ids
+ @param *args: Give Tuple Value
+ """
+
+ 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 _compute_day(self, cr, uid, ids, fields, args, context={}):
+ """
+ @param cr: the current row, from the database cursor,
+ @param uid: the current user’s ID for security checks,
+ @param ids: List of Openday’s IDs
+ @return: difference between current date and log date
+ @param context: A standard dictionary for contextual values
+ """
+ cal_obj = self.pool.get('resource.calendar')
+ res_obj = self.pool.get('resource.resource')
+
+ res = {}
+ for lead in self.browse(cr, uid, ids , context):
+ for field in fields:
+ res[lead.id] = {}
+ duration = 0
+ ans = False
+ if field == 'day_open':
+ if lead.date_open:
+ date_create = datetime.strptime(lead.create_date, "%Y-%m-%d %H:%M:%S")
+ date_open = datetime.strptime(lead.date_open, "%Y-%m-%d %H:%M:%S")
+ ans = date_open - date_create
+ date_until = lead.date_open
+ elif field == 'day_close':
+ if lead.date_closed:
+ date_create = datetime.strptime(lead.create_date, "%Y-%m-%d %H:%M:%S")
+ date_close = datetime.strptime(lead.date_closed, "%Y-%m-%d %H:%M:%S")
+ date_until = lead.date_closed
+ ans = date_close - date_create
+ if ans:
+ resource_id = False
+ if lead.user_id:
+ resource_ids = res_obj.search(cr, uid, [('user_id','=',lead.user_id.id)])
+ if len(resource_ids):
+ resource_id = resource_ids[0]
+
+ duration = float(ans.days)
+ if lead.section_id.resource_calendar_id:
+ 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,
+ mx.DateTime.strptime(lead.create_date, '%Y-%m-%d %H:%M:%S'),
+ duration,
+ resource=resource_id
+ )
+ no_days = []
+ date_until = mx.DateTime.strptime(date_until, '%Y-%m-%d %H:%M:%S')
+ for in_time, out_time in new_dates:
+ if in_time.date not in no_days:
+ no_days.append(in_time.date)
+ if out_time > date_until:
+ break
+ duration = len(no_days)
+ res[lead.id][field] = abs(int(duration))
+ return res
+
+ _columns = {
+
+ 'categ_id': fields.many2one('crm.case.categ', 'Lead Source', \
+ domain="[('section_id','=',section_id),\
+ ('object_id.model', '=', 'crm.opportunity')]"),
+ 'type_id': fields.many2one('crm.case.resource.type', 'Lead Type', \
+ domain="[('section_id','=',section_id),\
+ ('object_id.model', '=', 'crm.lead')]"),
+ 'partner_name': fields.char("Contact Name", size=64),
+
+ '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')]"),
+ 'opportunity_id': fields.many2one('crm.opportunity', 'Opportunity'),
+
+ 'user_id': fields.many2one('res.users', 'Salesman'),
+ '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),
+ }
+
+ _defaults = {
+ '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 convert_opportunity(self, cr, uid, ids, context=None):
+ """ Precomputation for converting lead to opportunity
+ @param cr: the current row, from the database cursor,
+ @param uid: the current user’s ID for security checks,
+ @param ids: List of closeday’s IDs
+ @param context: A standard dictionary for contextual values
+ @return: Value of action in dict
+ """
+ if not context:
+ context = {}
+ context.update({'active_ids': ids})
+
+ data_obj = self.pool.get('ir.model.data')
+ data_id = data_obj._get_id(cr, uid, 'crm', 'view_crm_lead2opportunity_create')
+ value = {}
+
+ view_id = False
+ if data_id:
+ view_id = data_obj.browse(cr, uid, data_id, context=context).res_id
+ for case in self.browse(cr, uid, ids):
+ context.update({'opportunity_id': case.id})
+ context.update({'active_id': case.id})
+ if not case.partner_id:
+ data_id = data_obj._get_id(cr, uid, 'crm', 'view_crm_lead2opportunity_partner')
+ view_id1 = False
+ if data_id:
+ view_id1 = data_obj.browse(cr, uid, data_id, context=context).res_id
+ value = {
+ 'name': _('Create Partner'),
+ 'view_type': 'form',
+ 'view_mode': 'form,tree',
+ 'res_model': 'crm.lead2opportunity.partner',
+ 'view_id': False,
+ 'context': context,
+ 'views': [(view_id1, 'form')],
+ 'type': 'ir.actions.act_window',
+ 'target': 'new',
+ 'nodestroy': True
+ }
+ break
+ else:
+ value = {
+ 'name': _('Create Opportunity'),
+ 'view_type': 'form',
+ 'view_mode': 'form,tree',
+ 'res_model': 'crm.lead2opportunity',
+ 'view_id': False,
+ 'context': context,
+ 'views': [(view_id, 'form')],
+ 'type': 'ir.actions.act_window',
+ 'target': 'new',
+ 'nodestroy': True
+ }
+ return value
+
+crm_lead()
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/crm/crm_lead_data.xml.moved b/addons/crm/crm_lead_data.xml.moved
new file mode 100644
index 00000000000..17211a9ef66
--- /dev/null
+++ b/addons/crm/crm_lead_data.xml.moved
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
+ New
+
+
+
+
+ Assigned
+
+
+
+
+ In Process
+
+
+
+
+ Converted
+
+
+
+
+ Recycled
+
+
+
+
+ Dead
+
+
+
+
+
+
+ Telesales
+
+
+
+
+ Mail
+
+
+
+
+ Email
+
+
+
+
+ Print
+
+
+
+
+ Web
+
+
+
+
+ Radio
+
+
+
+
+ Television
+
+
+
+
+ Newsletter
+
+
+
+
+
+
diff --git a/addons/crm/crm_lead_demo.xml.moved b/addons/crm/crm_lead_demo.xml.moved
new file mode 100644
index 00000000000..bc6638601c2
--- /dev/null
+++ b/addons/crm/crm_lead_demo.xml.moved
@@ -0,0 +1,112 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/crm/crm_lead_menu.xml.moved b/addons/crm/crm_lead_menu.xml.moved
new file mode 100644
index 00000000000..4d752ca8a9b
--- /dev/null
+++ b/addons/crm/crm_lead_menu.xml.moved
@@ -0,0 +1,33 @@
+
+
+
+
+
+ Leads
+ crm.lead
+ tree,form
+
+
+
+
+
+ tree
+
+
+
+
+
+ form
+
+
+
+
+
+
+
+
+
diff --git a/addons/crm/crm_lead_view.xml.moved b/addons/crm/crm_lead_view.xml.moved
new file mode 100644
index 00000000000..03318270e9b
--- /dev/null
+++ b/addons/crm/crm_lead_view.xml.moved
@@ -0,0 +1,331 @@
+
+
+
+
+
+
+
+ Lead Stages
+ crm.case.stage
+ form
+
+ [('object_id.model', '=', 'crm.lead')]
+ {'object_id':'crm.lead'}
+
+
+
+
+
+
+ Lead Resource Type
+ crm.case.resource.type
+ form
+
+ [('object_id.model', '=', 'crm.lead')]
+ {'object_id':'crm.lead'}
+
+
+
+
+
+
+ CRM - Leads Form
+ crm.lead
+ form
+
+
+
+
+
+
+
+
+ CRM - Leads Tree
+ crm.lead
+ tree
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ CRM - Leads Calendar
+ crm.lead
+ calendar
+
+
+
+
+
+
+
+
+
+
+
+
+
+ CRM - Leads Search
+ crm.lead
+ search
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/crm/crm_meeting_demo.xml b/addons/crm/crm_meeting_demo.xml
index a43f3e0d571..87d49d2f635 100644
--- a/addons/crm/crm_meeting_demo.xml
+++ b/addons/crm/crm_meeting_demo.xml
@@ -17,7 +17,7 @@
-
+
@@ -32,7 +32,7 @@
-
+
@@ -48,9 +48,9 @@
-
+
-
+
@@ -62,9 +62,9 @@
-
+
-
+
@@ -76,7 +76,7 @@
-
+
@@ -91,7 +91,7 @@
-
+
diff --git a/addons/crm/crm_meeting_view.xml b/addons/crm/crm_meeting_view.xml
index 35415a9d028..4c4856f46b0 100644
--- a/addons/crm/crm_meeting_view.xml
+++ b/addons/crm/crm_meeting_view.xml
@@ -25,12 +25,15 @@
-
-
+
+
+
+
+
diff --git a/addons/crm/crm_opportunity.py b/addons/crm/crm_opportunity.py
index 204890e348c..dec672c3277 100644
--- a/addons/crm/crm_opportunity.py
+++ b/addons/crm/crm_opportunity.py
@@ -231,7 +231,7 @@ class crm_opportunity(osv.osv):
}
value = {
'name': _('Meetings'),
- 'domain': "[('user_id','=',%s)]" % (uid),
+ 'domain': "[('user_id','=',%s),('opportunity_id','=',%s)]" % (uid,opp.id),
'context': context,
'view_type': 'form',
'view_mode': 'calendar,form,tree',
@@ -242,7 +242,6 @@ class crm_opportunity(osv.osv):
'search_view_id': res['res_id'],
'nodestroy': True
}
-
return value
crm_opportunity()
diff --git a/addons/crm/crm_opportunity.py.moved b/addons/crm/crm_opportunity.py.moved
new file mode 100644
index 00000000000..204890e348c
--- /dev/null
+++ b/addons/crm/crm_opportunity.py.moved
@@ -0,0 +1,249 @@
+#-*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2010 Tiny SPRL ().
+#
+# 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 .
+#
+##############################################################################
+
+from datetime import datetime
+from osv import fields,osv,orm
+from tools.translate import _
+import crm
+import time
+import mx.DateTime
+
+AVAILABLE_STATES = [
+ ('draft','Draft'),
+ ('open','Open'),
+ ('cancel', 'Lost'),
+ ('done', 'Converted'),
+ ('pending','Pending')
+]
+
+class crm_opportunity(osv.osv):
+ """ Opportunity Cases """
+
+ _name = "crm.opportunity"
+ _description = "Opportunity Cases"
+ _order = "priority,date_action,id desc"
+ _inherit = 'crm.case'
+
+ def case_open(self, cr, uid, ids, *args):
+ """
+ @param self: The object pointer
+ @param cr: the current row, from the database cursor,
+ @param uid: the current user’s ID for security checks,
+ @param ids: List of case's Ids
+ @param *args: Give Tuple Value
+ """
+
+ res = super(crm_opportunity, 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 _compute_day(self, cr, uid, ids, fields, args, context={}):
+ """
+ @param cr: the current row, from the database cursor,
+ @param uid: the current user’s ID for security checks,
+ @param ids: List of Openday’s IDs
+ @return: difference between current date and log date
+ @param context: A standard dictionary for contextual values
+ """
+ cal_obj = self.pool.get('resource.calendar')
+ res_obj = self.pool.get('resource.resource')
+
+ res = {}
+ for opportunity in self.browse(cr, uid, ids , context):
+ for field in fields:
+ res[opportunity.id] = {}
+ duration = 0
+ ans = False
+ if field == 'day_open':
+ if opportunity.date_open:
+ date_create = datetime.strptime(opportunity.create_date, "%Y-%m-%d %H:%M:%S")
+ date_open = datetime.strptime(opportunity.date_open, "%Y-%m-%d %H:%M:%S")
+ ans = date_open - date_create
+ date_until = opportunity.date_open
+ elif field == 'day_close':
+ if opportunity.date_closed:
+ date_create = datetime.strptime(opportunity.create_date, "%Y-%m-%d %H:%M:%S")
+ date_close = datetime.strptime(opportunity.date_closed, "%Y-%m-%d %H:%M:%S")
+ date_until = opportunity.date_closed
+ ans = date_close - date_create
+ if ans:
+ resource_id = False
+ if opportunity.user_id:
+ resource_ids = res_obj.search(cr, uid, [('user_id','=',opportunity.user_id.id)])
+ if resource_ids and len(resource_ids):
+ resource_id = resource_ids[0]
+
+ duration = float(ans.days)
+ if opportunity.section_id.resource_calendar_id:
+ duration = float(ans.days) * 24
+ new_dates = cal_obj.interval_get(cr,
+ uid,
+ opportunity.section_id.resource_calendar_id and opportunity.section_id.resource_calendar_id.id or False,
+ mx.DateTime.strptime(opportunity.create_date, '%Y-%m-%d %H:%M:%S'),
+ duration,
+ resource=resource_id
+ )
+ no_days = []
+ date_until = mx.DateTime.strptime(date_until, '%Y-%m-%d %H:%M:%S')
+ for in_time, out_time in new_dates:
+ if in_time.date not in no_days:
+ no_days.append(in_time.date)
+ if out_time > date_until:
+ break
+ duration = len(no_days)
+ res[opportunity.id][field] = abs(int(duration))
+ return res
+
+ _columns = {
+ 'stage_id': fields.many2one ('crm.case.stage', 'Stage', \
+ domain="[('section_id','=',section_id),\
+ ('object_id.model', '=', 'crm.opportunity')]"),
+ 'categ_id': fields.many2one('crm.case.categ', 'Category', \
+ domain="[('section_id','=',section_id), \
+ ('object_id.model', '=', 'crm.opportunity')]"),
+ 'priority': fields.selection(crm.AVAILABLE_PRIORITIES, 'Priority'),
+ 'referred': fields.char('Referred By', size=64),
+ 'probability': fields.float('Probability (%)'),
+ 'planned_revenue': fields.float('Expected Revenue'),
+ 'ref': fields.reference('Reference', selection=crm._links_get, size=128),
+ 'ref2': fields.reference('Reference 2', selection=crm._links_get, size=128),
+ 'date_closed': fields.datetime('Closed', readonly=True),
+ 'user_id': fields.many2one('res.users', 'Salesman'),
+ 'phone': fields.char("Phone", size=64),
+ 'date_deadline': fields.date('Expected Closing'),
+ 'date_action': fields.date('Next Action'),
+ 'state': fields.selection(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\'.\
+ \nIf the case needs to be reviewed then the state is set to \'Pending\'.'),
+
+ '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),
+ }
+
+ def onchange_stage_id(self, cr, uid, ids, stage_id, context={}):
+
+ """ @param self: The object pointer
+ @param cr: the current row, from the database cursor,
+ @param uid: the current user’s ID for security checks,
+ @param ids: List of stage’s IDs
+ @stage_id: change state id on run time """
+
+ if not stage_id:
+ return {'value':{}}
+
+ stage = self.pool.get('crm.case.stage').browse(cr, uid, stage_id, context)
+ if not stage.on_change:
+ return {'value':{}}
+ return {'value':{'probability':stage.probability}}
+
+ def stage_next(self, cr, uid, ids, context={}):
+
+ """ @param self: The object pointer
+ @param cr: the current row, from the database cursor,
+ @param uid: the current user’s ID for security checks,
+ @param ids: List of stage next’s IDs
+ @param context: A standard dictionary for contextual values """
+
+ res = super(crm_opportunity, self).stage_next(cr, uid, ids, context=context)
+ for case in self.browse(cr, uid, ids, context):
+ if case.stage_id and case.stage_id.on_change:
+ self.write(cr, uid, [case.id], {'probability': case.stage_id.probability})
+ return res
+
+ def stage_previous(self, cr, uid, ids, context={}):
+
+ """ @param self: The object pointer
+ @param cr: the current row, from the database cursor,
+ @param uid: the current user’s ID for security checks,
+ @param ids: List of stage previous’s IDs
+ @param context: A standard dictionary for contextual values """
+
+ res = super(crm_opportunity, self).stage_previous(cr, uid, ids, context=context)
+ for case in self.browse(cr, uid, ids, context):
+ if case.stage_id and case.stage_id.on_change:
+ self.write(cr, uid, [case.id], {'probability': case.stage_id.probability})
+ return res
+
+ _defaults = {
+ 'company_id': lambda s,cr,uid,c: s.pool.get('res.company')._company_default_get(cr, uid, 'crm.opportunity', context=c),
+ 'priority': lambda *a: crm.AVAILABLE_PRIORITIES[2][0],
+ 'state' : 'draft',
+ }
+
+ def action_makeMeeting(self, cr, uid, ids, context=None):
+ """
+ This opens Meeting's calendar view to schedule meeting on current Opportunity
+ @param self: The object pointer
+ @param cr: the current row, from the database cursor,
+ @param uid: the current user’s ID for security checks,
+ @param ids: List of Opportunity to Meeting IDs
+ @param context: A standard dictionary for contextual values
+
+ @return : Dictionary value for created Meeting view
+ """
+ value = {}
+ for opp in self.browse(cr, uid, ids):
+ data_obj = self.pool.get('ir.model.data')
+
+ # Get meeting views
+ result = data_obj._get_id(cr, uid, 'crm', 'view_crm_case_meetings_filter')
+ res = data_obj.read(cr, uid, result, ['res_id'])
+ id1 = data_obj._get_id(cr, uid, 'crm', 'crm_case_calendar_view_meet')
+ id2 = data_obj._get_id(cr, uid, 'crm', 'crm_case_form_view_meet')
+ id3 = data_obj._get_id(cr, uid, 'crm', 'crm_case_tree_view_meet')
+ if id1:
+ id1 = data_obj.browse(cr, uid, id1, context=context).res_id
+ if id2:
+ id2 = data_obj.browse(cr, uid, id2, context=context).res_id
+ if id3:
+ id3 = data_obj.browse(cr, uid, id3, context=context).res_id
+
+ context = {
+ 'default_opportunity_id': opp.id,
+ 'default_partner_id': opp.partner_id and opp.partner_id.id or False,
+ 'default_section_id': opp.section_id and opp.section_id.id or False,
+ 'default_email_from': opp.email_from,
+ 'default_state': 'open',
+ 'default_name': opp.name
+ }
+ value = {
+ 'name': _('Meetings'),
+ 'domain': "[('user_id','=',%s)]" % (uid),
+ 'context': context,
+ 'view_type': 'form',
+ 'view_mode': 'calendar,form,tree',
+ 'res_model': 'crm.meeting',
+ 'view_id': False,
+ 'views': [(id1, 'calendar'), (id2, 'form'), (id3, 'tree')],
+ 'type': 'ir.actions.act_window',
+ 'search_view_id': res['res_id'],
+ 'nodestroy': True
+ }
+
+ return value
+
+crm_opportunity()
+
diff --git a/addons/crm/crm_opportunity_data.xml.moved b/addons/crm/crm_opportunity_data.xml.moved
new file mode 100644
index 00000000000..b3780990a13
--- /dev/null
+++ b/addons/crm/crm_opportunity_data.xml.moved
@@ -0,0 +1,95 @@
+
+
+
+
+ Existing Customer
+
+
+
+
+ Self Generated
+
+
+
+
+ Employee
+
+
+
+
+ Partner
+
+
+
+
+ Campaign
+
+
+
+
+ Website
+
+
+
+
+ Word of mouth
+
+
+
+
+ Other
+
+
+
+
+
+
+ Prospecting
+
+
+
+
+ Needs Analysis
+
+
+
+
+ Value Proposition
+
+
+
+
+ Proposal/Price Quote
+
+
+
+
+ Negotiation/Review
+
+
+
+
+ Closed Won
+
+
+
+
+ Closed Lost
+
+
+
+
+
+
+ Existing Business
+
+
+
+
+ New Business
+
+
+
+
+
+
diff --git a/addons/crm/crm_opportunity_demo.xml.moved b/addons/crm/crm_opportunity_demo.xml.moved
new file mode 100644
index 00000000000..b893d536e44
--- /dev/null
+++ b/addons/crm/crm_opportunity_demo.xml.moved
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/crm/crm_opportunity_menu.xml b/addons/crm/crm_opportunity_menu.xml
index 3bcdbc7bb9f..55bf9354287 100644
--- a/addons/crm/crm_opportunity_menu.xml
+++ b/addons/crm/crm_opportunity_menu.xml
@@ -18,8 +18,8 @@
res_model="crm.phonecall"
src_model="crm.opportunity"
view_mode="calendar,tree,form"
- context="{'default_duration': 1.0}"
- domain="[('user_id','=',uid)]"
+ context="{'default_duration': 1.0 ,'default_opportunity_id': active_id}"
+ domain="[('user_id','=',uid),('opportunity_id', '=', active_id)]"
view_type="form"/>
diff --git a/addons/crm/crm_opportunity_menu.xml.moved b/addons/crm/crm_opportunity_menu.xml.moved
new file mode 100644
index 00000000000..3bcdbc7bb9f
--- /dev/null
+++ b/addons/crm/crm_opportunity_menu.xml.moved
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+ Opportunities
+ crm.opportunity
+ tree,form,graph
+
+
+
+
+
+ tree
+
+
+
+
+
+ form
+
+
+
+
+
+ graph
+
+
+
+
+
+
+
+
diff --git a/addons/crm/crm_opportunity_view.xml.moved b/addons/crm/crm_opportunity_view.xml.moved
new file mode 100644
index 00000000000..4bdc0d90158
--- /dev/null
+++ b/addons/crm/crm_opportunity_view.xml.moved
@@ -0,0 +1,329 @@
+
+
+
+
+
+
+
+ Opportunity Categories
+ crm.case.categ
+ form
+
+ [('object_id.model', '=', 'crm.opportunity')]
+ {'object_id':'crm.opportunity'}
+
+
+
+
+
+
+
+ Opportunity Stages
+ crm.case.stage
+ form
+
+ [('object_id.model', '=', 'crm.opportunity')]
+ {'object_id':'crm.opportunity'}
+
+
+
+
+
+
+
+ Opportunity Resource Type
+ crm.case.resource.type
+ form
+
+ [('object_id.model', '=', 'crm.opportunity')]
+ {'object_id':'crm.opportunity'}
+
+
+
+
+
+
+
+ Opportunities
+ crm.opportunity
+ form
+
+
+
+
+
+
+
+
+ Opportunities Tree
+ crm.opportunity
+ tree
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ CRM - Opportunity Graph
+ crm.opportunity
+ graph
+
+
+
+
+
+
+
+
+
+
+
+
+ CRM - Opportunities Search
+ crm.opportunity
+ search
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/crm/report/__init__.py b/addons/crm/report/__init__.py
index 640b78357de..41688e4c31f 100644
--- a/addons/crm/report/__init__.py
+++ b/addons/crm/report/__init__.py
@@ -21,10 +21,9 @@
#import report_businessopp
import crm_report
-import crm_claim_report
+import crm_lead_report
+import crm_opportunity_report
import crm_phonecall_report
-import crm_fundraising_report
-import crm_helpdesk_report
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/crm/report/crm_lead_report.py.moved b/addons/crm/report/crm_lead_report.py.moved
new file mode 100644
index 00000000000..d400700c0b5
--- /dev/null
+++ b/addons/crm/report/crm_lead_report.py.moved
@@ -0,0 +1,88 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2010 Tiny SPRL ().
+#
+# 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 .
+#
+##############################################################################
+
+from osv import fields,osv
+import tools
+
+AVAILABLE_STATES = [
+ ('draft','Draft'),
+ ('open','Open'),
+ ('cancel', 'Cancelled'),
+ ('done', 'Closed'),
+ ('pending','Pending')
+]
+
+class crm_lead_report(osv.osv):
+ """ CRM Lead Report """
+ _name = "crm.lead.report"
+ _auto = False
+ _inherit = "crm.case.report"
+ _description = "CRM Lead Report"
+
+ _columns = {
+ 'delay_close': fields.float('Delay to close',digits=(16,2),readonly=True, group_operator="avg",help="Number of Days to close the case"),
+ 'categ_id': fields.many2one('crm.case.categ', 'Category',\
+ domain="[('section_id','=',section_id),\
+ ('object_id.model', '=', 'crm.lead')]" , readonly=True),
+ 'stage_id': fields.many2one ('crm.case.stage', 'Stage', \
+ domain="[('section_id','=',section_id),\
+ ('object_id.model', '=', 'crm.lead')]", readonly=True),
+ 'partner_id': fields.many2one('res.partner', 'Partner' , readonly=True),
+ 'company_id': fields.many2one('res.company', 'Company', readonly=True),
+ }
+ def init(self, cr):
+
+ """
+ CRM Lead Report
+ @param cr: the current row, from the database cursor
+ """
+
+ tools.drop_view_if_exists(cr, 'crm_lead_report')
+ cr.execute("""
+ create or replace view crm_lead_report as (
+ select
+ min(c.id) as id,
+ to_char(c.create_date, 'YYYY') as name,
+ to_char(c.create_date, 'MM') as month,
+ to_char(c.create_date, 'YYYY-MM-DD') as day,
+ c.state as state,
+ c.user_id,
+ c.stage_id,
+ c.company_id,
+ c.section_id,
+ c.categ_id,
+ c.partner_id,
+ count(*) as nbr,
+ 0 as avg_answers,
+ 0.0 as perc_done,
+ 0.0 as perc_cancel,
+ date_trunc('day',c.create_date) as create_date,
+ avg(extract('epoch' from (c.date_closed-c.create_date)))/(3600*24) as delay_close
+ from
+ crm_lead c
+ group by to_char(c.create_date, 'YYYY'), to_char(c.create_date, 'MM'),\
+ c.state, c.user_id,c.section_id,c.stage_id,categ_id,c.partner_id,c.company_id
+ ,c.create_date,to_char(c.create_date, 'YYYY-MM-DD')
+ )""")
+
+crm_lead_report()
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/crm/report/crm_lead_report_view.xml.moved b/addons/crm/report/crm_lead_report_view.xml.moved
new file mode 100644
index 00000000000..d6502c190d9
--- /dev/null
+++ b/addons/crm/report/crm_lead_report_view.xml.moved
@@ -0,0 +1,116 @@
+
+
+
+
+
+
+
+ crm.lead.report.tree
+ crm.lead.report
+ tree
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ crm.lead.report.form
+ crm.lead.report
+
+ form
+
+
+
+
+
+
+
+
+
+
+
+ crm.lead.report.graph
+ crm.lead.report
+ graph
+
+
+
+
+
+
+
+
+
+
+
+
+ crm.lead.report.select
+ crm.lead.report
+
+ search
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Leads
+ crm.lead.report
+ form
+ {"search_default_User":1,"search_default_This Month":1,'group_by_no_leaf':1,'group_by':[]}
+ tree,graph
+
+
+
+
+
+
+ tree
+
+
+
+
+
+
+ graph
+
+
+
+
+
+
+
+
diff --git a/addons/crm/report/crm_opportunity_report.py.moved b/addons/crm/report/crm_opportunity_report.py.moved
new file mode 100644
index 00000000000..a3af4be8b7c
--- /dev/null
+++ b/addons/crm/report/crm_opportunity_report.py.moved
@@ -0,0 +1,100 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2010 Tiny SPRL ().
+#
+# 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 .
+#
+##############################################################################
+
+from osv import fields,osv
+import tools
+
+AVAILABLE_STATES = [
+ ('draft','Draft'),
+ ('open','Open'),
+ ('cancel', 'Cancelled'),
+ ('done', 'Closed'),
+ ('pending','Pending')
+]
+
+class crm_opportunity_report(osv.osv):
+ """ CRM Opportunity Report """
+ _name = "crm.opportunity.report"
+ _auto = False
+ _inherit = "crm.case.report"
+ _description = "CRM Opportunity Report"
+ _columns = {
+ 'probability': fields.float('Avg. Probability', readonly=True,group_operator='avg'),
+ 'amount_revenue': fields.float('Est.Revenue', readonly=True),
+ 'amount_revenue_prob': fields.float('Est. Rev*Prob.', readonly=True),
+ 'delay_close': fields.float('Delay to close',digits=(16,2),readonly=True, group_operator="avg",help="Number of Days to close the case"),
+ 'categ_id': fields.many2one('crm.case.categ', 'Category',\
+ domain="[('section_id','=',section_id),\
+ ('object_id.model', '=', 'crm.opportunity')]", readonly=True),
+ 'stage_id':fields.many2one('crm.case.stage', 'Stage',\
+ domain="[('section_id','=',section_id),\
+ ('object_id.model', '=', 'crm.opportunity')]", readonly=True),
+ 'partner_id': fields.many2one('res.partner', 'Partner', readonly=True),
+ 'company_id': fields.many2one('res.company', 'Company', readonly=True),
+ 'user_id':fields.many2one('res.users', 'User', readonly=True),
+ }
+
+ def init(self, cr):
+ """ Display Est.Revenue , Average Probability ,Est.Revenue Probability
+ @param cr: the current row, from the database cursor
+ """
+
+ tools.drop_view_if_exists(cr, 'crm_opportunity_report')
+ cr.execute("""
+ create or replace view crm_opportunity_report as (
+ select
+ min(c.id) as id,
+ to_char(c.create_date, 'YYYY') as name,
+ to_char(c.create_date, 'MM') as month,
+ to_char(c.create_date, 'YYYY-MM-DD') as day,
+ c.state as state,
+ c.user_id,
+ c.section_id,
+ c.categ_id,
+ c.stage_id,
+ c.partner_id,
+ c.company_id,
+ count(*) as nbr,
+ 0 as avg_answers,
+ 0.0 as perc_done,
+ 0.0 as perc_cancel,
+ date_trunc('day',c.create_date) as create_date,
+ sum(planned_revenue) as amount_revenue,
+ sum((planned_revenue*probability)/100.0)::decimal(16,2) as amount_revenue_prob,
+ avg(probability)::decimal(16,2) as probability,
+ avg(extract('epoch' from (c.date_closed-c.create_date)))/(3600*24) as delay_close
+ from
+ crm_opportunity c
+ group by
+ to_char(c.create_date, 'YYYY'),
+ to_char(c.create_date, 'MM'),
+ to_char(c.create_date, 'YYYY-MM-DD'),
+ c.state,
+ c.user_id,
+ c.section_id,
+ c.stage_id,
+ c.categ_id,
+ c.partner_id,
+ company_id,
+ create_date
+ )""")
+
+crm_opportunity_report()
diff --git a/addons/crm/report/crm_opportunity_report_view.xml.moved b/addons/crm/report/crm_opportunity_report_view.xml.moved
new file mode 100644
index 00000000000..29a66b838f0
--- /dev/null
+++ b/addons/crm/report/crm_opportunity_report_view.xml.moved
@@ -0,0 +1,122 @@
+
+
+
+
+
+
+
+ crm.opportunity.report.tree
+ crm.opportunity.report
+ tree
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ crm.opportunity.report.form
+ crm.opportunity.report
+
+ form
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ crm.opportunity.report.graph
+ crm.opportunity.report
+ graph
+
+
+
+
+
+
+
+
+
+
+
+
+ crm.opportunity.report.select
+ crm.opportunity.report
+
+ search
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Opportunities
+ crm.opportunity.report
+ form
+ tree,graph
+ {"search_default_User":1,"search_default_This Month":1,'group_by_no_leaf':1,'group_by':[]}
+
+
+
+
+ tree
+
+
+
+
+
+ graph
+
+
+
+
+
+
+
+
diff --git a/addons/crm/security/ir.model.access.csv b/addons/crm/security/ir.model.access.csv
index 2efb716deb1..37a36fc5504 100644
--- a/addons/crm/security/ir.model.access.csv
+++ b/addons/crm/security/ir.model.access.csv
@@ -5,10 +5,9 @@
"access_crm_case_categ","crm.case.categ","model_crm_case_categ","crm.group_crm_user",1,0,0,0
"access_crm_case_manger","crm.case manager","model_crm_case","crm.group_crm_user",1,1,1,1
"access_crm_case","crm.case","model_crm_case","crm.group_crm_manager",1,1,1,1
-"access_crm_claim","crm.claim","model_crm_claim","crm.group_crm_manager",1,1,1,1
-"access_crm_fundraising","crm.fundraising","model_crm_fundraising","crm.group_crm_manager",1,1,1,1
-"access_crm_helpdesk","crm.helpdesk","model_crm_helpdesk","crm.group_crm_manager",1,1,1,1
"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_opportunity","crm.opportunity","model_crm_opportunity","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
@@ -24,13 +23,16 @@
"access_crm_case_resource_type_manager","crm_case_resource_type manager","model_crm_case_resource_type","crm.group_crm_manager",1,1,1,1
"access_crm_case_report_user","crm.case.report","model_crm_case_report","crm.group_crm_user",1,0,0,0
"access_crm_case_report_manager","crm.case.report manager","model_crm_case_report","crm.group_crm_manager",1,1,1,1
-"access_crm_claim_report_user","crm.claim.report","model_crm_claim_report","crm.group_crm_user",1,0,0,0
-"access_crm_fundraising_report_user","crm.fundraising.report","model_crm_fundraising_report","crm.group_crm_user",1,0,0,0
+"access_crm_lead_report_user","crm.lead.report","model_crm_lead_report","crm.group_crm_user",1,0,0,0
"access_crm_phonecall_report_user","crm.phonecall.report","model_crm_phonecall_report","crm.group_crm_user",1,0,0,0
+"access_crm_opportunity_report_user","crm.opportunity.report","model_crm_opportunity_report","crm.group_crm_user",1,0,0,0
"access_report_crm_case_service_dashboard","report.crm.case.service.dashboard","model_report_crm_case_service_dashboard","crm.group_crm_user",1,0,0,0
+"access_crm_lead2partner","crm.lead2partner","model_crm_lead2partner","crm.group_crm_user",1,1,1,1
+"access_crm_lead2opportunity","crm.lead2opportunity","model_crm_lead2opportunity","crm.group_crm_user",1,1,1,1
+"access_crm_opportunity2phonecall","crm.opportunity2phonecall","model_crm_opportunity2phonecall","crm.group_crm_user",1,1,1,1
"access_crm_phonecall2phonecall","crm.phonecall2phonecall","model_crm_phonecall2phonecall","crm.group_crm_user",1,1,1,1
"access_crm_phonecall2partner","crm.phonecall2partner","model_crm_phonecall2partner","crm.group_crm_user",1,1,1,1
"access_crm_phonecall2opportunity","crm.phonecall2opportunity","model_crm_phonecall2opportunity","crm.group_crm_user",1,1,1,1
-"access_report_crm_helpdesk","report.crm.helpdesk","model_crm_helpdesk_report","crm.group_crm_user",1,1,1,1
"access_crm_send_mail","crm.send.mail","model_crm_send_mail","crm.group_crm_user",1,1,1,1
"access_crm_partner2opportunity","crm.partner2opportunity","model_crm_partner2opportunity","crm.group_crm_user",1,1,1,1
+"access_crm_lead2opportunity_partner","crm.lead2opportunity.partner","model_crm_lead2opportunity_partner","crm.group_crm_user",1,1,1,1
diff --git a/addons/crm/test/test_crm_lead.yml.moved b/addons/crm/test/test_crm_lead.yml.moved
new file mode 100644
index 00000000000..22fdfffca1b
--- /dev/null
+++ b/addons/crm/test/test_crm_lead.yml.moved
@@ -0,0 +1,113 @@
+- |
+ In order to test the CRM in OpenERP,
+ I will do a customer qualification process that
+ starts with a fist contact with a customer (a lead), which will be converted to a
+ business opportunity and a partner.
+- |
+ In order to test the flow, I create a two new users "user_crm" and
+ I assign the group "salesman".
+-
+ !record {model: res.users, id: res_users_usercrm0}:
+ company_id: base.main_company
+ context_lang: en_US
+ context_section_id: crm.section_sales_department
+ groups_id:
+ - crm.group_crm_user
+ 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
+ new customer, as well as an email "info@mycustomer.com".
+-
+ !record {model: crm.lead, id: crm_lead_newcustomer0}:
+ email_from: info@mycustomer.com
+ name: New Customer
+ partner_name: Sandip zala
+ phone: (855) 924-4364
+ mobile: (333) 715-1450
+ section_id: crm.section_sales_department
+ referred: False
+ title: M.
+- |
+ I check that the lead is in 'draft' state,
+-
+ !assert {model: crm.lead, id: crm_lead_newcustomer0, string: Lead in Draft}:
+ - state == "draft"
+-
+ I open lead by click on "Open" button,
+-
+ !python {model: crm.lead}: |
+ self.case_open(cr, uid, [ref("crm_lead_newcustomer0")])
+
+- |
+ As the lead seems to be a real business opportunity, I will convert it to a
+ partner
+ and a business opportunity by clicking on the "Convert" button.
+-
+ !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")]})
+-
+ |
+ Now, select "create a new partner" option in this wizard.
+-
+ !record {model: crm.lead2opportunity.partner, id: crm_lead2opportunity_partner_create_0}:
+ action: 'create'
+-
+ I click on "Continue" button of this wizard.
+-
+ !python {model: crm.lead2opportunity.partner}: |
+ self.make_partner(cr, uid, [ref("crm_lead2opportunity_partner_create_0")], {'active_ids': [ref("crm_lead_newcustomer0")]})
+-
+ Now, I give value to this wizard field.
+-
+ !record {model: crm.lead2opportunity, id: crm_lead2opportunity_stonage_0}:
+ name: Sandip zala
+ planned_revenue: 0.00
+ probability: 0.00
+-
+ Then, Click on "Create Opportunity" button of this wizard.
+-
+ !python {model: crm.lead2opportunity}: |
+ self.action_apply(cr, uid, [ref('crm_lead2opportunity_stonage_0')], {'active_id': ref('crm_lead_newcustomer0')})
+
+- |
+ 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
+
+- |
+ I check that the partner associated to this lead as the same country, phone number
+ and name than the opportunity.
+-
+ !python {model: crm.lead}: |
+ lead = self.browse(cr, uid, ref("crm_lead_newcustomer0"))
+ print "lead", lead.partner_name
+ obj_opportunity = self.pool.get('crm.opportunity')
+ ids = obj_opportunity.search(cr, uid, [('name', '=', lead.partner_name)])
+ opportunity = obj_opportunity.browse(cr, uid, ids)[0]
+ assert lead.partner_name == opportunity.partner_id.name
+ assert lead.phone == opportunity.phone
+-
+ |
+ # yaml is also not working smpt server and send new email.
+
+- |
+ I configure with smtp server.
+- |
+ And I communicate with lead through send New mail to Lead using it email address from user which are loged.
+- |
+ I check that communication history generated when send email to lead.
+- |
+ Then, I add a cc which receive copy of future communication between partner and users by mail.
+
+- |
+ I Reply to last Email to lead with some document attached.and check that communication history generated or not.
+
+
\ No newline at end of file
diff --git a/addons/crm/test/test_crm_opportunity.yml.moved b/addons/crm/test/test_crm_opportunity.yml.moved
new file mode 100644
index 00000000000..d7118dd0c90
--- /dev/null
+++ b/addons/crm/test/test_crm_opportunity.yml.moved
@@ -0,0 +1,81 @@
+- |
+ I start by creating a new Opportunity. And I select partner for opportunity.
+ I can see that after selecting partner his contact and email is automatically filled.
+-
+ !record {model: crm.opportunity, id: crm_opportunity_abcfuelcounits0}:
+ email_from: info@balmerinc.be
+ name: 'ABC FUEL CO 829264 - 10002 units '
+ partner_address_id: base.res_partner_address_1
+ partner_id: base.res_partner_9
+ probability: 1.0
+ stage_id: crm.stage_oppor1
+ categ_id: crm.categ_oppor2
+ section_id: crm.section_sales_department
+
+- |
+ I check that the opportunity is in 'New' state.
+-
+ !assert {model: crm.opportunity, id: crm_opportunity_abcfuelcounits0}:
+ - state == "draft"
+- |
+ I open opportunity by click on "Open" button,
+-
+ !python {model: crm.opportunity}: |
+ self.case_open(cr, uid, [ref("crm_opportunity_abcfuelcounits0")])
+
+- |
+ I schedule Meeting on this current opportunity by clicking on "schedule
+ Meeting".
+-
+ !python {model: crm.opportunity}: |
+ self.action_makeMeeting(cr, uid, [ref("crm_opportunity_abcfuelcounits0")])
+
+- |
+ I can see that Meeting's calendar view is shown.
+ then I click on the date on which I want schedule meeting.
+ I fill proper data for that meeting and save it
+-
+ !record {model: crm.meeting, id: crm_meeting_abcfuelcounits0}:
+ alarm_id: base_calendar.alarm3
+ date: '2010-04-16 00:00:00'
+ date_deadline: '2010-04-16 08:00:00'
+ duration: 8.0
+ email_from: info@balmerinc.be
+ name: 'ABC FUEL CO 829264 - 10002 units '
+ opportunity_id: 'crm_opportunity_abcfuelcounits0'
+ partner_address_id: base.res_partner_address_1
+ partner_id: base.res_partner_9
+ rrule_type: weekly
+ section_id: crm.section_sales_department
+ state: open
+- |
+ In order to schedule a phonecall to the partner
+ I click on "schedule call" button and select planned date for the call.
+-
+ !record {model: crm.opportunity2phonecall, id: crm_opportunity2phonecall_abcfuelcounits0}:
+ date: '2010-04-17 11:15:00'
+ name: 'ABC FUEL CO 829264 - 10002 units '
+ section_id: crm.section_sales_department
+ user_id: base.user_demo
+- |
+ schedule phonecall by apply (action_apply)function of opportunity2phoncall wizard
+-
+ !python {model: crm.opportunity2phonecall}: |
+ self.action_apply(cr, uid, [ref('crm_opportunity2phonecall_abcfuelcounits0')], {'active_ids': [ref("crm_opportunity_abcfuelcounits0")]})
+- |
+ I check that phonecall record is created for that opportunity.
+-
+ !python {model: crm.phonecall}: |
+ ids = self.search(cr, uid, [('name', '=', 'ABC FUEL CO 829264 - 10002 units')])
+ assert len(ids)
+- |
+ I can see phonecall record after click on "Schedule call" wizard.
+-
+ !record {model: crm.phonecall, id: crm_phonecall_abcfuelcounits0}:
+ date: '2010-04-17 11:15:00'
+ duration: 3.0
+ name: 'ABC FUEL CO 829264 - 10002 units'
+ partner_address_id: base.res_partner_address_1
+ partner_id: base.res_partner_9
+ section_id: crm.section_sales_department
+
\ No newline at end of file
diff --git a/addons/crm/wizard/__init__.py b/addons/crm/wizard/__init__.py
index cc51af05076..f3d92447acd 100644
--- a/addons/crm/wizard/__init__.py
+++ b/addons/crm/wizard/__init__.py
@@ -21,6 +21,10 @@
import crm_send_email
import crm_email_add_cc
+
+import crm_lead_to_partner
+import crm_lead_to_opportunity
+import crm_opportunity_to_phonecall
import crm_phonecall_to_phonecall
import crm_phonecall_to_partner
import crm_phonecall_to_opportunity
diff --git a/addons/crm/wizard/crm_lead_to_opportunity.py.moved b/addons/crm/wizard/crm_lead_to_opportunity.py.moved
new file mode 100644
index 00000000000..c8cce059f09
--- /dev/null
+++ b/addons/crm/wizard/crm_lead_to_opportunity.py.moved
@@ -0,0 +1,327 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2010 Tiny SPRL ().
+#
+# 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 .
+#
+##############################################################################
+
+from mx.DateTime import now
+from osv import osv, fields
+from tools.translate import _
+
+
+class crm_lead2opportunity(osv.osv_memory):
+ _name = 'crm.lead2opportunity'
+ _description = 'Lead To Opportunity'
+
+ def action_cancel(self, cr, uid, ids, context=None):
+ """
+ Closes Lead To Opportunity form
+ @param self: The object pointer
+ @param cr: the current row, from the database cursor,
+ @param uid: the current user’s ID for security checks,
+ @param ids: List of Lead to Partner's IDs
+ @param context: A standard dictionary for contextual values
+
+ """
+ return {'type': 'ir.actions.act_window_close'}
+
+ def action_apply(self, cr, uid, ids, context=None):
+ """
+ This converts lead to opportunity and opens Opportunity view
+ @param self: The object pointer
+ @param cr: the current row, from the database cursor,
+ @param uid: the current user’s ID for security checks,
+ @param ids: List of Lead to Opportunity IDs
+ @param context: A standard dictionary for contextual values
+
+ @return : Dictionary value for created Opportunity form
+ """
+ record_id = context and context.get('active_id', False) or False
+ if not record_id:
+ return {}
+
+ lead_obj = self.pool.get('crm.lead')
+ opp_obj = self. pool.get('crm.opportunity')
+ 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
+ result = data_obj._get_id(cr, uid, 'crm', 'view_crm_case_opportunities_filter')
+ res = data_obj.read(cr, uid, result, ['res_id'])
+ id2 = data_obj._get_id(cr, uid, 'crm', 'crm_case_form_view_oppor')
+ id3 = data_obj._get_id(cr, uid, 'crm', 'crm_case_tree_view_oppor')
+ if id2:
+ id2 = data_obj.browse(cr, uid, id2, context=context).res_id
+ if id3:
+ id3 = data_obj.browse(cr, uid, id3, context=context).res_id
+
+ lead = lead_obj.browse(cr, uid, record_id, context=context)
+ model_ids = model_obj.search(cr, uid, [('model', '=', 'crm.opportunity')])
+
+
+ for this in self.browse(cr, uid, ids, context=context):
+ new_opportunity_id = opp_obj.create(cr, uid, {
+ 'name': this.name,
+ 'referred': lead.referred,
+ 'planned_revenue': this.planned_revenue,
+ 'probability': this.probability,
+ 'partner_id': lead.partner_id and lead.partner_id.id or False,
+ 'section_id': lead.section_id and lead.section_id.id or False,
+ 'description': lead.description or False,
+ 'date_deadline': lead.date_deadline or False,
+ 'partner_address_id': lead.partner_address_id and lead.partner_address_id.id or False ,
+ 'priority': lead.priority,
+ 'phone': lead.phone,
+ 'email_from': lead.email_from
+ })
+ new_opportunity = opp_obj.browse(cr, uid, new_opportunity_id)
+ vals = {
+ 'partner_id': this.partner_id and this.partner_id.id or False,
+ }
+ if not lead.opportunity_id:
+ vals.update({'opportunity_id' : new_opportunity.id})
+
+ model_opportunity_id = self.pool.get('ir.model').search(cr, uid, [('model', '=', 'crm.opportunity')], context=context)[0]
+
+ for model in ('crm.case.log', 'crm.case.history'):
+ log_proxy = self.pool.get(model)
+ log_ids = log_proxy.search(cr, uid, [('model_id.model', '=', 'crm.lead'),('res_id', '=', lead.id)], context=context)
+ for log_id in log_ids:
+ log_proxy.copy(cr, uid, log_id, {'model_id':model_opportunity_id}, context=context)
+
+ lead_obj.write(cr, uid, [lead.id], vals)
+ lead_obj.case_close(cr, uid, [lead.id])
+
+ # Copy lead history to opportunity
+ for his_id in lead.history_line:
+ history_ids = history_obj.copy(cr, uid, his_id.id, \
+ {'model_id': model_ids[0], \
+ 'res_id': new_opportunity_id})
+
+ #opp_obj.case_open(cr, uid, [new_opportunity_id])
+
+ value = {
+ 'name': _('Opportunity'),
+ 'view_type': 'form',
+ 'view_mode': 'form,tree',
+ 'res_model': 'crm.opportunity',
+ 'res_id': int(new_opportunity_id),
+ 'view_id': False,
+ 'views': [(id2, 'form'), (id3, 'tree'), (False, 'calendar'), (False, 'graph')],
+ 'type': 'ir.actions.act_window',
+ 'search_view_id': res['res_id']
+ }
+ return value
+
+ _columns = {
+ 'name' : fields.char('Opportunity Summary', size=64, required=True, select=1),
+ 'probability': fields.float('Success Probability'),
+ 'planned_revenue': fields.float('Expected Revenue'),
+ 'partner_id': fields.many2one('res.partner', 'Partner'),
+ }
+
+ 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 user’s ID for security checks,
+ @param fields: List of fields for default value
+ @param context: A standard dictionary for contextual values
+
+ """
+ lead_obj = self.pool.get('crm.lead')
+
+ for lead in lead_obj.browse(cr, uid, context.get('active_ids', [])):
+ if lead.state in ['done', 'cancel']:
+ raise osv.except_osv(_("Warning !"), _("Closed/Cancelled \
+Leads Could not convert into Opportunity"))
+ if lead.state != 'open':
+ raise osv.except_osv(_('Warning !'), _('Lead should be in \
+\'Open\' state before converting to Opportunity.'))
+ return False
+
+ def default_get(self, cr, uid, fields, context=None):
+ """
+ This function gets default values
+ @param self: The object pointer
+ @param cr: the current row, from the database cursor,
+ @param uid: the current user’s ID for security checks,
+ @param fields: List of fields for default value
+ @param context: A standard dictionary for contextual values
+
+ @return : default values of fields.
+ """
+ lead_obj = self.pool.get('crm.lead')
+ rec_ids = context and context.get('active_ids', [])
+ partner_id = context.get('partner_id', False)
+ data = context and context.get('active_ids', []) or []
+ res = super(crm_lead2opportunity, self).default_get(cr, uid, fields, context=context)
+ for lead in lead_obj.browse(cr, uid, data, context=context):
+ if 'name' in fields:
+ res.update({'name': lead.partner_name})
+ if 'partner_id' in fields:
+ res.update({'partner_id': partner_id and partner_id[0] or False})
+ return res
+
+crm_lead2opportunity()
+
+
+class crm_lead2opportunity_partner(osv.osv_memory):
+ _name = 'crm.lead2opportunity.partner'
+ _description = 'Lead To Opportunity Partner'
+ _inherit = 'crm.lead2partner'
+
+ _columns = {
+ 'partner_id': fields.many2one('res.partner', 'Partner'),
+ 'action': fields.selection([('exist', 'Link to an existing partner'), ('create', 'Create a new partner')], 'Action'),
+ }
+
+ def default_get(self, cr, uid, fields, context=None):
+ """
+ This function gets default values
+ @param self: The object pointer
+ @param cr: the current row, from the database cursor,
+ @param uid: the current user’s ID for security checks,
+ @param fields: List of fields for default value
+ @param context: A standard dictionary for contextual values
+
+ @return : default values of fields.
+ """
+ lead_obj = self.pool.get('crm.lead')
+ partner_obj = self.pool.get('res.partner')
+ contact_obj = self.pool.get('res.partner.address')
+ rec_ids = context and context.get('active_ids', [])
+ partner_id = False
+
+ data = context and context.get('active_ids', []) or []
+ res = super(crm_lead2opportunity_partner, self).default_get(cr, uid, fields, context=context)
+
+ for lead in lead_obj.browse(cr, uid, data, context=context):
+ partner_ids = partner_obj.search(cr, uid, [('name', '=', lead.partner_name or lead.name)])
+ if not partner_ids and lead.email_from:
+ address_ids = contact_obj.search(cr, uid, [('email', '=', lead.email_from)])
+ if address_ids:
+ addresses = contact_obj.browse(cr, uid, address_ids)
+ partner_ids = addresses and [addresses[0].partner_id.id] or False
+ partner_id = partner_ids and partner_ids[0] or False
+
+ if 'partner_id' in fields:
+ res.update({'partner_id': partner_id})
+ if 'action' in fields:
+ res.update({'action': partner_id and 'exist' or 'create'})
+ return res
+
+ def make_partner(self, cr, uid, ids, context=None):
+ """
+ This function Makes partner based on action.
+ @param self: The object pointer
+ @param cr: the current row, from the database cursor,
+ @param uid: the current user’s ID for security checks,
+ @param ids: List of Lead to Partner's IDs
+ @param context: A standard dictionary for contextual values
+
+ @return : Dictionary value for created Partner form.
+ """
+ if not context:
+ context = {}
+
+ partner_ids = self._create_partner(cr, uid, ids, context)
+ mod_obj = self.pool.get('ir.model.data')
+ result = mod_obj._get_id(cr, uid, 'base', 'view_res_partner_filter')
+ res = mod_obj.read(cr, uid, result, ['res_id'])
+ value = {}
+ data_obj = self.pool.get('ir.model.data')
+ data_id = data_obj._get_id(cr, uid, 'crm', 'view_crm_lead2opportunity_create')
+ view_id = False
+ if data_id:
+ view_id = data_obj.browse(cr, uid, data_id, context=context).res_id
+
+ context.update({'partner_id': partner_ids})
+ value = {
+ 'name': _('Create Opportunity'),
+ 'view_type': 'form',
+ 'view_mode': 'form,tree',
+ 'res_model': 'crm.lead2opportunity',
+ 'view_id': False,
+ 'context': context,
+ 'views': [(view_id, 'form')],
+ 'type': 'ir.actions.act_window',
+ 'target': 'new',
+ }
+ return value
+
+ def action_skip(self, cr, uid, ids, context=None):
+ """
+ This skips partner creation
+ @param self: The object pointer
+ @param cr: the current row, from the database cursor,
+ @param uid: the current user’s ID for security checks,
+ @param ids: List of Lead to Opportunity IDs
+ @param context: A standard dictionary for contextual values
+
+ @return : Dictionary value for Opportunity form
+ """
+ value = {}
+ data_obj = self.pool.get('ir.model.data')
+ data_id = data_obj._get_id(cr, uid, 'crm', 'view_crm_lead2opportunity_create')
+ view_id = False
+ if data_id:
+ view_id = data_obj.browse(cr, uid, data_id, context=context).res_id
+
+ context.update({'partner_id': False})
+ value = {
+ 'name': _('Create Opportunity'),
+ 'view_type': 'form',
+ 'view_mode': 'form,tree',
+ 'res_model': 'crm.lead2opportunity',
+ 'view_id': False,
+ 'context': context,
+ 'views': [(view_id, 'form')],
+ 'type': 'ir.actions.act_window',
+ 'target': 'new',
+ }
+ return value
+
+
+ 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 user’s ID for security checks,
+ @param fields: List of fields for default value
+ @param context: A standard dictionary for contextual values
+
+ """
+ lead_obj = self.pool.get('crm.lead')
+
+ for lead in lead_obj.browse(cr, uid, context.get('active_ids', [])):
+ if lead.state in ['done', 'cancel']:
+ raise osv.except_osv(_("Warning !"), _("Closed/Cancelled \
+Leads Could not convert into Opportunity"))
+ if lead.state != 'open':
+ raise osv.except_osv(_('Warning !'), _('Lead should be in \
+\'Open\' state before converting to Opportunity.'))
+ return False
+
+crm_lead2opportunity_partner()
+
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/crm/wizard/crm_lead_to_opportunity_view.xml.moved b/addons/crm/wizard/crm_lead_to_opportunity_view.xml.moved
new file mode 100644
index 00000000000..229b54e09fe
--- /dev/null
+++ b/addons/crm/wizard/crm_lead_to_opportunity_view.xml.moved
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+ crm.lead2opportunity.create
+ crm.lead2opportunity
+ form
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Create Opportunity
+ ir.actions.act_window
+ crm.lead2opportunity
+ form
+ form
+ new
+
+
+
+
+ crm.lead2opportunity.partner.form
+ crm.lead2opportunity.partner
+ form
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/crm/wizard/crm_lead_to_partner.py.moved b/addons/crm/wizard/crm_lead_to_partner.py.moved
new file mode 100644
index 00000000000..267c3296844
--- /dev/null
+++ b/addons/crm/wizard/crm_lead_to_partner.py.moved
@@ -0,0 +1,216 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2010 Tiny SPRL ().
+#
+# 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 .
+#
+##############################################################################
+
+from osv import osv, fields
+from tools.translate import _
+
+class crm_lead2partner(osv.osv_memory):
+ """ Converts lead to partner """
+
+ _name = 'crm.lead2partner'
+ _description = 'Lead to Partner'
+
+ _columns = {
+ 'action': fields.selection([('exist', 'Link to an existing partner'), \
+ ('create', 'Create a new partner')], \
+ 'Action', required=True),
+ 'partner_id': fields.many2one('res.partner', 'Partner')
+ }
+
+ 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 user’s ID for security checks,
+ @param fields: List of fields for default value
+ @param context: A standard dictionary for contextual values
+
+ """
+
+ lead_obj = self.pool.get('crm.lead')
+ rec_ids = context and context.get('active_ids', [])
+ for lead in lead_obj.browse(cr, uid, rec_ids, context=context):
+ if lead.partner_id:
+ raise osv.except_osv(_('Warning !'),
+ _('A partner is already defined on this lead.'))
+
+ def default_get(self, cr, uid, fields, context=None):
+ """
+ This function gets default values
+ @param self: The object pointer
+ @param cr: the current row, from the database cursor,
+ @param uid: the current user’s ID for security checks,
+ @param fields: List of fields for default value
+ @param context: A standard dictionary for contextual values
+
+ @return : default values of fields.
+ """
+ lead_obj = self.pool.get('crm.lead')
+ partner_obj = self.pool.get('res.partner')
+ contact_obj = self.pool.get('res.partner.address')
+ rec_ids = context and context.get('active_ids', [])
+ partner_id = False
+
+ data = context and context.get('active_ids', []) or []
+ res = super(crm_lead2partner, self).default_get(cr, uid, fields, context=context)
+
+ for lead in lead_obj.browse(cr, uid, data, context=context):
+ partner_ids = partner_obj.search(cr, uid, [('name', '=', lead.partner_name or lead.name)])
+ if not partner_ids and lead.email_from:
+ address_ids = contact_obj.search(cr, uid, [('email', '=', lead.email_from)])
+ if address_ids:
+ addresses = contact_obj.browse(cr, uid, address_ids)
+ partner_ids = addresses and [addresses[0].partner_id.id] or False
+ partner_id = partner_ids and partner_ids[0] or False
+
+ if 'partner_id' in fields:
+ res.update({'partner_id': partner_id})
+ if 'action' in fields:
+ res.update({'action': partner_id and 'exist' or 'create'})
+ return res
+
+ def open_create_partner(self, cr, uid, ids, context=None):
+ """
+ This function Opens form of create partner.
+ @param self: The object pointer
+ @param cr: the current row, from the database cursor,
+ @param uid: the current user’s ID for security checks,
+ @param ids: List of Lead to Partner's IDs
+ @param context: A standard dictionary for contextual values
+
+ @return : Dictionary value for next form.
+ """
+ if not context:
+ context = {}
+
+ view_obj = self.pool.get('ir.ui.view')
+ view_id = view_obj.search(cr, uid, [('model', '=', 'crm.lead2partner'), \
+ ('name', '=', 'crm.lead2partner.view')])
+ return {
+ 'view_mode': 'form',
+ 'view_type': 'form',
+ 'view_id': view_id or False,
+ 'res_model': 'crm.lead2partner',
+ 'context': context,
+ 'type': 'ir.actions.act_window',
+ 'target': 'new',
+ }
+
+
+ def _create_partner(self, cr, uid, ids, context=None):
+ """
+ This function Creates partner based on action.
+ @param self: The object pointer
+ @param cr: the current row, from the database cursor,
+ @param uid: the current user’s ID for security checks,
+ @param ids: List of Lead to Partner's IDs
+ @param context: A standard dictionary for contextual values
+
+ @return : Dictionary {}.
+ """
+ if not context:
+ context = {}
+
+ lead_obj = self.pool.get('crm.lead')
+ partner_obj = self.pool.get('res.partner')
+ contact_obj = self.pool.get('res.partner.address')
+ partner_ids = []
+ partner_id = False
+ contact_id = False
+ rec_ids = context and context.get('active_ids', [])
+
+ for data in self.browse(cr, uid, ids):
+ for lead in lead_obj.browse(cr, uid, rec_ids):
+ if data.action == 'create':
+ partner_id = partner_obj.create(cr, uid, {
+ 'name': lead.partner_name or lead.name,
+ 'user_id': lead.user_id.id,
+ 'comment': lead.description,
+ })
+ function_id = self.pool.get('res.partner.function').search(cr,uid,[('name','=',lead.function_name)])
+ contact_id = contact_obj.create(cr, uid, {
+ 'partner_id': partner_id,
+ 'name': lead.name,
+ 'phone': lead.phone,
+ 'mobile': lead.mobile,
+ 'email': lead.email_from,
+ 'fax': lead.fax,
+ 'title': lead.title,
+ 'function': function_id and function_id[0] or False,
+ 'street': lead.street,
+ 'street2': lead.street2,
+ 'zip': lead.zip,
+ 'city': lead.city,
+ 'country_id': lead.country_id and lead.country_id.id or False,
+ 'state_id': lead.state_id and lead.state_id.id or False,
+ })
+
+ else:
+ if data.partner_id:
+ partner_id = data.partner_id.id
+ contact_id = partner_obj.address_get(cr, uid, [partner_id])['default']
+
+ partner_ids.append(partner_id)
+
+ vals = {}
+ if partner_id:
+ vals.update({'partner_id': partner_id})
+ if contact_id:
+ vals.update({'partner_address_id': contact_id})
+ lead_obj.write(cr, uid, [lead.id], vals)
+ return partner_ids
+
+ def make_partner(self, cr, uid, ids, context=None):
+ """
+ This function Makes partner based on action.
+ @param self: The object pointer
+ @param cr: the current row, from the database cursor,
+ @param uid: the current user’s ID for security checks,
+ @param ids: List of Lead to Partner's IDs
+ @param context: A standard dictionary for contextual values
+
+ @return : Dictionary value for created Partner form.
+ """
+ if not context:
+ context = {}
+
+ partner_ids = self._create_partner(cr, uid, ids, context)
+ mod_obj = self.pool.get('ir.model.data')
+ result = mod_obj._get_id(cr, uid, 'base', 'view_res_partner_filter')
+ res = mod_obj.read(cr, uid, result, ['res_id'])
+
+ value = {
+ 'domain': "[]",
+ 'view_type': 'form',
+ 'view_mode': 'form,tree',
+ 'res_model': 'res.partner',
+ 'res_id': partner_ids and int(partner_ids[0]) or False,
+ 'view_id': False,
+ 'context': context,
+ 'type': 'ir.actions.act_window',
+ 'search_view_id': res['res_id']
+ }
+ return value
+
+crm_lead2partner()
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/crm/wizard/crm_lead_to_partner_view.xml.moved b/addons/crm/wizard/crm_lead_to_partner_view.xml.moved
new file mode 100644
index 00000000000..53d4f1b5476
--- /dev/null
+++ b/addons/crm/wizard/crm_lead_to_partner_view.xml.moved
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+ crm.lead2partner.view.create
+ crm.lead2partner
+ form
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/crm/wizard/crm_opportunity_to_phonecall.py.moved b/addons/crm/wizard/crm_opportunity_to_phonecall.py.moved
new file mode 100644
index 00000000000..148ec3aec6e
--- /dev/null
+++ b/addons/crm/wizard/crm_opportunity_to_phonecall.py.moved
@@ -0,0 +1,139 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2010 Tiny SPRL ().
+#
+# 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 .
+#
+##############################################################################
+
+from osv import osv, fields
+from tools.translate import _
+
+class crm_opportunity2phonecall(osv.osv_memory):
+ """Converts Opportunity to Phonecall"""
+
+ _name = 'crm.opportunity2phonecall'
+ _description = 'Opportunity to Phonecall'
+
+ _columns = {
+ 'name' : fields.char('Call summary', size=64, required=True, select=1),
+ 'user_id' : fields.many2one('res.users', "Assign To"),
+ 'date': fields.datetime('Date' , required=True),
+ 'section_id': fields.many2one('crm.case.section', 'Sales Team'),
+ }
+
+ def default_get(self, cr, uid, fields, context=None):
+ """
+ This function gets default values
+ @param self: The object pointer
+ @param cr: the current row, from the database cursor,
+ @param uid: the current user’s ID for security checks,
+ @param fields: List of fields for default value
+ @param context: A standard dictionary for contextual values
+
+ @return : default values of fields.
+ """
+
+ opp_obj = self.pool.get('crm.opportunity')
+ record_ids = context and context.get('active_ids', []) or []
+ res = super(crm_opportunity2phonecall, self).default_get(cr, uid, fields, context=context)
+ for opp in opp_obj.browse(cr, uid, record_ids, context=context):
+ if 'name' in fields:
+ res.update({'name': opp.name})
+ if 'user_id' in fields:
+ res.update({'user_id': opp.user_id and opp.user_id.id or False})
+ if 'section_id' in fields:
+ res.update({'section_id': opp.section_id and opp.section_id.id or False})
+ return res
+
+ def action_cancel(self, cr, uid, ids, context=None):
+ """
+ Closes Opportunity to Phonecall form
+ @param self: The object pointer
+ @param cr: the current row, from the database cursor,
+ @param uid: the current user’s ID for security checks,
+ @param ids: List of Opportunity to Phonecall's IDs
+ @param context: A standard dictionary for contextual values
+ """
+ return {'type': 'ir.actions.act_window_close'}
+
+ def action_apply(self, cr, uid, ids, context=None):
+ """
+ This converts Opportunity to Phonecall and opens Phonecall view
+ @param self: The object pointer
+ @param cr: the current row, from the database cursor,
+ @param uid: the current user’s ID for security checks,
+ @param ids: List of Opportunity to Phonecall IDs
+ @param context: A standard dictionary for contextual values
+
+ @return : Dictionary value for created Opportunity form
+ """
+ value = {}
+ record_ids = context and context.get('active_ids', []) or []
+
+ phonecall_obj = self.pool.get('crm.phonecall')
+ opp_obj = self.pool.get('crm.opportunity')
+ mod_obj = self.pool.get('ir.model.data')
+ result = mod_obj._get_id(cr, uid, 'crm', 'view_crm_case_phonecalls_filter')
+ res = mod_obj.read(cr, uid, result, ['res_id'])
+
+ data_obj = self.pool.get('ir.model.data')
+ categ_id = mod_obj._get_id(cr, uid, 'crm', 'categ_phone1')
+ categ_id = data_obj.browse(cr, uid, categ_id, context=context).res_id
+
+ # Select the view
+ id2 = data_obj._get_id(cr, uid, 'crm', 'crm_case_phone_tree_view')
+ id3 = data_obj._get_id(cr, uid, 'crm', 'crm_case_phone_form_view')
+ if id2:
+ id2 = data_obj.browse(cr, uid, id2, context=context).res_id
+ if id3:
+ id3 = data_obj.browse(cr, uid, id3, context=context).res_id
+
+ for this in self.browse(cr, uid, ids, context=context):
+ for opp in opp_obj.browse(cr, uid, record_ids, context=context):
+ new_case = phonecall_obj.create(cr, uid, {
+ 'name' : opp.name,
+ 'case_id' : opp.id ,
+ 'user_id' : this.user_id and this.user_id.id or False,
+ 'categ_id' : categ_id,
+ 'description' : opp.description or False,
+ 'date' : this.date,
+ 'section_id' : opp.section_id and opp.section_id.id or False,
+ 'partner_id': opp.partner_id and opp.partner_id.id or False,
+ 'partner_address_id': opp.partner_address_id and opp.partner_address_id.id or False,
+ 'partner_phone' : opp.phone or (opp.partner_address_id and opp.partner_address_id.phone or False),
+ 'partner_mobile' : opp.partner_address_id and opp.partner_address_id.mobile or False,
+ 'priority': opp.priority,
+ 'opp_id': opp.id
+ }, context=context)
+
+ phonecall_obj.case_open(cr, uid, [new_case])
+
+ value = {
+ 'name': _('Phone Call'),
+ 'view_type': 'form',
+ 'view_mode': 'tree,form',
+ 'res_model': 'crm.phonecall',
+ 'res_id' : new_case,
+ 'views': [(id3, 'form'), (id2, 'tree'), (False, 'calendar'), (False, 'graph')],
+ 'type': 'ir.actions.act_window',
+ 'search_view_id': res['res_id']
+ }
+ return value
+
+crm_opportunity2phonecall()
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/crm/wizard/crm_opportunity_to_phonecall_view.xml.moved b/addons/crm/wizard/crm_opportunity_to_phonecall_view.xml.moved
new file mode 100644
index 00000000000..827ee867169
--- /dev/null
+++ b/addons/crm/wizard/crm_opportunity_to_phonecall_view.xml.moved
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+ crm.opportunity2phonecall.form
+ crm.opportunity2phonecall
+ form
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Schedule Call
+ crm.opportunity2phonecall
+ form
+ form
+
+ new
+
+
+
+
\ No newline at end of file
diff --git a/addons/crm/wizard/crm_send_email.py b/addons/crm/wizard/crm_send_email.py
index b07d500e2c9..65164db27b5 100644
--- a/addons/crm/wizard/crm_send_email.py
+++ b/addons/crm/wizard/crm_send_email.py
@@ -76,8 +76,7 @@ class crm_send_new_email(osv.osv_memory):
case = case_pool.browse(cr, uid, res_id)
if context.get('mail', 'new') == 'new':
- if case.history_line:
- message_id = case.history_line[0].message_id
+ message_id = res_id
else:
hist = hist_obj.browse(cr, uid, res_id)
message_id = hist.message_id
diff --git a/addons/crm_claim/__init__.py b/addons/crm_claim/__init__.py
new file mode 100644
index 00000000000..7395ea83fe5
--- /dev/null
+++ b/addons/crm_claim/__init__.py
@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2010 Tiny SPRL ().
+#
+# 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 .
+#
+##############################################################################
+
+import crm_claim
+import report
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+
diff --git a/addons/crm_claim/__openerp__.py b/addons/crm_claim/__openerp__.py
new file mode 100644
index 00000000000..385f861616b
--- /dev/null
+++ b/addons/crm_claim/__openerp__.py
@@ -0,0 +1,48 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2010 Tiny SPRL ().
+#
+# 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 .
+#
+##############################################################################
+
+
+{
+ 'name': 'Customer & Supplier Relationship Management',
+ 'version': '1.0',
+ 'category': 'Generic Modules/CRM & SRM',
+ 'description': """Claims""",
+ 'author': 'Tiny',
+ 'website': 'http://www.openerp.com',
+ 'depends': ['crm'],
+ 'init_xml': [
+ 'crm_claims_data.xml',
+ ],
+
+ 'update_xml': [
+ 'crm_claims_view.xml',
+ 'crm_claims_menu.xml',
+ 'security/ir.model.access.csv',
+ 'report/crm_claim_report_view.xml',
+ ],
+ 'demo_xml': [
+ 'crm_claims_demo.xml',
+ ],
+ 'installable': True,
+ 'active': False,
+}
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/crm/crm_claim.py b/addons/crm_claim/crm_claim.py
similarity index 99%
rename from addons/crm/crm_claim.py
rename to addons/crm_claim/crm_claim.py
index 43ec4fe9895..a2a2652ff23 100644
--- a/addons/crm/crm_claim.py
+++ b/addons/crm_claim/crm_claim.py
@@ -20,7 +20,7 @@
##############################################################################
from osv import fields, osv
-import crm
+from crm import crm
class crm_claim(osv.osv):
"""
@@ -70,4 +70,4 @@ class crm_claim(osv.osv):
crm_claim()
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/crm/crm_claims_data.xml b/addons/crm_claim/crm_claims_data.xml
similarity index 76%
rename from addons/crm/crm_claims_data.xml
rename to addons/crm_claim/crm_claims_data.xml
index fc1b37e14be..a176b3aa8e0 100644
--- a/addons/crm/crm_claims_data.xml
+++ b/addons/crm_claim/crm_claims_data.xml
@@ -8,19 +8,19 @@
Factual Claims
-
+ Value Claims
-
+ Policy Claims
-
+
@@ -30,13 +30,13 @@
Corrective
-
+ Preventive
-
+
@@ -46,33 +46,33 @@
Accepted as Claim
-
+ Fixed
-
+ Won't fix
-
+ Invalid
-
+ Awaiting Response
-
+
-
\ No newline at end of file
+
diff --git a/addons/crm/crm_claims_demo.xml b/addons/crm_claim/crm_claims_demo.xml
similarity index 81%
rename from addons/crm/crm_claims_demo.xml
rename to addons/crm_claim/crm_claims_demo.xml
index daa5914e167..db21223656e 100644
--- a/addons/crm/crm_claims_demo.xml
+++ b/addons/crm_claim/crm_claims_demo.xml
@@ -9,7 +9,7 @@
-
+
@@ -18,15 +18,15 @@
-
-
+
+
-
+
@@ -35,15 +35,15 @@
-
-
+
+
-
+
@@ -52,15 +52,15 @@
-
-
+
+
-
+
@@ -69,15 +69,15 @@
-
-
+
+
-
+
@@ -86,15 +86,15 @@
-
-
+
+
-
+
@@ -103,15 +103,15 @@
-
-
+
+
-
+
@@ -120,8 +120,8 @@
-
-
+
+
diff --git a/addons/crm/crm_claims_menu.xml b/addons/crm_claim/crm_claims_menu.xml
similarity index 96%
rename from addons/crm/crm_claims_menu.xml
rename to addons/crm_claim/crm_claims_menu.xml
index 16711036100..b0d17495dee 100644
--- a/addons/crm/crm_claims_menu.xml
+++ b/addons/crm_claim/crm_claims_menu.xml
@@ -15,7 +15,7 @@
tree,calendar,form,graph{"search_default_section_id":section_id,"search_default_current":1,"search_default_my_claims":1}
-
+
diff --git a/addons/crm/crm_claims_view.xml b/addons/crm_claim/crm_claims_view.xml
similarity index 98%
rename from addons/crm/crm_claims_view.xml
rename to addons/crm_claim/crm_claims_view.xml
index 39cc8778e0b..ffd0c4943e0 100644
--- a/addons/crm/crm_claims_view.xml
+++ b/addons/crm_claim/crm_claims_view.xml
@@ -184,7 +184,7 @@
@@ -195,7 +195,7 @@
diff --git a/addons/crm_claim/report/__init__.py b/addons/crm_claim/report/__init__.py
new file mode 100644
index 00000000000..4f13d7bd837
--- /dev/null
+++ b/addons/crm_claim/report/__init__.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2010 Tiny SPRL ().
+#
+# 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 .
+#
+##############################################################################
+
+import crm_claim_report
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+
diff --git a/addons/crm/report/crm_claim_report.py b/addons/crm_claim/report/crm_claim_report.py
similarity index 99%
rename from addons/crm/report/crm_claim_report.py
rename to addons/crm_claim/report/crm_claim_report.py
index 4148a834810..04f00f4a95e 100644
--- a/addons/crm/report/crm_claim_report.py
+++ b/addons/crm_claim/report/crm_claim_report.py
@@ -21,7 +21,7 @@
from osv import fields,osv
import tools
-import crm_report
+from crm.report import crm_report
class crm_claim_report(osv.osv):
diff --git a/addons/crm/report/crm_claim_report_view.xml b/addons/crm_claim/report/crm_claim_report_view.xml
similarity index 97%
rename from addons/crm/report/crm_claim_report_view.xml
rename to addons/crm_claim/report/crm_claim_report_view.xml
index 647a0125179..fb4b0af3287 100644
--- a/addons/crm/report/crm_claim_report_view.xml
+++ b/addons/crm_claim/report/crm_claim_report_view.xml
@@ -33,7 +33,7 @@
crm.claim.report.formcrm.claim.report
-
+ form
@@ -66,7 +66,7 @@
crm.claim.report.selectcrm.claim.report
-
+ search
diff --git a/addons/crm_claim/security/ir.model.access.csv b/addons/crm_claim/security/ir.model.access.csv
new file mode 100644
index 00000000000..f903ab0c1d7
--- /dev/null
+++ b/addons/crm_claim/security/ir.model.access.csv
@@ -0,0 +1,3 @@
+"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
+"access_crm_claim","crm.claim","model_crm_claim","crm.group_crm_manager",1,1,1,1
+"access_crm_claim_report_user","crm.claim.report","model_crm_claim_report","crm.group_crm_user",1,0,0,0
diff --git a/addons/crm_fundraising/__init__.py b/addons/crm_fundraising/__init__.py
new file mode 100644
index 00000000000..b16301ec63c
--- /dev/null
+++ b/addons/crm_fundraising/__init__.py
@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2010 Tiny SPRL ().
+#
+# 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 .
+#
+##############################################################################
+
+import crm_fundraising
+import report
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+
diff --git a/addons/crm_fundraising/__openerp__.py b/addons/crm_fundraising/__openerp__.py
new file mode 100644
index 00000000000..292325f1084
--- /dev/null
+++ b/addons/crm_fundraising/__openerp__.py
@@ -0,0 +1,48 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2010 Tiny SPRL ().
+#
+# 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 .
+#
+##############################################################################
+
+
+{
+ 'name': 'CRM Fundraising',
+ 'version': '1.0',
+ 'category': 'Generic Modules/CRM & SRM',
+ 'description': """Fundraising""",
+ 'author': 'Tiny',
+ 'website': 'http://www.openerp.com',
+ 'depends': ['crm'],
+ 'init_xml': [
+ 'crm_fundraising_data.xml',
+ ],
+
+ 'update_xml': [
+ 'crm_fundraising_view.xml',
+ 'crm_fundraising_menu.xml',
+ 'security/ir.model.access.csv',
+ 'report/crm_fundraising_report_view.xml',
+ ],
+ 'demo_xml': [
+ 'crm_fundraising_demo.xml',
+ ],
+ 'installable': True,
+ 'active': False,
+}
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/crm/crm_fundraising.py b/addons/crm_fundraising/crm_fundraising.py
similarity index 99%
rename from addons/crm/crm_fundraising.py
rename to addons/crm_fundraising/crm_fundraising.py
index 927a3d05915..30c413076ea 100644
--- a/addons/crm/crm_fundraising.py
+++ b/addons/crm_fundraising/crm_fundraising.py
@@ -20,7 +20,7 @@
##############################################################################
from osv import fields, osv, orm
-import crm
+from crm import crm
class crm_fundraising(osv.osv):
""" Fund Raising Cases """
diff --git a/addons/crm/crm_fund_data.xml b/addons/crm_fundraising/crm_fundraising_data.xml
similarity index 78%
rename from addons/crm/crm_fund_data.xml
rename to addons/crm_fundraising/crm_fundraising_data.xml
index 1c566279b90..03613d87a7f 100644
--- a/addons/crm/crm_fund_data.xml
+++ b/addons/crm_fundraising/crm_fundraising_data.xml
@@ -6,25 +6,25 @@
Social Rehabilitation And Rural Upliftment
-
+ Learning And Education
-
+ Healthcare
-
+ Arts And Culture
-
+
@@ -32,25 +32,25 @@
Cash
-
+ Cheque
-
+ Credit Card
-
+ Demand Draft
-
+
diff --git a/addons/crm/crm_fund_demo.xml b/addons/crm_fundraising/crm_fundraising_demo.xml
similarity index 92%
rename from addons/crm/crm_fund_demo.xml
rename to addons/crm_fundraising/crm_fundraising_demo.xml
index 23ea6835df1..c7588701af0 100644
--- a/addons/crm/crm_fund_demo.xml
+++ b/addons/crm_fundraising/crm_fundraising_demo.xml
@@ -12,7 +12,7 @@
-
+
@@ -30,7 +30,7 @@
-
+
@@ -48,7 +48,7 @@
-
+
@@ -65,7 +65,7 @@
-
+
@@ -82,7 +82,7 @@
-
+
@@ -99,7 +99,7 @@
-
+
@@ -118,7 +118,7 @@
-
+
@@ -136,7 +136,7 @@
-
+
diff --git a/addons/crm/crm_fund_menu.xml b/addons/crm_fundraising/crm_fundraising_menu.xml
similarity index 64%
rename from addons/crm/crm_fund_menu.xml
rename to addons/crm_fundraising/crm_fundraising_menu.xml
index 7a53ab1aa18..eab0603c446 100644
--- a/addons/crm/crm_fund_menu.xml
+++ b/addons/crm_fundraising/crm_fundraising_menu.xml
@@ -12,29 +12,29 @@
Fundscrm.fundraisingtree,form,graph
-
-
+
+ tree
-
-
+
+ form
-
-
+
+ graph
-
-
+
+
@@ -208,7 +208,7 @@
diff --git a/addons/crm_fundraising/report/__init__.py b/addons/crm_fundraising/report/__init__.py
new file mode 100644
index 00000000000..747d6315fdb
--- /dev/null
+++ b/addons/crm_fundraising/report/__init__.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2010 Tiny SPRL ().
+#
+# 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 .
+#
+##############################################################################
+
+import crm_fundraising_report
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+
diff --git a/addons/crm/report/crm_fundraising_report.py b/addons/crm_fundraising/report/crm_fundraising_report.py
similarity index 100%
rename from addons/crm/report/crm_fundraising_report.py
rename to addons/crm_fundraising/report/crm_fundraising_report.py
diff --git a/addons/crm/report/crm_fundraising_report_view.xml b/addons/crm_fundraising/report/crm_fundraising_report_view.xml
similarity index 97%
rename from addons/crm/report/crm_fundraising_report_view.xml
rename to addons/crm_fundraising/report/crm_fundraising_report_view.xml
index e1c32726b4f..dc759d0bf1c 100644
--- a/addons/crm/report/crm_fundraising_report_view.xml
+++ b/addons/crm_fundraising/report/crm_fundraising_report_view.xml
@@ -33,7 +33,7 @@
crm.fundraising.report.formcrm.fundraising.report
-
+ form
@@ -65,7 +65,7 @@
crm.fundraising.report.selectcrm.fundraising.report
-
+ search
diff --git a/addons/crm_fundraising/security/ir.model.access.csv b/addons/crm_fundraising/security/ir.model.access.csv
new file mode 100644
index 00000000000..43e607538ee
--- /dev/null
+++ b/addons/crm_fundraising/security/ir.model.access.csv
@@ -0,0 +1,3 @@
+"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
+"access_crm_fundraising","crm.fundraising","model_crm_fundraising","crm.group_crm_manager",1,1,1,1
+"access_crm_fundraising_report_user","crm.fundraising.report","model_crm_fundraising_report","crm.group_crm_user",1,0,0,0
diff --git a/addons/crm_helpdesk/__init__.py b/addons/crm_helpdesk/__init__.py
new file mode 100644
index 00000000000..5d270dbebf8
--- /dev/null
+++ b/addons/crm_helpdesk/__init__.py
@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2010 Tiny SPRL ().
+#
+# 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 .
+#
+##############################################################################
+
+import crm_helpdesk
+import report
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+
diff --git a/addons/crm_helpdesk/__openerp__.py b/addons/crm_helpdesk/__openerp__.py
new file mode 100644
index 00000000000..25aed0c425f
--- /dev/null
+++ b/addons/crm_helpdesk/__openerp__.py
@@ -0,0 +1,48 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2010 Tiny SPRL ().
+#
+# 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 .
+#
+##############################################################################
+
+
+{
+ 'name': 'CRM Helpdesk',
+ 'version': '1.0',
+ 'category': 'Generic Modules/CRM & SRM',
+ 'description': """Helpdesk Management""",
+ 'author': 'Tiny',
+ 'website': 'http://www.openerp.com',
+ 'depends': ['crm'],
+ 'init_xml': [
+ 'crm_helpdesk_data.xml',
+ ],
+
+ 'update_xml': [
+ 'crm_helpdesk_view.xml',
+ 'crm_helpdesk_menu.xml',
+ 'security/ir.model.access.csv',
+ 'report/crm_helpdesk_report_view.xml',
+ ],
+ 'demo_xml': [
+ 'crm_helpdesk_demo.xml',
+ ],
+ 'installable': True,
+ 'active': False,
+}
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/crm/crm_helpdesk.py b/addons/crm_helpdesk/crm_helpdesk.py
similarity index 99%
rename from addons/crm/crm_helpdesk.py
rename to addons/crm_helpdesk/crm_helpdesk.py
index 9bb93d17e1a..fda251d16ac 100644
--- a/addons/crm/crm_helpdesk.py
+++ b/addons/crm_helpdesk/crm_helpdesk.py
@@ -22,7 +22,7 @@
from osv import fields
from osv import orm
from osv import osv
-import crm
+from crm import crm
class crm_helpdesk(osv.osv):
""" Helpdesk Cases """
diff --git a/addons/crm/crm_helpdesk_data.xml b/addons/crm_helpdesk/crm_helpdesk_data.xml
similarity index 100%
rename from addons/crm/crm_helpdesk_data.xml
rename to addons/crm_helpdesk/crm_helpdesk_data.xml
diff --git a/addons/crm/crm_helpdesk_demo.xml b/addons/crm_helpdesk/crm_helpdesk_demo.xml
similarity index 100%
rename from addons/crm/crm_helpdesk_demo.xml
rename to addons/crm_helpdesk/crm_helpdesk_demo.xml
diff --git a/addons/crm/crm_helpdesk_menu.xml b/addons/crm_helpdesk/crm_helpdesk_menu.xml
similarity index 95%
rename from addons/crm/crm_helpdesk_menu.xml
rename to addons/crm_helpdesk/crm_helpdesk_menu.xml
index bd3f0889bd1..5030fd65506 100644
--- a/addons/crm/crm_helpdesk_menu.xml
+++ b/addons/crm_helpdesk/crm_helpdesk_menu.xml
@@ -11,7 +11,7 @@
crm.helpdesktree,calendar,form
-
+
diff --git a/addons/crm/crm_helpdesk_view.xml b/addons/crm_helpdesk/crm_helpdesk_view.xml
similarity index 98%
rename from addons/crm/crm_helpdesk_view.xml
rename to addons/crm_helpdesk/crm_helpdesk_view.xml
index fa2071f950b..15f00e66cf5 100644
--- a/addons/crm/crm_helpdesk_view.xml
+++ b/addons/crm_helpdesk/crm_helpdesk_view.xml
@@ -127,7 +127,7 @@
@@ -138,7 +138,7 @@
diff --git a/addons/crm_helpdesk/report/__init__.py b/addons/crm_helpdesk/report/__init__.py
new file mode 100644
index 00000000000..0e0ad35740e
--- /dev/null
+++ b/addons/crm_helpdesk/report/__init__.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2010 Tiny SPRL ().
+#
+# 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 .
+#
+##############################################################################
+
+import crm_helpdesk_report
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+
diff --git a/addons/crm/report/crm_helpdesk_report.py b/addons/crm_helpdesk/report/crm_helpdesk_report.py
similarity index 100%
rename from addons/crm/report/crm_helpdesk_report.py
rename to addons/crm_helpdesk/report/crm_helpdesk_report.py
diff --git a/addons/crm/report/crm_helpdesk_report_view.xml b/addons/crm_helpdesk/report/crm_helpdesk_report_view.xml
similarity index 99%
rename from addons/crm/report/crm_helpdesk_report_view.xml
rename to addons/crm_helpdesk/report/crm_helpdesk_report_view.xml
index b10f51162e7..39101be2449 100644
--- a/addons/crm/report/crm_helpdesk_report_view.xml
+++ b/addons/crm_helpdesk/report/crm_helpdesk_report_view.xml
@@ -30,7 +30,7 @@
crm.helpdesk.report.formcrm.helpdesk.report
-
+ form
diff --git a/addons/crm_helpdesk/security/ir.model.access.csv b/addons/crm_helpdesk/security/ir.model.access.csv
new file mode 100644
index 00000000000..c1420a5b2d6
--- /dev/null
+++ b/addons/crm_helpdesk/security/ir.model.access.csv
@@ -0,0 +1,3 @@
+"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
+"access_crm_helpdesk","crm.helpdesk","model_crm_helpdesk","crm.group_crm_manager",1,1,1,1
+"access_report_crm_helpdesk","report.crm.helpdesk","model_crm_helpdesk_report","crm.group_crm_user",1,1,1,1
diff --git a/addons/document_ftp/ftpserver/abstracted_fs.py b/addons/document_ftp/ftpserver/abstracted_fs.py
index 0ffa8eb80f2..1957b2db84c 100644
--- a/addons/document_ftp/ftpserver/abstracted_fs.py
+++ b/addons/document_ftp/ftpserver/abstracted_fs.py
@@ -97,7 +97,7 @@ class content_wrapper(StringIO.StringIO):
cr = db.cursor()
cr.commit()
try:
- getattr(self.pool.get('document.directory.content'), 'process_write_'+self.node.content.extension[1:])(cr, self.uid, self.node, self.getvalue())
+ getattr(self.pool.get('document.directory.content'), 'process_write')(cr, self.uid, self.node, self.getvalue())
finally:
cr.commit()
cr.close()
diff --git a/addons/sale_crm/__openerp__.py b/addons/sale_crm/__openerp__.py
index 187d0f401ed..045afbbd82c 100644
--- a/addons/sale_crm/__openerp__.py
+++ b/addons/sale_crm/__openerp__.py
@@ -38,7 +38,7 @@ crm modules.
'website': 'http://www.openerp.com',
'depends': ['sale', 'crm'],
'init_xml': [],
- 'update_xml': ['wizard/crm_make_sale_view.xml',
+ 'update_xml': ['sale_crm_wizard.xml',
'sale_crm_view.xml',
'process/sale_crm_process.xml',
'security/sale_crm_security.xml',
diff --git a/addons/sale_crm/sale_crm_view.xml b/addons/sale_crm/sale_crm_view.xml
index 0c997e506d3..24912052190 100644
--- a/addons/sale_crm/sale_crm_view.xml
+++ b/addons/sale_crm/sale_crm_view.xml
@@ -9,7 +9,7 @@
-
+
diff --git a/addons/sale_crm/sale_crm_wizard.xml b/addons/sale_crm/sale_crm_wizard.xml
new file mode 100644
index 00000000000..74dcf06e901
--- /dev/null
+++ b/addons/sale_crm/sale_crm_wizard.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
diff --git a/addons/sale_crm/wizard/__init__.py b/addons/sale_crm/wizard/__init__.py
index 04f40c92207..87048a13fc4 100644
--- a/addons/sale_crm/wizard/__init__.py
+++ b/addons/sale_crm/wizard/__init__.py
@@ -19,7 +19,7 @@
#
##############################################################################
-import crm_make_sale
+import makesale
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/sale_crm/wizard/crm_make_sale.py b/addons/sale_crm/wizard/crm_make_sale.py
deleted file mode 100644
index 01480b3f6df..00000000000
--- a/addons/sale_crm/wizard/crm_make_sale.py
+++ /dev/null
@@ -1,177 +0,0 @@
-# -*- coding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-2010 Tiny SPRL ().
-#
-# 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 .
-#
-##############################################################################
-
-from osv import fields, osv
-from tools.translate import _
-from mx.DateTime import now
-
-class crm_make_sale(osv.osv_memory):
- """ Make sale order for crm """
-
- _name = "crm.make.sale"
- _description = "Make sale"
-
- def _selectPartner(self, cr, uid, context=None):
- """
- This function gets default value for partner_id field.
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param context: A standard dictionary for contextual values
- @return : default value of partner_id field.
- """
-
- if not context:
- context = {}
-
- data = context and context.get('active_ids', []) or []
- case_obj = self.pool.get('crm.opportunity')
- case = case_obj.read(cr, uid, data, ['partner_id'])
- return case[0]['partner_id']
-
- def makeOrder(self, cr, uid, ids, context=None):
- """
- This function create Quotation on given case.
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param ids: List of crm make sale' ids
- @param context: A standard dictionary for contextual values
- @return : Dictionary value of created sale order.
- """
- if not context:
- context = {}
-
- mod_obj = self.pool.get('ir.model.data')
- result = mod_obj._get_id(cr, uid, 'sale', 'view_sales_order_filter')
- id = mod_obj.read(cr, uid, result, ['res_id'])
- case_obj = self.pool.get('crm.opportunity')
- sale_obj = self.pool.get('sale.order')
- partner_obj = self.pool.get('res.partner')
- sale_line_obj = self.pool.get('sale.order.line')
-
- data = context and context.get('active_ids', []) or []
-
- for make in self.browse(cr, uid, ids):
- default_partner_addr = partner_obj.address_get(cr, uid, [make.partner_id.id],
- ['invoice', 'delivery', 'contact'])
- default_pricelist = partner_obj.browse(cr, uid, make.partner_id.id,
- context).property_product_pricelist.id
- fpos_data = partner_obj.browse(cr, uid, make.partner_id.id, context).property_account_position
- new_ids = []
-
- for case in case_obj.browse(cr, uid, data):
- if case.partner_id and case.partner_id.id:
- partner_id = case.partner_id.id
- fpos = case.partner_id.property_account_position and case.partner_id.property_account_position.id or False
- partner_addr = partner_obj.address_get(cr, uid, [case.partner_id.id],
- ['invoice', 'delivery', 'contact'])
- pricelist = partner_obj.browse(cr, uid, case.partner_id.id,
- context).property_product_pricelist.id
- else:
- partner_id = make.partner_id.id
- fpos = fpos_data and fpos_data.id or False
- partner_addr = default_partner_addr
- pricelist = default_pricelist
-
- if False in partner_addr.values():
- raise osv.except_osv(_('Data Insufficient!'),_('Customer has no addresses defined!'))
-
- vals = {
- 'origin': 'CRM-Opportunity:%s' % str(case.id),
- 'section_id': case.section_id and case.section_id.id or False,
- 'picking_policy': make.picking_policy,
- 'shop_id': make.shop_id.id,
- 'partner_id': partner_id,
- 'pricelist_id': pricelist,
- 'partner_invoice_id': partner_addr['invoice'],
- 'partner_order_id': partner_addr['contact'],
- 'partner_shipping_id': partner_addr['delivery'],
- 'order_policy': 'manual',
- 'date_order': now(),
- 'fiscal_position': fpos,
- }
-
- if partner_id:
- partner = partner_obj.browse(cr, uid, partner_id, context=context)
- vals['user_id'] = partner.user_id and partner.user_id.id or uid
-
- if make.analytic_account.id:
- vals['project_id'] = make.analytic_account.id
- new_id = sale_obj.create(cr, uid, vals)
- for product_id in make.product_ids:
- value = sale_line_obj.product_id_change(cr, uid, [], pricelist,
- product_id.id, qty=1, partner_id=partner_id, fiscal_position=fpos)['value']
- value['product_id'] = product_id.id
- value['order_id'] = new_id
- value['tax_id'] = [(6,0,value['tax_id'])]
- sale_line_obj.create(cr, uid, value)
-
- case_obj.write(cr, uid, [case.id], {'ref': 'sale.order,%s' % new_id})
- new_ids.append(new_id)
-
- if make.close:
- case_obj.case_close(cr, uid, data)
-
- if not new_ids:
- return {}
- if len(new_ids)<=1:
- value = {
- 'domain': str([('id', 'in', new_ids)]),
- 'view_type': 'form',
- 'view_mode': 'form',
- 'res_model': 'sale.order',
- 'view_id': False,
- 'type': 'ir.actions.act_window',
- 'res_id': new_ids and new_ids[0]
- }
- else:
- value = {
- 'domain': str([('id', 'in', new_ids)]),
- 'view_type': 'form',
- 'view_mode': 'tree,form',
- 'res_model': 'sale.order',
- 'view_id': False,
- 'type': 'ir.actions.act_window',
- 'res_id':new_ids
- }
- return value
-
- _columns = {
- 'shop_id': fields.many2one('sale.shop', 'Shop', required = True),
- 'partner_id': fields.many2one('res.partner', 'Customer', required = True, help = 'Use this partner if there is no partner on the case'),
- 'picking_policy': fields.selection([('direct','Direct Delivery'),
- ('one','All at once')], 'Picking Policy', required = True),
- 'product_ids': fields.many2many('product.product', 'product_sale_rel',\
- 'sale_id', 'product_id', 'Products'),
- 'analytic_account': fields.many2one('account.analytic.account', 'Analytic Account'),
- 'close': fields.boolean('Close Case', help = 'Check this to close the case after having created the sale order.'),
- }
- _defaults = {
- 'partner_id': _selectPartner,
- 'close': lambda *a: 1
- }
-
-crm_make_sale()
-
-
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/sale_crm/wizard/crm_make_sale_view.xml b/addons/sale_crm/wizard/crm_make_sale_view.xml
deleted file mode 100644
index de6a29e5405..00000000000
--- a/addons/sale_crm/wizard/crm_make_sale_view.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
-
-
-
-
- crm.make.sale.form
- crm.make.sale
- form
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Make Quotation
- ir.actions.act_window
- crm.make.sale
- form
- form
- new
-
-
-
-
diff --git a/addons/sale_crm/wizard/makesale.py b/addons/sale_crm/wizard/makesale.py
new file mode 100644
index 00000000000..c6dc12abf11
--- /dev/null
+++ b/addons/sale_crm/wizard/makesale.py
@@ -0,0 +1,174 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2010 Tiny SPRL ().
+#
+# 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 .
+#
+##############################################################################
+
+from mx.DateTime import now
+
+import wizard
+import netsvc
+import ir
+import pooler
+from tools.translate import _
+
+sale_form = """
+