use crate::models::activity::{ActivityStatus, ActivityType};
use crate::models::interval::Interval;
use crate::models::task::TaskCompletedToday;
use crate::models::{activity::Activity, budget::TimeBudgetType, calendar::Calendar, goal::Goal};
use crate::technical::error::SchedulerError;
use std::collections::BTreeMap;
pub fn add_budget_min_week_activities(calendar: &Calendar, activities: &mut Vec<Activity>) {
crate::log_debug!("Adding budget min week activities...");
let mut get_to_week_min_budget_activities = vec![];
for budget in &calendar.budgets {
let mut is_min_week_reached = true;
for time_budget in &budget.time_budgets {
if time_budget.time_budget_type != TimeBudgetType::Week {
continue;
}
if time_budget.scheduled < time_budget.min_scheduled {
is_min_week_reached = false;
}
}
if !is_min_week_reached {
for time_budget in &budget.time_budgets {
if time_budget.time_budget_type == TimeBudgetType::Week
&& time_budget.scheduled < time_budget.min_scheduled
{
get_to_week_min_budget_activities.extend(
Activity::get_activities_to_get_min_week_budget(
budget,
calendar,
time_budget,
),
);
}
}
}
}
crate::log_dbg!(&get_to_week_min_budget_activities);
activities.extend(get_to_week_min_budget_activities);
}
pub fn add_budget_top_up_week_activities(calendar: &Calendar, activities: &mut Vec<Activity>) {
crate::log_debug!("Adding budget top up week activities...");
let mut top_up_activities = vec![];
for budget in &calendar.budgets {
let mut max_per_week = 0;
for time_budget in &budget.time_budgets {
if time_budget.time_budget_type == TimeBudgetType::Week
&& time_budget.scheduled != time_budget.max_scheduled
{
max_per_week = time_budget.max_scheduled;
}
}
for time_budget in &budget.time_budgets {
if time_budget.time_budget_type == TimeBudgetType::Period
&& time_budget.min_scheduled < time_budget.max_scheduled
&& time_budget.scheduled < time_budget.max_scheduled
{
top_up_activities.extend(Activity::get_activities_to_top_up_week_budget(
budget,
calendar,
time_budget,
max_per_week,
));
}
}
}
crate::log_dbg!(&top_up_activities);
activities.extend(top_up_activities);
}
pub(crate) fn add_simple_activities(
calendar: &mut Calendar,
goals: &BTreeMap<String, Goal>,
activities: &mut Vec<Activity>,
) -> Result<(), SchedulerError> {
crate::log_debug!("Adding simple activities...");
let mut simple_activities = vec![];
for goal in goals.values() {
if goal.min_duration.is_none() {
continue;
};
simple_activities.extend(Activity::get_simple_activities(goal, calendar));
}
activities.extend(simple_activities);
Ok(())
}
pub(crate) fn add_budget_min_day_activities(
calendar: &mut Calendar,
activities: &mut Vec<Activity>,
) {
crate::log_debug!("Adding budget min day/period activities...");
let mut min_day_activities = vec![];
for budget in &calendar.budgets {
for time_budget in &budget.time_budgets {
if time_budget.time_budget_type == TimeBudgetType::Week {
continue;
}
if time_budget.scheduled < time_budget.min_scheduled {
min_day_activities.extend(Activity::get_activities_to_get_to_min_day_budget(
budget,
calendar,
time_budget,
));
}
}
}
crate::log_dbg!(&min_day_activities);
activities.extend(min_day_activities);
}
pub(crate) fn add_tasks_completed_today(
calendar: &Calendar,
goals: &BTreeMap<String, Goal>,
tasks_completed_today: &[TaskCompletedToday],
activities: &mut Vec<Activity>,
) {
crate::log_debug!("Adding tasks completed today...");
for task in tasks_completed_today {
let Some(goal) = goals.get(&task.goalid) else {
continue;
};
let start_index = calendar.get_index_of(task.start);
let end_index = calendar.get_index_of(task.deadline);
let duration = end_index.saturating_sub(start_index);
if duration == 0 {
continue;
}
activities.push(Activity {
goal_id: goal.id.clone(),
activity_type: ActivityType::SimpleGoal,
title: goal.title.clone(),
min_block_size: duration,
max_block_size: duration,
total_duration: duration,
duration_left: duration,
status: ActivityStatus::Unprocessed,
start: task.start,
deadline: Some(task.deadline),
compatible_intervals: vec![Interval {
start: start_index,
end: end_index,
}],
incompatible_intervals: vec![],
flex: Some(1),
});
}
}