[calendar] [feature] Added Recurring Events
This commit is contained in:
parent
ea25409d3b
commit
9d00e1df61
5 changed files with 233 additions and 20 deletions
|
|
@ -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) {
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
52
docs/docs.attributions.md
Normal 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
|
||||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue