[calendar] [feature] Added Recurring Events

This commit is contained in:
Rushabh Mehta 2013-07-26 13:22:49 +05:30
parent ea25409d3b
commit 9d00e1df61
5 changed files with 233 additions and 20 deletions

View file

@ -24,6 +24,14 @@ cur_frm.cscript.add_list_breadcrumb = function(appframe) {
appframe.add_breadcrumb("icon-calendar", "Calendar/Event", "Calendar");
}
cur_frm.cscript.repeat_on = function(doc, cdt, cdn) {
if(doc.repeat_on==="Every Day") {
$.each(["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"], function(i,v) {
cur_frm.set_value(v, 1);
})
}
}
cur_frm.cscript.refresh = function(doc, cdt, cdn) {
}

View file

@ -22,6 +22,10 @@
from __future__ import unicode_literals
import webnotes
from webnotes.utils import getdate, cint, add_months, date_diff, add_days
weekdays = ["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"]
class DocType:
def __init__(self, d, dl):
self.doc, self.doclist = d, dl
@ -30,19 +34,91 @@ class DocType:
def get_events(start, end):
roles = webnotes.get_roles()
events = webnotes.conn.sql("""select name, subject,
starts_on, ends_on, owner, all_day, event_type
starts_on, ends_on, owner, all_day, event_type, repeat_this_event, repeat_on,
monday, tuesday, wednesday, thursday, friday, saturday, sunday
from tabEvent where (
(starts_on between %s and %s)
or (ends_on between %s and %s)
(starts_on between '%(start)s' and '%(end)s')
or (ends_on between '%(start)s' and '%(end)s')
) or (
starts_on < '%(start)s' and ifnull(repeat_this_event,0)=1 and
ifnull(repeat_till, "3000-01-01 00:00:00") > '%(start)s'
)
and (event_type='Public' or owner=%s
and (event_type='Public' or owner='%(user)s'
or exists(select * from `tabEvent User` where
`tabEvent User`.parent=tabEvent.name and person=%s)
`tabEvent User`.parent=tabEvent.name and person='%(user)s')
or exists(select * from `tabEvent Role` where
`tabEvent Role`.parent=tabEvent.name
and `tabEvent Role`.role in ('%s')))
order by starts_on""" % ('%s', '%s', '%s', '%s', '%s', '%s',
"', '".join(roles)), (start, end, start, end,
webnotes.session.user, webnotes.session.user), as_dict=1)
return events
and `tabEvent Role`.role in ('%(roles)s')))
order by starts_on""" % {
"start": start,
"end": end,
"user": webnotes.session.user,
"roles": "', '".join(roles)
}, as_dict=1)
# process recurring events
start = start.split(" ")[0]
end = end.split(" ")[0]
add_events = []
def add_event(e, date):
new_event = e.copy()
new_event.starts_on = date + " " + e.starts_on.split(" ")[1]
new_event.ends_on = date + " " + e.ends_on.split(" ")[1]
add_events.append(new_event)
for e in events:
if e.repeat_this_event:
event_start, time_str = e.starts_on.split(" ")
if e.repeat_on=="Every Year":
start_year = cint(start.split("-")[0])
end_year = cint(end.split("-")[0])
event_start = "-".join(event_start.split("-")[1:])
# repeat for all years in period
for year in range(start_year, end_year+1):
date = str(year) + "-" + event_start
if date > start and date < end:
add_event(e, date)
events.remove(e)
if e.repeat_on=="Every Month":
date = start.split("-")[0] + "-" + start.split("-")[1] + "-" + event_start.split("-")[2]
# last day of month issue, start from prev month!
try:
getdate(date)
except ValueError:
date = date.split("-")
date = date[0] + "-" + str(cint(date[1]) - 1) + "-" + date[2]
start_from = date
for i in xrange(int(date_diff(end, start) / 30) + 3):
if date >= start and date <= end and date >= event_start:
add_event(e, date)
date = add_months(start_from, i+1)
events.remove(e)
if e.repeat_on=="Every Week":
weekday = getdate(event_start).weekday()
# monday is 0
start_weekday = getdate(start).weekday()
# start from nearest weeday after last monday
date = add_days(start, weekday - start_weekday)
for cnt in xrange(int(date_diff(end, start) / 7) + 3):
if date >= start and date <= end and date >= event_start:
add_event(e, date)
date = add_days(date, 7)
events.remove(e)
if e.repeat_on=="Every Day":
for cnt in xrange(date_diff(end, start) + 1):
date = add_days(start, cnt)
if date <= end and e[weekdays[getdate(date).weekday()]]:
add_event(e, date)
events.remove(e)
return events + add_events

View file

@ -2,7 +2,7 @@
{
"creation": "2013-06-10 13:17:47",
"docstatus": 0,
"modified": "2013-07-05 14:36:46",
"modified": "2013-07-26 13:19:41",
"modified_by": "Administrator",
"owner": "Administrator"
},
@ -72,6 +72,12 @@
"fieldname": "column_break_4",
"fieldtype": "Column Break"
},
{
"doctype": "DocField",
"fieldname": "all_day",
"fieldtype": "Check",
"label": "All Day"
},
{
"doctype": "DocField",
"fieldname": "starts_on",
@ -88,9 +94,84 @@
},
{
"doctype": "DocField",
"fieldname": "all_day",
"fieldname": "section_break_8",
"fieldtype": "Section Break"
},
{
"doctype": "DocField",
"fieldname": "repeat_this_event",
"fieldtype": "Check",
"label": "All Day"
"label": "Repeat this Event"
},
{
"depends_on": "repeat_this_event",
"doctype": "DocField",
"fieldname": "repeat_on",
"fieldtype": "Select",
"label": "Repeat On",
"options": "\nEvery Day\nEvery Week\nEvery Month\nEvery Year"
},
{
"depends_on": "repeat_this_event",
"description": "Leave blank if you have not decided the end date.",
"doctype": "DocField",
"fieldname": "repeat_till",
"fieldtype": "Date",
"label": "Repeat Till"
},
{
"doctype": "DocField",
"fieldname": "column_break_11",
"fieldtype": "Column Break"
},
{
"depends_on": "eval:doc.repeat_this_event && doc.repeat_on===\"Every Day\"",
"doctype": "DocField",
"fieldname": "monday",
"fieldtype": "Check",
"label": "Monday"
},
{
"depends_on": "eval:doc.repeat_this_event && doc.repeat_on===\"Every Day\"",
"doctype": "DocField",
"fieldname": "tuesday",
"fieldtype": "Check",
"label": "Tuesday"
},
{
"depends_on": "eval:doc.repeat_this_event && doc.repeat_on===\"Every Day\"",
"doctype": "DocField",
"fieldname": "wednesday",
"fieldtype": "Check",
"label": "Wednesday"
},
{
"depends_on": "eval:doc.repeat_this_event && doc.repeat_on===\"Every Day\"",
"doctype": "DocField",
"fieldname": "thursday",
"fieldtype": "Check",
"label": "Thursday"
},
{
"depends_on": "eval:doc.repeat_this_event && doc.repeat_on===\"Every Day\"",
"doctype": "DocField",
"fieldname": "friday",
"fieldtype": "Check",
"label": "Friday"
},
{
"depends_on": "eval:doc.repeat_this_event && doc.repeat_on===\"Every Day\"",
"doctype": "DocField",
"fieldname": "saturday",
"fieldtype": "Check",
"label": "Saturday"
},
{
"depends_on": "eval:doc.repeat_this_event && doc.repeat_on===\"Every Day\"",
"doctype": "DocField",
"fieldname": "sunday",
"fieldtype": "Check",
"label": "Sunday"
},
{
"doctype": "DocField",

52
docs/docs.attributions.md Normal file
View file

@ -0,0 +1,52 @@
---
{
"_label": "Attributions"
}
---
ERPNext is made using these amazing Open Source Projects.
### System Requirements:
1. [Linux Operating System](http://en.wikipedia.org/wiki/Linux): The operating system that brought a revolution in Open Source software.
1. [MySQL Database](http://www.mysql.com/): The world's most popular Open Source Database.
1. [Apache HTTPD web server](http://httpd.apache.org): The Number One HTTP Server On The Internet.
1. [Memcached](http://memcached.org/): Free & open source, high-performance, distributed memory object caching system.
### Tools and Languages:
1. [Python Programming Language](http://python.org/): The "batteries included" language that lets you write elegant code, quickly. With third-party modules:
- MySQLdb
- pytz
- jinja2
- markdown2
- dateutil
- termcolor
- python-memcached
- requests
- chardet
- pygeoip
- dropbox
- google-api-python-client
1. [Git - Source Code Management](http://git-scm.com/): Git - Source Code Management
### Libraries and Frameworks
1. [wnframework](https://github.com/webnotes/wnframework): The full stack Python + Javascript web application framework on which ERPNext is built.
1. [JQuery](http://jquery.com/): The write less, do more Javascript Library.
1. [JQuery UI](http://jqueryui.com/): A curated set of user interface interactions, effects, widgets, and themes built on top of the jQuery JavaScript Library.
1. [Bootstrap](http://twitter.github.com/bootstrap/index.html): Sleek, intuitive, and powerful front-end framework for faster and easier web development.
1. [Font Awesome](http://fortawesome.github.com/Font-Awesome/): The iconic font designed for use with Twitter Bootstrap.
1. [SlickGrid](https://github.com/mleibman/SlickGrid): A lightning fast JavaScript grid/spreadsheet.
1. [FullCalendar](http://arshaw.com/fullcalendar/): FullCalendar is a jQuery plugin that provides a full-sized, drag and drop calendar.
1. [Flot Charting Library](http://www.flotcharts.org/): Attractive JavaScript plotting for jQuery.
1. [Ace Code Editor](http://ace.ajax.org/): High Performance Code Editor for the web.
1. [JQuery.Gantt](http://taitems.github.com/jQuery.Gantt/): Draw Gantt charts with the famous jQuery ease of development.
1. [JQuery Tag-it](http://aehlke.github.io/tag-it/): Simple and configurable tag editing widget with autocomplete support.
1. [JSColor](http://jscolor.com/): HTML/Javascript Color Picker.
1. [QUnit](http://qunitjs.com/): A JavaScript Unit Testing framework.
1. [Downloadify](https://github.com/dcneiner/Downloadify): A tiny javascript + Flash library that enables the creation and download of text files without server interaction.
1. [GeoLite](http://dev.maxmind.com/geoip/geolite): GeoLite data created by MaxMind, available from <a href="https://www.maxmind.com">https://www.maxmind.com</a>.
---
For more information please write to us at support@erpnext.com

View file

@ -152,11 +152,7 @@ def getdate(string_date):
if " " in string_date:
string_date = string_date.split(" ")[0]
try:
return datetime.datetime.strptime(string_date, "%Y-%m-%d").date()
except ValueError:
webnotes.msgprint("Cannot understand date - '%s'" % \
(string_date,), raise_exception=1)
return datetime.datetime.strptime(string_date, "%Y-%m-%d").date()
def add_to_date(date, years=0, months=0, days=0):
"""Adds `days` to the given date"""
@ -165,7 +161,7 @@ def add_to_date(date, years=0, months=0, days=0):
date = getdate(date)
else:
raise Exception, "Start date required"
from dateutil.relativedelta import relativedelta
date += relativedelta(years=years, months=months, days=days)