This repository has been archived on 2024-11-20. You can view files and clone it, but cannot push or open issues or pull requests.
p61-project/domain/entities/HabitHistory.ts
2024-04-11 12:32:09 +02:00

81 lines
2.4 KiB
TypeScript

import { getISODate, getWeekNumber } from "@/utils/dates"
import type { Habit } from "./Habit"
import type { HabitProgress } from "./HabitProgress"
import type { GoalProgress } from "./Goal"
import { GoalBooleanProgress, GoalNumericProgress } from "./Goal"
export interface HabitHistoryJSON {
habit: Habit
progressHistory: HabitProgress[]
}
export class HabitHistory implements HabitHistoryJSON {
public habit: Habit
private _progressHistory: HabitProgress[] = []
public constructor(options: HabitHistoryJSON) {
const { habit, progressHistory } = options
this.habit = habit
this.progressHistory = progressHistory
}
/**
* Progress History sorted chronologically (from old to most recent progress at the end).
*/
public get progressHistory(): HabitProgress[] {
return this._progressHistory
}
public set progressHistory(progressHistory: HabitProgress[]) {
this._progressHistory = [...progressHistory]
this._progressHistory.sort((a, b) => {
return a.date.getTime() - b.date.getTime()
})
}
public getProgressesByDate(date: Date): HabitProgress[] {
return this._progressHistory.filter((progress) => {
if (this.habit.goal.frequency === "monthly") {
return (
date.getFullYear() === progress.date.getFullYear() &&
date.getMonth() === progress.date.getMonth()
)
}
if (this.habit.goal.frequency === "weekly") {
return (
getWeekNumber(date) === getWeekNumber(progress.date) &&
date.getFullYear() === progress.date.getFullYear()
)
}
if (this.habit.goal.frequency === "daily") {
return getISODate(date) === getISODate(progress.date)
}
return false
})
}
public getGoalProgressByDate(date: Date): GoalProgress {
const progresses = this.getProgressesByDate(date)
if (this.habit.goal.isBoolean()) {
const lastSavedProgress = progresses[progresses.length - 1]
return new GoalBooleanProgress({
goal: this.habit.goal,
progress: lastSavedProgress?.goalProgress?.isCompleted() ?? false,
})
}
if (this.habit.goal.isNumeric()) {
return new GoalNumericProgress({
goal: this.habit.goal,
progress: progresses.reduce((sum, current) => {
const goalProgress = current.goalProgress as GoalNumericProgress
return sum + goalProgress.progress
}, 0),
})
}
throw new Error("Invalid")
}
}