use crate::cli::parser::Commands;
use crate::core::add::AddLogic;
use crate::db::pool::DbPool;
use crate::errors::{AppError, AppResult};
use crate::models::location::Location;
use crate::utils::date;
use crate::utils::time::parse_optional_time;
use chrono::NaiveDate;
fn validate_sickleave_args(
pos: Location,
date: Option<NaiveDate>, to: Option<NaiveDate>,
) -> Result<Option<(NaiveDate, NaiveDate)>, AppError> {
let d = match date {
Some(d) => d,
None => return Ok(None), };
match pos {
Location::SickLeave => {
let t = to.unwrap_or(d);
if d > t {
return Err(AppError::InvalidDateRange { from: d, to: t });
}
Ok(Some((d, t)))
}
_ => {
if to.is_some() {
return Err(AppError::InvalidArgs(
"--to can only be used with --pos s".into(),
));
}
Ok(None)
}
}
}
pub fn handle(cmd: &Commands, cfg: &crate::config::Config) -> AppResult<()> {
if let Commands::Add {
date,
pos,
start,
lunch,
work_gap,
no_work_gap,
end,
edit_pair,
edit,
to,
} = cmd
{
let pos_final = match pos {
Some(code) => Location::from_code(code).ok_or_else(|| {
AppError::InvalidPosition(format!(
"Invalid location code '{}'. Use a valid code such as 'office', 'remote', 'customer', ...",
code
))
})?,
None => Location::Office,
};
let d = date::parse_date(date).map_err(|_| AppError::InvalidDate(date.to_string()))?;
let start_parsed = parse_optional_time(start.as_ref())?;
let end_parsed = parse_optional_time(end.as_ref())?;
let lunch_opt = *lunch;
let mut pool = DbPool::new(&cfg.database)?;
let work_gap: Option<bool> = if *work_gap {
Some(true)
} else if *no_work_gap {
Some(false)
} else {
None
};
let sick_range = validate_sickleave_args(pos_final, Some(d), *to)?;
match sick_range {
Some((_from_date, to_date)) => {
if start_parsed.is_some() || end_parsed.is_some() {
return Err(AppError::InvalidArgs(
"--in/--out cannot be used with --pos s (use only --to)".into(),
));
}
AddLogic::apply(
cfg,
&mut pool,
d,
pos_final,
None,
None,
None,
None,
*edit,
*edit_pair,
Some(to_date),
pos.clone(),
)?;
}
None => {
AddLogic::apply(
cfg,
&mut pool,
d,
pos_final,
start_parsed,
lunch_opt,
work_gap,
end_parsed,
*edit,
*edit_pair,
None,
pos.clone(),
)?;
}
}
}
Ok(())
}