use anyhow::Result;
use chrono::NaiveDate;
use sqlx::PgPool;
use uuid::Uuid;
use backbone_orm::org_scope;
use crate::domain::entity::MaintenanceSchedule;
pub const TABLE_NAME: &str = "maintenance.maintenance_schedules";
pub struct MaintenanceScheduleRepository(
backbone_orm::GenericCrudRepository<MaintenanceSchedule, backbone_orm::SoftDelete>,
);
impl std::ops::Deref for MaintenanceScheduleRepository {
type Target = backbone_orm::GenericCrudRepository<MaintenanceSchedule, backbone_orm::SoftDelete>;
fn deref(&self) -> &Self::Target { &self.0 }
}
impl MaintenanceScheduleRepository {
pub fn new(pool: PgPool) -> Self {
Self(backbone_orm::GenericCrudRepository::new(pool, TABLE_NAME))
}
}
pub struct NewScheduleRow<'a> {
pub id: Uuid,
pub asset_id: Uuid,
pub name: &'a str,
pub interval_days: i32,
pub next_due_date: NaiveDate,
}
impl MaintenanceScheduleRepository {
pub async fn insert_schedule(
&self,
pool: &PgPool,
s: &NewScheduleRow<'_>,
) -> Result<(), sqlx::Error> {
org_scope::execute_scoped(
pool,
sqlx::query(
r#"INSERT INTO maintenance.maintenance_schedules
(id, asset_id, name, interval_days, next_due_date, status)
VALUES ($1,$2,$3,$4,$5,'active')"#,
)
.bind(s.id).bind(s.asset_id).bind(s.name)
.bind(s.interval_days).bind(s.next_due_date),
)
.await?;
Ok(())
}
pub async fn advance_next_due(
&self,
conn: &mut sqlx::PgConnection,
schedule_id: Uuid,
performed_date: NaiveDate,
) -> Result<(), sqlx::Error> {
sqlx::query(
r#"UPDATE maintenance.maintenance_schedules
SET next_due_date = ($2::date + make_interval(days => interval_days))::date
WHERE id=$1 AND status='active' AND (metadata->>'deleted_at') IS NULL"#,
)
.bind(schedule_id).bind(performed_date)
.execute(conn)
.await?;
Ok(())
}
}
backbone_core::impl_crud_repository!(MaintenanceScheduleRepository, MaintenanceSchedule, soft_delete);