Beispiel #1
0
    def __call__(self):
        uid = self.request.get('uid')
        uid_catalog = getToolByName(self.context, 'uid_catalog')
        brains = uid_catalog({'UID': uid})
        if len(brains) == 0:
            msg = _(u'msg_no_task_found',
                    default=u'No task found with this UID')
            IStatusMessage(self.request).addStatusMessage(msg, type="error")
            self.request.response.redirect('@@tracker')
            return

        xmtask = brains[0].getObject()
        try:
            self.context.portal_workflow.doActionFor(xmtask, 'complete')
        except WorkflowException:
            msg = _(u'msg_close_task_failed',
                    default=u'Closing of task failed.')
            IStatusMessage(self.request).addStatusMessage(msg, type="error")
            self.request.response.redirect('@@tracker')
            return

        # Remove the tracked task as it is not needed anymore.
        tracker = self.tracker()
        task = tracker.get_task(uid)
        tracker.tasks.remove(task)
        msg = _(u'msg_close_task_success', default=u'Task has been closed.')
        IStatusMessage(self.request).addStatusMessage(msg, type="info")
        self.request.response.redirect('@@tracker')
Beispiel #2
0
    def __call__(self):
        uid = self.request.get('uid')
        text = self.request.get('text')
        if not text:
            msg = _(u'msg_missing_description',
                    default='Entry not added. Please provide a description.')
            IStatusMessage(self.request).addStatusMessage(msg, type="error")
            self.request.response.redirect('@@tracker')
            return

        tracker = self.tracker()
        if tracker.starttime is None:
            msg = _(u'msg_no_tracking_without_starttime',
                    default=u'Cannot track time when the tracker has not '
                            u'started.')
            IStatusMessage(self.request).addStatusMessage(msg, type="error")
            self.request.response.redirect('@@tracker')
            return

        task = tracker.get_task(uid)
        if task is None:
            # We are dealing with an unassigned entry
            task = tracker.unassigned
        add_entry(tracker, task, text)
        tracker.starttime = mx.DateTime.now()
        msg = _(u'msg_added_entry', default=u'Added entry')
        IStatusMessage(self.request).addStatusMessage(msg, type="info")
        self.request.response.redirect('@@tracker')
Beispiel #3
0
    def edit_entry(self, **kwargs):
        """ In this call we handle a form which contains one entry.
        This entry has a text and time field which we expect to change.
        """
        plone = self.getCommandSet("plone")
        core = self.getCommandSet("core")
        tracker = get_tracker(self.context)
        text = self.request.get('text')
        if not text:
            message = _(u'msg_empty_text',
                        default=u'Empty text, this is not allowed')
            plone.issuePortalMessage(message, msgtype="error")
            return
        time = self.request.get('time')
        uid = self.request.get('uid')
        idx = int(self.request.get('entry_number'))

        task = tracker.get_task(uid)
        entry = task.entries[idx]
        try:
            seconds = time_to_seconds(time)
        except TimeformattingError:
            msg = _(u'Invalid time (0:00-23:59): ${time}',
                    mapping=dict(time=unicode(time)))
            plone.issuePortalMessage(msg, msgtype='error')
            return
        entry.time = mx.DateTime.DateTimeDeltaFrom(seconds=seconds)
        entry.text = text
        message = _(u'msg_update_entry', default=u'Entry updated')
        plone.issuePortalMessage(message)

        # Refresh entire task to also update the remaining time and so. Keep
        # the details open.
        self.task_refresh(uid=uid, open_details=True)
Beispiel #4
0
def book(caller, xmtask, entries):
    """Utility method for booking entries.

    caller: 'self' of the calling view

    """
    bookings_per_day = split_entries(entries)
    for day, booking in bookings_per_day.items():
        # Round the time to the nearest quarter of an hour.
        time = round_time_to_quarter_hours(booking['time'])
        # Watch out: time.minutes is the minutes you want *plus*
        # time.hours times 60... So we use time.tuple() instead and we
        # ignore days and seconds.
        days, hours, minutes, seconds = time.tuple()
        day = DateTime(day)
        try:
            create_booking(xmtask,
                           title=booking['title'],
                           hours=hours,
                           minutes=minutes,
                           description=booking['description'],
                           day=day)
        except Unauthorized:
            msg = _(u'msg_failed_add_booking',
                    default=u'Not permitted to add booking to task. Check'
                    u' if the task is in the correct state.')
            IStatusMessage(caller.request).addStatusMessage(msg,
                                                          type="error")
            # The caller needs to know that the booking has failed.
            # So either we should return False (and return True
            # otherwise) or raise an exception ourselves.
            raise Unauthorized
