[FIX]: crm: fixed problem of wrong date for recurrent event in calendar view

bzr revid: rpa@openerp.co.in-20100105093049-1csbi99sfauc7ptd
This commit is contained in:
rpa (Open ERP) 2010-01-05 15:00:49 +05:30
parent ce38f837b9
commit 224a171910
2 changed files with 147 additions and 145 deletions

View File

@ -21,9 +21,9 @@
{
'name': 'Customer & Supplier Relationship Management',
'version': '1.0',
'category': 'Generic Modules/CRM & SRM',
'name': 'Customer & Supplier Relationship Management',
'version': '1.0',
'category': 'Generic Modules/CRM & SRM',
'description': """The generic Open ERP Customer Relationship Management
system enables a group of people to intelligently and efficiently manage
leads, opportunities, tasks, issues, requests, bugs, campaign, claims, etc.
@ -41,67 +41,68 @@ appropriate staff, and making sure all future correspondence gets to the right
place.
The CRM module has a email gateway for the synchronisation interface
between mails and Open ERP.""",
'author': 'Tiny',
'website': 'http://www.openerp.com',
'depends': ['base',
'caldav',
'process',
'mail_gateway',
],
between mails and Open ERP.""",
'author': 'Tiny',
'website': 'http://www.openerp.com',
'depends': ['base',
'caldav',
'process',
'mail_gateway',
],
'init_xml': ['crm_data.xml',
'crm_meeting_data.xml',
'crm_claims_data.xml',
'crm_fund_data.xml',
'crm_helpdesk_data.xml',
'crm_jobs_data.xml',
'crm_lead_data.xml',
'crm_meeting_data.xml',
'crm_claims_data.xml',
'crm_fund_data.xml',
'crm_helpdesk_data.xml',
'crm_jobs_data.xml',
'crm_lead_data.xml',
'crm_meeting_data.xml',
'crm_opportunity_data.xml',
'crm_phonecall_data.xml',
],
'crm_opportunity_data.xml',
'crm_phonecall_data.xml',
],
'update_xml': [
'crm_wizard.xml',
'crm_view.xml',
'crm_config_view.xml',
'crm_job_wizard.xml',
'crm_jobs_view.xml',
'crm_jobs_menu.xml',
'crm_lead_wizard.xml',
'crm_lead_view.xml',
'crm_lead_menu.xml',
'crm_meeting_wizard.xml',
'crm_meeting_view.xml',
'crm_meeting_menu.xml',
'crm_opportunity_wizard.xml',
'crm_opportunity_view.xml',
'crm_opportunity_menu.xml',
'crm_fund_view.xml',
'crm_fund_menu.xml',
'crm_claims_view.xml',
'crm_claims_menu.xml',
'crm_phonecall_wizard.xml',
'crm_phonecall_view.xml',
'crm_phonecall_menu.xml',
'crm_report_view.xml',
'crm_helpdesk_view.xml',
'crm_report.xml',
'security/crm_security.xml',
'security/ir.model.access.csv',
'crm_wizard.xml',
'crm_view.xml',
'crm_config_view.xml',
'crm_job_wizard.xml',
'crm_jobs_view.xml',
'crm_jobs_menu.xml',
'crm_lead_wizard.xml',
'crm_lead_view.xml',
'crm_lead_menu.xml',
'crm_meeting_wizard.xml',
'crm_meeting_view.xml',
'crm_meeting_menu.xml',
'crm_opportunity_wizard.xml',
'crm_opportunity_view.xml',
'crm_opportunity_menu.xml',
'crm_fund_view.xml',
'crm_fund_menu.xml',
'crm_claims_view.xml',
'crm_claims_menu.xml',
'crm_phonecall_wizard.xml',
'crm_phonecall_view.xml',
'crm_phonecall_menu.xml',
'crm_report_view.xml',
'crm_helpdesk_view.xml',
'crm_report.xml',
'security/crm_security.xml',
'security/ir.model.access.csv',
'process/crm_configuration_process.xml'
],
],
'demo_xml': [
'crm_demo.xml',
'crm_claims_demo.xml',
'crm_fund_demo.xml',
'crm_helpdesk_demo.xml',
'crm_jobs_demo.xml',
'crm_lead_demo.xml',
'crm_demo.xml',
'crm_meeting_demo.xml',
'crm_opportunity_demo.xml',
'crm_phonecall_demo.xml'],
'installable': True,
'active': False,
'certificate': '0079056041421',
'crm_claims_demo.xml',
'crm_fund_demo.xml',
'crm_helpdesk_demo.xml',
'crm_jobs_demo.xml',
'crm_lead_demo.xml',
'crm_meeting_demo.xml',
'crm_opportunity_demo.xml',
'crm_phonecall_demo.xml'],
'installable': True,
'active': False,
'certificate': '0079056041421',
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
##############################################################################
#
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
#
@ -15,7 +15,7 @@
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
@ -31,17 +31,17 @@ from tools.translate import _
from dateutil import parser
class crm_meeting(osv.osv):
_name = 'crm.meeting'
_name = 'crm.meeting'
_description = "Meeting Cases"
_order = "id desc"
_inherits = {'crm.case':"inherit_case_id"}
_inherits = {'crm.case':"inherit_case_id"}
__attribute__ = {
'class' : {'field':'class', 'type':'text'},
'created' : {'field':'create_date', 'type':'datetime'}, # keep none for now
'description' : {'field':'description', 'type':'text'},
'dtstart' : {'field':'date', 'type':'datetime'},
'dtstart' : {'field':'date', 'type':'datetime'},
'location' : {'field':'location', 'type':'text'},
#'organizer' : {'field':'partner_id', 'sub-field':'name', 'type':'many2one'},
#'organizer' : {'field':'partner_id', 'sub-field':'name', 'type':'many2one'},
'priority' : {'field':'priority', 'type':'int'},
'dtstamp' : {'field':'date', 'type':'datetime'},
'seq' : None,
@ -52,10 +52,10 @@ class crm_meeting(osv.osv):
'uid' : {'field':'id', 'type':'text'},
'url' : {'field':'caldav_url', 'type':'text'},
'recurid' : None,
# 'attach' : {'field':'attachment_ids', 'sub-field':'datas', 'type':'list'},
# 'attach' : {'field':'attachment_ids', 'sub-field':'datas', 'type':'list'},
'attendee' : {'field':'attendees', 'type':'many2many', 'object' : 'crm.caldav.attendee'},
# 'categories' : {'field':'categ_id', 'sub-field':'name'},
# 'categories' : {'field':None , 'sub-field':'name', 'type':'text'},
# 'categories' : {'field':None , 'sub-field':'name', 'type':'text'},
'comment' : None,
'contact' : None,
'exdate' : {'field':'exdate', 'type':'datetime'},
@ -69,10 +69,10 @@ class crm_meeting(osv.osv):
# 'duration' : {'field':'duration'},
'dtend' : {'field':'date_closed', 'type':'datetime'},
'valarm' : {'field':'alarm_id', 'type':'many2one', 'object' : 'crm.caldav.alarm'},
}
}
_columns = {
'inherit_case_id': fields.many2one('crm.case','Case',ondelete='cascade'),
'inherit_case_id': fields.many2one('crm.case', 'Case', ondelete='cascade'),
'class' : fields.selection([('PUBLIC', 'PUBLIC'), ('PRIVATE', 'PRIVATE'), \
('CONFIDENTIAL', 'CONFIDENTIAL')], 'Privacy'),
'location' : fields.char('Location', size=264, help="Gives Location of Meeting"),
@ -90,12 +90,12 @@ class crm_meeting(osv.osv):
'alarm_id' : fields.many2one('crm.caldav.alarm', 'Alarm'),
}
_defaults = {
_defaults = {
'class': lambda *a: 'PUBLIC',
'transparent': lambda *a: 'OPAQUE',
}
def run_scheduler(self, cr, uid, automatic=False, use_new_cursor=False, \
context=None):
if not context:
@ -106,7 +106,7 @@ class crm_meeting(osv.osv):
join crm_case on c.inherit_case_id = crm_case.id \
join crm_caldav_alarm alarm on (alarm.id=c.alarm_id) \
where alarm_id is not null and alarm.active=True')
case_with_alarm = cr.dictfetchall()
case_with_alarm = cr.dictfetchall()
case_obj = self.pool.get('crm.meeting')
attendee_obj = self.pool.get('crm.caldav.attendee')
mail_to = []
@ -125,7 +125,7 @@ class crm_meeting(osv.osv):
if att.cn.rsplit(':')[-1]:
mail_to.append(att.cn.rsplit(':')[-1])
if mail_to:
sub = 'Event Reminder for ' + case_val.name or ''
sub = 'Event Reminder for ' + case_val.name or ''
body = (case_val.name or '')+ '\n\t' + (case_val.description or '') + '\n\nEvent time: ' \
+(case_val.date) + '\n\nLocation: ' + (case_val.location or '') + \
'\n\nMembers Details: ' + '\n'.join(mail_to)
@ -144,15 +144,15 @@ class crm_meeting(osv.osv):
crm_data = self.read(cr, uid, ids, [], context ={'read' :True})
event_obj = self.pool.get('caldav.event')
event_obj.__attribute__.update(self.__attribute__)
attendee_obj = self.pool.get('caldav.attendee')
crm_attendee = self.pool.get('crm.caldav.attendee')
attendee_obj.__attribute__.update(crm_attendee.__attribute__)
alarm_obj = self.pool.get('caldav.alarm')
crm_alarm = self.pool.get('crm.caldav.alarm')
alarm_obj.__attribute__.update(crm_alarm.__attribute__)
ical = event_obj.export_ical(cr, uid, crm_data, {'model': 'crm.meeting'})
caendar_val = ical.serialize()
caendar_val = caendar_val.replace('"', '').strip()
@ -166,7 +166,7 @@ class crm_meeting(osv.osv):
attendee_obj = self.pool.get('caldav.attendee')
crm_attendee = self.pool.get('crm.caldav.attendee')
attendee_obj.__attribute__.update(crm_attendee.__attribute__)
alarm_obj = self.pool.get('caldav.alarm')
crm_alarm = self.pool.get('crm.caldav.alarm')
alarm_obj.__attribute__.update(crm_alarm.__attribute__)
@ -175,7 +175,7 @@ class crm_meeting(osv.osv):
section_id = self.pool.get('crm.case.section').search(cr, uid, \
[('name', 'like', 'Meeting%')])[0]
val.update({'section_id' : section_id})
is_exists = common.uid2openobjectid(cr, val['id'], self._name )
is_exists = common.uid2openobjectid(cr, val['id'], self._name)
val.pop('id')
if val.has_key('create_date'): val.pop('create_date')
val['caldav_url'] = context.get('url') or ''
@ -199,19 +199,19 @@ class crm_meeting(osv.osv):
until_date = until_date and datetime.datetime.strptime(until_date, "%Y-%m-%d") or False
for data in cr.dictfetchall():
if count > limit:
break
event_date = datetime.datetime.strptime(data['date'], "%Y-%m-%d %H:%M:%S")
break
event_date = datetime.datetime.strptime(data['date'], "%Y-%m-%d %H:%M:%S")
if start_date and start_date <= event_date:
start_date = event_date
if not data['rrule']:
if not data['rrule']:
idval = common.real_id2caldav_id(data['id'], data['date'])
result.append(idval)
count += 1
result.append(idval)
count += 1
else:
exdate = data['exdate'] and data['exdate'].split(',') or []
event_obj = self.pool.get('caldav.event')
rrule_str = data['rrule']
new_rrule_str = []
rrule_str = data['rrule']
new_rrule_str = []
rrule_until_date = False
for rule in rrule_str.split(';'):
name, value = rule.split('=')
@ -219,23 +219,24 @@ class crm_meeting(osv.osv):
value = parser.parse(value)
rrule_until_date = parser.parse(value.strftime("%Y-%m-%d"))
if until_date and until_date >= rrule_until_date:
until_date = rrule_until_date
until_date = rrule_until_date
if until_date:
until_date = until_date.strftime("%Y%m%d%H%M%S")
value = until_date
new_rule = '%s=%s'%(name, value)
new_rrule_str.append(new_rule)
new_rrule_str = ';'.join(new_rrule_str)
start_date = datetime.datetime.strptime(data['date'], "%Y-%m-%d %H:%M:%S")
rdates = event_obj.get_recurrent_dates(str(new_rrule_str), exdate, start_date)
for rdate in rdates:
for rdate in rdates:
idval = common.real_id2caldav_id(data['id'], rdate)
result.append(idval)
result.append(idval)
count += 1
ids = result
ids = result
return ids
def search(self, cr, uid, args, offset=0, limit=100, order=None,
context=None, count=False):
context=None, count=False):
args_without_date = []
start_date = False
until_date = False
@ -250,8 +251,8 @@ class crm_meeting(osv.osv):
res = super(crm_meeting, self).search(cr, uid, args_without_date, offset,
limit, order, context, count)
return self.get_recurrent_ids(cr, uid, res, start_date, until_date, limit)
return self.get_recurrent_ids(cr, uid, res, start_date, until_date, limit)
def write(self, cr, uid, ids, vals, context=None, check=True, update_check=True):
if isinstance(ids, (str, int, long)):
@ -272,14 +273,14 @@ class crm_meeting(osv.osv):
if isinstance(ids, (str, int, long)):
select = [ids]
else:
select = ids
select = ids
select = map(lambda x:common.caldav_id2real_id(x), select)
res = super(crm_meeting, self).browse(cr, uid, select, context, list_class, fields_process)
res = super(crm_meeting, self).browse(cr, uid, select, context, list_class, fields_process)
if isinstance(ids, (str, int, long)):
return res and res[0] or False
return res
def read(self, cr, uid, ids, fields=None, context={}, load='_classic_read'):
def read(self, cr, uid, ids, fields=None, context={}, load='_classic_read'):
if isinstance(ids, (str, int, long)):
select = [ids]
else:
@ -288,32 +289,32 @@ class crm_meeting(osv.osv):
result = []
if fields and 'date' not in fields:
fields.append('date')
for caldav_id, real_id in select:
for caldav_id, real_id in select:
res = super(crm_meeting, self).read(cr, uid, real_id, fields=fields, context=context, \
load=load)
ls = common.caldav_id2real_id(caldav_id, with_date=True)
if not isinstance(ls, (str, int, long)) and len(ls) >= 2:
ls = common.caldav_id2real_id(caldav_id, with_date=True)
if not isinstance(ls, (str, int, long)) and len(ls) >= 2:
res['date'] = ls[1]
res['id'] = caldav_id
result.append(res)
if isinstance(ids, (str, int, long)):
return result and result[0] or False
return result and result[0] or False
return result
def copy(self, cr, uid, id, default=None, context={}):
def copy(self, cr, uid, id, default=None, context={}):
return super(crm_meeting, self).copy(cr, uid, common.caldav_id2real_id(id), \
default, context)
def unlink(self, cr, uid, ids, context=None):
for id in ids:
ls = common.caldav_id2real_id(caldav_id)
if not isinstance(ls, (str, int, long)) and len(ls) >= 2:
if not isinstance(ls, (str, int, long)) and len(ls) >= 2:
date_new = ls[1]
for record in self.read(cr, uid, [common.caldav_id2real_id(id)], \
['date', 'rrule', 'exdate']):
if record['rrule']:
exdate = (record['exdate'] and (record['exdate'] + ',' ) or '') + \
exdate = (record['exdate'] and (record['exdate'] + ',') or '') + \
''.join((re.compile('\d')).findall(date_new)) + 'Z'
if record['date'] == date_new:
self.write(cr, uid, [common.caldav_id2real_id(id)], {'exdate' : exdate})
@ -333,57 +334,57 @@ class crm_meeting(osv.osv):
if isinstance(ids, (str, int, long)):
select = [ids]
else:
select = ids
select = ids
case_data = self.browse(cr, uid, select)
new_ids = []
for case in case_data:
if case.inherit_case_id:
new_ids.append(case.inherit_case_id.id)
res = getattr(self.pool.get('crm.case'),method)(cr, uid, new_ids, *args, **argv)
res = getattr(self.pool.get('crm.case'), method)(cr, uid, new_ids, *args, **argv)
if isinstance(ids, (str, int, long)) and isinstance(res, list):
return res and res[0] or False
return res
def onchange_case_id(self, cr, uid, ids, *args, **argv):
return self._map_ids('onchange_case_id',cr,uid,ids,*args,**argv)
return self._map_ids('onchange_case_id', cr, uid, ids, *args, **argv)
def onchange_partner_id(self, cr, uid, ids, *args, **argv):
return self._map_ids('onchange_partner_id',cr,uid,ids,*args,**argv)
return self._map_ids('onchange_partner_id', cr, uid, ids, *args, **argv)
def onchange_partner_address_id(self, cr, uid, ids, *args, **argv):
return self._map_ids('onchange_partner_address_id',cr,uid,ids,*args,**argv)
return self._map_ids('onchange_partner_address_id', cr, uid, ids, *args, **argv)
def onchange_categ_id(self, cr, uid, ids, *args, **argv):
return self._map_ids('onchange_categ_id',cr,uid,ids,*args,**argv)
def case_close(self,cr, uid, ids, *args, **argv):
return self._map_ids('case_close',cr,uid,ids,*args,**argv)
def case_open(self,cr, uid, ids, *args, **argv):
return self._map_ids('case_open',cr,uid,ids,*args,**argv)
def case_cancel(self,cr, uid, ids, *args, **argv):
return self._map_ids('case_cancel',cr,uid,ids,*args,**argv)
def case_reset(self,cr, uid, ids, *args, **argv):
return self._map_ids('case_reset',cr,uid,ids,*args,**argv)
return self._map_ids('onchange_categ_id', cr, uid, ids, *args, **argv)
def case_close(self, cr, uid, ids, *args, **argv):
return self._map_ids('case_close', cr, uid, ids, *args, **argv)
def case_open(self, cr, uid, ids, *args, **argv):
return self._map_ids('case_open', cr, uid, ids, *args, **argv)
def case_cancel(self, cr, uid, ids, *args, **argv):
return self._map_ids('case_cancel', cr, uid, ids, *args, **argv)
def case_reset(self, cr, uid, ids, *args, **argv):
return self._map_ids('case_reset', cr, uid, ids, *args, **argv)
def msg_new(self, cr, uid, msg):
def msg_new(self, cr, uid, msg):
mailgate_obj = self.pool.get('mail.gateway')
msg_body = mailgate_obj.msg_body_get(msg)
data = {
'name': msg['Subject'],
'email_from': msg['From'],
'email_cc': msg['Cc'],
'user_id': False,
'description': msg_body['body'],
'history_line': [(0, 0, {'description': msg_body['body'], 'email': msg['From'] })],
'name': msg['Subject'],
'email_from': msg['From'],
'email_cc': msg['Cc'],
'user_id': False,
'description': msg_body['body'],
'history_line': [(0, 0, {'description': msg_body['body'], 'email': msg['From'] })],
}
res = mailgate_obj.partner_get(cr, uid, msg['From'])
if res:
data.update(res)
res = self.create(cr, uid, data)
res = self.create(cr, uid, data)
return res
def msg_update(self, cr, uid, ids, *args, **argv):
return self._map_ids('msg_update',cr, uid, ids, *args, **argv)
return self._map_ids('msg_update', cr, uid, ids, *args, **argv)
def emails_get(self, cr, uid, ids, *args, **argv):
return self._map_ids('emails_get',cr, uid, ids, *args, **argv)
def msg_send(self, cr, uid, ids, *args, **argv):
return self._map_ids('msg_send',cr, uid, ids, *args, **argv)
return self._map_ids('emails_get', cr, uid, ids, *args, **argv)
def msg_send(self, cr, uid, ids, *args, **argv):
return self._map_ids('msg_send', cr, uid, ids, *args, **argv)
crm_meeting()
@ -392,16 +393,16 @@ class crm_meeting_generic_wizard(osv.osv_memory):
_name = 'crm.meeting.generic_wizard'
_columns = {
'section_id': fields.many2one('crm.case.section', 'Section', required=True),
'user_id': fields.many2one('res.users', 'Responsible'),
'section_id': fields.many2one('crm.case.section', 'Section', required=True),
'user_id': fields.many2one('res.users', 'Responsible'),
}
def _get_default_section(self, cr, uid, context):
case_id = context.get('active_id',False)
case_id = context.get('active_id', False)
if not case_id:
return False
case_obj = self.pool.get('crm.meeting')
case = case_obj.read(cr, uid, case_id, ['state','section_id'])
case = case_obj.read(cr, uid, case_id, ['state', 'section_id'])
if case['state'] in ('done'):
raise osv.except_osv(_('Error !'), _('You can not assign Closed Case.'))
return case['section_id']
@ -412,28 +413,28 @@ class crm_meeting_generic_wizard(osv.osv_memory):
}
def action_create(self, cr, uid, ids, context=None):
case_obj = self.pool.get('crm.meeting')
case_id = context.get('active_id',[])
case_id = context.get('active_id', [])
res = self.read(cr, uid, ids)[0]
case = case_obj.browse(cr, uid, case_id)
if case.state in ('done'):
raise osv.except_osv(_('Error !'), _('You can not assign Closed Case.'))
new_case_id = case_obj.copy(cr, uid, case_id, default=
{
'section_id':res.get('section_id',False),
'user_id':res.get('user_id',False),
'section_id':res.get('section_id', False),
'user_id':res.get('user_id', False),
'case_id' : case.inherit_case_id.id
}, context=context)
}, context=context)
case_obj.case_close(cr, uid, [case_id])
data_obj = self.pool.get('ir.model.data')
result = data_obj._get_id(cr, uid, 'crm', 'view_crm_case_meetings_filter')
search_view = data_obj.read(cr, uid, result, ['res_id'])
new_case = case_obj.read(cr, uid, new_case_id, ['id'])
value = {
'name': _('Meetings'),
'view_type': 'form',
'view_mode': 'calendar, tree, form',
'res_model': 'crm.meeting',
'type': 'ir.actions.act_window',
new_case = case_obj.read(cr, uid, new_case_id, ['id'])
value = {
'name': _('Meetings'),
'view_type': 'form',
'view_mode': 'calendar, tree, form',
'res_model': 'crm.meeting',
'type': 'ir.actions.act_window',
'search_view_id': search_view['res_id']
}
return value