cdb/src/variant.rs

140 lines
4 KiB
Rust
Raw Normal View History

2024-05-03 16:22:59 +00:00
use mongodb::bson::doc;
use crate::{
2024-05-10 08:56:07 +00:00
cache::InventoryCache,
2024-05-03 16:22:59 +00:00
cdb_col, get_mongo,
transaction::{BatchTransaction, Price, Transaction},
};
/// 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-05-06 06:24:23 +00:00
#[derive(Debug, Clone)]
2024-05-03 16:22:59 +00:00
pub struct Variant {
pub item: String,
pub variant: String,
2024-05-06 06:24:23 +00:00
pub amount: u64,
2024-05-10 08:56:07 +00:00
pub depends: Vec<String>,
2024-05-03 16:22:59 +00:00
}
impl Variant {
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")
.map(|x| x.as_u64().unwrap())
.unwrap_or(1),
2024-05-10 08:56:07 +00:00
depends: json
.as_mapping()
.unwrap()
.get("depends")
.map(|x| {
x.as_sequence()
.unwrap()
.into_iter()
.map(|x| x.as_str().unwrap().to_string())
.collect()
})
.unwrap_or(Vec::new()),
2024-05-06 06:24:23 +00:00
}
}
2024-05-03 16:22:59 +00:00
pub async fn demand(&self, uuid: &str, price: Price, destination: String) -> Option<String> {
let db = get_mongo!();
// check if supply transaction exists
let supply_t = cdb_col!(db, "supply");
if supply_t
.find_one(doc! { "_id": uuid }, None)
.await
.unwrap()
.is_none()
{
return None;
}
// todo : demand batch
// mark as used
let demand_t = cdb_col!(db, "demand");
demand_t
.insert_one(
doc! {
"_id": uuid,
"destination": destination,
"price": price.as_bson()
},
None,
)
.await
.unwrap();
Some(uuid.to_string())
}
/// Records a supply transaction in the database.
///
/// # Arguments
///
/// * `amount` - The quantity of items supplied.
/// * `price` - The price of the supplied items.
/// * `origin` - The origin or source of the supplied items.
///
/// # Returns
///
/// Returns a UUID string representing the transaction.
pub async fn supply(&self, amount: usize, price: Price, origin: &str) -> String {
let db = get_mongo!();
let col: mongodb::Collection<mongodb::bson::Document> =
2024-05-10 09:03:34 +00:00
db.database("cdb").collection("supply");
2024-05-03 16:22:59 +00:00
let mut transactions = vec![];
for _ in 0..amount {
transactions.push(Transaction::new(
&self.item,
&self.variant,
price.clone(),
origin,
));
}
for transaction in &transactions {
2024-05-10 09:03:34 +00:00
let r = col.insert_one(transaction.as_doc(), None).await.unwrap();
2024-05-10 08:56:07 +00:00
// update cache
2024-05-10 09:03:34 +00:00
InventoryCache::push(&transaction.uuid).await;
2024-05-03 16:22:59 +00:00
}
// batch transaction
let ret_uuid = if amount == 1 {
transactions.first().unwrap().uuid.clone()
} else {
let batch =
BatchTransaction::new(transactions.iter().map(|x| x.uuid.clone()).collect());
2024-05-10 09:03:34 +00:00
let col: mongodb::Collection<mongodb::bson::Document> =
db.database("cdb").collection("transactions_batch");
col.insert_one(batch.as_doc(), None).await.unwrap();
2024-05-03 16:22:59 +00:00
batch.uuid
};
ret_uuid
}
2024-05-10 08:56:07 +00:00
pub fn as_bson(&self) -> mongodb::bson::Document {
mongodb::bson::doc! {
"item": &self.item,
"variant": &self.variant,
"amount": self.amount as u32,
"depends": &self.depends
}
}
2024-05-03 16:22:59 +00:00
}