use anyhow::Result;
use rust_decimal::Decimal;
use sqlx::{PgPool, Row};
use uuid::Uuid;
use backbone_orm::company_scope::fetch_all_rows_scoped;
use crate::domain::entity::SalaryComponent;
pub const TABLE_NAME: &str = "payroll.salary_components";
pub struct SalaryComponentRepository(
backbone_orm::GenericCrudRepository<SalaryComponent, backbone_orm::SoftDelete>,
);
impl std::ops::Deref for SalaryComponentRepository {
type Target = backbone_orm::GenericCrudRepository<SalaryComponent, backbone_orm::SoftDelete>;
fn deref(&self) -> &Self::Target { &self.0 }
}
impl SalaryComponentRepository {
pub fn new(pool: PgPool) -> Self {
Self(backbone_orm::GenericCrudRepository::new(pool, TABLE_NAME))
}
}
pub struct NewComponentRow<'a> {
pub id: Uuid,
pub structure_id: Uuid,
pub name: &'a str,
pub component_type: &'a str,
pub amount: Decimal,
pub gl_account_id: Uuid,
}
pub struct ComponentRow {
pub name: String,
pub component_type: String,
pub amount: Decimal,
pub gl_account_id: Uuid,
}
impl SalaryComponentRepository {
pub async fn insert_component(
&self,
conn: &mut sqlx::PgConnection,
c: &NewComponentRow<'_>,
) -> Result<(), sqlx::Error> {
sqlx::query(
r#"INSERT INTO payroll.salary_components
(id, structure_id, name, component_type, amount, gl_account_id)
VALUES ($1,$2,$3,$4::component_type,$5,$6)"#,
)
.bind(c.id).bind(c.structure_id).bind(c.name).bind(c.component_type)
.bind(c.amount).bind(c.gl_account_id)
.execute(conn)
.await?;
Ok(())
}
pub async fn list_by_structure(
&self,
pool: &PgPool,
structure_id: Uuid,
) -> Result<Vec<ComponentRow>, sqlx::Error> {
let rows = fetch_all_rows_scoped(
pool,
sqlx::query(
"SELECT name, component_type::text AS ct, amount, gl_account_id FROM payroll.salary_components WHERE structure_id=$1")
.bind(structure_id),
)
.await?;
Ok(rows.iter().map(|r| ComponentRow {
name: r.get("name"), component_type: r.get("ct"), amount: r.get("amount"),
gl_account_id: r.get("gl_account_id"),
}).collect())
}
}
backbone_core::impl_crud_repository!(SalaryComponentRepository, SalaryComponent, soft_delete);