diff --git a/src/lib.rs b/src/lib.rs index 01b4fc04..e0ceaa28 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -98,12 +98,14 @@ pub fn run_scheduler( let simple_goal_activities = activity_generator::generate_simple_goal_activities(&calendar, goals); dbg!(&simple_goal_activities); - activity_placer::place(&mut calendar, simple_goal_activities); //generate and place budget goal activities let budget_goal_activities: Vec = activity_generator::generate_budget_goal_activities(&calendar, goals); + dbg!(&budget_goal_activities); dbg!(&calendar); + + activity_placer::place(&mut calendar, simple_goal_activities); activity_placer::place(&mut calendar, budget_goal_activities); calendar.log_impossible_min_day_budgets(); diff --git a/src/models/activity.rs b/src/models/activity.rs index 62ff4a0d..2b57ce81 100644 --- a/src/models/activity.rs +++ b/src/models/activity.rs @@ -196,9 +196,11 @@ impl Activity { // or yield flex 1 or maximum of the set from activity.flex()? }; + let filters_option: Option = calendar.get_filters_for(goal.id.clone()); + let compatible_hours_overlay = Activity::get_compatible_hours_overlay( calendar, - goal.filters.clone(), + filters_option, adjusted_goal_start, adjusted_goal_deadline, goal.not_on.clone(), @@ -227,7 +229,7 @@ impl Activity { goal: &Goal, calendar: &Calendar, ) -> Vec { - if goal.children.is_some() || goal.filters.as_ref().is_none() { + if goal.filters.as_ref().is_none() { return vec![]; } if let Some(config) = &goal.budget_config { diff --git a/src/models/budget.rs b/src/models/budget.rs index 78d88e89..80f4852d 100644 --- a/src/models/budget.rs +++ b/src/models/budget.rs @@ -6,13 +6,18 @@ use std::{ use chrono::{Datelike, Duration}; use serde::Deserialize; -use super::{activity::ActivityType, calendar::Calendar, goal::Goal}; +use super::{ + activity::ActivityType, + calendar::Calendar, + goal::{Filters, Goal}, +}; #[derive(Debug, Clone, Deserialize)] pub struct Budget { pub originating_goal_id: String, pub participating_goals: Vec, pub time_budgets: Vec, + pub time_filters: Filters, } impl Budget { pub fn reduce_for_(&mut self, goal: &str, duration_offset: usize) { diff --git a/src/models/calendar.rs b/src/models/calendar.rs index da13fd52..429e2239 100644 --- a/src/models/calendar.rs +++ b/src/models/calendar.rs @@ -244,6 +244,7 @@ impl Calendar { originating_goal_id: budget_id.clone(), participating_goals: descendants_added, time_budgets: get_time_budgets_from(self, goal), + time_filters: goal.filters.clone().unwrap(), }); continue; } @@ -258,6 +259,7 @@ impl Calendar { originating_goal_id: budget_id.clone(), participating_goals: descendants_added, time_budgets: get_time_budgets_from(self, goal), + time_filters: goal.filters.clone().unwrap(), }); break; } @@ -266,8 +268,8 @@ impl Calendar { if let Some(goal) = goal_map.get(&descendant_of_which_to_add_children) { if let Some(children) = &goal.children { descendants.extend(children.clone()); - descendants_added.push(descendant_of_which_to_add_children); } + descendants_added.push(descendant_of_which_to_add_children); } } } @@ -317,6 +319,15 @@ impl Calendar { } impossible_activities } + + pub(crate) fn get_filters_for(&self, id: String) -> Option { + for budget in self.budgets.iter() { + if budget.participating_goals.contains(&id) { + return Some(budget.time_filters.clone()); + } + } + None + } } impl Debug for Calendar { fn fmt(&self, f: &mut Formatter) -> std::fmt::Result { diff --git a/tests/jsons/stable/budget-with-subgoal/expected.json b/tests/jsons/stable/budget-with-subgoal/expected.json new file mode 100644 index 00000000..9f16214f --- /dev/null +++ b/tests/jsons/stable/budget-with-subgoal/expected.json @@ -0,0 +1,184 @@ +{ + "scheduled": [ + { + "day": "2024-01-08", + "tasks": [ + { + "taskid": 0, + "goalid": "free", + "title": "free", + "duration": 6, + "start": "2024-01-08T00:00:00", + "deadline": "2024-01-08T06:00:00" + }, + { + "taskid": 1, + "goalid": "103b2eff-6ba5-47b5-ad4f-81d8e8ef5998", + "title": "Plan my work week", + "duration": 1, + "start": "2024-01-08T06:00:00", + "deadline": "2024-01-08T07:00:00" + }, + { + "taskid": 2, + "goalid": "678eab49-960e-4519-ad0b-031a2f22aaba", + "title": "Work 💪🏽", + "duration": 7, + "start": "2024-01-08T07:00:00", + "deadline": "2024-01-08T14:00:00" + }, + { + "taskid": 3, + "goalid": "free", + "title": "free", + "duration": 10, + "start": "2024-01-08T14:00:00", + "deadline": "2024-01-09T00:00:00" + } + ] + }, + { + "day": "2024-01-09", + "tasks": [ + { + "taskid": 4, + "goalid": "free", + "title": "free", + "duration": 6, + "start": "2024-01-09T00:00:00", + "deadline": "2024-01-09T06:00:00" + }, + { + "taskid": 5, + "goalid": "678eab49-960e-4519-ad0b-031a2f22aaba", + "title": "Work 💪🏽", + "duration": 8, + "start": "2024-01-09T06:00:00", + "deadline": "2024-01-09T14:00:00" + }, + { + "taskid": 6, + "goalid": "free", + "title": "free", + "duration": 10, + "start": "2024-01-09T14:00:00", + "deadline": "2024-01-10T00:00:00" + } + ] + }, + { + "day": "2024-01-10", + "tasks": [ + { + "taskid": 7, + "goalid": "free", + "title": "free", + "duration": 6, + "start": "2024-01-10T00:00:00", + "deadline": "2024-01-10T06:00:00" + }, + { + "taskid": 8, + "goalid": "678eab49-960e-4519-ad0b-031a2f22aaba", + "title": "Work 💪🏽", + "duration": 8, + "start": "2024-01-10T06:00:00", + "deadline": "2024-01-10T14:00:00" + }, + { + "taskid": 9, + "goalid": "free", + "title": "free", + "duration": 10, + "start": "2024-01-10T14:00:00", + "deadline": "2024-01-11T00:00:00" + } + ] + }, + { + "day": "2024-01-11", + "tasks": [ + { + "taskid": 10, + "goalid": "free", + "title": "free", + "duration": 6, + "start": "2024-01-11T00:00:00", + "deadline": "2024-01-11T06:00:00" + }, + { + "taskid": 11, + "goalid": "678eab49-960e-4519-ad0b-031a2f22aaba", + "title": "Work 💪🏽", + "duration": 8, + "start": "2024-01-11T06:00:00", + "deadline": "2024-01-11T14:00:00" + }, + { + "taskid": 12, + "goalid": "free", + "title": "free", + "duration": 10, + "start": "2024-01-11T14:00:00", + "deadline": "2024-01-12T00:00:00" + } + ] + }, + { + "day": "2024-01-12", + "tasks": [ + { + "taskid": 13, + "goalid": "free", + "title": "free", + "duration": 6, + "start": "2024-01-12T00:00:00", + "deadline": "2024-01-12T06:00:00" + }, + { + "taskid": 14, + "goalid": "678eab49-960e-4519-ad0b-031a2f22aaba", + "title": "Work 💪🏽", + "duration": 8, + "start": "2024-01-12T06:00:00", + "deadline": "2024-01-12T14:00:00" + }, + { + "taskid": 15, + "goalid": "free", + "title": "free", + "duration": 10, + "start": "2024-01-12T14:00:00", + "deadline": "2024-01-13T00:00:00" + } + ] + }, + { + "day": "2024-01-13", + "tasks": [ + { + "taskid": 16, + "goalid": "free", + "title": "free", + "duration": 24, + "start": "2024-01-13T00:00:00", + "deadline": "2024-01-14T00:00:00" + } + ] + }, + { + "day": "2024-01-14", + "tasks": [ + { + "taskid": 17, + "goalid": "free", + "title": "free", + "duration": 24, + "start": "2024-01-14T00:00:00", + "deadline": "2024-01-15T00:00:00" + } + ] + } + ], + "impossible": [] +} \ No newline at end of file diff --git a/tests/jsons/stable/budget-with-subgoal/input.json b/tests/jsons/stable/budget-with-subgoal/input.json new file mode 100644 index 00000000..903126d6 --- /dev/null +++ b/tests/jsons/stable/budget-with-subgoal/input.json @@ -0,0 +1,37 @@ +{ + "startDate": "2024-01-08T00:00:00", + "endDate": "2024-01-15T00:00:00", + "goals": [ + { + "id": "678eab49-960e-4519-ad0b-031a2f22aaba", + "title": "Work 💪🏽", + "filters": { + "afterTime": 6, + "beforeTime": 18, + "onDays": [ + "mon", + "tue", + "wed", + "thu", + "fri" + ] + }, + "createdAt": "2024-01-08T10:59:47.133Z", + "children": [ + "103b2eff-6ba5-47b5-ad4f-81d8e8ef5998" + ], + "budget": { + "minPerDay": 6, + "maxPerDay": 10, + "minPerWeek": 40, + "maxPerWeek": 40 + } + }, + { + "id": "103b2eff-6ba5-47b5-ad4f-81d8e8ef5998", + "title": "Plan my work week", + "createdAt": "2024-01-08T10:59:47.137Z", + "minDuration": 1 + } + ] +} \ No newline at end of file diff --git a/tests/jsons/stable/budget-with-subgoal/observed.json b/tests/jsons/stable/budget-with-subgoal/observed.json new file mode 100644 index 00000000..9f16214f --- /dev/null +++ b/tests/jsons/stable/budget-with-subgoal/observed.json @@ -0,0 +1,184 @@ +{ + "scheduled": [ + { + "day": "2024-01-08", + "tasks": [ + { + "taskid": 0, + "goalid": "free", + "title": "free", + "duration": 6, + "start": "2024-01-08T00:00:00", + "deadline": "2024-01-08T06:00:00" + }, + { + "taskid": 1, + "goalid": "103b2eff-6ba5-47b5-ad4f-81d8e8ef5998", + "title": "Plan my work week", + "duration": 1, + "start": "2024-01-08T06:00:00", + "deadline": "2024-01-08T07:00:00" + }, + { + "taskid": 2, + "goalid": "678eab49-960e-4519-ad0b-031a2f22aaba", + "title": "Work 💪🏽", + "duration": 7, + "start": "2024-01-08T07:00:00", + "deadline": "2024-01-08T14:00:00" + }, + { + "taskid": 3, + "goalid": "free", + "title": "free", + "duration": 10, + "start": "2024-01-08T14:00:00", + "deadline": "2024-01-09T00:00:00" + } + ] + }, + { + "day": "2024-01-09", + "tasks": [ + { + "taskid": 4, + "goalid": "free", + "title": "free", + "duration": 6, + "start": "2024-01-09T00:00:00", + "deadline": "2024-01-09T06:00:00" + }, + { + "taskid": 5, + "goalid": "678eab49-960e-4519-ad0b-031a2f22aaba", + "title": "Work 💪🏽", + "duration": 8, + "start": "2024-01-09T06:00:00", + "deadline": "2024-01-09T14:00:00" + }, + { + "taskid": 6, + "goalid": "free", + "title": "free", + "duration": 10, + "start": "2024-01-09T14:00:00", + "deadline": "2024-01-10T00:00:00" + } + ] + }, + { + "day": "2024-01-10", + "tasks": [ + { + "taskid": 7, + "goalid": "free", + "title": "free", + "duration": 6, + "start": "2024-01-10T00:00:00", + "deadline": "2024-01-10T06:00:00" + }, + { + "taskid": 8, + "goalid": "678eab49-960e-4519-ad0b-031a2f22aaba", + "title": "Work 💪🏽", + "duration": 8, + "start": "2024-01-10T06:00:00", + "deadline": "2024-01-10T14:00:00" + }, + { + "taskid": 9, + "goalid": "free", + "title": "free", + "duration": 10, + "start": "2024-01-10T14:00:00", + "deadline": "2024-01-11T00:00:00" + } + ] + }, + { + "day": "2024-01-11", + "tasks": [ + { + "taskid": 10, + "goalid": "free", + "title": "free", + "duration": 6, + "start": "2024-01-11T00:00:00", + "deadline": "2024-01-11T06:00:00" + }, + { + "taskid": 11, + "goalid": "678eab49-960e-4519-ad0b-031a2f22aaba", + "title": "Work 💪🏽", + "duration": 8, + "start": "2024-01-11T06:00:00", + "deadline": "2024-01-11T14:00:00" + }, + { + "taskid": 12, + "goalid": "free", + "title": "free", + "duration": 10, + "start": "2024-01-11T14:00:00", + "deadline": "2024-01-12T00:00:00" + } + ] + }, + { + "day": "2024-01-12", + "tasks": [ + { + "taskid": 13, + "goalid": "free", + "title": "free", + "duration": 6, + "start": "2024-01-12T00:00:00", + "deadline": "2024-01-12T06:00:00" + }, + { + "taskid": 14, + "goalid": "678eab49-960e-4519-ad0b-031a2f22aaba", + "title": "Work 💪🏽", + "duration": 8, + "start": "2024-01-12T06:00:00", + "deadline": "2024-01-12T14:00:00" + }, + { + "taskid": 15, + "goalid": "free", + "title": "free", + "duration": 10, + "start": "2024-01-12T14:00:00", + "deadline": "2024-01-13T00:00:00" + } + ] + }, + { + "day": "2024-01-13", + "tasks": [ + { + "taskid": 16, + "goalid": "free", + "title": "free", + "duration": 24, + "start": "2024-01-13T00:00:00", + "deadline": "2024-01-14T00:00:00" + } + ] + }, + { + "day": "2024-01-14", + "tasks": [ + { + "taskid": 17, + "goalid": "free", + "title": "free", + "duration": 24, + "start": "2024-01-14T00:00:00", + "deadline": "2024-01-15T00:00:00" + } + ] + } + ], + "impossible": [] +} \ No newline at end of file