task.py :  » Project-Management » Task-Coach » TaskCoach-1.0.3 » taskcoachlib » domain » task » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Project Management » Task Coach 
Task Coach » TaskCoach 1.0.3 » taskcoachlib » domain » task » task.py
# -*- coding: utf-8 -*-

'''
Task Coach - Your friendly task manager
Copyright (C) 2004-2010 Frank Niessink <frank@niessink.com>
Copyright (C) 2008 Jrme Laheurte <fraca7@free.fr>

Task Coach is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Task Coach is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
'''

import wx
from taskcoachlib import patterns
from taskcoachlib.domain import base,date,categorizable,note,attachment
from taskcoachlib.domain.attribute import color,icon


class Task(note.NoteOwner, attachment.AttachmentOwner, 
           categorizable.CategorizableCompositeObject):
    
    def __init__(self, subject='', description='', dueDate=None, 
            startDate=None, completionDate=None, budget=None, 
            priority=0, id=None, hourlyFee=0, # pylint: disable-msg=W0622
            fixedFee=0, reminder=None, categories=None,
            efforts=None, shouldMarkCompletedWhenAllChildrenCompleted=None, 
            recurrence=None, percentageComplete=0, *args, **kwargs):
        kwargs['id'] = id
        kwargs['subject'] = subject
        kwargs['description'] = description
        kwargs['categories'] = categories
        super(Task, self).__init__(*args, **kwargs)
        self.__dueDate = base.Attribute(dueDate or date.Date(), self, 
                                        self.dueDateEvent)
        self.__startDate = base.Attribute(startDate or date.Today(), self, 
                                          self.startDateEvent)
        self.__completionDate = completionDate or date.Date()
        percentageComplete = 100 if self.__completionDate != date.Date() else percentageComplete
        self.__percentageComplete = base.Attribute(percentageComplete, 
                                                   self, self.percentageCompleteEvent)
        self.__budget = base.Attribute(budget or date.TimeDelta(), self, 
                                       self.budgetEvent)
        self._efforts = efforts or []
        self.__priority = base.Attribute(priority, self, self.priorityEvent)
        self.__hourlyFee = base.Attribute(hourlyFee, self, self.hourlyFeeEvent)
        self.__fixedFee = base.Attribute(fixedFee, self, self.fixedFeeEvent)
        self.__reminder = base.Attribute(reminder, self, self.reminderEvent)
        if recurrence is None:
            recurrence = date.Recurrence()
        self._recurrence = recurrence
        self._shouldMarkCompletedWhenAllChildrenCompleted = \
            shouldMarkCompletedWhenAllChildrenCompleted
        for effort in self._efforts:
            effort.setTask(self)

    def __setstate__(self, state, event=None):
        notify = event is None
        event = event or patterns.Event()
        super(Task, self).__setstate__(state, event)
        self.setStartDate(state['startDate'], event)
        self.setDueDate(state['dueDate'], event)
        self.setCompletionDate(state['completionDate'], event)
        self.setPercentageComplete(state['percentageComplete'], event)
        self.setRecurrence(state['recurrence'], event)
        self.setReminder(state['reminder'], event)
        self.setEfforts(state['efforts'], event)
        self.setBudget(state['budget'], event)
        self.setPriority(state['priority'], event)
        self.setHourlyFee(state['hourlyFee'], event)
        self.setFixedFee(state['fixedFee'], event)
        self.setShouldMarkCompletedWhenAllChildrenCompleted( \
            state['shouldMarkCompletedWhenAllChildrenCompleted'], event)
        if notify:
            event.send()
        
    def __getstate__(self):
        state = super(Task, self).__getstate__()
        state.update(dict(dueDate=self.__dueDate.get(), 
            startDate=self.__startDate.get(), 
            completionDate=self.__completionDate, 
            percentageComplete=self.__percentageComplete.get(),
            children=self.children(), parent=self.parent(), 
            efforts=self._efforts, budget=self.__budget.get(), 
            priority=self.__priority.get(), 
            hourlyFee=self.__hourlyFee.get(), fixedFee=self.__fixedFee.get(), 
            recurrence=self._recurrence.copy(),
            reminder=self.__reminder.get(),
            shouldMarkCompletedWhenAllChildrenCompleted=\
                self._shouldMarkCompletedWhenAllChildrenCompleted))
        return state

    def __getcopystate__(self):
        state = super(Task, self).__getcopystate__()
        state.update(dict(dueDate=self.__dueDate.get(), 
            startDate=self.__startDate.get(), 
            completionDate=self.__completionDate,
            percentageComplete=self.__percentageComplete.get(), 
            efforts=[effort.copy() for effort in self._efforts], 
            budget=self.__budget.get(), priority=self.__priority.get(), 
            hourlyFee=self.__hourlyFee.get(), fixedFee=self.__fixedFee.get(), 
            recurrence=self._recurrence.copy(),
            reminder=self.__reminder.get(), 
            shouldMarkCompletedWhenAllChildrenCompleted=\
                self._shouldMarkCompletedWhenAllChildrenCompleted))
        return state
        
    def allChildrenCompleted(self):
        ''' Return whether all children (non-recursively) are completed. '''
        children = self.children()
        return all(child.completed() for child in children) if children \
            else False        

    def newChild(self, subject='New subtask'): # pylint: disable-msg=W0221
        ''' Subtask constructor '''
        return super(Task, self).newChild(subject=subject, 
            dueDate=self.dueDate(),
            startDate=max(date.Today(), self.startDate()), parent=self)

    def addChild(self, child, event=None):
        if child in self.children():
            return
        notify = event is None
        event = event or patterns.Event()
        super(Task, self).addChild(child, event)
        self.childChangeEvent(child, event)
            
        if self.shouldBeMarkedCompleted():
            self.setCompletionDate(child.completionDate(), event)
        elif self.completed() and not child.completed():
            self.setCompletionDate(date.Date(), event)

        if child.dueDate() > self.dueDate():
            self.setDueDate(child.dueDate(), event)            
        if child.startDate() < self.startDate():
            self.setStartDate(child.startDate(), event)

        if notify:
            event.send()
        
    def removeChild(self, child, event=None):
        if child not in self.children():
            return
        notify = event is None
        event = event or patterns.Event()
        super(Task, self).removeChild(child, event)
        self.childChangeEvent(child, event)
            
        if self.shouldBeMarkedCompleted(): 
            # The removed child was the last uncompleted child
            self.setCompletionDate(date.Today(), event)
        
        if notify:    
            event.send()
            
    def childChangeEvent(self, child, event):
        childHasTotalTimeSpent = child.timeSpent(recursive=True)
        childHasTotalBudget = child.budget(recursive=True)
        childHasTotalBudgetLeft = child.budgetLeft(recursive=True)
        childHasTotalRevenue = child.revenue(recursive=True)
        childTotalPriority = child.priority(recursive=True)
        # Determine what changes due to the child being added or removed:
        if childHasTotalTimeSpent:
            self.totalTimeSpentEvent(event)
        if childHasTotalRevenue:
            self.totalRevenueEvent(event)
        if childHasTotalBudget:
            self.totalBudgetEvent(event)
        if childHasTotalBudgetLeft or (childHasTotalTimeSpent and \
                                       (childHasTotalBudget or self.budget())):
            self.totalBudgetLeftEvent(event)
        if childTotalPriority > self.priority():
            self.totalPriorityEvent(event)
        if child.isBeingTracked(recursive=True):
            activeEfforts = child.activeEfforts(recursive=True)
            if self.isBeingTracked(recursive=True):
                self.startTrackingEvent(event, *activeEfforts) # pylint: disable-msg=W0142
            else:
                self.stopTrackingEvent(event, *activeEfforts) # pylint: disable-msg=W0142
        
    def dueDate(self, recursive=False):
        if recursive:
            childrenDueDates = [child.dueDate(recursive=True) for child in \
                                self.children() if not child.completed()]
            return min(childrenDueDates + [self.__dueDate.get()])
        else:
            return self.__dueDate.get()

    def setDueDate(self, dueDate, event=None):
        self.__dueDate.set(dueDate, event)
            
    def dueDateEvent(self, event):
        dueDate = self.dueDate()
        event.addSource(self, dueDate, type='task.dueDate')
        
        for child in self.children():
            if child.dueDate() > dueDate:
                child.setDueDate(dueDate, event)
                
        if self.parent():
            parent = self.parent()
            if dueDate > parent.dueDate():
                parent.setDueDate(dueDate, event)

    def startDate(self, recursive=False):
        if recursive:
            childrenStartDates = [child.startDate(recursive=True) for child in \
                                  self.children() if not child.completed()]
            return min(childrenStartDates + [self.__startDate.get()])
        else:
            return self.__startDate.get()

    def setStartDate(self, startDate, event=None):
        self.__startDate.set(startDate, event)
            
    def startDateEvent(self, event):
        startDate = self.startDate()
        event.addSource(self, startDate, type='task.startDate')
        
        if not self.recurrence(True): 
            # Let Task.recur() handle the change in start date
            for child in self.children():
                if startDate > child.startDate():
                    child.setStartDate(startDate, event)
            
            parent = self.parent()
            if parent and startDate < parent.startDate():
                parent.setStartDate(startDate, event)

    def timeLeft(self, recursive=False):
        return self.dueDate(recursive) - date.Today()
        
    def completionDate(self, recursive=False):
        if recursive:
            childrenCompletionDates = [child.completionDate(recursive=True) \
                for child in self.children() if child.completed()]
            return max(childrenCompletionDates + [self.__completionDate])
        else:
            return self.__completionDate

    def setCompletionDate(self, completionDate=None, event=None):
        completionDate = completionDate or date.Today()
        if completionDate == self.__completionDate:
            return
        notify = event is None
        event = event or patterns.Event()
        if completionDate != date.Date() and self.recurrence():
            self.recur(event)
        else:
            parent = self.parent()
            if parent:
                oldParentTotalPriority = parent.priority(recursive=True) 
            self.__completionDate = completionDate
            event.addSource(self, completionDate, type='task.completionDate')
            if parent and parent.priority(recursive=True) != \
                          oldParentTotalPriority:
                self.totalPriorityEvent(event)                    
            if completionDate != date.Date():
                self.setReminder(None, event)
                
            self.setPercentageComplete(100 if self.completed() else 0, event)
                
            if parent:
                if self.completed():
                    if parent.shouldBeMarkedCompleted():
                        parent.setCompletionDate(completionDate, event)
                else:
                    if parent.completed():
                        parent.setCompletionDate(date.Date(), event)
            if self.completed():
                for child in self.children():
                    if not child.completed():
                        child.setRecurrence(event=event)
                        child.setCompletionDate(completionDate, event)
                
                if self.isBeingTracked():
                    self.stopTracking(event)
                    
        if notify:
            event.send()

    def shouldBeMarkedCompleted(self):
        ''' Return whether this task should be marked completed. It should be
            marked completed when 1) it's not completed, 2) all of its children
            are completed, 3) its setting says it should be completed when
            all of its children are completed. '''
        shouldMarkCompletedAccordingToSetting = \
            self.settings.getboolean('behavior', # pylint: disable-msg=E1101
                'markparentcompletedwhenallchildrencompleted')
        shouldMarkCompletedAccordingToTask = \
            self.shouldMarkCompletedWhenAllChildrenCompleted()
        return ((shouldMarkCompletedAccordingToTask == True) or \
                ((shouldMarkCompletedAccordingToTask == None) and \
                  shouldMarkCompletedAccordingToSetting)) and \
               (not self.completed()) and self.allChildrenCompleted()
      
    def completed(self):
        return self.completionDate() != date.Date()

    def overdue(self):
        return self.dueDate() < date.Today() and not self.completed()

    def inactive(self):
        return (self.startDate() > date.Today()) and not self.completed()
        
    def active(self):
        return not self.inactive() and not self.completed()

    def dueSoon(self):
        manyDays = self.settings.getint('behavior', 'duesoondays') # pylint: disable-msg=E1101
        return (0 <= self.timeLeft().days < manyDays and not self.completed())

    def dueToday(self):
        return (self.dueDate() == date.Today() and not self.completed())

    def dueTomorrow(self):
        return (self.dueDate() == date.Tomorrow() and not self.completed())
    
   # effort related methods:

    def efforts(self, recursive=False):
        childEfforts = []
        if recursive:
            for child in self.children():
                childEfforts.extend(child.efforts(recursive=True))
        return self._efforts + childEfforts

    def activeEfforts(self, recursive=False):
        return [effort for effort in self.efforts(recursive) \
            if effort.isBeingTracked()]

    def isBeingTracked(self, recursive=False):
        return self.activeEfforts(recursive)
        
    def addEffort(self, effort, event=None):
        if effort in self._efforts:
            return
        wasTracking = self.isBeingTracked()
        self._efforts.append(effort)
        notify = event is None
        event = event or patterns.Event()
        self.addEffortEvent(event, effort)
        if effort.isBeingTracked() and not wasTracking:
            self.startTrackingEvent(event, effort)
        self.timeSpentEvent(event, effort)
        if notify:
            event.send()
  
    def addEffortEvent(self, event, *efforts):
        event.addSource(self, *efforts, **dict(type='task.effort.add'))
          
    def startTrackingEvent(self, event, *efforts):    
        for ancestor in [self] + self.ancestors():
            event.addSource(ancestor, *efforts, 
                            **dict(type=ancestor.trackStartEventType()))

    def removeEffort(self, effort, event=None):
        if effort not in self._efforts:
            return
        self._efforts.remove(effort)
        notify = event is None
        event = event or patterns.Event()
        self.removeEffortEvent(event, effort)
        if effort.isBeingTracked() and not self.isBeingTracked():
            self.stopTrackingEvent(event, effort)
        self.timeSpentEvent(event, effort)
        if notify:
            event.send()
        
    def removeEffortEvent(self, event, *efforts):
        event.addSource(self, *efforts, **dict(type='task.effort.remove'))
        
    def stopTrackingEvent(self, event, *efforts):
        for ancestor in [self] + self.ancestors():
            event.addSource(ancestor, *efforts, 
                            **dict(type=ancestor.trackStopEventType()))
            
    def timeSpentEvent(self, event, effort):
        event.addSource(self, self.timeSpent(), type='task.timeSpent')
        self.totalTimeSpentEvent(event, effort)
        if self.budget():
            self.budgetLeftEvent(event)
        elif self.budget(recursive=True):
            self.totalBudgetLeftEvent(event)
        if self.hourlyFee() > 0:
            self.revenueEvent(event)
    
    def totalTimeSpentEvent(self, event, *efforts):
        for ancestor in [self] + self.ancestors():
            event.addSource(ancestor, *efforts, 
                            **dict(type=ancestor.totalTimeSpentChangedEventType()))
    
    def revenueEvent(self, event):
        event.addSource(self, self.revenue(), type='task.revenue')
        self.totalRevenueEvent(event)
    
    def totalRevenueEvent(self, event):
        for ancestor in [self] + self.ancestors():
            event.addSource(ancestor, ancestor.revenue(recursive=True), 
                            type='task.totalRevenue')
    
    def setEfforts(self, efforts, event=None):
        if efforts == self._efforts:
            return
        notify = event is None
        event = event or patterns.Event() 
        oldEfforts = self._efforts
        self._efforts = efforts
        self.removeEffortEvent(event, oldEfforts)
        self.addEffortEvent(event, efforts)
        if notify:
            event.send()

    def timeSpent(self, recursive=False):
        return sum((effort.duration() for effort in self.efforts(recursive)), 
                   date.TimeDelta())

    def stopTracking(self, event=None):
        notify = event is None
        event = event or patterns.Event()
        for effort in self.activeEfforts():
            effort.setStop(event=event)
        if notify:
            event.send()
                
    def budget(self, recursive=False):
        result = self.__budget.get()
        if recursive:
            for task in self.children():
                result += task.budget(recursive)
        return result
        
    def setBudget(self, budget, event=None):
        self.__budget.set(budget, event)
        
    def budgetEvent(self, event):
        event.addSource(self, self.budget(), type='task.budget')
        self.totalBudgetEvent(event)
        self.budgetLeftEvent(event)
    
    def totalBudgetEvent(self, event):
        for ancestor in [self] + self.ancestors():
            event.addSource(ancestor, ancestor.budget(recursive=True), 
                            type='task.totalBudget')
        
    def budgetLeftEvent(self, event):
        event.addSource(self, self.budgetLeft(), type='task.budgetLeft')
        self.totalBudgetLeftEvent(event)
    
    def totalBudgetLeftEvent(self, event):
        for ancestor in [self] + self.ancestors():
            event.addSource(ancestor, ancestor.budgetLeft(recursive=True), 
                            type='task.totalBudgetLeft')
    
    def budgetLeft(self, recursive=False):
        budget = self.budget(recursive)
        return budget - self.timeSpent(recursive) if budget else budget

    def foregroundColor(self, recursive=False):
        fgColor = super(Task, self).foregroundColor(recursive)
        if not recursive:
            return fgColor
        statusColor = self.statusColor()
        if statusColor == wx.BLACK:
            return fgColor
        elif fgColor == None:
            return statusColor
        else:
            return color.ColorMixer.mix((fgColor, statusColor))
    
    def statusColor(self):
        ''' Return the current color of task, based on its status (completed,
            overdue, duesoon, inactive, or active). '''
        if self.completed():
            status = 'completed'
        elif self.overdue(): 
            status = 'overdue'
        elif self.dueSoon():
            status = 'duesoon'
        elif self.inactive(): 
            status = 'inactive'
        else:
            status = 'active'
        return self.colorForStatus(status)
    
    @classmethod
    def colorForStatus(class_, status):
        return wx.Colour(*eval(class_.settings.get('color', '%stasks'%status)))
    
    def foregroundColorChangedEvent(self, event):
        super(Task, self).foregroundColorChangedEvent(event)
        fgColor = self.foregroundColor()
        for task in [self] + self.childrenWithoutOwnForegroundColor():
            for eachEffort in task.efforts():
                event.addSource(eachEffort, fgColor, 
                                type=eachEffort.foregroundColorChangedEventType())
    
    def backgroundColorChangedEvent(self, event):
        super(Task, self).backgroundColorChangedEvent(event)
        bgColor = self.backgroundColor()
        for task in [self] + self.childrenWithoutOwnBackgroundColor():
            for eachEffort in task.efforts():
                event.addSource(eachEffort, bgColor, 
                                type=eachEffort.backgroundColorChangedEventType())

    def icon(self, recursive=False):
        icon = super(Task, self).icon(recursive=False)
        if not icon and recursive:
            icon = self.categoryIcon() or self.__stateBasedIcon(selected=False)
        return self.pluralOrSingularIcon(icon)

    def selectedIcon(self, recursive=False):
        icon = super(Task, self).selectedIcon(recursive=False)
        if not icon and recursive:
            icon = self.categorySelectedIcon() or self.__stateBasedIcon(selected=True)
        return self.pluralOrSingularIcon(icon)

    stateColorMap = (('completed', '_green'), ('overdue', '_red'),
                     ('dueSoon', '_orange'), ('inactive', '_grey'))

    def __stateBasedIcon(self, selected=False):
        if self.isBeingTracked():
            taskIcon = 'clock'
        else:
            taskIcon = 'led'
            for state, color in self.stateColorMap:
                if getattr(self, state)():
                    taskIcon += color
                    break
            else:
                taskIcon += '_blue'
            taskIcon = self.pluralOrSingularIcon(taskIcon+'_icon')[:-len('_icon')]
            hasChildren = any(child for child in self.children() if not child.isDeleted())
            taskIcon += '_open' if selected and hasChildren else ''
        return taskIcon + '_icon'
    
    @classmethod
    def totalTimeSpentChangedEventType(class_):
        return 'task.totalTimeSpent'

    @classmethod
    def trackStartEventType(class_):
        return '%s.track.start'%class_

    @classmethod
    def trackStopEventType(class_):
        return '%s.track.stop'%class_
    
    # percentage Complete
    
    def percentageComplete(self, recursive=False):
        percentages = [self.__percentageComplete.get()] 
        if recursive:
            percentages.extend([child.percentageComplete(recursive) for child in self.children()])
        return sum(percentages)/len(percentages)
    
    def setPercentageComplete(self, percentage, event=None):
        if percentage == self.percentageComplete():
            return
        notify = event is None
        event = event or patterns.Event()
        oldPercentage = self.percentageComplete()
        self.__percentageComplete.set(percentage, event)
        if percentage == 100 and oldPercentage != 100 and not self.completed():
            self.setCompletionDate(date.Today(), event)
        elif oldPercentage == 100 and percentage != 100 and self.completed():
            self.setCompletionDate(date.Date(), event)
        if notify:
            event.send()
        
    def percentageCompleteEvent(self, event):
        event.addSource(self, self.percentageComplete(), 
                        type='task.percentageComplete')
        self.totalPercentageCompleteEvent(event)
        
    def totalPercentageCompleteEvent(self, event):
        for ancestor in [self] + self.ancestors():
            event.addSource(ancestor, ancestor.percentageComplete(recursive=True), 
                            **dict(type='task.totalPercentageComplete'))

        
    # priority
    
    def priority(self, recursive=False):
        if recursive:
            childPriorities = [child.priority(recursive=True) \
                               for child in self.children() \
                               if not child.completed()]
            return max(childPriorities + [self.__priority.get()])
        else:
            return self.__priority.get()
        
    def setPriority(self, priority, event=None):
        self.__priority.set(priority, event)
        
    def priorityEvent(self, event):
        event.addSource(self, self.priority(), type='task.priority')
        self.totalPriorityEvent(event)
    
    def totalPriorityEvent(self, event):
        for ancestor in [self] + self.ancestors():
            event.addSource(ancestor, ancestor.priority(recursive=True),
                            type='task.totalPriority')
                
    # revenue
    
    def hourlyFee(self, recursive=False): # pylint: disable-msg=W0613
        return self.__hourlyFee.get()
    
    def setHourlyFee(self, hourlyFee, event=None):
        self.__hourlyFee.set(hourlyFee, event)

    def hourlyFeeEvent(self, event):
        event.addSource(self, self.hourlyFee(), 
                        type=self.hourlyFeeChangedEventType())
        if self.timeSpent() > date.TimeDelta():
            for objectWithRevenue in [self] + self.efforts():
                objectWithRevenue.revenueEvent(event)
            
    @classmethod
    def hourlyFeeChangedEventType(class_):
        return '%s.hourlyFee'%class_
                
    def revenue(self, recursive=False):
        childRevenues = sum(child.revenue(recursive) for child in 
                            self.children()) if recursive else 0
        return self.timeSpent().hours() * self.hourlyFee() + self.fixedFee() + \
               childRevenues
    
    def fixedFee(self, recursive=False):
        childFixedFees = sum(child.fixedFee(recursive) for child in 
                             self.children()) if recursive else 0
        return self.__fixedFee.get() + childFixedFees
    
    def setFixedFee(self, fixedFee, event=None):
        self.__fixedFee.set(fixedFee, event)
        
    def fixedFeeEvent(self, event):
        event.addSource(self, self.fixedFee(), type='task.fixedFee')
        self.totalFixedFeeEvent(event)
        self.revenueEvent(event)
    
    def totalFixedFeeEvent(self, event):
        for ancestor in [self] + self.ancestors():
            event.addSource(ancestor, ancestor.fixedFee(recursive=True),
                            type='task.totalFixedFee')
        
    # reminder
    
    def reminder(self, recursive=False): # pylint: disable-msg=W0613
        return self.__reminder.get()

    def setReminder(self, reminderDateTime=None, event=None):
        if reminderDateTime == date.DateTime.max:
            reminderDateTime = None
        self.__reminder.set(reminderDateTime, event)
            
    def reminderEvent(self, event):
        event.addSource(self, self.reminder(), type='task.reminder')
                    
    # Recurrence
    
    def recurrence(self, recursive=False):
        if not self._recurrence and recursive and self.parent():
            return self.parent().recurrence(recursive)
        else:
            return self._recurrence
        
    def setRecurrence(self, recurrence=None, event=None):
        recurrence = recurrence or date.Recurrence()
        if recurrence == self._recurrence:
            return
        notify = event is None
        event = event or patterns.Event()
        self._recurrence = recurrence
        event.addSource(self, recurrence, type='task.recurrence')
        if notify:
            event.send()
            
    def recur(self, event=None):
        notify = event is None
        event = event or patterns.Event()
        self.setCompletionDate(date.Date(), event)
        nextStartDate = self.recurrence(recursive=True)(self.startDate(), next=False)
        self.setStartDate(nextStartDate, event)
        nextDueDate = self.recurrence(recursive=True)(self.dueDate(), next=False)
        self.setDueDate(nextDueDate, event)
        if self.reminder():
            nextReminder = self.recurrence(recursive=True)(self.reminder(), next=False)
            self.setReminder(nextReminder, event)
        for child in self.children():
            if not child.recurrence():
                child.recur(event)
        self.recurrence()(next=True)
        if notify:
            event.send()
                        
    # behavior
    
    def setShouldMarkCompletedWhenAllChildrenCompleted(self, newValue, event=None):
        if newValue == self._shouldMarkCompletedWhenAllChildrenCompleted:
            return
        notify = event is None
        event = event or patterns.Event() 
        self._shouldMarkCompletedWhenAllChildrenCompleted = newValue
        event.addSource(self, newValue, 
                        type='task.setting.shouldMarkCompletedWhenAllChildrenCompleted')
        if notify:
            event.send()

    def shouldMarkCompletedWhenAllChildrenCompleted(self):
        return self._shouldMarkCompletedWhenAllChildrenCompleted
    
    @classmethod
    def modificationEventTypes(class_):
        eventTypes = super(Task, class_).modificationEventTypes()
        return eventTypes + ['task.dueDate', 'task.startDate', 
                             'task.completionDate', 'task.effort.add', 
                             'task.effort.remove', 'task.budget',
                             'task.percentageComplete', 
                             'task.priority', 
                             class_.hourlyFeeChangedEventType(), 
                             'task.fixedFee',
                             'task.reminder', 'task.recurrence',
                             'task.setting.shouldMarkCompletedWhenAllChildrenCompleted']
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.