use async_trait::async_trait;
use chrono::NaiveDate;
use rust_decimal::Decimal;
use sqlx::PgPool;
use uuid::Uuid;
#[async_trait]
pub trait OvertimeInputs: Send + Sync {
async fn overtime_stretches(
&self,
employee_id: Uuid,
from: NaiveDate,
to: NaiveDate,
) -> Result<Vec<(NaiveDate, Decimal)>, sqlx::Error>;
}
pub struct PoolOvertimeInputs {
pool: PgPool,
}
impl PoolOvertimeInputs {
pub fn new(pool: PgPool) -> Self {
Self { pool }
}
}
#[async_trait]
impl OvertimeInputs for PoolOvertimeInputs {
async fn overtime_stretches(
&self,
employee_id: Uuid,
from: NaiveDate,
to: NaiveDate,
) -> Result<Vec<(NaiveDate, Decimal)>, sqlx::Error> {
let rows: Vec<(NaiveDate, Decimal)> = sqlx::query_as(
r#"SELECT date,
GREATEST(SUM((time_debt->>'overtime_minutes')::numeric) / 60, 0)
FROM attendance.attendances
WHERE employee_id = $1
AND date BETWEEN $2 AND $3
AND (metadata->>'deleted_at') IS NULL
GROUP BY date"#,
)
.bind(employee_id)
.bind(from)
.bind(to)
.fetch_all(&self.pool)
.await?;
Ok(rows
.into_iter()
.filter(|(_, hours)| *hours > Decimal::ZERO)
.collect())
}
}