2009-12-18 13:44:31 +00:00
|
|
|
|
# -*- coding: utf-8 -*-
|
2009-12-04 08:25:52 +00:00
|
|
|
|
##############################################################################
|
2010-03-25 12:07:00 +00:00
|
|
|
|
#
|
2009-12-04 08:25:52 +00:00
|
|
|
|
# OpenERP, Open Source Management Solution
|
2010-01-12 09:18:39 +00:00
|
|
|
|
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
2009-12-04 08:25:52 +00:00
|
|
|
|
#
|
|
|
|
|
# This program is free software: you can redistribute it and/or modify
|
2009-12-18 13:44:31 +00:00
|
|
|
|
# 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.
|
2009-12-04 08:25:52 +00:00
|
|
|
|
#
|
|
|
|
|
# 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
|
2009-12-18 13:44:31 +00:00
|
|
|
|
# GNU Affero General Public License for more details.
|
2009-12-04 08:25:52 +00:00
|
|
|
|
#
|
2009-12-18 13:44:31 +00:00
|
|
|
|
# You should have received a copy of the GNU Affero General Public License
|
2010-03-25 12:07:00 +00:00
|
|
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2009-12-04 08:25:52 +00:00
|
|
|
|
#
|
|
|
|
|
##############################################################################
|
2010-03-25 12:07:00 +00:00
|
|
|
|
|
2010-04-30 12:39:39 +00:00
|
|
|
|
from datetime import datetime, timedelta, date
|
2009-12-16 14:16:20 +00:00
|
|
|
|
from dateutil import parser
|
2010-02-11 14:08:46 +00:00
|
|
|
|
from dateutil import rrule
|
2010-02-11 12:37:41 +00:00
|
|
|
|
from osv import fields, osv
|
|
|
|
|
from service import web_services
|
2010-01-25 05:46:13 +00:00
|
|
|
|
from tools.translate import _
|
2010-02-01 13:38:58 +00:00
|
|
|
|
import pytz
|
2009-12-14 11:07:43 +00:00
|
|
|
|
import re
|
2010-02-01 11:28:02 +00:00
|
|
|
|
import time
|
2010-02-11 12:37:41 +00:00
|
|
|
|
import tools
|
2009-12-04 08:25:52 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
months = {
|
2010-04-06 09:01:56 +00:00
|
|
|
|
1: "January", 2: "February", 3: "March", 4: "April", \
|
|
|
|
|
5: "May", 6: "June", 7: "July", 8: "August", 9: "September", \
|
|
|
|
|
10: "October", 11: "November", 12: "December"
|
|
|
|
|
}
|
2010-02-05 05:41:34 +00:00
|
|
|
|
|
2010-04-30 12:39:39 +00:00
|
|
|
|
def get_recurrent_dates(rrulestring, exdate, startdate=None, exrule=None):
|
2010-03-18 11:30:31 +00:00
|
|
|
|
"""
|
2010-04-05 10:37:31 +00:00
|
|
|
|
Get recurrent dates based on Rule string considering exdate and start date
|
|
|
|
|
@param rrulestring: Rulestring
|
|
|
|
|
@param exdate: List of exception dates for rrule
|
|
|
|
|
@param startdate: Startdate for computing recurrent dates
|
|
|
|
|
@return: List of Recurrent dates
|
2010-03-18 11:30:31 +00:00
|
|
|
|
"""
|
2010-03-02 05:28:50 +00:00
|
|
|
|
def todate(date):
|
2010-03-03 12:59:53 +00:00
|
|
|
|
val = parser.parse(''.join((re.compile('\d')).findall(date)))
|
2010-03-02 05:28:50 +00:00
|
|
|
|
return val
|
2010-04-05 10:37:31 +00:00
|
|
|
|
|
2010-02-11 14:08:46 +00:00
|
|
|
|
if not startdate:
|
|
|
|
|
startdate = datetime.now()
|
2010-07-02 13:30:13 +00:00
|
|
|
|
if not exdate:
|
|
|
|
|
exdate = []
|
|
|
|
|
rset1 = rrule.rrulestr(str(rrulestring), dtstart=startdate, forceset=True)
|
2010-02-11 14:08:46 +00:00
|
|
|
|
|
|
|
|
|
for date in exdate:
|
|
|
|
|
datetime_obj = todate(date)
|
|
|
|
|
rset1._exdate.append(datetime_obj)
|
2010-04-30 12:39:39 +00:00
|
|
|
|
if exrule:
|
|
|
|
|
rset1.exrule(rrule.rrulestr(str(exrule), dtstart=startdate))
|
2010-07-02 13:30:13 +00:00
|
|
|
|
|
2010-07-06 05:42:47 +00:00
|
|
|
|
return list(rset1._iter())
|
2010-02-11 14:08:46 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
def base_calendar_id2real_id(base_calendar_id=None, with_date=False):
|
2010-03-18 11:30:31 +00:00
|
|
|
|
"""
|
2010-04-05 10:37:31 +00:00
|
|
|
|
This function converts virtual event id into real id of actual event
|
|
|
|
|
@param base_calendar_id: Id of calendar
|
|
|
|
|
@param with_date: If value passed to this param it will return dates based on value of withdate + base_calendar_id
|
2010-03-18 11:30:31 +00:00
|
|
|
|
"""
|
2010-03-25 12:07:00 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
if base_calendar_id and isinstance(base_calendar_id, (str, unicode)):
|
|
|
|
|
res = base_calendar_id.split('-')
|
2010-04-05 10:37:31 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
if len(res) >= 2:
|
|
|
|
|
real_id = res[0]
|
|
|
|
|
if with_date:
|
|
|
|
|
real_date = time.strftime("%Y-%m-%d %H:%M:%S", \
|
|
|
|
|
time.strptime(res[1], "%Y%m%d%H%M%S"))
|
|
|
|
|
start = datetime.strptime(real_date, "%Y-%m-%d %H:%M:%S")
|
|
|
|
|
end = start + timedelta(hours=with_date)
|
|
|
|
|
return (int(real_id), real_date, end.strftime("%Y-%m-%d %H:%M:%S"))
|
|
|
|
|
return int(real_id)
|
2010-04-05 10:37:31 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
return base_calendar_id and int(base_calendar_id) or base_calendar_id
|
2010-01-21 09:09:21 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
def real_id2base_calendar_id(real_id, recurrent_date):
|
2010-03-18 11:30:31 +00:00
|
|
|
|
"""
|
2010-04-05 10:37:31 +00:00
|
|
|
|
Convert real id of record into virtual id using recurrent_date
|
|
|
|
|
e.g. real id is 1 and recurrent_date is 01-12-2009 10:00:00 then it will return
|
|
|
|
|
1-20091201100000
|
2010-03-18 11:30:31 +00:00
|
|
|
|
@return: real id with recurrent date.
|
|
|
|
|
"""
|
2010-03-25 12:07:00 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
if real_id and recurrent_date:
|
|
|
|
|
recurrent_date = time.strftime("%Y%m%d%H%M%S", \
|
2010-04-06 07:28:49 +00:00
|
|
|
|
time.strptime(recurrent_date, "%Y-%m-%d %H:%M:%S"))
|
2010-02-11 12:37:41 +00:00
|
|
|
|
return '%d-%s' % (real_id, recurrent_date)
|
|
|
|
|
return real_id
|
2010-01-12 12:06:53 +00:00
|
|
|
|
|
2010-05-14 10:14:26 +00:00
|
|
|
|
def _links_get(self, cr, uid, context=None):
|
2010-03-18 11:30:31 +00:00
|
|
|
|
"""
|
|
|
|
|
Get request link.
|
|
|
|
|
@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: list of dictionary which contain object and name and id.
|
|
|
|
|
"""
|
2010-03-25 12:07:00 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
obj = self.pool.get('res.request.link')
|
|
|
|
|
ids = obj.search(cr, uid, [])
|
2010-03-23 12:26:31 +00:00
|
|
|
|
res = obj.read(cr, uid, ids, ['object', 'name'], context=context)
|
2010-02-11 12:37:41 +00:00
|
|
|
|
return [(r['object'], r['name']) for r in res]
|
2009-12-04 08:25:52 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
html_invitation = """
|
|
|
|
|
<html>
|
|
|
|
|
<head>
|
|
|
|
|
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
|
|
|
|
|
<title>%(name)s</title>
|
|
|
|
|
</head>
|
|
|
|
|
<body>
|
|
|
|
|
<table border="0" cellspacing="10" cellpadding="0" width="100%%"
|
|
|
|
|
style="font-family: Arial, Sans-serif; font-size: 14">
|
|
|
|
|
<tr>
|
|
|
|
|
<td width="100%%">Hello,</td>
|
|
|
|
|
</tr>
|
|
|
|
|
<tr>
|
|
|
|
|
<td width="100%%">You are invited for <i>%(company)s</i> Event.</td>
|
|
|
|
|
</tr>
|
|
|
|
|
<tr>
|
|
|
|
|
<td width="100%%">Below are the details of event:</td>
|
|
|
|
|
</tr>
|
|
|
|
|
</table>
|
|
|
|
|
|
|
|
|
|
<table cellspacing="0" cellpadding="5" border="0" summary=""
|
|
|
|
|
style="width: 90%%; font-family: Arial, Sans-serif; border: 1px Solid #ccc; background-color: #f6f6f6">
|
|
|
|
|
<tr valign="center" align="center">
|
|
|
|
|
<td bgcolor="DFDFDF">
|
|
|
|
|
<h3>%(name)s</h3>
|
|
|
|
|
</td>
|
|
|
|
|
</tr>
|
|
|
|
|
<tr>
|
|
|
|
|
<td>
|
|
|
|
|
<table cellpadding="8" cellspacing="0" border="0"
|
|
|
|
|
style="font-size: 14" summary="Eventdetails" bgcolor="f6f6f6"
|
|
|
|
|
width="90%%">
|
|
|
|
|
<tr>
|
|
|
|
|
<td width="21%%">
|
|
|
|
|
<div><b>Start Date</b></div>
|
|
|
|
|
</td>
|
|
|
|
|
<td><b>:</b></td>
|
|
|
|
|
<td>%(start_date)s</td>
|
|
|
|
|
<td width="15%%">
|
|
|
|
|
<div><b>End Date</b></div>
|
|
|
|
|
</td>
|
|
|
|
|
<td><b>:</b></td>
|
|
|
|
|
<td width="25%%">%(end_date)s</td>
|
|
|
|
|
</tr>
|
|
|
|
|
<tr valign="top">
|
|
|
|
|
<td><b>Description</b></td>
|
|
|
|
|
<td><b>:</b></td>
|
|
|
|
|
<td colspan="3">%(description)s</td>
|
|
|
|
|
</tr>
|
|
|
|
|
<tr valign="top">
|
|
|
|
|
<td>
|
|
|
|
|
<div><b>Location</b></div>
|
|
|
|
|
</td>
|
|
|
|
|
<td><b>:</b></td>
|
|
|
|
|
<td colspan="3">%(location)s</td>
|
|
|
|
|
</tr>
|
|
|
|
|
<tr valign="top">
|
|
|
|
|
<td>
|
|
|
|
|
<div><b>Event Attendees</b></div>
|
|
|
|
|
</td>
|
|
|
|
|
<td><b>:</b></td>
|
|
|
|
|
<td colspan="3">
|
|
|
|
|
<div>
|
|
|
|
|
<div>%(attendees)s</div>
|
|
|
|
|
</div>
|
|
|
|
|
</td>
|
|
|
|
|
</tr>
|
|
|
|
|
</table>
|
|
|
|
|
</td>
|
|
|
|
|
</tr>
|
|
|
|
|
</table>
|
|
|
|
|
<table border="0" cellspacing="10" cellpadding="0" width="100%%"
|
|
|
|
|
style="font-family: Arial, Sans-serif; font-size: 14">
|
|
|
|
|
<tr>
|
|
|
|
|
<td width="100%%">From:</td>
|
|
|
|
|
</tr>
|
|
|
|
|
<tr>
|
|
|
|
|
<td width="100%%">%(user)s</td>
|
|
|
|
|
</tr>
|
|
|
|
|
<tr valign="top">
|
|
|
|
|
<td width="100%%">-<font color="a7a7a7">-------------------------</font></td>
|
|
|
|
|
</tr>
|
|
|
|
|
<tr>
|
|
|
|
|
<td width="100%%"> <font color="a7a7a7">%(sign)s</font></td>
|
|
|
|
|
</tr>
|
|
|
|
|
</table>
|
|
|
|
|
</body>
|
|
|
|
|
</html>
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
class calendar_attendee(osv.osv):
|
2010-03-18 11:30:31 +00:00
|
|
|
|
"""
|
|
|
|
|
Calendar Attendee Information
|
|
|
|
|
"""
|
2010-02-11 12:37:41 +00:00
|
|
|
|
_name = 'calendar.attendee'
|
|
|
|
|
_description = 'Attendee information'
|
|
|
|
|
_rec_name = 'cutype'
|
|
|
|
|
|
|
|
|
|
__attribute__ = {}
|
|
|
|
|
|
|
|
|
|
def _get_address(self, name=None, email=None):
|
2010-03-18 11:30:31 +00:00
|
|
|
|
"""
|
2010-05-14 10:14:26 +00:00
|
|
|
|
Gives email information in ical CAL-ADDRESS type format
|
|
|
|
|
@param name: Name for CAL-ADDRESS value
|
|
|
|
|
@param email: Email address for CAL-ADDRESS value
|
2010-03-18 11:30:31 +00:00
|
|
|
|
"""
|
2010-02-11 12:37:41 +00:00
|
|
|
|
if name and email:
|
|
|
|
|
name += ':'
|
|
|
|
|
return (name or '') + (email and ('MAILTO:' + email) or '')
|
|
|
|
|
|
|
|
|
|
def _compute_data(self, cr, uid, ids, name, arg, context):
|
2010-03-18 11:30:31 +00:00
|
|
|
|
"""
|
2010-05-14 10:14:26 +00:00
|
|
|
|
Compute data on function fields for attendee values .
|
2010-03-18 11:30:31 +00:00
|
|
|
|
@param cr: the current row, from the database cursor,
|
|
|
|
|
@param uid: the current user’s ID for security checks,
|
|
|
|
|
@param ids: List of calendar attendee’s IDs.
|
|
|
|
|
@param name: name of field.
|
|
|
|
|
@param context: A standard dictionary for contextual values
|
|
|
|
|
@return: Dictionary of form {id: {'field Name': value'}}.
|
|
|
|
|
"""
|
2010-02-11 12:37:41 +00:00
|
|
|
|
name = name[0]
|
|
|
|
|
result = {}
|
|
|
|
|
for attdata in self.browse(cr, uid, ids, context=context):
|
|
|
|
|
id = attdata.id
|
|
|
|
|
result[id] = {}
|
|
|
|
|
if name == 'sent_by':
|
|
|
|
|
if not attdata.sent_by_uid:
|
|
|
|
|
result[id][name] = ''
|
|
|
|
|
continue
|
2010-01-25 12:57:21 +00:00
|
|
|
|
else:
|
2010-04-06 07:28:49 +00:00
|
|
|
|
result[id][name] = self._get_address(attdata.sent_by_uid.name, \
|
2010-02-11 12:37:41 +00:00
|
|
|
|
attdata.sent_by_uid.address_id.email)
|
2010-05-14 10:14:26 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
if name == 'cn':
|
|
|
|
|
if attdata.user_id:
|
2010-05-13 11:37:59 +00:00
|
|
|
|
result[id][name] = attdata.user_id.name
|
2010-02-11 12:37:41 +00:00
|
|
|
|
elif attdata.partner_address_id:
|
2010-05-13 11:37:59 +00:00
|
|
|
|
result[id][name] = attdata.partner_address_id.name or attdata.partner_id.name
|
2010-02-11 12:37:41 +00:00
|
|
|
|
else:
|
2010-05-13 11:37:59 +00:00
|
|
|
|
result[id][name] = attdata.email or ''
|
2010-05-14 10:14:26 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
if name == 'delegated_to':
|
|
|
|
|
todata = []
|
2010-05-13 11:37:59 +00:00
|
|
|
|
for child in attdata.child_ids:
|
|
|
|
|
if child.email:
|
|
|
|
|
todata.append('MAILTO:' + child.email)
|
2010-02-11 12:37:41 +00:00
|
|
|
|
result[id][name] = ', '.join(todata)
|
2010-05-14 10:14:26 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
if name == 'delegated_from':
|
|
|
|
|
fromdata = []
|
2010-05-13 11:37:59 +00:00
|
|
|
|
for parent in attdata.parent_ids:
|
|
|
|
|
if parent.email:
|
|
|
|
|
fromdata.append('MAILTO:' + parent.email)
|
2010-02-11 12:37:41 +00:00
|
|
|
|
result[id][name] = ', '.join(fromdata)
|
2010-05-14 10:14:26 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
if name == 'event_date':
|
|
|
|
|
if attdata.ref:
|
2010-03-17 14:11:30 +00:00
|
|
|
|
result[id][name] = attdata.ref.date
|
2010-02-11 12:37:41 +00:00
|
|
|
|
else:
|
|
|
|
|
result[id][name] = False
|
2010-05-14 10:14:26 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
if name == 'event_end_date':
|
|
|
|
|
if attdata.ref:
|
2010-03-18 11:30:31 +00:00
|
|
|
|
result[id][name] = attdata.ref.date_deadline
|
2010-02-11 12:37:41 +00:00
|
|
|
|
else:
|
|
|
|
|
result[id][name] = False
|
2010-05-14 10:14:26 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
if name == 'sent_by_uid':
|
|
|
|
|
if attdata.ref:
|
2010-03-18 11:30:31 +00:00
|
|
|
|
result[id][name] = (attdata.ref.user_id.id, attdata.ref.user_id.name)
|
2010-02-11 12:37:41 +00:00
|
|
|
|
else:
|
|
|
|
|
result[id][name] = uid
|
2010-05-14 10:14:26 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
if name == 'language':
|
|
|
|
|
user_obj = self.pool.get('res.users')
|
2010-03-23 12:26:31 +00:00
|
|
|
|
lang = user_obj.read(cr, uid, uid, ['context_lang'], context=context)['context_lang']
|
2010-02-11 12:37:41 +00:00
|
|
|
|
result[id][name] = lang.replace('_', '-')
|
2010-05-14 10:14:26 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
return result
|
2010-01-22 13:55:53 +00:00
|
|
|
|
|
2010-05-14 10:14:26 +00:00
|
|
|
|
def _links_get(self, cr, uid, context=None):
|
2010-03-18 11:30:31 +00:00
|
|
|
|
"""
|
2010-03-25 13:05:11 +00:00
|
|
|
|
Get request link for ref field in calendar attendee.
|
2010-03-18 11:30:31 +00:00
|
|
|
|
@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: list of dictionary which contain object and name and id.
|
|
|
|
|
"""
|
2010-03-25 12:07:00 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
obj = self.pool.get('res.request.link')
|
|
|
|
|
ids = obj.search(cr, uid, [])
|
2010-03-23 12:26:31 +00:00
|
|
|
|
res = obj.read(cr, uid, ids, ['object', 'name'], context=context)
|
2010-02-11 12:37:41 +00:00
|
|
|
|
return [(r['object'], r['name']) for r in res]
|
|
|
|
|
|
|
|
|
|
def _lang_get(self, cr, uid, context={}):
|
2010-03-18 11:30:31 +00:00
|
|
|
|
"""
|
2010-05-14 10:14:26 +00:00
|
|
|
|
Get language for language selection field.
|
2010-03-18 11:30:31 +00:00
|
|
|
|
@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: list of dictionary which contain code and name and id.
|
|
|
|
|
"""
|
2010-02-11 12:37:41 +00:00
|
|
|
|
obj = self.pool.get('res.lang')
|
|
|
|
|
ids = obj.search(cr, uid, [])
|
2010-03-23 12:26:31 +00:00
|
|
|
|
res = obj.read(cr, uid, ids, ['code', 'name'], context=context)
|
2010-02-11 12:37:41 +00:00
|
|
|
|
res = [((r['code']).replace('_', '-'), r['name']) for r in res]
|
2009-12-21 09:49:00 +00:00
|
|
|
|
return res
|
2009-12-14 11:07:43 +00:00
|
|
|
|
|
2010-01-21 15:05:53 +00:00
|
|
|
|
_columns = {
|
2010-02-11 12:37:41 +00:00
|
|
|
|
'cutype': fields.selection([('individual', 'Individual'), \
|
|
|
|
|
('group', 'Group'), ('resource', 'Resource'), \
|
|
|
|
|
('room', 'Room'), ('unknown', '') ], \
|
2010-04-29 13:50:23 +00:00
|
|
|
|
'Invite Type', help="Specify the type of Invitation"),
|
|
|
|
|
'member': fields.char('Member', size=124,
|
|
|
|
|
help="Indicate the groups that the attendee belongs to"),
|
2010-02-11 12:37:41 +00:00
|
|
|
|
'role': fields.selection([('req-participant', 'Participation required'), \
|
|
|
|
|
('chair', 'Chair Person'), \
|
|
|
|
|
('opt-participant', 'Optional Participation'), \
|
|
|
|
|
('non-participant', 'For information Purpose')], 'Role', \
|
2010-04-29 13:50:23 +00:00
|
|
|
|
help='Participation role for the calendar user'),
|
|
|
|
|
'state': fields.selection([('tentative', 'Tentative'),
|
|
|
|
|
('needs-action', 'Needs Action'),
|
|
|
|
|
('accepted', 'Accepted'),
|
|
|
|
|
('declined', 'Declined'),
|
2010-04-06 08:39:14 +00:00
|
|
|
|
('delegated', 'Delegated')], 'State', readonly=True, \
|
2010-04-29 13:50:23 +00:00
|
|
|
|
help="Status of the attendee's participation"),
|
|
|
|
|
'rsvp': fields.boolean('Required Reply?',
|
|
|
|
|
help="Indicats whether the favor of a reply is requested"),
|
2010-02-11 12:37:41 +00:00
|
|
|
|
'delegated_to': fields.function(_compute_data, method=True, \
|
|
|
|
|
string='Delegated To', type="char", size=124, store=True, \
|
|
|
|
|
multi='delegated_to', help="The users that the original \
|
2010-04-29 13:50:23 +00:00
|
|
|
|
request was delegated to"),
|
2010-02-11 12:37:41 +00:00
|
|
|
|
'delegated_from': fields.function(_compute_data, method=True, string=\
|
2010-04-29 13:50:23 +00:00
|
|
|
|
'Delegated From', type="char", store=True, size=124, multi='delegated_from'),
|
2010-04-06 08:39:14 +00:00
|
|
|
|
'parent_ids': fields.many2many('calendar.attendee', 'calendar_attendee_parent_rel', \
|
2010-04-29 13:50:23 +00:00
|
|
|
|
'attendee_id', 'parent_id', 'Delegrated From'),
|
2010-04-06 08:39:14 +00:00
|
|
|
|
'child_ids': fields.many2many('calendar.attendee', 'calendar_attendee_child_rel', \
|
2010-04-29 13:50:23 +00:00
|
|
|
|
'attendee_id', 'child_id', 'Delegrated To'),
|
2010-04-06 08:39:14 +00:00
|
|
|
|
'sent_by': fields.function(_compute_data, method=True, string='Sent By', \
|
|
|
|
|
type="char", multi='sent_by', store=True, size=124, \
|
2010-04-29 13:50:23 +00:00
|
|
|
|
help="Specify the user that is acting on behalf of the calendar user"),
|
2010-04-06 08:39:14 +00:00
|
|
|
|
'sent_by_uid': fields.function(_compute_data, method=True, string='Sent By User', \
|
2010-04-29 13:50:23 +00:00
|
|
|
|
type="many2one", relation="res.users", multi='sent_by_uid'),
|
2010-04-06 08:39:14 +00:00
|
|
|
|
'cn': fields.function(_compute_data, method=True, string='Common name', \
|
2010-04-29 13:50:23 +00:00
|
|
|
|
type="char", size=124, multi='cn', store=True),
|
2010-03-25 12:07:00 +00:00
|
|
|
|
'dir': fields.char('URI Reference', size=124, help="Reference to the URI\
|
2010-04-29 13:50:23 +00:00
|
|
|
|
that points to the directory information corresponding to the attendee."),
|
2010-04-06 08:39:14 +00:00
|
|
|
|
'language': fields.function(_compute_data, method=True, string='Language', \
|
|
|
|
|
type="selection", selection=_lang_get, multi='language', \
|
2010-04-06 07:28:49 +00:00
|
|
|
|
store=True, help="To specify the language for text values in a\
|
2010-04-29 13:50:23 +00:00
|
|
|
|
property or property parameter."),
|
|
|
|
|
'user_id': fields.many2one('res.users', 'User'),
|
|
|
|
|
'partner_address_id': fields.many2one('res.partner.address', 'Contact'),
|
2010-04-06 08:39:14 +00:00
|
|
|
|
'partner_id': fields.related('partner_address_id', 'partner_id', type='many2one', \
|
2010-04-29 13:50:23 +00:00
|
|
|
|
relation='res.partner', string='Partner', help="Partner related to contact"),
|
|
|
|
|
'email': fields.char('Email', size=124, help="Email of Invited Person"),
|
2010-04-06 08:39:14 +00:00
|
|
|
|
'event_date': fields.function(_compute_data, method=True, string='Event Date', \
|
2010-04-29 13:50:23 +00:00
|
|
|
|
type="datetime", multi='event_date'),
|
2010-04-06 07:28:49 +00:00
|
|
|
|
'event_end_date': fields.function(_compute_data, method=True, \
|
|
|
|
|
string='Event End Date', type="datetime", \
|
2010-04-29 13:50:23 +00:00
|
|
|
|
multi='event_end_date'),
|
|
|
|
|
'ref': fields.reference('Event Ref', selection=_links_get, size=128),
|
|
|
|
|
'availability': fields.selection([('free', 'Free'), ('busy', 'Busy')], 'Free/Busy', readonly="True"),
|
2010-02-11 12:37:41 +00:00
|
|
|
|
}
|
|
|
|
|
_defaults = {
|
2010-07-02 07:34:06 +00:00
|
|
|
|
'state': 'needs-action',
|
2010-01-21 15:05:53 +00:00
|
|
|
|
}
|
2010-06-24 12:55:03 +00:00
|
|
|
|
|
|
|
|
|
def copy(self, cr, uid, id, default=None, context=None):
|
|
|
|
|
raise osv.except_osv(_('Warning!'), _('Can not Duplicate'))
|
2010-03-25 12:07:00 +00:00
|
|
|
|
|
2010-04-30 12:39:39 +00:00
|
|
|
|
def get_ics_file(self, cr, uid, event_obj, context=None):
|
|
|
|
|
"""
|
|
|
|
|
Returns iCalendar file for the event invitation
|
|
|
|
|
@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 event_obj: Event object (browse record)
|
|
|
|
|
@param context: A standard dictionary for contextual values
|
|
|
|
|
@return: .ics file content
|
|
|
|
|
"""
|
|
|
|
|
res = None
|
|
|
|
|
def ics_datetime(idate, short=False):
|
|
|
|
|
if short:
|
|
|
|
|
return date.fromtimestamp(time.mktime(time.strptime(idate, '%Y-%m-%d')))
|
|
|
|
|
else:
|
|
|
|
|
return datetime.strptime(idate, '%Y-%m-%d %H:%M:%S')
|
|
|
|
|
try:
|
|
|
|
|
import vobject
|
|
|
|
|
except ImportError:
|
|
|
|
|
return res
|
|
|
|
|
cal = vobject.iCalendar()
|
|
|
|
|
event = cal.add('vevent')
|
|
|
|
|
event.add('created').value = ics_datetime(time.strftime('%Y-%m-%d %H:%M:%S'))
|
|
|
|
|
event.add('dtstart').value = ics_datetime(event_obj.date)
|
|
|
|
|
event.add('dtend').value = ics_datetime(event_obj.date_deadline)
|
|
|
|
|
event.add('summary').value = event_obj.name
|
|
|
|
|
if event_obj.description:
|
|
|
|
|
event.add('description').value = event_obj.description
|
|
|
|
|
if event_obj.location:
|
|
|
|
|
event.add('location').value = event_obj.location
|
|
|
|
|
if event_obj.rrule:
|
|
|
|
|
event.add('rrule').value = event_obj.rrule
|
2010-05-27 10:10:34 +00:00
|
|
|
|
if event_obj.user_id:
|
|
|
|
|
event_org = event.add('organizer')
|
|
|
|
|
event_org.params['CN'] = [event_obj.user_id.name]
|
|
|
|
|
event_org.value = 'MAILTO:' + (event_obj.user_id.user_email or event_obj.user_id.name)
|
2010-04-30 12:39:39 +00:00
|
|
|
|
if event_obj.alarm_id:
|
|
|
|
|
# computes alarm data
|
|
|
|
|
valarm = event.add('valarm')
|
|
|
|
|
alarm_object = self.pool.get('res.alarm')
|
|
|
|
|
alarm_data = alarm_object.read(cr, uid, event_obj.alarm_id.id, context=context)
|
|
|
|
|
# Compute trigger data
|
|
|
|
|
interval = alarm_data['trigger_interval']
|
|
|
|
|
occurs = alarm_data['trigger_occurs']
|
|
|
|
|
duration = (occurs == 'after' and alarm_data['trigger_duration']) \
|
|
|
|
|
or -(alarm_data['trigger_duration'])
|
|
|
|
|
related = alarm_data['trigger_related']
|
|
|
|
|
trigger = valarm.add('TRIGGER')
|
|
|
|
|
trigger.params['related'] = [related.upper()]
|
|
|
|
|
if interval == 'days':
|
|
|
|
|
delta = timedelta(days=duration)
|
|
|
|
|
if interval == 'hours':
|
|
|
|
|
delta = timedelta(hours=duration)
|
|
|
|
|
if interval == 'minutes':
|
|
|
|
|
delta = timedelta(minutes=duration)
|
|
|
|
|
trigger.value = delta
|
2010-05-10 04:46:50 +00:00
|
|
|
|
|
2010-04-30 12:39:39 +00:00
|
|
|
|
# Compute other details
|
|
|
|
|
valarm.add('DESCRIPTION').value = alarm_data['name'] or 'OpenERP'
|
2010-05-10 04:46:50 +00:00
|
|
|
|
|
2010-04-30 12:39:39 +00:00
|
|
|
|
for attendee in event_obj.attendee_ids:
|
|
|
|
|
attendee_add = event.add('attendee')
|
|
|
|
|
attendee_add.params['CUTYPE'] = [str(attendee.cutype)]
|
|
|
|
|
attendee_add.params['ROLE'] = [str(attendee.role)]
|
|
|
|
|
attendee_add.params['RSVP'] = [str(attendee.rsvp)]
|
2010-05-27 10:10:34 +00:00
|
|
|
|
attendee_add.value = 'MAILTO:' + (attendee.email or '')
|
2010-04-30 12:39:39 +00:00
|
|
|
|
res = cal.serialize()
|
|
|
|
|
return res
|
|
|
|
|
|
2010-05-14 10:14:26 +00:00
|
|
|
|
def _send_mail(self, cr, uid, ids, mail_to, email_from=tools.config.get('email_from', False), context=None):
|
2010-03-18 11:30:31 +00:00
|
|
|
|
"""
|
2010-05-14 10:14:26 +00:00
|
|
|
|
Send mail for event invitation to event attendees.
|
2010-03-18 11:30:31 +00:00
|
|
|
|
@param cr: the current row, from the database cursor,
|
|
|
|
|
@param uid: the current user’s ID for security checks,
|
2010-05-14 10:14:26 +00:00
|
|
|
|
@param ids: List of attendee’s IDs.
|
|
|
|
|
@param email_from: Email address for user sending the mail
|
2010-03-18 11:30:31 +00:00
|
|
|
|
@param context: A standard dictionary for contextual values
|
|
|
|
|
@return: True
|
|
|
|
|
"""
|
2010-05-14 10:14:26 +00:00
|
|
|
|
if not context:
|
|
|
|
|
context = {}
|
2010-03-25 12:07:00 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
company = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.name
|
|
|
|
|
for att in self.browse(cr, uid, ids, context=context):
|
|
|
|
|
sign = att.sent_by_uid and att.sent_by_uid.signature or ''
|
|
|
|
|
sign = '<br>'.join(sign and sign.split('\n') or [])
|
2010-03-17 14:11:30 +00:00
|
|
|
|
res_obj = att.ref
|
2010-04-06 07:28:49 +00:00
|
|
|
|
sub = '[%s Invitation][%d] %s' % (company, att.id, res_obj.name)
|
2010-02-11 12:37:41 +00:00
|
|
|
|
att_infos = []
|
2010-04-30 12:39:39 +00:00
|
|
|
|
other_invitaion_ids = self.search(cr, uid, [('ref', '=', res_obj._name + ',' + str(res_obj.id))])
|
2010-02-11 12:37:41 +00:00
|
|
|
|
for att2 in self.browse(cr, uid, other_invitaion_ids):
|
|
|
|
|
att_infos.append(((att2.user_id and att2.user_id.name) or \
|
|
|
|
|
(att2.partner_id and att2.partner_id.name) or \
|
2010-04-06 07:28:49 +00:00
|
|
|
|
att2.email) + ' - Status: ' + att2.state.title())
|
2010-04-29 13:50:23 +00:00
|
|
|
|
body_vals = {'name': res_obj.name,
|
|
|
|
|
'start_date': res_obj.date,
|
|
|
|
|
'end_date': res_obj.date_deadline or False,
|
|
|
|
|
'description': res_obj.description or '-',
|
|
|
|
|
'location': res_obj.location or '-',
|
|
|
|
|
'attendees': '<br>'.join(att_infos),
|
|
|
|
|
'user': res_obj.user_id and res_obj.user_id.name or 'OpenERP User',
|
|
|
|
|
'sign': sign,
|
2010-02-11 12:37:41 +00:00
|
|
|
|
'company': company
|
|
|
|
|
}
|
|
|
|
|
body = html_invitation % body_vals
|
|
|
|
|
if mail_to and email_from:
|
2010-05-27 10:10:34 +00:00
|
|
|
|
attach = self.get_ics_file(cr, uid, res_obj, context=context)
|
2010-02-11 12:37:41 +00:00
|
|
|
|
tools.email_send(
|
2010-05-14 10:14:26 +00:00
|
|
|
|
email_from,
|
|
|
|
|
mail_to,
|
|
|
|
|
sub,
|
|
|
|
|
body,
|
|
|
|
|
attach=attach and [('invitation.ics', attach)] or None,
|
|
|
|
|
subtype='html',
|
2010-04-06 09:01:56 +00:00
|
|
|
|
reply_to=email_from
|
|
|
|
|
)
|
2010-02-11 12:37:41 +00:00
|
|
|
|
return True
|
2010-04-20 12:52:35 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
def onchange_user_id(self, cr, uid, ids, user_id, *args, **argv):
|
2010-03-18 11:30:31 +00:00
|
|
|
|
"""
|
2010-04-06 07:28:49 +00:00
|
|
|
|
Make entry on email and availbility on change of user_id field.
|
2010-03-18 11:30:31 +00:00
|
|
|
|
@param cr: the current row, from the database cursor,
|
|
|
|
|
@param uid: the current user’s ID for security checks,
|
|
|
|
|
@param ids: List of calendar attendee’s IDs.
|
2010-05-14 10:14:26 +00:00
|
|
|
|
@param user_id: Changed value of User id
|
2010-03-18 11:30:31 +00:00
|
|
|
|
@return: dictionary of value. which put value in email and availability fields.
|
|
|
|
|
"""
|
2010-03-25 12:07:00 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
if not user_id:
|
|
|
|
|
return {'value': {'email': ''}}
|
|
|
|
|
usr_obj = self.pool.get('res.users')
|
|
|
|
|
user = usr_obj.browse(cr, uid, user_id, *args)
|
|
|
|
|
return {'value': {'email': user.address_id.email, 'availability':user.availability}}
|
2010-01-25 12:57:21 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
def do_tentative(self, cr, uid, ids, context=None, *args):
|
2010-05-14 10:14:26 +00:00
|
|
|
|
""" Makes event invitation as Tentative
|
|
|
|
|
@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 calendar attendee’s IDs
|
|
|
|
|
@param *args: Get Tupple value
|
|
|
|
|
@param context: A standard dictionary for contextual values
|
|
|
|
|
"""
|
2010-07-02 07:34:06 +00:00
|
|
|
|
return self.write(cr, uid, ids, {'state': 'tentative'}, context)
|
2010-02-11 12:37:41 +00:00
|
|
|
|
|
|
|
|
|
def do_accept(self, cr, uid, ids, context=None, *args):
|
2010-03-18 11:30:31 +00:00
|
|
|
|
"""
|
2010-05-14 10:14:26 +00:00
|
|
|
|
Update state of invitation as Accepted and
|
|
|
|
|
if the invited user is other then event user it will make a copy of this event for invited user
|
2010-03-18 11:30:31 +00:00
|
|
|
|
@param cr: the current row, from the database cursor,
|
|
|
|
|
@param uid: the current user’s ID for security checks,
|
|
|
|
|
@param ids: List of calendar attendee’s IDs.
|
2010-05-14 10:14:26 +00:00
|
|
|
|
@param context: A standard dictionary for contextual values
|
2010-03-18 11:30:31 +00:00
|
|
|
|
@return: True
|
|
|
|
|
"""
|
|
|
|
|
if not context:
|
|
|
|
|
context = {}
|
2010-03-19 05:59:41 +00:00
|
|
|
|
|
2010-03-18 12:37:00 +00:00
|
|
|
|
for vals in self.browse(cr, uid, ids, context=context):
|
|
|
|
|
user = vals.user_id
|
2010-03-08 07:05:23 +00:00
|
|
|
|
if user:
|
2010-03-18 12:37:00 +00:00
|
|
|
|
mod_obj = self.pool.get(vals.ref._name)
|
|
|
|
|
if vals.ref:
|
|
|
|
|
if vals.ref.user_id.id != user.id:
|
2010-04-06 07:28:49 +00:00
|
|
|
|
defaults = {'user_id': user.id}
|
2010-03-18 12:37:00 +00:00
|
|
|
|
new_event = mod_obj.copy(cr, uid, vals.ref.id, default=defaults, context=context)
|
|
|
|
|
self.write(cr, uid, vals.id, {'state': 'accepted'}, context)
|
2010-03-19 05:59:41 +00:00
|
|
|
|
|
2010-03-08 07:05:23 +00:00
|
|
|
|
return True
|
2010-02-11 12:37:41 +00:00
|
|
|
|
|
|
|
|
|
def do_decline(self, cr, uid, ids, context=None, *args):
|
2010-05-14 10:14:26 +00:00
|
|
|
|
""" Marks event invitation as Declined
|
|
|
|
|
@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 calendar attendee’s IDs
|
|
|
|
|
@param *args: Get Tupple value
|
|
|
|
|
@param context: A standard dictionary for contextual values """
|
2010-03-25 12:07:00 +00:00
|
|
|
|
|
2010-07-02 07:34:06 +00:00
|
|
|
|
return self.write(cr, uid, ids, {'state': 'declined'}, context)
|
2010-02-11 12:37:41 +00:00
|
|
|
|
|
2010-03-18 06:31:52 +00:00
|
|
|
|
def create(self, cr, uid, vals, context=None):
|
2010-05-14 10:14:26 +00:00
|
|
|
|
""" Overrides orm create method.
|
|
|
|
|
@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 """
|
2010-03-18 11:30:31 +00:00
|
|
|
|
|
2010-03-18 06:31:52 +00:00
|
|
|
|
if not context:
|
|
|
|
|
context = {}
|
2010-02-11 12:37:41 +00:00
|
|
|
|
if not vals.get("email") and vals.get("cn"):
|
|
|
|
|
cnval = vals.get("cn").split(':')
|
2010-04-06 07:28:49 +00:00
|
|
|
|
email = filter(lambda x:x.__contains__('@'), cnval)
|
2010-07-01 06:05:16 +00:00
|
|
|
|
vals['email'] = email and email[0] or ''
|
2010-02-11 12:37:41 +00:00
|
|
|
|
vals['cn'] = vals.get("cn")
|
|
|
|
|
res = super(calendar_attendee, self).create(cr, uid, vals, context)
|
|
|
|
|
return res
|
2010-03-25 12:07:00 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
calendar_attendee()
|
|
|
|
|
|
|
|
|
|
class res_alarm(osv.osv):
|
2010-05-14 10:14:26 +00:00
|
|
|
|
"""Resource Alarm """
|
2010-02-11 12:37:41 +00:00
|
|
|
|
_name = 'res.alarm'
|
|
|
|
|
_description = 'Basic Alarm Information'
|
2010-05-14 10:14:26 +00:00
|
|
|
|
|
2010-01-21 08:14:58 +00:00
|
|
|
|
_columns = {
|
2010-04-29 13:50:23 +00:00
|
|
|
|
'name':fields.char('Name', size=256, required=True),
|
2010-04-06 07:28:49 +00:00
|
|
|
|
'trigger_occurs': fields.selection([('before', 'Before'), \
|
|
|
|
|
('after', 'After')], \
|
2010-04-29 13:50:23 +00:00
|
|
|
|
'Triggers', required=True),
|
2010-04-06 07:28:49 +00:00
|
|
|
|
'trigger_interval': fields.selection([('minutes', 'Minutes'), \
|
|
|
|
|
('hours', 'Hours'), \
|
2010-04-06 08:39:14 +00:00
|
|
|
|
('days', 'Days')], 'Interval', \
|
2010-04-29 13:50:23 +00:00
|
|
|
|
required=True),
|
|
|
|
|
'trigger_duration': fields.integer('Duration', required=True),
|
2010-04-06 07:28:49 +00:00
|
|
|
|
'trigger_related': fields.selection([('start', 'The event starts'), \
|
|
|
|
|
('end', 'The event ends')], \
|
2010-04-29 13:50:23 +00:00
|
|
|
|
'Related to', required=True),
|
2010-02-11 12:37:41 +00:00
|
|
|
|
'duration': fields.integer('Duration', help="""Duration' and 'Repeat' \
|
2010-04-29 13:50:23 +00:00
|
|
|
|
are both optional, but if one occurs, so MUST the other"""),
|
|
|
|
|
'repeat': fields.integer('Repeat'),
|
2010-03-25 12:07:00 +00:00
|
|
|
|
'active': fields.boolean('Active', help="If the active field is set to \
|
2010-05-12 13:16:01 +00:00
|
|
|
|
true, it will allow you to hide the event alarm information without removing it.")
|
2010-02-11 12:37:41 +00:00
|
|
|
|
}
|
2010-01-22 13:55:53 +00:00
|
|
|
|
_defaults = {
|
2010-07-02 07:34:06 +00:00
|
|
|
|
'trigger_interval': 'minutes',
|
|
|
|
|
'trigger_duration': 5,
|
|
|
|
|
'trigger_occurs': 'before',
|
|
|
|
|
'trigger_related': 'start',
|
|
|
|
|
'active': 1,
|
2010-01-22 13:55:53 +00:00
|
|
|
|
}
|
2010-02-11 12:37:41 +00:00
|
|
|
|
|
2010-05-14 10:14:26 +00:00
|
|
|
|
def do_alarm_create(self, cr, uid, ids, model, date, context=None):
|
2010-03-18 11:30:31 +00:00
|
|
|
|
"""
|
2010-05-14 10:14:26 +00:00
|
|
|
|
Create Alarm for event.
|
2010-03-18 11:30:31 +00:00
|
|
|
|
@param cr: the current row, from the database cursor,
|
|
|
|
|
@param uid: the current user’s ID for security checks,
|
|
|
|
|
@param ids: List of res alarm’s IDs.
|
|
|
|
|
@param model: Model name.
|
2010-05-14 10:14:26 +00:00
|
|
|
|
@param date: Event date
|
2010-03-18 11:30:31 +00:00
|
|
|
|
@param context: A standard dictionary for contextual values
|
|
|
|
|
@return: True
|
|
|
|
|
"""
|
2010-05-14 10:14:26 +00:00
|
|
|
|
if not context:
|
|
|
|
|
context = {}
|
2010-02-11 12:37:41 +00:00
|
|
|
|
alarm_obj = self.pool.get('calendar.alarm')
|
2010-07-01 06:05:16 +00:00
|
|
|
|
res_alarm_obj = self.pool.get('res.alarm')
|
2010-02-11 12:37:41 +00:00
|
|
|
|
ir_obj = self.pool.get('ir.model')
|
|
|
|
|
model_id = ir_obj.search(cr, uid, [('model', '=', model)])[0]
|
2010-03-25 12:07:00 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
model_obj = self.pool.get(model)
|
2010-04-06 09:01:56 +00:00
|
|
|
|
for data in model_obj.browse(cr, uid, ids, context):
|
2010-03-25 12:07:00 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
basic_alarm = data.alarm_id
|
2010-07-01 06:05:16 +00:00
|
|
|
|
cal_alarm = data.base_calendar_alarm_id
|
|
|
|
|
if (not basic_alarm and cal_alarm) or (basic_alarm and cal_alarm):
|
|
|
|
|
new_res_alarm = None
|
|
|
|
|
# Find for existing res.alarm
|
|
|
|
|
duration = cal_alarm.trigger_duration
|
|
|
|
|
interval = cal_alarm.trigger_interval
|
|
|
|
|
occurs = cal_alarm.trigger_occurs
|
|
|
|
|
related = cal_alarm.trigger_related
|
|
|
|
|
domain = [('trigger_duration', '=', duration), ('trigger_interval', '=', interval), ('trigger_occurs', '=', occurs), ('trigger_related', '=', related)]
|
|
|
|
|
alarm_ids = res_alarm_obj.search(cr, uid, domain, context=context)
|
|
|
|
|
if not alarm_ids:
|
|
|
|
|
val = {
|
|
|
|
|
'trigger_duration': duration,
|
|
|
|
|
'trigger_interval': interval,
|
|
|
|
|
'trigger_occurs': occurs,
|
|
|
|
|
'trigger_related': related,
|
|
|
|
|
'name': str(duration) + ' ' + str(interval) + ' ' + str(occurs)
|
|
|
|
|
}
|
|
|
|
|
new_res_alarm = res_alarm_obj.create(cr, uid, val, context=context)
|
|
|
|
|
else:
|
|
|
|
|
new_res_alarm = alarm_ids[0]
|
|
|
|
|
cr.execute('Update %s set base_calendar_alarm_id=%s, alarm_id=%s \
|
|
|
|
|
where id=%s' % (model_obj._table, \
|
|
|
|
|
cal_alarm.id, new_res_alarm, data.id))
|
2010-07-01 13:08:19 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
self.do_alarm_unlink(cr, uid, [data.id], model)
|
|
|
|
|
if basic_alarm:
|
|
|
|
|
vals = {
|
2010-04-29 13:50:23 +00:00
|
|
|
|
'action': 'display',
|
|
|
|
|
'description': data.description,
|
|
|
|
|
'name': data.name,
|
|
|
|
|
'attendee_ids': [(6, 0, map(lambda x:x.id, data.attendee_ids))],
|
|
|
|
|
'trigger_related': basic_alarm.trigger_related,
|
|
|
|
|
'trigger_duration': basic_alarm.trigger_duration,
|
|
|
|
|
'trigger_occurs': basic_alarm.trigger_occurs,
|
|
|
|
|
'trigger_interval': basic_alarm.trigger_interval,
|
|
|
|
|
'duration': basic_alarm.duration,
|
|
|
|
|
'repeat': basic_alarm.repeat,
|
|
|
|
|
'state': 'run',
|
|
|
|
|
'event_date': data[date],
|
|
|
|
|
'res_id': data.id,
|
|
|
|
|
'model_id': model_id,
|
2010-02-11 12:37:41 +00:00
|
|
|
|
'user_id': uid
|
|
|
|
|
}
|
|
|
|
|
alarm_id = alarm_obj.create(cr, uid, vals)
|
|
|
|
|
cr.execute('Update %s set base_calendar_alarm_id=%s, alarm_id=%s \
|
|
|
|
|
where id=%s' % (model_obj._table, \
|
|
|
|
|
alarm_id, basic_alarm.id, data.id))
|
2010-04-05 10:37:31 +00:00
|
|
|
|
cr.commit()
|
2010-02-11 12:37:41 +00:00
|
|
|
|
return True
|
|
|
|
|
|
2010-05-14 10:14:26 +00:00
|
|
|
|
def do_alarm_unlink(self, cr, uid, ids, model, context=None):
|
2010-03-18 11:30:31 +00:00
|
|
|
|
"""
|
2010-03-25 12:07:00 +00:00
|
|
|
|
Delete alarm specified in ids
|
2010-03-18 11:30:31 +00:00
|
|
|
|
@param cr: the current row, from the database cursor,
|
|
|
|
|
@param uid: the current user’s ID for security checks,
|
|
|
|
|
@param ids: List of res alarm’s IDs.
|
2010-05-14 10:14:26 +00:00
|
|
|
|
@param model: Model name for which alarm is to be cleared.
|
2010-03-18 11:30:31 +00:00
|
|
|
|
@return: True
|
|
|
|
|
"""
|
2010-05-14 10:14:26 +00:00
|
|
|
|
if not context:
|
|
|
|
|
context = {}
|
2010-02-11 12:37:41 +00:00
|
|
|
|
alarm_obj = self.pool.get('calendar.alarm')
|
|
|
|
|
ir_obj = self.pool.get('ir.model')
|
|
|
|
|
model_id = ir_obj.search(cr, uid, [('model', '=', model)])[0]
|
|
|
|
|
model_obj = self.pool.get(model)
|
2010-04-06 09:01:56 +00:00
|
|
|
|
for datas in model_obj.browse(cr, uid, ids, context):
|
2010-02-11 12:37:41 +00:00
|
|
|
|
alarm_ids = alarm_obj.search(cr, uid, [('model_id', '=', model_id), ('res_id', '=', datas.id)])
|
|
|
|
|
if alarm_ids:
|
|
|
|
|
alarm_obj.unlink(cr, uid, alarm_ids)
|
|
|
|
|
cr.execute('Update %s set base_calendar_alarm_id=NULL, alarm_id=NULL\
|
2010-04-06 07:28:49 +00:00
|
|
|
|
where id=%s' % (model_obj._table, datas.id))
|
2010-02-11 12:37:41 +00:00
|
|
|
|
cr.commit()
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
res_alarm()
|
|
|
|
|
|
|
|
|
|
class calendar_alarm(osv.osv):
|
|
|
|
|
_name = 'calendar.alarm'
|
|
|
|
|
_description = 'Event alarm information'
|
|
|
|
|
_inherit = 'res.alarm'
|
|
|
|
|
__attribute__ = {}
|
|
|
|
|
|
|
|
|
|
_columns = {
|
2010-05-14 10:14:26 +00:00
|
|
|
|
'alarm_id': fields.many2one('res.alarm', 'Basic Alarm', ondelete='cascade'),
|
2010-04-06 09:01:56 +00:00
|
|
|
|
'name': fields.char('Summary', size=124, help="""Contains the text to be \
|
|
|
|
|
used as the message subject for email \
|
2010-05-14 10:14:26 +00:00
|
|
|
|
or contains the text to be used for display"""),
|
2010-04-06 09:01:56 +00:00
|
|
|
|
'action': fields.selection([('audio', 'Audio'), ('display', 'Display'), \
|
|
|
|
|
('procedure', 'Procedure'), ('email', 'Email') ], 'Action', \
|
2010-05-14 10:14:26 +00:00
|
|
|
|
required=True, help="Defines the action to be invoked when an alarm is triggered"),
|
2010-04-06 09:01:56 +00:00
|
|
|
|
'description': fields.text('Description', help='Provides a more complete \
|
|
|
|
|
description of the calendar component, than that \
|
2010-05-14 10:14:26 +00:00
|
|
|
|
provided by the "SUMMARY" property'),
|
2010-04-06 09:01:56 +00:00
|
|
|
|
'attendee_ids': fields.many2many('calendar.attendee', 'alarm_attendee_rel', \
|
2010-05-14 10:14:26 +00:00
|
|
|
|
'alarm_id', 'attendee_id', 'Attendees', readonly=True),
|
2010-04-06 09:01:56 +00:00
|
|
|
|
'attach': fields.binary('Attachment', help="""* Points to a sound resource,\
|
|
|
|
|
which is rendered when the alarm is triggered for audio,
|
|
|
|
|
* File which is intended to be sent as message attachments for email,
|
|
|
|
|
* Points to a procedure resource, which is invoked when\
|
2010-05-14 10:14:26 +00:00
|
|
|
|
the alarm is triggered for procedure."""),
|
|
|
|
|
'res_id': fields.integer('Resource ID'),
|
|
|
|
|
'model_id': fields.many2one('ir.model', 'Model'),
|
|
|
|
|
'user_id': fields.many2one('res.users', 'Owner'),
|
|
|
|
|
'event_date': fields.datetime('Event Date'),
|
|
|
|
|
'event_end_date': fields.datetime('Event End Date'),
|
|
|
|
|
'trigger_date': fields.datetime('Trigger Date', readonly="True"),
|
2010-04-06 09:01:56 +00:00
|
|
|
|
'state':fields.selection([
|
2010-05-14 10:14:26 +00:00
|
|
|
|
('draft', 'Draft'),
|
|
|
|
|
('run', 'Run'),
|
|
|
|
|
('stop', 'Stop'),
|
|
|
|
|
('done', 'Done'),
|
|
|
|
|
], 'State', select=True, readonly=True),
|
2010-02-11 12:37:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_defaults = {
|
2010-07-02 07:34:06 +00:00
|
|
|
|
'action': 'email',
|
|
|
|
|
'state': 'run',
|
2010-02-11 12:37:41 +00:00
|
|
|
|
}
|
2010-05-14 10:14:26 +00:00
|
|
|
|
|
|
|
|
|
def create(self, cr, uid, vals, context=None):
|
2010-03-18 11:30:31 +00:00
|
|
|
|
"""
|
2010-05-14 10:14:26 +00:00
|
|
|
|
Overrides orm create method.
|
2010-03-18 11:30:31 +00:00
|
|
|
|
@param self: The object pointer
|
|
|
|
|
@param cr: the current row, from the database cursor,
|
|
|
|
|
@param vals: dictionary of fields value.{‘name_of_the_field’: value, ...}
|
|
|
|
|
@param context: A standard dictionary for contextual values
|
|
|
|
|
@return: new record id for calendar_alarm.
|
|
|
|
|
"""
|
2010-05-14 10:14:26 +00:00
|
|
|
|
if not context:
|
|
|
|
|
context = {}
|
2010-02-11 12:37:41 +00:00
|
|
|
|
event_date = vals.get('event_date', False)
|
|
|
|
|
if event_date:
|
|
|
|
|
dtstart = datetime.strptime(vals['event_date'], "%Y-%m-%d %H:%M:%S")
|
|
|
|
|
if vals['trigger_interval'] == 'days':
|
|
|
|
|
delta = timedelta(days=vals['trigger_duration'])
|
|
|
|
|
if vals['trigger_interval'] == 'hours':
|
|
|
|
|
delta = timedelta(hours=vals['trigger_duration'])
|
|
|
|
|
if vals['trigger_interval'] == 'minutes':
|
|
|
|
|
delta = timedelta(minutes=vals['trigger_duration'])
|
2010-04-06 07:28:49 +00:00
|
|
|
|
trigger_date = dtstart + (vals['trigger_occurs'] == 'after' and delta or -delta)
|
2010-02-11 12:37:41 +00:00
|
|
|
|
vals['trigger_date'] = trigger_date
|
|
|
|
|
res = super(calendar_alarm, self).create(cr, uid, vals, context)
|
|
|
|
|
return res
|
2010-01-21 15:05:53 +00:00
|
|
|
|
|
2010-03-18 11:30:31 +00:00
|
|
|
|
def do_run_scheduler(self, cr, uid, automatic=False, use_new_cursor=False, \
|
2010-02-11 12:37:41 +00:00
|
|
|
|
context=None):
|
2010-05-14 10:14:26 +00:00
|
|
|
|
"""Scheduler for event reminder
|
2010-04-06 09:01:56 +00:00
|
|
|
|
@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 calendar alarm’s IDs.
|
|
|
|
|
@param use_new_cursor: False or the dbname
|
|
|
|
|
@param context: A standard dictionary for contextual values
|
2010-03-25 12:07:00 +00:00
|
|
|
|
"""
|
2010-02-11 12:37:41 +00:00
|
|
|
|
if not context:
|
|
|
|
|
context = {}
|
2010-07-02 13:30:13 +00:00
|
|
|
|
current_datetime = datetime.now()
|
2010-02-11 12:37:41 +00:00
|
|
|
|
request_obj = self.pool.get('res.request')
|
2010-07-02 13:30:13 +00:00
|
|
|
|
alarm_ids = self.search(cr, uid, [('state', '!=', 'done')], context=context)
|
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
mail_to = []
|
2010-07-02 13:30:13 +00:00
|
|
|
|
|
|
|
|
|
for alarm in self.browse(cr, uid, alarm_ids, context=context):
|
|
|
|
|
next_trigger_date = None
|
|
|
|
|
update_vals = {}
|
|
|
|
|
model_obj = self.pool.get(alarm.model_id.model)
|
|
|
|
|
res_obj = model_obj.browse(cr, uid, alarm.res_id, context=context)
|
|
|
|
|
re_dates = []
|
|
|
|
|
|
|
|
|
|
if res_obj.rrule:
|
|
|
|
|
event_date = datetime.strptime(res_obj.date, '%Y-%m-%d %H:%M:%S')
|
|
|
|
|
recurrent_dates = get_recurrent_dates(res_obj.rrule, res_obj.exdate, event_date, res_obj.exrule)
|
|
|
|
|
|
|
|
|
|
trigger_interval = alarm.trigger_interval
|
|
|
|
|
if trigger_interval == 'days':
|
|
|
|
|
delta = timedelta(days=alarm.trigger_duration)
|
|
|
|
|
if trigger_interval == 'hours':
|
|
|
|
|
delta = timedelta(hours=alarm.trigger_duration)
|
|
|
|
|
if trigger_interval == 'minutes':
|
|
|
|
|
delta = timedelta(minutes=alarm.trigger_duration)
|
|
|
|
|
delta = alarm.trigger_occurs == 'after' and delta or -delta
|
|
|
|
|
|
|
|
|
|
for rdate in recurrent_dates:
|
2010-07-06 05:42:47 +00:00
|
|
|
|
if rdate + delta > current_datetime:
|
|
|
|
|
break
|
2010-07-02 13:30:13 +00:00
|
|
|
|
if rdate + delta <= current_datetime:
|
|
|
|
|
re_dates.append(rdate.strftime("%Y-%m-%d %H:%M:%S"))
|
|
|
|
|
rest_dates = recurrent_dates[len(re_dates):]
|
|
|
|
|
next_trigger_date = rest_dates and rest_dates[0] or None
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
re_dates = [alarm.trigger_date]
|
|
|
|
|
|
|
|
|
|
for r_date in re_dates:
|
|
|
|
|
ref = alarm.model_id.model + ',' + str(alarm.res_id)
|
|
|
|
|
|
|
|
|
|
# search for alreay sent requests
|
|
|
|
|
if request_obj.search(cr, uid, [('trigger_date', '=', r_date), ('ref_doc1', '=', ref)], context=context):
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
if alarm.action == 'display':
|
|
|
|
|
value = {
|
|
|
|
|
'name': alarm.name,
|
|
|
|
|
'act_from': alarm.user_id.id,
|
|
|
|
|
'act_to': alarm.user_id.id,
|
|
|
|
|
'body': alarm.description,
|
|
|
|
|
'trigger_date': r_date,
|
|
|
|
|
'ref_doc1': ref
|
|
|
|
|
}
|
|
|
|
|
request_id = request_obj.create(cr, uid, value)
|
|
|
|
|
request_ids = [request_id]
|
|
|
|
|
for attendee in res_obj.attendee_ids:
|
|
|
|
|
if attendee.user_id:
|
|
|
|
|
value['act_to'] = attendee.user_id.id
|
|
|
|
|
request_id = request_obj.create(cr, uid, value)
|
|
|
|
|
request_ids.append(request_id)
|
|
|
|
|
request_obj.request_send(cr, uid, request_ids)
|
|
|
|
|
|
|
|
|
|
if alarm.action == 'email':
|
|
|
|
|
sub = '[Openobject Reminder] %s' % (alarm.name)
|
|
|
|
|
body = """
|
|
|
|
|
Event: %s
|
|
|
|
|
Event Date: %s
|
|
|
|
|
Description: %s
|
|
|
|
|
|
|
|
|
|
From:
|
|
|
|
|
%s
|
|
|
|
|
|
|
|
|
|
----
|
|
|
|
|
%s
|
|
|
|
|
|
|
|
|
|
""" % (alarm.name, alarm.trigger_date, alarm.description, \
|
|
|
|
|
alarm.user_id.name, alarm.user_id.signature)
|
|
|
|
|
mail_to = [alarm.user_id.address_id.email]
|
|
|
|
|
for att in alarm.attendee_ids:
|
|
|
|
|
mail_to.append(att.user_id.address_id.email)
|
|
|
|
|
if mail_to:
|
|
|
|
|
tools.email_send(
|
|
|
|
|
tools.config.get('email_from', False),
|
|
|
|
|
mail_to,
|
|
|
|
|
sub,
|
|
|
|
|
body
|
|
|
|
|
)
|
|
|
|
|
if next_trigger_date:
|
|
|
|
|
update_vals.update({'trigger_date': next_trigger_date})
|
|
|
|
|
else:
|
|
|
|
|
update_vals.update({'state': 'done'})
|
|
|
|
|
self.write(cr, uid, [alarm.id], update_vals)
|
2010-02-11 12:37:41 +00:00
|
|
|
|
return True
|
2010-01-21 08:14:58 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
calendar_alarm()
|
2010-01-21 08:14:58 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
|
|
|
|
|
class calendar_event(osv.osv):
|
|
|
|
|
_name = "calendar.event"
|
|
|
|
|
_description = "Calendar Event"
|
|
|
|
|
__attribute__ = {}
|
2010-03-25 12:07:00 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
def _tz_get(self, cr, uid, context={}):
|
|
|
|
|
return [(x.lower(), x) for x in pytz.all_timezones]
|
|
|
|
|
|
2010-04-19 13:47:20 +00:00
|
|
|
|
def onchange_allday(self, cr, uid, ids, allday, context={}):
|
2010-05-14 10:14:26 +00:00
|
|
|
|
"""Sets duration as 24 Hours if event is selcted for all day
|
2010-04-19 13:47:20 +00:00
|
|
|
|
@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 calendar event’s IDs.
|
|
|
|
|
@param allday: Value of allday boolean
|
|
|
|
|
@param context: A standard dictionary for contextual values
|
|
|
|
|
"""
|
|
|
|
|
if not allday or not ids:
|
|
|
|
|
return {}
|
|
|
|
|
event = self.browse(cr, uid, ids, context=context)[0]
|
|
|
|
|
value = {
|
|
|
|
|
'duration': 24
|
|
|
|
|
}
|
|
|
|
|
return {'value': value}
|
|
|
|
|
|
2010-05-14 10:14:26 +00:00
|
|
|
|
def onchange_dates(self, cr, uid, ids, start_date, duration=False, end_date=False, allday=False, context=None):
|
|
|
|
|
"""Returns duration and/or end date based on values passed
|
2010-03-25 12:07:00 +00:00
|
|
|
|
@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 calendar event’s IDs.
|
2010-05-14 10:14:26 +00:00
|
|
|
|
@param start_date: Starting date
|
|
|
|
|
@param duration: Duration between start date and end date
|
|
|
|
|
@param end_date: Ending Datee
|
2010-03-25 12:07:00 +00:00
|
|
|
|
@param context: A standard dictionary for contextual values
|
|
|
|
|
"""
|
2010-05-14 10:14:26 +00:00
|
|
|
|
if not context:
|
|
|
|
|
context = {}
|
2010-03-04 09:54:42 +00:00
|
|
|
|
value = {}
|
2010-04-19 13:47:20 +00:00
|
|
|
|
if not start_date:
|
|
|
|
|
return value
|
2010-03-17 11:14:52 +00:00
|
|
|
|
if not end_date and not duration:
|
|
|
|
|
duration = 8.00
|
2010-04-19 13:47:20 +00:00
|
|
|
|
value['duration'] = duration
|
|
|
|
|
|
|
|
|
|
if allday: # For all day event
|
|
|
|
|
value = {
|
|
|
|
|
'duration': 24
|
|
|
|
|
}
|
2010-06-24 12:55:03 +00:00
|
|
|
|
duration = 0.0
|
2010-04-19 13:47:20 +00:00
|
|
|
|
|
2010-03-17 11:14:52 +00:00
|
|
|
|
start = datetime.strptime(start_date, "%Y-%m-%d %H:%M:%S")
|
2010-03-04 09:54:42 +00:00
|
|
|
|
if end_date and not duration:
|
|
|
|
|
end = datetime.strptime(end_date, "%Y-%m-%d %H:%M:%S")
|
|
|
|
|
diff = end - start
|
2010-04-06 07:28:49 +00:00
|
|
|
|
duration = float(diff.days)* 24 + (float(diff.seconds) / 3600)
|
2010-03-04 09:54:42 +00:00
|
|
|
|
value['duration'] = round(duration, 2)
|
|
|
|
|
elif not end_date:
|
|
|
|
|
end = start + timedelta(hours=duration)
|
|
|
|
|
value['date_deadline'] = end.strftime("%Y-%m-%d %H:%M:%S")
|
2010-04-19 13:47:20 +00:00
|
|
|
|
|
2010-03-04 09:54:42 +00:00
|
|
|
|
return {'value': value}
|
2010-02-11 12:37:41 +00:00
|
|
|
|
|
2010-05-14 10:14:26 +00:00
|
|
|
|
def _set_rrulestring(self, cr, uid, id, name, value, arg, context=None):
|
2010-04-05 10:37:31 +00:00
|
|
|
|
"""
|
2010-05-14 10:14:26 +00:00
|
|
|
|
Sets values of fields that defines event recurrence from the value of rrule string
|
2010-04-05 10:37:31 +00:00
|
|
|
|
@param self: The object pointer
|
|
|
|
|
@param cr: the current row, from the database cursor,
|
2010-04-06 07:25:15 +00:00
|
|
|
|
@param id: List of calendar event's ids.
|
2010-04-05 10:37:31 +00:00
|
|
|
|
@param context: A standard dictionary for contextual values
|
|
|
|
|
@return: dictionary of rrule value.
|
|
|
|
|
"""
|
2010-05-14 10:14:26 +00:00
|
|
|
|
if not context:
|
|
|
|
|
context = {}
|
2010-04-06 07:25:15 +00:00
|
|
|
|
cr.execute("UPDATE %s set freq='None',interval=0,count=0,end_date=Null,\
|
2010-04-05 10:37:31 +00:00
|
|
|
|
mo=False,tu=False,we=False,th=False,fr=False,sa=False,su=False,\
|
2010-04-06 07:25:15 +00:00
|
|
|
|
day=0,select1='date',month_list=Null ,byday=Null where id=%s" % (self._table, id))
|
2010-04-29 13:50:23 +00:00
|
|
|
|
|
2010-04-05 10:37:31 +00:00
|
|
|
|
if not value:
|
2010-04-06 07:25:15 +00:00
|
|
|
|
cr.execute("UPDATE %s set rrule_type='none' where id=%s" % (self._table, id))
|
2010-04-05 10:37:31 +00:00
|
|
|
|
return True
|
|
|
|
|
val = {}
|
|
|
|
|
for part in value.split(';'):
|
|
|
|
|
if part.lower().__contains__('freq') and len(value.split(';')) <=2:
|
|
|
|
|
rrule_type = part.lower()[5:]
|
|
|
|
|
break
|
|
|
|
|
else:
|
|
|
|
|
rrule_type = 'custom'
|
|
|
|
|
break
|
|
|
|
|
ans = value.split(';')
|
|
|
|
|
for i in ans:
|
|
|
|
|
val[i.split('=')[0].lower()] = i.split('=')[1].lower()
|
2010-04-06 07:25:15 +00:00
|
|
|
|
if not val.get('interval'):
|
|
|
|
|
rrule_type = 'custom'
|
|
|
|
|
elif int(val.get('interval')) > 1: #If interval is other than 1 rule is custom
|
2010-04-05 11:37:31 +00:00
|
|
|
|
rrule_type = 'custom'
|
2010-04-05 10:37:31 +00:00
|
|
|
|
|
|
|
|
|
qry = "UPDATE %(table)s set rrule_type=\'%(rule_type)s\' "
|
2010-04-05 11:37:31 +00:00
|
|
|
|
|
|
|
|
|
if rrule_type == 'custom':
|
|
|
|
|
new_val = val.copy()
|
|
|
|
|
for k, v in val.items():
|
|
|
|
|
if val['freq'] == 'weekly' and val.get('byday'):
|
|
|
|
|
for day in val['byday'].split(','):
|
|
|
|
|
new_val[day] = True
|
|
|
|
|
val.pop('byday')
|
2010-04-29 13:50:23 +00:00
|
|
|
|
|
2010-04-05 11:37:31 +00:00
|
|
|
|
if val.get('until'):
|
|
|
|
|
until = parser.parse(''.join((re.compile('\d')).findall(val.get('until'))))
|
|
|
|
|
new_val['end_date'] = until.strftime('%Y-%m-%d')
|
|
|
|
|
val.pop('until')
|
|
|
|
|
new_val.pop('until')
|
2010-04-29 13:50:23 +00:00
|
|
|
|
|
2010-04-05 11:37:31 +00:00
|
|
|
|
if val.get('bymonthday'):
|
|
|
|
|
new_val['day'] = val.get('bymonthday')
|
|
|
|
|
val.pop('bymonthday')
|
|
|
|
|
new_val['select1'] = 'date'
|
|
|
|
|
new_val.pop('bymonthday')
|
2010-04-29 13:50:23 +00:00
|
|
|
|
|
2010-04-05 11:37:31 +00:00
|
|
|
|
if val.get('byday'):
|
|
|
|
|
d = val.get('byday')
|
2010-04-06 07:25:15 +00:00
|
|
|
|
if '-' in d:
|
2010-04-06 08:39:14 +00:00
|
|
|
|
new_val['byday'] = d[:2]
|
|
|
|
|
new_val['week_list'] = d[2:4].upper()
|
2010-04-06 07:25:15 +00:00
|
|
|
|
else:
|
|
|
|
|
new_val['byday'] = d[:1]
|
|
|
|
|
new_val['week_list'] = d[1:3].upper()
|
2010-04-05 11:37:31 +00:00
|
|
|
|
new_val['select1'] = 'day'
|
2010-04-29 13:50:23 +00:00
|
|
|
|
|
2010-04-05 11:37:31 +00:00
|
|
|
|
if val.get('bymonth'):
|
|
|
|
|
new_val['month_list'] = val.get('bymonth')
|
|
|
|
|
val.pop('bymonth')
|
|
|
|
|
new_val.pop('bymonth')
|
2010-04-29 13:50:23 +00:00
|
|
|
|
|
2010-04-05 11:37:31 +00:00
|
|
|
|
for k, v in new_val.items():
|
|
|
|
|
temp = ", %s='%s'" % (k, v)
|
|
|
|
|
qry += temp
|
|
|
|
|
|
2010-04-05 10:37:31 +00:00
|
|
|
|
whr = " where id=%(id)s"
|
|
|
|
|
qry = qry + whr
|
|
|
|
|
val.update({
|
2010-04-29 13:50:23 +00:00
|
|
|
|
'table': self._table,
|
|
|
|
|
'rule_type': rrule_type,
|
|
|
|
|
'id': id,
|
2010-04-06 09:01:56 +00:00
|
|
|
|
})
|
2010-04-05 10:37:31 +00:00
|
|
|
|
cr.execute(qry % val)
|
|
|
|
|
return True
|
|
|
|
|
|
2010-03-04 12:59:13 +00:00
|
|
|
|
def _get_rulestring(self, cr, uid, ids, name, arg, context=None):
|
2010-03-18 11:30:31 +00:00
|
|
|
|
"""
|
2010-05-14 10:14:26 +00:00
|
|
|
|
Gets Recurrence rule string according to value type RECUR of iCalendar from the values given.
|
2010-03-18 11:30:31 +00:00
|
|
|
|
@param self: The object pointer
|
|
|
|
|
@param cr: the current row, from the database cursor,
|
2010-04-06 07:28:49 +00:00
|
|
|
|
@param id: List of calendar event's ids.
|
2010-03-18 11:30:31 +00:00
|
|
|
|
@param context: A standard dictionary for contextual values
|
|
|
|
|
@return: dictionary of rrule value.
|
|
|
|
|
"""
|
2010-03-04 12:59:13 +00:00
|
|
|
|
result = {}
|
2010-04-08 05:43:07 +00:00
|
|
|
|
for datas in self.read(cr, uid, ids, context=context):
|
2010-04-08 06:07:15 +00:00
|
|
|
|
event = datas['id']
|
2010-03-04 12:59:13 +00:00
|
|
|
|
if datas.get('rrule_type'):
|
|
|
|
|
if datas.get('rrule_type') == 'none':
|
2010-04-08 06:07:15 +00:00
|
|
|
|
result[event] = False
|
2010-06-30 10:26:30 +00:00
|
|
|
|
cr.execute("UPDATE %s set exrule=Null where id=%s" % (self._table, event))
|
2010-03-04 12:59:13 +00:00
|
|
|
|
elif datas.get('rrule_type') == 'custom':
|
2010-04-15 09:12:02 +00:00
|
|
|
|
if datas.get('interval', 0) < 0:
|
|
|
|
|
raise osv.except_osv('Warning!', 'Interval can not be Negative')
|
|
|
|
|
if datas.get('count', 0) < 0:
|
|
|
|
|
raise osv.except_osv('Warning!', 'Count can not be Negative')
|
2010-05-14 10:14:26 +00:00
|
|
|
|
rrule_custom = self.compute_rule_string(cr, uid, datas, \
|
2010-04-08 05:43:07 +00:00
|
|
|
|
context=context)
|
2010-04-08 06:07:15 +00:00
|
|
|
|
result[event] = rrule_custom
|
2010-03-04 12:59:13 +00:00
|
|
|
|
else:
|
2010-04-08 06:07:15 +00:00
|
|
|
|
result[event] = self.compute_rule_string(cr, uid, {'freq': datas.get('rrule_type').upper(), 'interval': 1}, context=context)
|
2010-03-25 12:07:00 +00:00
|
|
|
|
|
2010-03-04 12:59:13 +00:00
|
|
|
|
return result
|
|
|
|
|
|
2010-01-21 08:14:58 +00:00
|
|
|
|
_columns = {
|
2010-04-29 13:50:23 +00:00
|
|
|
|
'id': fields.integer('ID'),
|
|
|
|
|
'sequence': fields.integer('Sequence'),
|
2010-06-24 12:55:03 +00:00
|
|
|
|
'name': fields.char('Description', size=64, required=False, states={'done': [('readonly', True)]}),
|
|
|
|
|
'date': fields.datetime('Date', states={'done': [('readonly', True)]}),
|
|
|
|
|
'date_deadline': fields.datetime('Deadline', states={'done': [('readonly', True)]}),
|
2010-04-29 13:50:23 +00:00
|
|
|
|
'create_date': fields.datetime('Created', readonly=True),
|
2010-06-24 12:55:03 +00:00
|
|
|
|
'duration': fields.float('Duration', states={'done': [('readonly', True)]}),
|
|
|
|
|
'description': fields.text('Description', states={'done': [('readonly', True)]}),
|
2010-02-11 12:37:41 +00:00
|
|
|
|
'class': fields.selection([('public', 'Public'), ('private', 'Private'), \
|
2010-06-24 12:55:03 +00:00
|
|
|
|
('confidential', 'Confidential')], 'Mark as', states={'done': [('readonly', True)]}),
|
|
|
|
|
'location': fields.char('Location', size=264, help="Location of Event", states={'done': [('readonly', True)]}),
|
2010-04-07 05:14:20 +00:00
|
|
|
|
'show_as': fields.selection([('free', 'Free'), ('busy', 'Busy')], \
|
2010-06-24 12:55:03 +00:00
|
|
|
|
'Show as', states={'done': [('readonly', True)]}),
|
2010-07-02 07:34:06 +00:00
|
|
|
|
'base_calendar_url': fields.char('Caldav URL', size=264),
|
|
|
|
|
'state': fields.selection([('tentative', 'Tentative'),
|
|
|
|
|
('confirmed', 'Confirmed'),
|
|
|
|
|
('cancelled', 'Cancelled')], 'State', readonly=True),
|
2010-02-11 12:37:41 +00:00
|
|
|
|
'exdate': fields.text('Exception Date/Times', help="This property \
|
2010-05-14 06:49:06 +00:00
|
|
|
|
defines the list of date/time exceptions for arecurring calendar component."),
|
2010-02-11 12:37:41 +00:00
|
|
|
|
'exrule': fields.char('Exception Rule', size=352, help="defines a \
|
2010-05-14 06:49:06 +00:00
|
|
|
|
rule or repeating pattern for an exception to a recurrence set"),
|
2010-04-06 08:39:14 +00:00
|
|
|
|
'rrule': fields.function(_get_rulestring, type='char', size=124, method=True, \
|
2010-04-06 07:28:49 +00:00
|
|
|
|
string='Recurrent Rule', store=True, \
|
|
|
|
|
fnct_inv=_set_rrulestring, help='Defines a\
|
|
|
|
|
rule or repeating pattern for recurring events\n\
|
2010-04-06 08:39:14 +00:00
|
|
|
|
e.g.: Every other month on the last Sunday of the month for 10 occurrences:\
|
2010-04-29 13:50:23 +00:00
|
|
|
|
FREQ=MONTHLY;INTERVAL=2;COUNT=10;BYDAY=-1SU'),
|
2010-02-11 12:37:41 +00:00
|
|
|
|
'rrule_type': fields.selection([('none', ''), ('daily', 'Daily'), \
|
|
|
|
|
('weekly', 'Weekly'), ('monthly', 'Monthly'), \
|
2010-06-24 12:55:03 +00:00
|
|
|
|
('yearly', 'Yearly'), ('custom', 'Custom')], 'Recurrency', states={'done': [('readonly', True)]}),
|
|
|
|
|
'alarm_id': fields.many2one('res.alarm', 'Alarm', states={'done': [('readonly', True)]}),
|
2010-04-29 13:50:23 +00:00
|
|
|
|
'base_calendar_alarm_id': fields.many2one('calendar.alarm', 'Alarm'),
|
|
|
|
|
'recurrent_uid': fields.integer('Recurrent ID'),
|
|
|
|
|
'recurrent_id': fields.datetime('Recurrent ID date'),
|
2010-04-06 08:39:14 +00:00
|
|
|
|
'vtimezone': fields.related('user_id', 'context_tz', type='char', size=24, \
|
2010-04-29 13:50:23 +00:00
|
|
|
|
string='Timezone', store=True),
|
2010-06-24 12:55:03 +00:00
|
|
|
|
'user_id': fields.many2one('res.users', 'Responsible', states={'done': [('readonly', True)]}),
|
2010-03-04 12:59:13 +00:00
|
|
|
|
'freq': fields.selection([('None', 'No Repeat'), \
|
2010-04-07 05:14:20 +00:00
|
|
|
|
('secondly', 'Secondly'), \
|
|
|
|
|
('minutely', 'Minutely'), \
|
|
|
|
|
('hourly', 'Hourly'), \
|
|
|
|
|
('daily', 'Daily'), \
|
|
|
|
|
('weekly', 'Weekly'), \
|
|
|
|
|
('monthly', 'Monthly'), \
|
2010-04-29 13:50:23 +00:00
|
|
|
|
('yearly', 'Yearly')], 'Frequency'),
|
|
|
|
|
'interval': fields.integer('Interval'),
|
|
|
|
|
'count': fields.integer('Count'),
|
|
|
|
|
'mo': fields.boolean('Mon'),
|
|
|
|
|
'tu': fields.boolean('Tue'),
|
|
|
|
|
'we': fields.boolean('Wed'),
|
|
|
|
|
'th': fields.boolean('Thu'),
|
|
|
|
|
'fr': fields.boolean('Fri'),
|
|
|
|
|
'sa': fields.boolean('Sat'),
|
|
|
|
|
'su': fields.boolean('Sun'),
|
2010-03-04 12:59:13 +00:00
|
|
|
|
'select1': fields.selection([('date', 'Date of month'), \
|
2010-04-29 13:50:23 +00:00
|
|
|
|
('day', 'Day of month')], 'Option'),
|
|
|
|
|
'day': fields.integer('Date of month'),
|
2010-03-04 12:59:13 +00:00
|
|
|
|
'week_list': fields.selection([('MO', 'Monday'), ('TU', 'Tuesday'), \
|
|
|
|
|
('WE', 'Wednesday'), ('TH', 'Thursday'), \
|
|
|
|
|
('FR', 'Friday'), ('SA', 'Saturday'), \
|
2010-04-29 13:50:23 +00:00
|
|
|
|
('SU', 'Sunday')], 'Weekday'),
|
2010-03-04 12:59:13 +00:00
|
|
|
|
'byday': fields.selection([('1', 'First'), ('2', 'Second'), \
|
|
|
|
|
('3', 'Third'), ('4', 'Fourth'), \
|
2010-04-06 08:39:14 +00:00
|
|
|
|
('5', 'Fifth'), ('-1', 'Last')], 'By day'),
|
|
|
|
|
'month_list': fields.selection(months.items(), 'Month'),
|
2010-04-19 13:47:20 +00:00
|
|
|
|
'end_date': fields.date('Repeat Until'),
|
2010-05-14 10:14:26 +00:00
|
|
|
|
'attendee_ids': fields.many2many('calendar.attendee', 'event_attendee_rel', \
|
|
|
|
|
'event_id', 'attendee_id', 'Attendees'),
|
2010-06-24 12:55:03 +00:00
|
|
|
|
'allday': fields.boolean('All Day', states={'done': [('readonly', True)]}),
|
2010-05-03 12:59:01 +00:00
|
|
|
|
'active': fields.boolean('Active', help="If the active field is set to \
|
2010-05-12 13:16:01 +00:00
|
|
|
|
true, it will allow you to hide the event alarm information without removing it.")
|
2010-01-21 12:58:40 +00:00
|
|
|
|
}
|
2010-04-19 13:47:20 +00:00
|
|
|
|
|
2010-01-21 12:58:40 +00:00
|
|
|
|
_defaults = {
|
2010-07-02 07:34:06 +00:00
|
|
|
|
'state': 'tentative',
|
|
|
|
|
'class': 'public',
|
|
|
|
|
'show_as': 'busy',
|
|
|
|
|
'freq': 'None',
|
|
|
|
|
'select1': 'date',
|
|
|
|
|
'interval': 1,
|
|
|
|
|
'active': 1,
|
|
|
|
|
}
|
2010-04-29 13:50:23 +00:00
|
|
|
|
|
2010-04-19 13:47:20 +00:00
|
|
|
|
def open_event(self, cr, uid, ids, context=None):
|
|
|
|
|
"""
|
|
|
|
|
Open Event From for Editing
|
|
|
|
|
@param cr: the current row, from the database cursor,
|
|
|
|
|
@param uid: the current user’s ID for security checks,
|
|
|
|
|
@param ids: List of event’s IDs
|
|
|
|
|
@param context: A standard dictionary for contextual values
|
|
|
|
|
@return: Dictionary value which open Crm Meeting form.
|
|
|
|
|
"""
|
|
|
|
|
if not context:
|
|
|
|
|
context = {}
|
2010-04-29 13:50:23 +00:00
|
|
|
|
|
2010-04-19 13:47:20 +00:00
|
|
|
|
data_obj = self.pool.get('ir.model.data')
|
2010-04-29 13:50:23 +00:00
|
|
|
|
|
2010-04-19 13:47:20 +00:00
|
|
|
|
value = {}
|
2010-04-29 13:50:23 +00:00
|
|
|
|
|
2010-04-19 13:47:20 +00:00
|
|
|
|
id2 = data_obj._get_id(cr, uid, 'base_calendar', 'event_form_view')
|
|
|
|
|
id3 = data_obj._get_id(cr, uid, 'base_calendar', 'event_tree_view')
|
|
|
|
|
id4 = data_obj._get_id(cr, uid, 'base_calendar', 'event_calendar_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
|
|
|
|
|
if id4:
|
|
|
|
|
id4 = data_obj.browse(cr, uid, id4, context=context).res_id
|
|
|
|
|
for id in ids:
|
|
|
|
|
value = {
|
|
|
|
|
'name': _('Event'),
|
|
|
|
|
'view_type': 'form',
|
|
|
|
|
'view_mode': 'form,tree',
|
|
|
|
|
'res_model': 'calendar.event',
|
|
|
|
|
'view_id': False,
|
2010-05-14 10:14:26 +00:00
|
|
|
|
'views': [(id2, 'form'), (id3, 'tree'), (id4, 'calendar')],
|
2010-04-19 13:47:20 +00:00
|
|
|
|
'type': 'ir.actions.act_window',
|
|
|
|
|
'res_id': base_calendar_id2real_id(id),
|
|
|
|
|
'nodestroy': True
|
|
|
|
|
}
|
2010-04-29 13:50:23 +00:00
|
|
|
|
|
2010-04-19 13:47:20 +00:00
|
|
|
|
return value
|
2010-03-25 12:07:00 +00:00
|
|
|
|
|
2010-03-08 06:47:18 +00:00
|
|
|
|
def modify_this(self, cr, uid, event_id, defaults, real_date, context=None, *args):
|
2010-05-14 10:14:26 +00:00
|
|
|
|
"""Modifies only one event record out of virtual recurrent events
|
|
|
|
|
and creates new event as a specific instance of a Recurring Event",
|
2010-03-25 12:07:00 +00:00
|
|
|
|
@param self: The object pointer
|
|
|
|
|
@param cr: the current row, from the database cursor,
|
|
|
|
|
@param uid: the current user’s ID for security checks,
|
2010-05-14 10:14:26 +00:00
|
|
|
|
@param event_id: Id of Recurring Event
|
|
|
|
|
@param real_date: Date of event recurrence that is being modified
|
2010-03-25 12:07:00 +00:00
|
|
|
|
@param context: A standard dictionary for contextual values
|
2010-05-14 10:14:26 +00:00
|
|
|
|
@param *args: Get Tupple Value
|
2010-03-25 12:07:00 +00:00
|
|
|
|
"""
|
2010-03-18 11:30:31 +00:00
|
|
|
|
|
2010-03-08 06:47:18 +00:00
|
|
|
|
event_id = base_calendar_id2real_id(event_id)
|
|
|
|
|
datas = self.read(cr, uid, event_id, context=context)
|
2010-02-11 12:37:41 +00:00
|
|
|
|
defaults.update({
|
2010-04-29 13:50:23 +00:00
|
|
|
|
'recurrent_uid': base_calendar_id2real_id(datas['id']),
|
|
|
|
|
'recurrent_id': defaults.get('date') or real_date,
|
|
|
|
|
'rrule_type': 'none',
|
2010-04-06 07:28:49 +00:00
|
|
|
|
'rrule': ''
|
|
|
|
|
})
|
2010-03-03 12:59:53 +00:00
|
|
|
|
exdate = datas['exdate'] and datas['exdate'].split(',') or []
|
2010-03-05 09:21:22 +00:00
|
|
|
|
if real_date and defaults.get('date'):
|
|
|
|
|
exdate.append(real_date)
|
2010-03-08 06:47:18 +00:00
|
|
|
|
self.write(cr, uid, event_id, {'exdate': ','.join(exdate)}, context=context)
|
|
|
|
|
new_id = self.copy(cr, uid, event_id, default=defaults, context=context)
|
2010-02-11 12:37:41 +00:00
|
|
|
|
return new_id
|
|
|
|
|
|
2010-03-17 05:42:43 +00:00
|
|
|
|
def modify_all(self, cr, uid, event_ids, defaults, context=None, *args):
|
2010-03-18 11:30:31 +00:00
|
|
|
|
"""
|
2010-05-14 10:14:26 +00:00
|
|
|
|
Modifies the recurring event
|
2010-03-18 11:30:31 +00:00
|
|
|
|
@param cr: the current row, from the database cursor,
|
|
|
|
|
@param uid: the current user’s ID for security checks,
|
|
|
|
|
@param event_ids: List of crm meeting’s IDs.
|
2010-05-14 10:14:26 +00:00
|
|
|
|
@param context: A standard dictionary for contextual values
|
2010-03-18 11:30:31 +00:00
|
|
|
|
@return: True
|
|
|
|
|
"""
|
2010-04-29 13:50:23 +00:00
|
|
|
|
|
2010-03-17 05:42:43 +00:00
|
|
|
|
for event_id in event_ids:
|
|
|
|
|
event_id = base_calendar_id2real_id(event_id)
|
2010-03-25 12:07:00 +00:00
|
|
|
|
|
2010-03-17 05:42:43 +00:00
|
|
|
|
defaults.pop('id')
|
|
|
|
|
defaults.update({'table': self._table})
|
2010-03-25 12:07:00 +00:00
|
|
|
|
|
2010-03-18 11:30:31 +00:00
|
|
|
|
qry = "UPDATE %(table)s set name = '%(name)s', \
|
2010-04-06 07:28:49 +00:00
|
|
|
|
date = '%(date)s', date_deadline = '%(date_deadline)s'"
|
2010-03-17 05:42:43 +00:00
|
|
|
|
if defaults.get('alarm_id'):
|
2010-03-18 11:30:31 +00:00
|
|
|
|
qry += ", alarm_id = %(alarm_id)s"
|
2010-03-17 05:42:43 +00:00
|
|
|
|
if defaults.get('location'):
|
2010-03-18 11:30:31 +00:00
|
|
|
|
qry += ", location = '%(location)s'"
|
|
|
|
|
qry += "WHERE id = %s" % (event_id)
|
2010-03-25 13:05:11 +00:00
|
|
|
|
cr.execute(qry %(defaults))
|
2010-04-29 13:50:23 +00:00
|
|
|
|
|
2010-03-04 14:02:09 +00:00
|
|
|
|
return True
|
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
def get_recurrent_ids(self, cr, uid, select, base_start_date, base_until_date, limit=100):
|
2010-05-14 10:14:26 +00:00
|
|
|
|
"""Gives virtual event ids for recurring events based on value of Recurrence Rule
|
|
|
|
|
This method gives ids of dates that comes between start date and end date of calendar views
|
2010-03-25 12:07:00 +00:00
|
|
|
|
@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 base_start_date: Get Start Date
|
|
|
|
|
@param base_until_date: Get End Date
|
|
|
|
|
@param limit: The Number of Results to Return """
|
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
if not limit:
|
|
|
|
|
limit = 100
|
|
|
|
|
if isinstance(select, (str, int, long)):
|
|
|
|
|
ids = [select]
|
|
|
|
|
else:
|
|
|
|
|
ids = select
|
|
|
|
|
result = []
|
|
|
|
|
if ids and (base_start_date or base_until_date):
|
|
|
|
|
cr.execute("select m.id, m.rrule, m.date, m.date_deadline, \
|
2010-04-30 08:48:24 +00:00
|
|
|
|
m.exdate, m.exrule from " + self._table + \
|
2010-02-11 12:37:41 +00:00
|
|
|
|
" m where m.id in ("\
|
|
|
|
|
+ ','.join(map(lambda x: str(x), ids))+")")
|
|
|
|
|
|
|
|
|
|
count = 0
|
|
|
|
|
for data in cr.dictfetchall():
|
2010-04-19 13:47:20 +00:00
|
|
|
|
start_date = base_start_date and datetime.strptime(base_start_date[:10], "%Y-%m-%d") or False
|
|
|
|
|
until_date = base_until_date and datetime.strptime(base_until_date[:10], "%Y-%m-%d") or False
|
2010-02-11 12:37:41 +00:00
|
|
|
|
if count > limit:
|
|
|
|
|
break
|
2010-04-30 13:22:06 +00:00
|
|
|
|
event_date = datetime.strptime(data['date'], "%Y-%m-%d %H:%M:%S")
|
2010-04-30 13:11:51 +00:00
|
|
|
|
# To check: If the start date is replace by event date .. the event date will be changed by that of calendar code
|
|
|
|
|
# if start_date and start_date <= event_date:
|
|
|
|
|
# start_date = event_date
|
|
|
|
|
start_date = event_date
|
2010-02-11 12:37:41 +00:00
|
|
|
|
if not data['rrule']:
|
|
|
|
|
if start_date and (event_date < start_date):
|
|
|
|
|
continue
|
|
|
|
|
if until_date and (event_date > until_date):
|
|
|
|
|
continue
|
|
|
|
|
idval = real_id2base_calendar_id(data['id'], data['date'])
|
|
|
|
|
result.append(idval)
|
|
|
|
|
count += 1
|
|
|
|
|
else:
|
2010-03-25 12:07:00 +00:00
|
|
|
|
exdate = data['exdate'] and data['exdate'].split(',') or []
|
2010-02-11 12:37:41 +00:00
|
|
|
|
rrule_str = data['rrule']
|
|
|
|
|
new_rrule_str = []
|
|
|
|
|
rrule_until_date = False
|
|
|
|
|
is_until = False
|
|
|
|
|
for rule in rrule_str.split(';'):
|
|
|
|
|
name, value = rule.split('=')
|
|
|
|
|
if name == "UNTIL":
|
|
|
|
|
is_until = True
|
|
|
|
|
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
|
|
|
|
|
if until_date:
|
|
|
|
|
value = until_date.strftime("%Y%m%d%H%M%S")
|
|
|
|
|
new_rule = '%s=%s' % (name, value)
|
|
|
|
|
new_rrule_str.append(new_rule)
|
|
|
|
|
if not is_until and until_date:
|
|
|
|
|
value = until_date.strftime("%Y%m%d%H%M%S")
|
|
|
|
|
name = "UNTIL"
|
|
|
|
|
new_rule = '%s=%s' % (name, value)
|
|
|
|
|
new_rrule_str.append(new_rule)
|
|
|
|
|
new_rrule_str = ';'.join(new_rrule_str)
|
2010-04-30 08:48:24 +00:00
|
|
|
|
rdates = get_recurrent_dates(str(new_rrule_str), exdate, start_date, data['exrule'])
|
2010-07-02 13:30:13 +00:00
|
|
|
|
for r_date in rdates:
|
2010-02-11 12:37:41 +00:00
|
|
|
|
if start_date and r_date < start_date:
|
|
|
|
|
continue
|
|
|
|
|
if until_date and r_date > until_date:
|
|
|
|
|
continue
|
2010-07-02 13:30:13 +00:00
|
|
|
|
idval = real_id2base_calendar_id(data['id'], r_date.strftime("%Y-%m-%d %H:%M:%S"))
|
2010-02-11 12:37:41 +00:00
|
|
|
|
result.append(idval)
|
|
|
|
|
count += 1
|
|
|
|
|
if result:
|
|
|
|
|
ids = result
|
|
|
|
|
if isinstance(select, (str, int, long)):
|
|
|
|
|
return ids and ids[0] or False
|
|
|
|
|
return ids
|
2010-04-29 13:50:23 +00:00
|
|
|
|
|
2010-03-04 12:59:13 +00:00
|
|
|
|
def compute_rule_string(self, cr, uid, datas, context=None, *args):
|
2010-03-18 11:30:31 +00:00
|
|
|
|
"""
|
2010-05-14 10:14:26 +00:00
|
|
|
|
Compute rule string according to value type RECUR of iCalendar from the values given.
|
2010-03-18 11:30:31 +00:00
|
|
|
|
@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 datas: dictionary of freq and interval value.
|
2010-05-14 10:14:26 +00:00
|
|
|
|
@param context: A standard dictionary for contextual values
|
|
|
|
|
@return: String value of the format RECUR of iCalendar
|
2010-03-18 11:30:31 +00:00
|
|
|
|
"""
|
2010-03-25 12:07:00 +00:00
|
|
|
|
|
2010-03-04 12:59:13 +00:00
|
|
|
|
weekdays = ['mo', 'tu', 'we', 'th', 'fr', 'sa', 'su']
|
|
|
|
|
weekstring = ''
|
|
|
|
|
monthstring = ''
|
|
|
|
|
yearstring = ''
|
2010-04-06 09:01:56 +00:00
|
|
|
|
|
2010-03-04 12:59:13 +00:00
|
|
|
|
freq = datas.get('freq')
|
|
|
|
|
if freq == 'None':
|
|
|
|
|
return ''
|
2010-04-29 13:50:23 +00:00
|
|
|
|
|
2010-04-06 07:25:15 +00:00
|
|
|
|
interval_srting = datas.get('interval') and (';INTERVAL=' + str(datas.get('interval'))) or ''
|
2010-04-29 13:50:23 +00:00
|
|
|
|
|
2010-03-04 12:59:13 +00:00
|
|
|
|
if freq == 'weekly':
|
2010-04-05 10:37:31 +00:00
|
|
|
|
|
2010-03-04 12:59:13 +00:00
|
|
|
|
byday = map(lambda x: x.upper(), filter(lambda x: datas.get(x) and x in weekdays, datas))
|
|
|
|
|
if byday:
|
|
|
|
|
weekstring = ';BYDAY=' + ','.join(byday)
|
|
|
|
|
|
|
|
|
|
elif freq == 'monthly':
|
|
|
|
|
if datas.get('select1')=='date' and (datas.get('day') < 1 or datas.get('day') > 31):
|
|
|
|
|
raise osv.except_osv(_('Error!'), ("Please select proper Day of month"))
|
|
|
|
|
if datas.get('select1')=='day':
|
|
|
|
|
monthstring = ';BYDAY=' + datas.get('byday') + datas.get('week_list')
|
|
|
|
|
elif datas.get('select1')=='date':
|
|
|
|
|
monthstring = ';BYMONTHDAY=' + str(datas.get('day'))
|
|
|
|
|
|
|
|
|
|
elif freq == 'yearly':
|
2010-04-06 07:25:15 +00:00
|
|
|
|
if datas.get('select1')=='date' and (datas.get('day') < 1 or datas.get('day') > 31):
|
2010-03-04 12:59:13 +00:00
|
|
|
|
raise osv.except_osv(_('Error!'), ("Please select proper Day of month"))
|
|
|
|
|
bymonth = ';BYMONTH=' + str(datas.get('month_list'))
|
|
|
|
|
if datas.get('select1')=='day':
|
|
|
|
|
bystring = ';BYDAY=' + datas.get('byday') + datas.get('week_list')
|
|
|
|
|
elif datas.get('select1')=='date':
|
|
|
|
|
bystring = ';BYMONTHDAY=' + str(datas.get('day'))
|
|
|
|
|
yearstring = bymonth + bystring
|
|
|
|
|
|
|
|
|
|
if datas.get('end_date'):
|
2010-07-01 13:08:19 +00:00
|
|
|
|
datas['end_date'] = ''.join((re.compile('\d')).findall(datas.get('end_date'))) + 'T235959Z'
|
2010-04-06 07:25:15 +00:00
|
|
|
|
enddate = (datas.get('count') and (';COUNT=' + str(datas.get('count'))) or '') +\
|
2010-03-04 12:59:13 +00:00
|
|
|
|
((datas.get('end_date') and (';UNTIL=' + datas.get('end_date'))) or '')
|
|
|
|
|
|
2010-04-06 07:25:15 +00:00
|
|
|
|
rrule_string = 'FREQ=' + freq.upper() + weekstring + interval_srting \
|
|
|
|
|
+ enddate + monthstring + yearstring
|
2010-03-04 12:59:13 +00:00
|
|
|
|
|
|
|
|
|
return rrule_string
|
|
|
|
|
|
2010-04-05 10:37:31 +00:00
|
|
|
|
|
2010-04-29 13:50:23 +00:00
|
|
|
|
def search(self, cr, uid, args, offset=0, limit=100, order=None,
|
2010-02-11 12:37:41 +00:00
|
|
|
|
context=None, count=False):
|
2010-03-18 11:30:31 +00:00
|
|
|
|
"""
|
2010-04-06 07:28:49 +00:00
|
|
|
|
Overrides orm search method.
|
2010-03-18 11:30:31 +00:00
|
|
|
|
@param cr: the current row, from the database cursor,
|
|
|
|
|
@param user: the current user’s ID for security checks,
|
|
|
|
|
@param args: list of tuples of form [(‘name_of_the_field’, ‘operator’, value), ...].
|
2010-03-25 12:07:00 +00:00
|
|
|
|
@param offset: The Number of Results to Pass
|
|
|
|
|
@param limit: The Number of Results to Return
|
2010-05-14 10:14:26 +00:00
|
|
|
|
@param context: A standard dictionary for contextual values
|
|
|
|
|
@param count: If its True the method returns number of records instead of ids
|
2010-03-25 12:07:00 +00:00
|
|
|
|
@return: List of id
|
2010-03-18 11:30:31 +00:00
|
|
|
|
"""
|
2010-02-11 12:37:41 +00:00
|
|
|
|
args_without_date = []
|
|
|
|
|
start_date = False
|
|
|
|
|
until_date = False
|
|
|
|
|
for arg in args:
|
|
|
|
|
if arg[0] not in ('date', unicode('date')):
|
|
|
|
|
args_without_date.append(arg)
|
|
|
|
|
else:
|
|
|
|
|
if arg[1] in ('>', '>='):
|
2010-04-19 13:48:59 +00:00
|
|
|
|
if start_date:
|
|
|
|
|
continue
|
2010-02-11 12:37:41 +00:00
|
|
|
|
start_date = arg[2]
|
|
|
|
|
elif arg[1] in ('<', '<='):
|
2010-04-19 13:48:59 +00:00
|
|
|
|
if until_date:
|
|
|
|
|
continue
|
2010-02-11 12:37:41 +00:00
|
|
|
|
until_date = arg[2]
|
|
|
|
|
res = super(calendar_event, 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)
|
|
|
|
|
|
|
|
|
|
|
2010-05-10 04:46:50 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
def write(self, cr, uid, ids, vals, context=None, check=True, update_check=True):
|
2010-03-18 11:30:31 +00:00
|
|
|
|
"""
|
2010-05-14 10:14:26 +00:00
|
|
|
|
Overrides orm write method.
|
2010-03-18 11:30:31 +00:00
|
|
|
|
@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 meeting's ids
|
|
|
|
|
@param vals: Dictionary of field value.
|
2010-05-14 10:14:26 +00:00
|
|
|
|
@param context: A standard dictionary for contextual values
|
2010-03-18 11:30:31 +00:00
|
|
|
|
@return: True
|
|
|
|
|
"""
|
2010-02-11 12:37:41 +00:00
|
|
|
|
if not context:
|
|
|
|
|
context = {}
|
|
|
|
|
if isinstance(ids, (str, int, long)):
|
|
|
|
|
select = [ids]
|
|
|
|
|
else:
|
|
|
|
|
select = ids
|
|
|
|
|
new_ids = []
|
2010-03-08 06:47:18 +00:00
|
|
|
|
for event_id in select:
|
|
|
|
|
if len(str(event_id).split('-')) > 1:
|
|
|
|
|
data = self.read(cr, uid, event_id, ['date', 'date_deadline', \
|
|
|
|
|
'rrule', 'duration'])
|
2010-03-05 09:21:22 +00:00
|
|
|
|
if data.get('rrule'):
|
|
|
|
|
real_date = data.get('date')
|
|
|
|
|
data.update(vals)
|
2010-03-08 06:47:18 +00:00
|
|
|
|
new_id = self.modify_this(cr, uid, event_id, data, \
|
|
|
|
|
real_date, context)
|
2010-03-18 11:30:31 +00:00
|
|
|
|
context.update({'active_id': new_id, 'active_ids': [new_id]})
|
2010-03-05 09:21:22 +00:00
|
|
|
|
continue
|
2010-03-08 06:47:18 +00:00
|
|
|
|
event_id = base_calendar_id2real_id(event_id)
|
|
|
|
|
if not event_id in new_ids:
|
|
|
|
|
new_ids.append(event_id)
|
2010-05-14 06:49:06 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
res = super(calendar_event, self).write(cr, uid, new_ids, vals, context=context)
|
2010-07-02 13:30:13 +00:00
|
|
|
|
if (vals.has_key('alarm_id') or vals.has_key('base_calendar_alarm_id'))\
|
|
|
|
|
or (vals.has_key('date') or vals.has_key('duration') or vals.has_key('date_deadline')):
|
|
|
|
|
# change alarm details
|
2010-02-11 12:37:41 +00:00
|
|
|
|
alarm_obj = self.pool.get('res.alarm')
|
2010-03-08 06:47:18 +00:00
|
|
|
|
alarm_obj.do_alarm_create(cr, uid, new_ids, self._name, 'date', \
|
|
|
|
|
context=context)
|
2010-02-11 12:37:41 +00:00
|
|
|
|
return res
|
|
|
|
|
|
|
|
|
|
def browse(self, cr, uid, ids, context=None, list_class=None, fields_process={}):
|
2010-03-18 11:30:31 +00:00
|
|
|
|
"""
|
2010-04-06 07:28:49 +00:00
|
|
|
|
Overrides orm browse method.
|
2010-03-18 11:30:31 +00:00
|
|
|
|
@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 meeting's ids
|
2010-05-14 10:14:26 +00:00
|
|
|
|
@param context: A standard dictionary for contextual values
|
2010-03-18 11:30:31 +00:00
|
|
|
|
@return: the object list.
|
|
|
|
|
"""
|
2010-02-11 12:37:41 +00:00
|
|
|
|
if isinstance(ids, (str, int, long)):
|
|
|
|
|
select = [ids]
|
|
|
|
|
else:
|
|
|
|
|
select = ids
|
|
|
|
|
select = map(lambda x: base_calendar_id2real_id(x), select)
|
2010-03-08 06:47:18 +00:00
|
|
|
|
res = super(calendar_event, self).browse(cr, uid, select, context, \
|
|
|
|
|
list_class, fields_process)
|
2010-02-11 12:37:41 +00:00
|
|
|
|
if isinstance(ids, (str, int, long)):
|
|
|
|
|
return res and res[0] or False
|
2010-03-25 12:07:00 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
return res
|
|
|
|
|
|
2010-05-14 10:14:26 +00:00
|
|
|
|
def read(self, cr, uid, ids, fields=None, context=None, load='_classic_read'):
|
2010-03-18 11:30:31 +00:00
|
|
|
|
"""
|
2010-04-06 07:28:49 +00:00
|
|
|
|
Overrides orm Read method.Read List of fields for calendar event.
|
2010-03-18 11:30:31 +00:00
|
|
|
|
@param cr: the current row, from the database cursor,
|
|
|
|
|
@param user: the current user’s ID for security checks,
|
|
|
|
|
@param ids: List of calendar event's id.
|
|
|
|
|
@param fields: List of fields.
|
2010-05-14 10:14:26 +00:00
|
|
|
|
@param context: A standard dictionary for contextual values
|
2010-03-18 11:30:31 +00:00
|
|
|
|
@return: List of Dictionary of form [{‘name_of_the_field’: value, ...}, ...]
|
|
|
|
|
"""
|
2010-05-14 10:14:26 +00:00
|
|
|
|
if not context:
|
|
|
|
|
context = {}
|
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
if isinstance(ids, (str, int, long)):
|
|
|
|
|
select = [ids]
|
|
|
|
|
else:
|
|
|
|
|
select = ids
|
|
|
|
|
select = map(lambda x: (x, base_calendar_id2real_id(x)), select)
|
|
|
|
|
result = []
|
|
|
|
|
if fields and 'date' not in fields:
|
|
|
|
|
fields.append('date')
|
|
|
|
|
for base_calendar_id, real_id in select:
|
2010-04-06 07:28:49 +00:00
|
|
|
|
res = super(calendar_event, self).read(cr, uid, real_id, fields=fields, context=context, load=load)
|
2010-07-01 13:08:19 +00:00
|
|
|
|
ls = base_calendar_id2real_id(base_calendar_id, with_date=res and res.get('duration', 0) or 0)
|
2010-02-11 12:37:41 +00:00
|
|
|
|
if not isinstance(ls, (str, int, long)) and len(ls) >= 2:
|
|
|
|
|
res['date'] = ls[1]
|
|
|
|
|
res['date_deadline'] = ls[2]
|
|
|
|
|
res['id'] = base_calendar_id
|
|
|
|
|
|
|
|
|
|
result.append(res)
|
|
|
|
|
if isinstance(ids, (str, int, long)):
|
|
|
|
|
return result and result[0] or False
|
|
|
|
|
return result
|
|
|
|
|
|
2010-05-14 10:14:26 +00:00
|
|
|
|
def copy(self, cr, uid, id, default=None, context=None):
|
2010-03-18 11:30:31 +00:00
|
|
|
|
"""
|
|
|
|
|
Duplicate record on specified id.
|
|
|
|
|
@param self: the object pointer.
|
|
|
|
|
@param cr: the current row, from the database cursor,
|
|
|
|
|
@param id: id of record from which we duplicated.
|
2010-05-14 10:14:26 +00:00
|
|
|
|
@param context: A standard dictionary for contextual values
|
2010-03-18 11:30:31 +00:00
|
|
|
|
@return: Duplicate record id.
|
|
|
|
|
"""
|
2010-05-14 10:14:26 +00:00
|
|
|
|
if not context:
|
|
|
|
|
context = {}
|
2010-02-11 12:37:41 +00:00
|
|
|
|
res = super(calendar_event, self).copy(cr, uid, base_calendar_id2real_id(id), default, context)
|
|
|
|
|
alarm_obj = self.pool.get('res.alarm')
|
2010-07-01 06:05:16 +00:00
|
|
|
|
alarm_obj.do_alarm_create(cr, uid, [res], self._name, 'date', context=context)
|
2010-03-25 12:07:00 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
return res
|
|
|
|
|
|
|
|
|
|
def unlink(self, cr, uid, ids, context=None):
|
2010-03-18 11:30:31 +00:00
|
|
|
|
"""
|
|
|
|
|
Deletes records specified in ids.
|
|
|
|
|
@param self: the object pointer.
|
|
|
|
|
@param cr: the current row, from the database cursor,
|
|
|
|
|
@param id: List of calendar event's id.
|
2010-05-14 10:14:26 +00:00
|
|
|
|
@param context: A standard dictionary for contextual values
|
2010-03-18 11:30:31 +00:00
|
|
|
|
@return: True
|
|
|
|
|
"""
|
2010-02-11 12:37:41 +00:00
|
|
|
|
res = False
|
2010-07-01 13:08:19 +00:00
|
|
|
|
for event_id in ids:
|
|
|
|
|
if isinstance(event_id, (int, long)):
|
|
|
|
|
res = super(calendar_event, self).unlink(cr, uid, event_id)
|
|
|
|
|
self.pool.get('res.alarm').do_alarm_unlink(cr, uid, [event_id], self._name)
|
|
|
|
|
continue
|
|
|
|
|
event_id, date_new = event_id.split('-')
|
|
|
|
|
event_id = [int(event_id)]
|
|
|
|
|
for record in self.read(cr, uid, event_id, ['date', 'rrule', 'exdate']):
|
|
|
|
|
if record['rrule']:
|
|
|
|
|
# Remove one of the recurrent event
|
|
|
|
|
date_new = time.strftime("%Y-%m-%d %H:%M:%S", \
|
|
|
|
|
time.strptime(date_new, "%Y%m%d%H%M%S"))
|
|
|
|
|
exdate = (record['exdate'] and (record['exdate'] + ',') or '') + ''.join((re.compile('\d')).findall(date_new)) + 'Z'
|
|
|
|
|
res = self.write(cr, uid, event_id, {'exdate': exdate})
|
|
|
|
|
else:
|
|
|
|
|
res = super(calendar_event, self).unlink(cr, uid, event_id)
|
|
|
|
|
self.pool.get('res.alarm').do_alarm_unlink(cr, uid, event_id, self._name)
|
2010-02-11 12:37:41 +00:00
|
|
|
|
return res
|
2010-01-12 12:06:53 +00:00
|
|
|
|
|
2010-05-14 10:14:26 +00:00
|
|
|
|
def create(self, cr, uid, vals, context=None):
|
2010-03-18 11:30:31 +00:00
|
|
|
|
"""
|
|
|
|
|
Create new record.
|
|
|
|
|
@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: dictionary of every field value.
|
2010-05-14 10:14:26 +00:00
|
|
|
|
@param context: A standard dictionary for contextual values
|
2010-03-18 11:30:31 +00:00
|
|
|
|
@return: new created record id.
|
|
|
|
|
"""
|
2010-05-14 10:14:26 +00:00
|
|
|
|
if not context:
|
|
|
|
|
context = {}
|
2010-02-11 12:37:41 +00:00
|
|
|
|
res = super(calendar_event, self).create(cr, uid, vals, context)
|
|
|
|
|
alarm_obj = self.pool.get('res.alarm')
|
2010-07-01 06:05:16 +00:00
|
|
|
|
alarm_obj.do_alarm_create(cr, uid, [res], self._name, 'date', context=context)
|
2010-02-11 12:37:41 +00:00
|
|
|
|
return res
|
2010-07-02 07:34:06 +00:00
|
|
|
|
|
|
|
|
|
def do_tentative(self, cr, uid, ids, context=None, *args):
|
|
|
|
|
""" Makes event invitation as Tentative
|
|
|
|
|
@param self: The object pointer
|
|
|
|
|
@param cr: the current row, from the database cursor,
|
|
|
|
|
@param uid: the current user’s ID for security checks,
|
2010-07-02 09:10:42 +00:00
|
|
|
|
@param ids: List of Event IDs
|
2010-07-02 07:34:06 +00:00
|
|
|
|
@param *args: Get Tupple value
|
|
|
|
|
@param context: A standard dictionary for contextual values
|
|
|
|
|
"""
|
|
|
|
|
return self.write(cr, uid, ids, {'state': 'tentative'}, context)
|
|
|
|
|
|
|
|
|
|
def do_cancel(self, cr, uid, ids, context=None, *args):
|
|
|
|
|
""" Makes event invitation as Tentative
|
|
|
|
|
@param self: The object pointer
|
|
|
|
|
@param cr: the current row, from the database cursor,
|
|
|
|
|
@param uid: the current user’s ID for security checks,
|
2010-07-02 09:10:42 +00:00
|
|
|
|
@param ids: List of Event IDs
|
2010-07-02 07:34:06 +00:00
|
|
|
|
@param *args: Get Tupple value
|
|
|
|
|
@param context: A standard dictionary for contextual values
|
|
|
|
|
"""
|
|
|
|
|
return self.write(cr, uid, ids, {'state': 'cancelled'}, context)
|
|
|
|
|
|
|
|
|
|
def do_confirm(self, cr, uid, ids, context=None, *args):
|
|
|
|
|
""" Makes event invitation as Tentative
|
|
|
|
|
@param self: The object pointer
|
|
|
|
|
@param cr: the current row, from the database cursor,
|
|
|
|
|
@param uid: the current user’s ID for security checks,
|
2010-07-02 09:10:42 +00:00
|
|
|
|
@param ids: List of Event IDs
|
2010-07-02 07:34:06 +00:00
|
|
|
|
@param *args: Get Tupple value
|
|
|
|
|
@param context: A standard dictionary for contextual values
|
|
|
|
|
"""
|
|
|
|
|
return self.write(cr, uid, ids, {'state': 'confirmed'}, context)
|
2009-12-18 11:50:40 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
calendar_event()
|
2009-12-04 08:25:52 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
class calendar_todo(osv.osv):
|
2010-03-25 12:07:00 +00:00
|
|
|
|
""" Calendar Task """
|
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
_name = "calendar.todo"
|
|
|
|
|
_inherit = "calendar.event"
|
|
|
|
|
_description = "Calendar Task"
|
2009-12-04 08:25:52 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
def _get_date(self, cr, uid, ids, name, arg, context):
|
2010-04-29 13:50:23 +00:00
|
|
|
|
"""
|
2010-04-06 09:01:56 +00:00
|
|
|
|
Get Date
|
|
|
|
|
@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 calendar todo's IDs.
|
|
|
|
|
@param args: list of tuples of form [(‘name_of_the_field’, ‘operator’, value), ...].
|
|
|
|
|
@param context: A standard dictionary for contextual values
|
2010-03-25 12:07:00 +00:00
|
|
|
|
"""
|
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
res = {}
|
|
|
|
|
for event in self.browse(cr, uid, ids, context=context):
|
|
|
|
|
res[event.id] = event.date_start
|
|
|
|
|
return res
|
2009-12-04 08:25:52 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
def _set_date(self, cr, uid, id, name, value, arg, context):
|
2010-04-29 13:50:23 +00:00
|
|
|
|
"""
|
2010-04-06 09:01:56 +00:00
|
|
|
|
Set Date
|
|
|
|
|
@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 id: calendar's ID.
|
|
|
|
|
@param value: Get Value
|
|
|
|
|
@param args: list of tuples of form [(‘name_of_the_field’, ‘operator’, value), ...].
|
|
|
|
|
@param context: A standard dictionary for contextual values
|
2010-03-25 12:07:00 +00:00
|
|
|
|
"""
|
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
event = self.browse(cr, uid, id, context=context)
|
2010-04-06 07:28:49 +00:00
|
|
|
|
cr.execute("UPDATE %s set date_start='%s' where id=%s" \
|
|
|
|
|
% (self._table, value, id))
|
2010-02-11 12:37:41 +00:00
|
|
|
|
return True
|
2009-12-16 14:16:20 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
_columns = {
|
|
|
|
|
'date': fields.function(_get_date, method=True, fnct_inv=_set_date, \
|
2010-04-29 13:50:23 +00:00
|
|
|
|
string='Duration', store=True, type='datetime'),
|
|
|
|
|
'duration': fields.integer('Duration'),
|
2009-12-04 08:25:52 +00:00
|
|
|
|
}
|
2010-03-25 12:07:00 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
__attribute__ = {}
|
2010-03-25 12:07:00 +00:00
|
|
|
|
|
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
calendar_todo()
|
2010-03-25 12:07:00 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
class ir_attachment(osv.osv):
|
|
|
|
|
_name = 'ir.attachment'
|
|
|
|
|
_inherit = 'ir.attachment'
|
|
|
|
|
|
|
|
|
|
def search_count(self, cr, user, args, context=None):
|
2010-04-29 13:50:23 +00:00
|
|
|
|
"""
|
2010-04-06 09:01:56 +00:00
|
|
|
|
@param self: The object pointer
|
|
|
|
|
@param cr: the current row, from the database cursor,
|
|
|
|
|
@param user: the current user’s ID for security checks,
|
|
|
|
|
@param args: list of tuples of form [(‘name_of_the_field’, ‘operator’, value), ...].
|
|
|
|
|
@param context: A standard dictionary for contextual values
|
2010-03-25 12:07:00 +00:00
|
|
|
|
"""
|
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
args1 = []
|
|
|
|
|
for arg in args:
|
|
|
|
|
args1.append(map(lambda x:str(x).split('-')[0], arg))
|
|
|
|
|
return super(ir_attachment, self).search_count(cr, user, args1, context)
|
|
|
|
|
|
2010-04-29 13:50:23 +00:00
|
|
|
|
def search(self, cr, uid, args, offset=0, limit=None, order=None,
|
2010-02-11 12:37:41 +00:00
|
|
|
|
context=None, count=False):
|
2010-04-29 13:50:23 +00:00
|
|
|
|
"""
|
2010-04-06 09:01:56 +00:00
|
|
|
|
@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 args: list of tuples of form [(‘name_of_the_field’, ‘operator’, value), ...].
|
|
|
|
|
@param offset: The Number of Results to pass,
|
|
|
|
|
@param limit: The Number of Results to Return,
|
|
|
|
|
@param context: A standard dictionary for contextual values
|
2010-03-25 12:07:00 +00:00
|
|
|
|
"""
|
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
new_args = args
|
|
|
|
|
for i, arg in enumerate(new_args):
|
|
|
|
|
if arg[0] == 'res_id':
|
|
|
|
|
new_args[i] = (arg[0], arg[1], base_calendar_id2real_id(arg[2]))
|
2010-04-29 13:50:23 +00:00
|
|
|
|
return super(ir_attachment, self).search(cr, uid, new_args, offset=offset,
|
|
|
|
|
limit=limit, order=order,
|
2010-02-11 12:37:41 +00:00
|
|
|
|
context=context, count=False)
|
|
|
|
|
ir_attachment()
|
|
|
|
|
|
|
|
|
|
class ir_values(osv.osv):
|
|
|
|
|
_inherit = 'ir.values'
|
|
|
|
|
|
|
|
|
|
def set(self, cr, uid, key, key2, name, models, value, replace=True, \
|
|
|
|
|
isobject=False, meta=False, preserve_user=False, company=False):
|
2010-04-29 13:50:23 +00:00
|
|
|
|
"""
|
2010-04-06 09:01:56 +00:00
|
|
|
|
Set IR 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,
|
2010-04-29 13:50:23 +00:00
|
|
|
|
@param model: Get The Model
|
2010-04-06 09:01:56 +00:00
|
|
|
|
"""
|
2010-03-25 12:07:00 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
new_model = []
|
|
|
|
|
for data in models:
|
|
|
|
|
if type(data) in (list, tuple):
|
|
|
|
|
new_model.append((data[0], base_calendar_id2real_id(data[1])))
|
2009-12-15 13:43:55 +00:00
|
|
|
|
else:
|
2010-02-11 12:37:41 +00:00
|
|
|
|
new_model.append(data)
|
2010-03-18 11:30:31 +00:00
|
|
|
|
return super(ir_values, self).set(cr, uid, key, key2, name, new_model, \
|
2010-02-11 12:37:41 +00:00
|
|
|
|
value, replace, isobject, meta, preserve_user, company)
|
2009-12-17 06:26:30 +00:00
|
|
|
|
|
2010-05-14 10:14:26 +00:00
|
|
|
|
def get(self, cr, uid, key, key2, models, meta=False, context=None, \
|
2010-02-11 12:37:41 +00:00
|
|
|
|
res_id_req=False, without_user=True, key2_req=True):
|
2010-04-29 13:50:23 +00:00
|
|
|
|
"""
|
2010-04-06 09:01:56 +00:00
|
|
|
|
Get IR 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,
|
2010-04-29 13:50:23 +00:00
|
|
|
|
@param model: Get The Model
|
2010-04-06 09:01:56 +00:00
|
|
|
|
"""
|
2010-05-14 10:14:26 +00:00
|
|
|
|
if not context:
|
|
|
|
|
context = {}
|
2010-02-11 12:37:41 +00:00
|
|
|
|
new_model = []
|
|
|
|
|
for data in models:
|
|
|
|
|
if type(data) in (list, tuple):
|
|
|
|
|
new_model.append((data[0], base_calendar_id2real_id(data[1])))
|
2009-12-14 11:07:43 +00:00
|
|
|
|
else:
|
2010-02-11 12:37:41 +00:00
|
|
|
|
new_model.append(data)
|
|
|
|
|
return super(ir_values, self).get(cr, uid, key, key2, new_model, \
|
|
|
|
|
meta, context, res_id_req, without_user, key2_req)
|
|
|
|
|
|
|
|
|
|
ir_values()
|
|
|
|
|
|
|
|
|
|
class ir_model(osv.osv):
|
2009-12-18 13:44:31 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
_inherit = 'ir.model'
|
|
|
|
|
|
2010-05-14 10:14:26 +00:00
|
|
|
|
def read(self, cr, uid, ids, fields=None, context=None,
|
2010-02-11 12:37:41 +00:00
|
|
|
|
load='_classic_read'):
|
2010-04-06 09:01:56 +00:00
|
|
|
|
"""
|
2010-05-14 10:14:26 +00:00
|
|
|
|
Overrides orm read method.
|
2010-04-06 09:01:56 +00:00
|
|
|
|
@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 IR Model’s IDs.
|
2010-04-29 13:50:23 +00:00
|
|
|
|
@param context: A standard dictionary for contextual values
|
2010-04-06 09:01:56 +00:00
|
|
|
|
"""
|
2010-05-26 12:15:25 +00:00
|
|
|
|
new_ids = isinstance(ids, (str, int, long)) and [ids] or ids
|
2010-05-14 10:14:26 +00:00
|
|
|
|
if not context:
|
|
|
|
|
context = {}
|
2010-05-26 12:15:25 +00:00
|
|
|
|
data = super(ir_model, self).read(cr, uid, new_ids, fields=fields, \
|
2010-02-11 12:37:41 +00:00
|
|
|
|
context=context, load=load)
|
|
|
|
|
if data:
|
|
|
|
|
for val in data:
|
|
|
|
|
val['id'] = base_calendar_id2real_id(val['id'])
|
2010-05-19 12:22:19 +00:00
|
|
|
|
return isinstance(ids, (str, int, long)) and data[0] or data
|
2010-02-11 12:37:41 +00:00
|
|
|
|
|
|
|
|
|
ir_model()
|
|
|
|
|
|
|
|
|
|
class virtual_report_spool(web_services.report_spool):
|
|
|
|
|
|
|
|
|
|
def exp_report(self, db, uid, object, ids, datas=None, context=None):
|
2010-04-29 13:50:23 +00:00
|
|
|
|
"""
|
2010-04-06 09:01:56 +00:00
|
|
|
|
Export Report
|
|
|
|
|
@param self: The object pointer
|
|
|
|
|
@param db: get the current database,
|
|
|
|
|
@param uid: the current user’s ID for security checks,
|
2010-04-29 13:50:23 +00:00
|
|
|
|
@param context: A standard dictionary for contextual values
|
2010-04-06 09:01:56 +00:00
|
|
|
|
"""
|
2010-03-25 12:07:00 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
if object == 'printscreen.list':
|
|
|
|
|
return super(virtual_report_spool, self).exp_report(db, uid, \
|
|
|
|
|
object, ids, datas, context)
|
|
|
|
|
new_ids = []
|
|
|
|
|
for id in ids:
|
|
|
|
|
new_ids.append(base_calendar_id2real_id(id))
|
2010-04-05 10:37:31 +00:00
|
|
|
|
if datas.get('id', False):
|
|
|
|
|
datas['id'] = base_calendar_id2real_id(datas['id'])
|
2010-02-11 12:37:41 +00:00
|
|
|
|
return super(virtual_report_spool, self).exp_report(db, uid, object, new_ids, datas, context)
|
|
|
|
|
|
|
|
|
|
virtual_report_spool()
|
|
|
|
|
|
|
|
|
|
class res_users(osv.osv):
|
|
|
|
|
_inherit = 'res.users'
|
|
|
|
|
|
|
|
|
|
def _get_user_avail(self, cr, uid, ids, context=None):
|
2010-04-06 09:01:56 +00:00
|
|
|
|
"""
|
2010-05-14 10:14:26 +00:00
|
|
|
|
Get User Availability
|
2010-04-06 09:01:56 +00:00
|
|
|
|
@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 res user’s IDs.
|
2010-04-29 13:50:23 +00:00
|
|
|
|
@param context: A standard dictionary for contextual values
|
2010-04-06 09:01:56 +00:00
|
|
|
|
"""
|
2010-03-25 12:07:00 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
current_datetime = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
|
|
|
|
res = {}
|
|
|
|
|
attendee_obj = self.pool.get('calendar.attendee')
|
|
|
|
|
attendee_ids = attendee_obj.search(cr, uid, [
|
2010-04-29 13:50:23 +00:00
|
|
|
|
('event_date', '<=', current_datetime), ('event_end_date', '<=', current_datetime),
|
2010-02-11 12:37:41 +00:00
|
|
|
|
('state', '=', 'accepted'), ('user_id', 'in', ids)
|
|
|
|
|
])
|
|
|
|
|
|
2010-03-18 11:30:31 +00:00
|
|
|
|
# result = cr.dictfetchall()
|
2010-02-11 12:37:41 +00:00
|
|
|
|
for attendee_data in attendee_obj.read(cr, uid, attendee_ids, ['user_id']):
|
|
|
|
|
user_id = attendee_data['user_id']
|
|
|
|
|
status = 'busy'
|
|
|
|
|
res.update({user_id:status})
|
|
|
|
|
|
2010-03-25 12:07:00 +00:00
|
|
|
|
#TOCHECK: Delegated Event
|
2010-02-11 12:37:41 +00:00
|
|
|
|
for user_id in ids:
|
|
|
|
|
if user_id not in res:
|
|
|
|
|
res[user_id] = 'free'
|
|
|
|
|
|
|
|
|
|
return res
|
|
|
|
|
|
|
|
|
|
def _get_user_avail_fun(self, cr, uid, ids, name, args, context=None):
|
2010-04-06 09:01:56 +00:00
|
|
|
|
"""
|
2010-05-14 10:14:26 +00:00
|
|
|
|
Get User Availability Function
|
2010-04-06 09:01:56 +00:00
|
|
|
|
@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 res user’s IDs.
|
2010-04-29 13:50:23 +00:00
|
|
|
|
@param context: A standard dictionary for contextual values
|
2010-04-06 09:01:56 +00:00
|
|
|
|
"""
|
2010-03-25 12:07:00 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
return self._get_user_avail(cr, uid, ids, context=context)
|
|
|
|
|
|
|
|
|
|
_columns = {
|
|
|
|
|
'availability': fields.function(_get_user_avail_fun, type='selection', \
|
|
|
|
|
selection=[('free', 'Free'), ('busy', 'Busy')], \
|
2010-04-29 13:50:23 +00:00
|
|
|
|
string='Free/Busy', method=True),
|
2010-02-11 12:37:41 +00:00
|
|
|
|
}
|
2010-05-14 10:14:26 +00:00
|
|
|
|
|
2010-02-11 12:37:41 +00:00
|
|
|
|
res_users()
|
2010-03-04 12:59:13 +00:00
|
|
|
|
|
2010-04-06 07:28:49 +00:00
|
|
|
|
|
2010-04-06 08:39:14 +00:00
|
|
|
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|