Skip to content

Commit

Permalink
Fix week ordering between years (#5)
Browse files Browse the repository at this point in the history
  • Loading branch information
LucaScorpion authored Jan 4, 2024
1 parent ad63533 commit 4721099
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 21 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## v1.5.2

- Fix week ordering between years.

## v1.5.1

- Add "Tijd voor tijd" to leave tasks.
Expand Down
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "TimeChimp Billability Chart",
"description": "Adds a billability chart on the TimeChimp hours page.",
"version": "1.5.1",
"version": "1.5.2",
"manifest_version": 3,
"permissions": [
"webRequest"
Expand Down
45 changes: 25 additions & 20 deletions src/content/stats.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Time } from '../TimeChimpApi';
import { getWeek } from 'date-fns';
import { getWeek, getYear } from 'date-fns';

const LEAVE_TASKS = [
'Bijzonder verlof',
Expand All @@ -8,9 +8,10 @@ const LEAVE_TASKS = [
'Verlof',
];

type TimesByWeek = Record<number, Time[]>;
type TimesByYearWeek = Record<string, Time[]>;

interface Stats {
year: number;
week: number;
billableHours: number;
nonBillableHours: number;
Expand All @@ -29,37 +30,38 @@ export function calculateTimeStats(
showWeeks: number,
rollWeeks: number,
) {
const timesByWeek = groupTimesByWeek(times);
removeLeaveOnlyWeeks(timesByWeek);
const stats = calculateStatsPerWeek(timesByWeek);
const timesByYearWeek = groupTimesByYearWeek(times);
removeLeaveOnlyWeeks(timesByYearWeek);
const stats = calculateStatsPerWeek(timesByYearWeek);
const rollingStats = calculateRollingStats(stats, showWeeks, rollWeeks);
return rollingStats.reverse();
}

function groupTimesByWeek(times: Time[]) {
return times.reduce<TimesByWeek>((acc, time) => {
const week = getWeek(new Date(time.date));
function groupTimesByYearWeek(times: Time[]) {
return times.reduce<TimesByYearWeek>((acc, time) => {
const date = new Date(time.date);
const yearWeek = `${getYear(date)}-${getWeek(date)}`;

if (!acc[week]) {
acc[week] = [];
if (!acc[yearWeek]) {
acc[yearWeek] = [];
}

acc[week].push(time);
acc[yearWeek].push(time);
return acc;
}, []);
}, {});
}

function removeLeaveOnlyWeeks(timesByWeek: TimesByWeek) {
Object.entries(timesByWeek).forEach(([weekStr, times]) => {
function removeLeaveOnlyWeeks(timesByYearWeek: TimesByYearWeek) {
Object.entries(timesByYearWeek).forEach(([yearWeekStr, times]) => {
if (times.every((t) => LEAVE_TASKS.includes(t.taskName))) {
delete timesByWeek[Number(weekStr)];
delete timesByYearWeek[yearWeekStr];
}
});
}

function calculateStatsPerWeek(timesByWeek: TimesByWeek) {
return Object.entries(timesByWeek)
.map<Stats>(([weekStr, times]) => {
function calculateStatsPerWeek(timesByYearWeek: TimesByYearWeek) {
return Object.entries(timesByYearWeek)
.map<Stats>(([yearWeekStr, times]) => {
const billableHours = sum(
times.filter((t) => t.billable).map((t) => t.hours),
);
Expand All @@ -73,7 +75,8 @@ function calculateStatsPerWeek(timesByWeek: TimesByWeek) {
const totalHoursWithoutLeave = billableHours + nonBillableHours;

return {
week: Number(weekStr),
year: Number(yearWeekStr.substring(0, 4)),
week: Number(yearWeekStr.substring(5)),
billableHours,
nonBillableHours,
totalHours: sum(times.map((t) => t.hours)),
Expand All @@ -88,7 +91,9 @@ function calculateStatsPerWeek(timesByWeek: TimesByWeek) {
(100 * nonBillableHours) / totalHoursWithoutLeave,
};
})
.sort((a, b) => b.week - a.week);
.sort((a, b) =>
a.year === b.year ? b.week - a.week : b.year - a.year,
);
}

function calculateRollingStats(
Expand Down

0 comments on commit 4721099

Please sign in to comment.