Ejemplo n.º 1
0
    def _calc_facts(self, df: pd.DataFrame, hours_target: float,
                    hours_max: float):
        shifted_dt = df[wc.COL_LOG_DATETIME].shift(1)
        stop_mask = df[wc.COL_TYPE] == wc.TOKEN_STOP

        # calculate total working time
        total_time = (df[stop_mask][wc.COL_LOG_DATETIME] -
                      shifted_dt[stop_mask]).sum()
        total_time_str = format_timedelta(total_time)

        # calculate breaks
        break_duration = self.auto_break.get_duration(total_time)
        break_duration_str = format_timedelta(break_duration)
        hours_target_dt = timedelta(hours=hours_target) + break_duration
        hours_max_dt = timedelta(hours=hours_max) + break_duration

        # calculate remaining time
        now = (datetime.now(timezone.utc).astimezone(
            tz=wc.LOCAL_TIMEZONE).replace(microsecond=0))
        eow_dt = now + (hours_target_dt - total_time)
        eow_str = eow_dt.strftime("%H:%M:%S")
        remaining_time = max(eow_dt - now, timedelta(minutes=0))
        remaining_time_str = format_timedelta(remaining_time)

        # calculate overtime
        overtime = max(total_time - hours_target_dt, timedelta(minutes=0))
        overtime_str = format_timedelta(overtime)

        # calculcate percentage values
        percentage_done = round(total_time.total_seconds() /
                                hours_target_dt.total_seconds() * 100)
        percentage_remaining = max(0, 100 - percentage_done)
        percentage_overtime = max(
            round(overtime.total_seconds() /
                  (hours_max_dt - hours_target_dt).total_seconds() * 100),
            0,
        )

        def _short_hours_str(value: str):
            return value[:len("00:00")]

        return dict(
            break_duration=break_duration_str,
            break_duration_short=_short_hours_str(break_duration_str),
            eow=eow_str,
            eow_short=_short_hours_str(eow_str),
            overtime=overtime_str,
            overtime_short=_short_hours_str(overtime_str),
            percentage_done=percentage_done,
            percentage_overtime=percentage_overtime,
            percentage_remaining=percentage_remaining,
            remaining_time=remaining_time_str,
            remaining_time_short=_short_hours_str(remaining_time_str),
            total_time=total_time_str,
            total_time_short=_short_hours_str(total_time_str),
        )
Ejemplo n.º 2
0
    def test_format_timedelta_valid_days(self):
        actual = format_timedelta(np.timedelta64(2, "D"))
        expected = "48:00:00"

        self.assertEqual(actual, expected)

        actual = format_timedelta(np.timedelta64(20, "D"))
        expected = "480:00:00"

        self.assertEqual(actual, expected)
Ejemplo n.º 3
0
    def task_report(self, task_id):
        """Generate a report of a given task."""
        task_mask = self._log_df[wc.COL_CATEGORY] == wc.TOKEN_TASK
        task_id_mask = self._log_df[wc.COL_TASK_IDENTIFIER] == task_id
        mask = task_mask & task_id_mask
        task_df = self._log_df[mask]

        if task_df.shape[0] == 0:
            sys.stderr.write((f"Task ID {task_id} is unknown. "
                              "See 'wl task list' to list all known tasks.\n"))
            exit(1)

        intervals = extract_intervals(task_df, logger=logger)

        intervals_detailed = intervals[["date", "start", "stop",
                                        "interval"]].rename(
                                            columns={
                                                "date": "Date",
                                                "start": "Start",
                                                "stop": "Stop",
                                                "interval": "Duration",
                                            })
        print("Log entries:\n")
        print(
            intervals_detailed.to_string(
                index=False,
                formatters={
                    "Start":
                    lambda x: x.strftime("%H:%M:%S"),
                    "Stop":
                    lambda x: x.strftime("%H:%M:%S"),
                    "Duration":
                    lambda x: format_timedelta(
                        timedelta(microseconds=int(x) / 1e3)),
                },
            ))

        print("---")
        print("Daily aggregated:\n")
        intervals_daily = intervals.groupby(by="date")[["interval"]].sum()
        intervals_daily.index.name = "Date"
        intervals_daily = intervals_daily.rename(
            columns={"interval": "Duration"})
        print(intervals_daily.to_string())

        print(f"---\nTotal: {intervals_detailed['Duration'].sum()}")
Ejemplo n.º 4
0
    def test_invalid_value_none(self):
        expected = "00:00:00"

        td = None
        actual = format_timedelta(td)
        self.assertEqual(expected, actual)
Ejemplo n.º 5
0
    def test_format_timedelta_valid(self):
        actual = format_timedelta(np.timedelta64(100, "s"))
        expected = "00:01:40"

        self.assertEqual(actual, expected)
Ejemplo n.º 6
0
    def test_format_timedelta_nat(self):
        """It should not break if a numpy not-a-time value is passed."""
        actual = format_timedelta(np.timedelta64("nAt"))
        expected = "00:00:00"

        self.assertEqual(actual, expected)
Ejemplo n.º 7
0
 def test_default_behaviour(self):
     td = timedelta(hours=1, minutes=5, seconds=30)
     expected = "01:05:30"
     actual = format_timedelta(td)
     self.assertEqual(expected, actual)