Beispiel #5
0
    def __call__(self):
        """Book unassigned entry on the selected task"""
        selected_task_uid = self.request.get('selected_task_uid', None)
        if selected_task_uid is None:
            msg = _(u'msg_missing_task',
                    default='No task selected, cannot book entry.')
            IStatusMessage(self.request).addStatusMessage(msg, type="error")
            self.request.response.redirect('@@tracker')
            return
        uid_catalog = getToolByName(self.context, 'uid_catalog')
        brains = uid_catalog({'UID': selected_task_uid})
        if len(brains) == 0:
            msg = _(u'msg_no_task_found',
                    default=u'No task found with this UID')
            IStatusMessage(self.request).addStatusMessage(msg, type="error")
            self.request.response.redirect('@@tracker')
            return
        xmtask = brains[0].getObject()

        unassigned_task_id = self.request.get('unassigned_task_id', None)
        # ^^^ Not really needed.
        entry_number = self.request.get('entry_number', None)
        if entry_number is None or unassigned_task_id is None:
            msg = u'Missing essential form parameters'
            IStatusMessage(self.request).addStatusMessage(msg, type="error")
            self.request.response.redirect('@@tracker')
            return
        tracker = self.tracker()
        task = tracker.get_task(unassigned_task_id)
        entry_number = int(entry_number)
        entry = task.entries[entry_number]

        # Now the actual booking.
        try:
            book(self, xmtask, [entry])
        except Unauthorized:
            # A message has already been added to the request.  We
            # just need to redirect and return.
            self.request.response.redirect('@@tracker')
            return

        msg = _(u'msg_added_booking', default=u'Added booking to task')
        IStatusMessage(self.request).addStatusMessage(msg, type="info")
        # Remove booked entry.
        del task.entries[entry_number]
        self.request.response.redirect('@@tracker')
Beispiel #6
0
 def start_timer(self):
     tracker = get_tracker(self.context)
     tracker.starttime = mx.DateTime.now()
     zope = self.getCommandSet('zope')
     zope.refreshProvider('#startstop', 'xm.tracker.startstop')
     message = _(u'msg_started_timer',
                 default=u'Started the timer')
     plone = self.getCommandSet("plone")
     plone.issuePortalMessage(message)
Beispiel #7
0
    def track_time(self, uid, text):
        plone = self.getCommandSet("plone")
        if not text:
            message = _(u'msg_empty_text',
                        default=u'Empty text, this is not allowed')
            plone.issuePortalMessage(message, msgtype='error')
            return
        context = aq_inner(self.context)
        tracker = get_tracker(context)
        task = tracker.get_task(uid)
        if task is None:
            task = tracker.unassigned
        add_entry(tracker, task, text)

        self.task_refresh(uid=uid)

        message = _(u'msg_added_entry', default=u'Added entry')
        plone.issuePortalMessage(message)
        tracker.starttime = mx.DateTime.now()
Beispiel #8
0
    def __call__(self):
        uid = self.request.get('uid')
        tracker = self.tracker()
        task = tracker.get_task(uid)
        if len(task.entries) == 0:
            msg = _(u'msg_no_entries_found',
                    default=u'No entries found for this task')
            IStatusMessage(self.request).addStatusMessage(msg, type="error")
            self.request.response.redirect('@@tracker')
            return

        uid_catalog = getToolByName(self.context, 'uid_catalog')
        brains = uid_catalog({'UID': uid})
        if len(brains) == 0:
            msg = _(u'msg_no_task_found',
                    default=u'No task found with this UID')
            IStatusMessage(self.request).addStatusMessage(msg, type="error")
            self.request.response.redirect('@@tracker')
            return

        xmtask = brains[0].getObject()
        try:
            book(self, xmtask, task.entries)
        except Unauthorized:
            # A message has already been added to the request.  We
            # just need to redirect and return.
            self.request.response.redirect('@@tracker')
            return

        msg = _(u'msg_added_booking', default=u'Added booking to task')
        IStatusMessage(self.request).addStatusMessage(msg, type="info")
        # Remove current entries.  No need to book twice...
        task.entries = PersistentList()
        if self.request.get('book_and_close', None):
            # When redirecting we get a new request, so the uid
            # parameter gets lost, so we need to add it here ourselves.
            self.request.response.redirect('@@close_task?uid=%s' % uid)
        else:
            self.request.response.redirect('@@tracker')
Beispiel #9
0
 def booked_today_string(self):
     day_total = getMultiAdapter(
         (self.context, self.request), name=u'daytotal')
     booked = day_total.raw_total()
     booked = mx.DateTime.DateTimeDeltaFrom(hours=booked)
     tasks = sum([task.total_time() for task in self.tracker.tasks])
     unassigned = self.tracker.unassigned.total_time()
     tracked = tasks + unassigned
     booked = booked.strftime('%H:%M')
     tracked = tracked.strftime('%H:%M')
     return _(u'msg_total_booked_tracked',
              default=u'Booked: $booked | Tracked: $tracked',
              mapping=dict(booked=booked, tracked=tracked))
Beispiel #10
0
    def __call__(self):
        uid = self.request.get('uid')
        entry_number = int(self.request.get('entry_number'))
        tracker = self.tracker()
        task = tracker.get_task(uid)
        if task is None:
            msg = _(u'msg_no_task_found',
                    default=u'No task found with this UID')
            IStatusMessage(self.request).addStatusMessage(msg, type="error")
            self.request.response.redirect('@@tracker')
            return

        try:
            task.entries.pop(entry_number)
        except IndexError:
            msg = _(u'msg_remove_entry_failed',
                    default=u'Failed to remove entry')
            IStatusMessage(self.request).addStatusMessage(msg, type="error")
        else:
            msg = _(u'msg_remove_entry_success', default=u'Removed entry')
            IStatusMessage(self.request).addStatusMessage(msg, type="info")
        self.request.response.redirect('@@tracker')
Beispiel #11
0
 def __call__(self):
     tracker = self.tracker()
     tracker.starttime = mx.DateTime.now()
     msg = _(u'msg_started_timer', default=u'Started the timer')
     IStatusMessage(self.request).addStatusMessage(msg, type="info")
     self.request.response.redirect('@@tracker')
Beispiel #12
0
 def __str__(self):
     return _(u'time_formatting_error',
              default='Invalid time format. Must be x:xx or xx:xx')