use anyhow::Result;
use rust_decimal::Decimal;
use sqlx::{PgPool, Row};
use uuid::Uuid;
use backbone_orm::org_scope;
use crate::domain::entity::DeliveryNoteItem;
pub const TABLE_NAME: &str = "inventory.delivery_note_items";
pub struct DeliveryNoteItemRepository(
backbone_orm::GenericCrudRepository<DeliveryNoteItem, backbone_orm::SoftDelete>,
);
impl std::ops::Deref for DeliveryNoteItemRepository {
type Target = backbone_orm::GenericCrudRepository<DeliveryNoteItem, backbone_orm::SoftDelete>;
fn deref(&self) -> &Self::Target { &self.0 }
}
impl DeliveryNoteItemRepository {
pub fn new(pool: PgPool) -> Self {
Self(backbone_orm::GenericCrudRepository::new(pool, TABLE_NAME))
}
}
pub struct NewDeliveryItemRow {
pub id: Uuid,
pub delivery_id: Uuid,
pub item_id: Uuid,
pub quantity: Decimal,
}
pub struct DeliveryItemRow {
pub id: Uuid,
pub item_id: Uuid,
pub quantity: Decimal,
}
pub struct DeliveryCancelItemRow {
pub item_id: Uuid,
pub quantity: Decimal,
pub cogs_amount: Decimal,
}
impl DeliveryNoteItemRepository {
pub async fn insert_item(
&self,
conn: &mut sqlx::PgConnection,
l: &NewDeliveryItemRow,
) -> Result<(), sqlx::Error> {
sqlx::query(
r#"INSERT INTO inventory.delivery_note_items (id, delivery_id, item_id, quantity, valuation_rate, cogs_amount)
VALUES ($1,$2,$3,$4,0,0)"#,
)
.bind(l.id).bind(l.delivery_id).bind(l.item_id).bind(l.quantity)
.execute(conn)
.await?;
Ok(())
}
pub async fn fetch_items(
&self,
pool: &PgPool,
delivery_id: Uuid,
) -> Result<Vec<DeliveryItemRow>, sqlx::Error> {
let rows = org_scope::fetch_all_rows_scoped(
pool,
sqlx::query(
r#"SELECT id, item_id, quantity FROM inventory.delivery_note_items
WHERE delivery_id=$1 AND (metadata->>'deleted_at') IS NULL ORDER BY id"#,
)
.bind(delivery_id),
)
.await?;
Ok(rows.iter().map(|it| DeliveryItemRow {
id: it.get("id"), item_id: it.get("item_id"), quantity: it.get("quantity"),
}).collect())
}
pub async fn update_valuation(
&self,
conn: &mut sqlx::PgConnection,
line_id: Uuid,
valuation_rate: Decimal,
cogs_amount: Decimal,
) -> Result<(), sqlx::Error> {
sqlx::query("UPDATE inventory.delivery_note_items SET valuation_rate=$2, cogs_amount=$3 WHERE id=$1")
.bind(line_id).bind(valuation_rate).bind(cogs_amount)
.execute(conn)
.await?;
Ok(())
}
pub async fn fetch_cancel_items(
&self,
pool: &PgPool,
delivery_id: Uuid,
) -> Result<Vec<DeliveryCancelItemRow>, sqlx::Error> {
let rows = org_scope::fetch_all_rows_scoped(
pool,
sqlx::query(
r#"SELECT item_id, quantity, cogs_amount FROM inventory.delivery_note_items
WHERE delivery_id=$1 AND (metadata->>'deleted_at') IS NULL ORDER BY id"#,
)
.bind(delivery_id),
)
.await?;
Ok(rows.iter().map(|it| DeliveryCancelItemRow {
item_id: it.get("item_id"), quantity: it.get("quantity"), cogs_amount: it.get("cogs_amount"),
}).collect())
}
}
backbone_core::impl_crud_repository!(DeliveryNoteItemRepository, DeliveryNoteItem, soft_delete);