use crate::{
database::Result,
entities::{
Client, Company, DateTime, Duration, Invoice, Job, NaiveDate, RunningWork, Tag, Work,
Worker,
},
};
use std::collections::HashMap;
pub(crate) trait JobberCreate {
fn create_company<T>(&mut self, f: impl FnOnce(&mut Company) -> Result<T>) -> Result<T>;
fn create_worker<T>(&mut self, id: &str, f: impl FnOnce(&mut Worker) -> Result<T>)
-> Result<T>;
fn create_client<T>(&mut self, id: &str, f: impl FnOnce(&mut Client) -> Result<T>)
-> Result<T>;
fn create_job<T>(
&mut self,
pos: Option<usize>,
f: impl FnOnce(&mut Job) -> Result<T>,
) -> Result<T>;
fn create_tag<T>(&mut self, name: &str, f: impl FnOnce(&mut Tag) -> Result<T>) -> Result<T>;
fn create_invoice(
&mut self,
job_ids: impl Iterator<Item = usize>,
subject: Option<String>,
until: Option<NaiveDate>,
) -> Result<usize>;
}
pub(crate) trait JobberDelete {
fn delete_company(&mut self) -> Result<()>;
fn delete_worker(&mut self, id: &str, delete: bool) -> Result<()>;
fn delete_client(&mut self, id: &str, delete: bool) -> Result<()>;
fn delete_job(&mut self, id: usize, delete: bool) -> Result<()>;
fn delete_tag(&mut self, id: &str, delete: bool) -> Result<()>;
fn delete_invoice(&mut self, id: usize, delete: bool) -> Result<()>;
fn delete_work(&mut self, job_id: usize, work_pos: usize, delete: bool) -> Result<()>;
}
pub(crate) trait JobberGet {
fn get_company(&self) -> Result<&Company>;
fn get_worker(&self, id: &str) -> Result<&Worker>;
fn get_client(&self, id: &str) -> Result<&Client>;
fn get_job(&self, pos: usize) -> Result<&Job>;
fn get_tag(&self, name: &str) -> Result<&Tag>;
fn get_tags(&self) -> &HashMap<String, Tag>;
fn get_invoice(&self, no: usize) -> Result<&Invoice>;
fn get_full_client_name(&self, id: &str) -> Result<String> {
Ok(format!("{} ({})", self.get_client(id)?.address.name, id))
}
fn get_full_worker_name(&self, id: &str) -> Result<String> {
Ok(format!("{} ({})", self.get_worker(id)?.full_name, id))
}
}
pub(crate) trait JobberEdit {
fn edit_company<T>(&mut self, f: impl FnOnce(&mut Company) -> Result<T>) -> Result<T>;
fn edit_worker<T>(&mut self, id: &str, f: impl FnOnce(&mut Worker) -> Result<T>) -> Result<T>;
fn edit_client<T>(&mut self, id: &str, f: impl FnOnce(&mut Client) -> Result<T>) -> Result<T>;
fn edit_job<T>(&mut self, pos: usize, f: impl FnOnce(&mut Job) -> Result<T>) -> Result<T>;
fn edit_tag<T>(&mut self, name: &str, f: impl FnOnce(&mut Tag) -> Result<T>) -> Result<T>;
}
pub(crate) trait JobberWork {
fn start_work(
&mut self,
job: usize,
start: DateTime,
subject: Option<impl ToString>,
tags: impl IntoIterator<Item = impl ToString>,
) -> Result<RunningWork>;
fn end_work(
&mut self,
job: usize,
end: DateTime,
subject: Mod<impl ToString>,
tags: impl IntoIterator<Item = impl ToString>,
) -> Result<Work>;
fn add_work(
&mut self,
job: usize,
start: DateTime,
end: DateTime,
subject: impl ToString,
tags: impl IntoIterator<Item = impl ToString>,
) -> Result<Work>;
fn cancel_work(&mut self, job: usize) -> Result<RunningWork>;
fn sort(&mut self, job_id: usize) -> Result<()>;
fn duration_by_worker(&self, worker_id: impl ToString) -> Duration;
fn duration_by_client(&self, client_id: impl ToString) -> Duration;
fn duration_by_day(&self, job_id: Option<usize>, day: DateTime) -> Duration;
fn work_range(&self, job_id: &Option<usize>, deleted: Deleted) -> (DateTime, DateTime);
}
#[derive(Copy, Clone)]
pub(crate) enum Deleted {
No,
Yes,
All,
}
impl From<bool> for Deleted {
fn from(value: bool) -> Self {
match value {
true => Self::Yes,
false => Self::No,
}
}
}
impl Deleted {
pub(crate) fn check(&self, deleted: bool) -> bool {
match self {
Deleted::No => !deleted,
Deleted::Yes => deleted,
Deleted::All => true,
}
}
}
pub(crate) trait JobberIter {
fn iter_workers(&self, deleted: Deleted) -> impl Iterator<Item = (&String, &Worker)>;
fn iter_clients(&self, deleted: Deleted) -> impl Iterator<Item = (&String, &Client)>;
fn iter_jobs(&self, deleted: Deleted) -> impl Iterator<Item = (usize, &Job)>;
fn iter_tags(&self, deleted: Deleted) -> impl Iterator<Item = (&String, &Tag)>;
fn iter_invoices(&self, deleted: Deleted) -> impl Iterator<Item = (usize, &Invoice)>;
}
pub(crate) trait Jobber:
JobberCreate + JobberDelete + JobberGet + JobberEdit + JobberWork + JobberIter
{
}
pub(crate) enum Mod<T = String> {
None,
Set(T),
Replace(T),
Append(T),
}