use sqlx::PgPool;
use uuid::Uuid;
use backbone_orm::org_scope;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum GlVoucher {
PurchaseReceipt,
DeliveryNote,
StockReconciliation,
LandedCost,
}
impl GlVoucher {
fn table(self) -> &'static str {
match self {
GlVoucher::PurchaseReceipt => "purchase_receipts",
GlVoucher::DeliveryNote => "delivery_notes",
GlVoucher::StockReconciliation => "stock_reconciliations",
GlVoucher::LandedCost => "landed_costs",
}
}
}
pub struct GlSettlementState {
pub posting_state: String,
pub journal_id: Option<Uuid>,
pub accounting_post_id: Option<Uuid>,
}
pub struct GlVoucherRepository;
impl Default for GlVoucherRepository {
fn default() -> Self { Self::new() }
}
impl GlVoucherRepository {
pub fn new() -> Self { Self }
pub async fn mark_posted(
&self,
pool: &PgPool,
voucher: GlVoucher,
voucher_id: Uuid,
journal_id: Uuid,
post_id: Uuid,
) -> Result<(), sqlx::Error> {
let sql = format!(
"UPDATE inventory.{} SET posting_state='posted'::gl_posting_state, journal_id=$2, accounting_post_id=$3, posted_at=now() WHERE id=$1 AND posting_state <> 'posted'::gl_posting_state",
voucher.table(),
);
org_scope::execute_scoped(
pool,
sqlx::query(&sql).bind(voucher_id).bind(journal_id).bind(post_id),
)
.await?;
Ok(())
}
pub async fn mark_failed(
&self,
pool: &PgPool,
voucher: GlVoucher,
voucher_id: Uuid,
) -> Result<(), sqlx::Error> {
let sql = format!(
"UPDATE inventory.{} SET posting_state='failed'::gl_posting_state WHERE id=$1",
voucher.table(),
);
org_scope::execute_scoped(pool, sqlx::query(&sql).bind(voucher_id)).await?;
Ok(())
}
pub async fn mark_reversal_posted(
&self,
pool: &PgPool,
voucher: GlVoucher,
voucher_id: Uuid,
journal_id: Uuid,
post_id: Uuid,
) -> Result<(), sqlx::Error> {
let sql = format!(
"UPDATE inventory.{} SET reversal_journal_id=$2, reversal_accounting_post_id=$3 WHERE id=$1",
voucher.table(),
);
org_scope::execute_scoped(
pool,
sqlx::query(&sql).bind(voucher_id).bind(journal_id).bind(post_id),
)
.await?;
Ok(())
}
pub async fn mark_not_applicable(
&self,
pool: &PgPool,
voucher: GlVoucher,
voucher_id: Uuid,
) -> Result<(), sqlx::Error> {
let sql = format!(
"UPDATE inventory.{} SET posting_state='not_applicable'::gl_posting_state WHERE id=$1",
voucher.table(),
);
org_scope::execute_scoped(pool, sqlx::query(&sql).bind(voucher_id)).await?;
Ok(())
}
}