diff --git a/src/flow.rs b/src/core/flow.rs similarity index 100% rename from src/flow.rs rename to src/core/flow.rs diff --git a/src/item.rs b/src/core/item.rs similarity index 94% rename from src/item.rs rename to src/core/item.rs index a407b4a..65c182e 100644 --- a/src/item.rs +++ b/src/core/item.rs @@ -35,6 +35,7 @@ pub struct Item { pub variants: HashMap, } +/// Get the path of an image file in `path` pub fn get_image(path: &std::path::Path) -> Option { let parent = path.parent()?; let file_name = path.file_stem()?.to_str()?; @@ -120,12 +121,14 @@ impl Item { self.variants.get(variant).cloned() } + /// Get all active `Transaction`s of this `Item` not yet consumed pub async fn inventory(&self) -> Vec { sqlx::query_as("SELECT * FROM transactions WHERE item = $1 AND consumed_timestamp IS NULL ORDER BY created DESC") .bind(&self.id) .fetch_all(get_pg!()).await.unwrap() } + /// Get all active `Transaction`s of this `Item` not yet consumed of `origin` pub async fn inventory_by_origin(&self, origin: &str) -> Vec { sqlx::query_as("SELECT * FROM transactions WHERE item = $1 AND consumed_timestamp IS NULL AND origin = $2 ORDER BY created DESC") .bind(&self.id) @@ -133,6 +136,7 @@ impl Item { .fetch_all(get_pg!()).await.unwrap() } + /// Get all active `Transaction`s of this `Item` not yet consumed of `destination` pub async fn consumed_by_destination(&self, destination: &str) -> Vec { sqlx::query_as("SELECT * FROM transactions WHERE item = $1 AND consumed_timestamp IS NOT NULL AND destination = $2 ORDER BY created DESC") .bind(&self.id) diff --git a/src/location.rs b/src/core/location.rs similarity index 100% rename from src/location.rs rename to src/core/location.rs diff --git a/src/core/mod.rs b/src/core/mod.rs new file mode 100644 index 0000000..1761011 --- /dev/null +++ b/src/core/mod.rs @@ -0,0 +1,5 @@ +pub mod flow; +pub mod item; +pub mod location; +pub mod transaction; +pub mod variant; diff --git a/src/transaction.rs b/src/core/transaction.rs similarity index 96% rename from src/transaction.rs rename to src/core/transaction.rs index 5c2c71a..2b95645 100644 --- a/src/transaction.rs +++ b/src/core/transaction.rs @@ -54,14 +54,17 @@ impl Transaction { .fetch_one(get_pg!()).await.unwrap() } + /// Get a reference to the `Item` of the `Transaction` pub async fn item(&self) -> Option<&Item> { get_itemdb!().get_item(&self.item) } + /// Get a reference to the `Variant` of the `Item` of the `Transaction` pub async fn item_variant(&self) -> Option { get_itemdb!().get_item(&self.item)?.variant(&self.variant) } + /// Get a `Transaction` via `id` pub async fn get(id: &uuid::Uuid) -> Option { sqlx::query_as("SELECT * FROM transactions WHERE id = $1") .bind(id) @@ -203,7 +206,7 @@ impl ToAPI for Transaction { "timestamp": self.created.timestamp(), "consumed": consumed, "note": self.note, - "expired": self.is_expired().await + "expired": self.is_expired().await, }) } } diff --git a/src/variant.rs b/src/core/variant.rs similarity index 96% rename from src/variant.rs rename to src/core/variant.rs index 692b44a..e14628b 100644 --- a/src/variant.rs +++ b/src/core/variant.rs @@ -104,6 +104,8 @@ impl Variant { } } + /// Get a API id for this Item Variant. + /// The ID has the format: `::` pub fn item_variant_id(&self) -> String { format!("{}::{}", self.item, self.variant) } @@ -189,6 +191,7 @@ impl Variant { .unwrap() } + /// Get Transactions within `year` and `month` pub async fn get_transaction_timeslice(&self, year: i32, month: u32) -> Vec { let (start, end) = timestamp_range(year, month); @@ -198,6 +201,7 @@ impl Variant { .fetch_all(get_pg!()).await.unwrap() } + /// Get all unique origins pub async fn get_unique_origins(&self) -> Vec { let res: Vec<(String,)> = sqlx::query_as("SELECT DISTINCT(origin) FROM transactions WHERE origin NOT LIKE 'flow::%' AND item = $1 AND variant = $2") .bind(&self.item) @@ -206,6 +210,7 @@ impl Variant { res.into_iter().map(|x| x.0).collect() } + /// Get all unique destinations pub async fn get_unique_destinations(&self) -> Vec { let res: Vec<(String,)> = sqlx::query_as("SELECT DISTINCT(destination) FROM transactions WHERE destination NOT LIKE 'flow::%' AND item = $1 AND variant = $2") .bind(&self.item) @@ -214,6 +219,7 @@ impl Variant { res.into_iter().map(|x| x.0).collect() } + /// Get the last `limit` price values for `origin` pub async fn price_history_by_origin(&self, origin: &str, limit: Option) -> Vec { let res: Vec<(f64,)> = sqlx::query_as( &format!("SELECT price FROM transactions WHERE item = $1 AND variant = $2 AND origin = $3 ORDER BY created DESC {}", if let Some(limit) = limit { @@ -227,6 +233,7 @@ impl Variant { res.into_iter().map(|x| x.0).collect() } + /// Get the latest price for `origin` pub async fn get_latest_price(&self, origin: Option) -> f64 { if let Some(origin) = origin { let res: (f64,) = sqlx::query_as("SELECT price FROM transactions WHERE item = $1 AND variant = $2 AND origin = $3 ORDER BY created DESC LIMIT 1") @@ -257,6 +264,7 @@ impl Variant { (false, 0) } + /// Check if the `Variant` satisfies `StorageConditions` pub async fn satisfy_condition(&self, conditions: &StorageConditions) -> bool { if let Some(needs) = &self.needs { if let Some(room_temp) = conditions.accurate_temperature().await { @@ -346,7 +354,8 @@ impl Variant { "name": self.name, "min": self.min, "expiry": self.expiry, - "barcodes": self.barcodes + "barcodes": self.barcodes, + "needs": self.needs }) } } diff --git a/src/main.rs b/src/main.rs index 67779c0..b97670f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,15 +7,16 @@ use rocket::{http::Method, launch}; use tokio::sync::OnceCell; mod config; +mod core; mod db; -mod flow; mod integrity; -mod item; mod json_store; -mod location; +pub use core::flow; +pub use core::item; +pub use core::location; +pub use core::transaction; +pub use core::variant; mod routes; -mod transaction; -mod variant; pub static PG: OnceCell = OnceCell::const_new();