2024-07-24 14:38:56 +00:00
|
|
|
use mongod::Model;
|
2024-05-03 16:22:59 +00:00
|
|
|
use mongodb::bson::doc;
|
2024-07-24 14:38:56 +00:00
|
|
|
use serde::{Deserialize, Serialize};
|
2024-06-22 00:05:22 +00:00
|
|
|
use serde_json::json;
|
2024-05-03 16:22:59 +00:00
|
|
|
|
2024-07-24 14:38:56 +00:00
|
|
|
use crate::transaction::{Consumed, Price, Transaction};
|
2024-05-03 16:22:59 +00:00
|
|
|
|
|
|
|
/// Represents a specific instance of an item with potential variations.
|
|
|
|
///
|
|
|
|
/// This struct is used to describe a particular variation or instance of an item
|
|
|
|
/// in the real world. It may include attributes or properties that deviate from
|
|
|
|
/// the standard definition of the item. For example, different colors, sizes, or
|
|
|
|
/// configurations.
|
2024-07-24 14:38:56 +00:00
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
2024-05-03 16:22:59 +00:00
|
|
|
pub struct Variant {
|
2024-05-10 09:59:05 +00:00
|
|
|
/// Associated Item
|
2024-05-03 16:22:59 +00:00
|
|
|
pub item: String,
|
2024-05-10 09:59:05 +00:00
|
|
|
/// Variant Name
|
2024-05-03 16:22:59 +00:00
|
|
|
pub variant: String,
|
2024-05-10 09:59:05 +00:00
|
|
|
/// Amount of items this variant represents
|
2024-05-06 06:24:23 +00:00
|
|
|
pub amount: u64,
|
2024-05-10 09:59:05 +00:00
|
|
|
/// Dependencies for the item variant.
|
2024-05-10 08:56:07 +00:00
|
|
|
pub depends: Vec<String>,
|
2024-05-03 16:22:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Variant {
|
2024-05-10 09:59:05 +00:00
|
|
|
/// Create variant from itemdb yaml
|
2024-05-06 06:24:23 +00:00
|
|
|
pub fn from_yml(json: &serde_yaml::Value, variant: &str, item: &str) -> Self {
|
|
|
|
Self {
|
|
|
|
item: item.to_string(),
|
|
|
|
variant: variant.to_string(),
|
|
|
|
amount: json
|
|
|
|
.as_mapping()
|
|
|
|
.unwrap()
|
|
|
|
.get("amount")
|
2024-06-21 19:14:45 +00:00
|
|
|
.map_or(1, |x| x.as_u64().unwrap()),
|
2024-05-10 08:56:07 +00:00
|
|
|
depends: json
|
|
|
|
.as_mapping()
|
|
|
|
.unwrap()
|
|
|
|
.get("depends")
|
|
|
|
.map(|x| {
|
|
|
|
x.as_sequence()
|
|
|
|
.unwrap()
|
2024-06-21 19:14:45 +00:00
|
|
|
.iter()
|
2024-05-10 08:56:07 +00:00
|
|
|
.map(|x| x.as_str().unwrap().to_string())
|
|
|
|
.collect()
|
|
|
|
})
|
2024-06-21 19:14:45 +00:00
|
|
|
.unwrap_or_default(),
|
2024-05-06 06:24:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-05-10 09:59:05 +00:00
|
|
|
pub async fn supply_log(&self) -> Vec<String> {
|
|
|
|
let filter = doc! {
|
|
|
|
"item": &self.item,
|
|
|
|
"variant": &self.variant
|
|
|
|
};
|
|
|
|
|
2024-08-13 02:13:38 +00:00
|
|
|
let result = Transaction::find_partial(filter, json!({}), None)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
2024-05-10 09:59:05 +00:00
|
|
|
|
|
|
|
let mut ret = Vec::new();
|
|
|
|
|
|
|
|
for doc in result {
|
2024-07-24 14:38:56 +00:00
|
|
|
ret.push(doc._id);
|
2024-05-10 09:59:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ret
|
|
|
|
}
|
|
|
|
|
2024-08-13 02:13:38 +00:00
|
|
|
pub async fn inventory(&self) -> Vec<Transaction> {
|
|
|
|
let filter = doc! {
|
|
|
|
"item": &self.item,
|
|
|
|
"variant": &self.variant,
|
|
|
|
"consumed": { "$exists": false }
|
|
|
|
};
|
|
|
|
|
|
|
|
Transaction::find(filter, None).await.unwrap()
|
|
|
|
}
|
|
|
|
|
2024-05-10 09:59:05 +00:00
|
|
|
pub async fn demand_log(&self) -> Vec<String> {
|
|
|
|
let filter = doc! {
|
|
|
|
"item": &self.item,
|
2024-07-24 14:38:56 +00:00
|
|
|
"variant": &self.variant,
|
|
|
|
"consumed": { "$exists": true }
|
2024-05-10 09:59:05 +00:00
|
|
|
};
|
|
|
|
|
2024-08-13 02:13:38 +00:00
|
|
|
let result = Transaction::find_partial(filter, json!({}), None)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
2024-05-10 09:59:05 +00:00
|
|
|
|
|
|
|
let mut ret = Vec::new();
|
|
|
|
|
|
|
|
for doc in result {
|
2024-07-24 14:38:56 +00:00
|
|
|
ret.push(doc._id);
|
2024-05-10 09:59:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ret
|
|
|
|
}
|
|
|
|
|
2024-07-24 14:38:56 +00:00
|
|
|
pub async fn demand(uuid: &str, price: Price, destination: &str) -> Option<()> {
|
|
|
|
// check if transaction exists
|
|
|
|
let mut t = Transaction::get(uuid).await?;
|
|
|
|
t.update(&json!({
|
|
|
|
"consumed": Consumed{ destination: destination.to_string(), price }
|
2024-08-13 02:13:38 +00:00
|
|
|
}))
|
|
|
|
.await
|
|
|
|
.ok()?;
|
2024-07-24 14:38:56 +00:00
|
|
|
|
|
|
|
Some(())
|
2024-05-03 16:22:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Records a supply transaction in the database.
|
|
|
|
///
|
|
|
|
/// # Arguments
|
|
|
|
///
|
|
|
|
/// * `price` - The price of the supplied items.
|
|
|
|
/// * `origin` - The origin or source of the supplied items.
|
|
|
|
///
|
|
|
|
/// # Returns
|
|
|
|
///
|
|
|
|
/// Returns a UUID string representing the transaction.
|
2024-07-24 14:38:56 +00:00
|
|
|
pub async fn supply(&self, price: Price, origin: Option<&str>) -> String {
|
|
|
|
let t = Transaction::new(&self.item, &self.variant, price, origin);
|
2024-05-03 16:22:59 +00:00
|
|
|
|
2024-07-24 14:38:56 +00:00
|
|
|
t.insert().await.unwrap();
|
2024-05-10 08:56:07 +00:00
|
|
|
|
2024-07-24 14:38:56 +00:00
|
|
|
t._id
|
2024-05-03 16:22:59 +00:00
|
|
|
}
|
2024-05-10 08:56:07 +00:00
|
|
|
|
2024-06-22 00:05:22 +00:00
|
|
|
pub fn api_json(&self) -> serde_json::Value {
|
|
|
|
json!({
|
|
|
|
"item": self.item,
|
|
|
|
"variant": self.variant,
|
|
|
|
"amount": self.amount as u32,
|
|
|
|
"depends": self.depends
|
|
|
|
})
|
|
|
|
}
|
2024-05-03 16:22:59 +00:00
|
|
|
}
|