use crate::entities::{DateTime, Duration, Error, Job, Money, Result, Scheme, Work};
use derive_more::Deref;
use serde::{Deserialize, Serialize};
#[derive(Debug, Deref, derive_more::DerefMut, Clone, Default, Serialize, Deserialize)]
pub(crate) struct Bill {
pub(crate) worker: String,
pub(crate) subject: String,
#[deref]
#[deref_mut]
pub(crate) work: Vec<Work>,
pub(crate) scheme: Scheme,
pub(crate) deleted: bool,
}
impl Bill {
pub(crate) fn worked(&self) -> Duration {
self.scheme
.measure_work(self.work.iter().map(|work| &work.work_time))
}
pub(crate) fn revenue(&self) -> Result<Money> {
self.scheme.measure_revenue(self.worked())
}
}
pub(crate) trait Billable {
fn bill(&mut self, job_id: usize, until: Option<DateTime>) -> Result<Bill>;
}
impl Billable for Job {
fn bill(&mut self, job_id: usize, until: Option<DateTime>) -> Result<Bill> {
let work_time: Vec<_> = self
.work
.extract_if(.., |w| {
if let Some(until) = until {
w.end() < until
} else {
true
}
})
.collect();
Ok(Bill {
worker: self.worker.clone(),
subject: self.subject.clone(),
work: work_time,
scheme: if let Some(scheme) = &self.scheme {
scheme.clone()
} else {
return Err(Error::JobMissingScheme(job_id));
},
deleted: false,
})
}
}