quanta + properties
Some checks failed
ci/woodpecker/push/build Pipeline failed

This commit is contained in:
JMARyA 2025-05-18 22:30:18 +02:00
parent 91d39a4d83
commit 16353c7683
Signed by: jmarya
GPG key ID: 901B2ADDF27C2263
8 changed files with 123 additions and 86 deletions

View file

@ -121,6 +121,8 @@ impl Flow {
Some(&format!("flow::{}::{}", self.kind, self.id)),
info.location.as_ref().map(|x| x.as_str()),
info.note.as_ref().map(|x| x.as_str()),
info.quanta,
info.properties.clone()
)
.await;
ret.entry(item.item_variant_id().clone())

View file

@ -96,7 +96,7 @@ impl Item {
for (variant_id, variant) in variants_lst {
variants.insert(
variant_id.as_str().unwrap().to_string(),
Variant::from_yml(&variant, variant_id.as_str().unwrap(), &id),
Variant::from_yml(variant, variant_id.as_str().unwrap(), &id),
);
}

View file

@ -25,6 +25,10 @@ pub struct Transaction {
pub location: Option<String>,
/// Notes on Transaction
pub note: Option<String>,
/// Qantized Unit
pub quanta: Option<i64>,
/// Custom properties
pub properties: Option<serde_json::Value>,
/// Timestamp of the Transaction
pub created: chrono::DateTime<chrono::Utc>,
/// Destination of the Item or who consumed it
@ -35,6 +39,18 @@ pub struct Transaction {
pub consumed_timestamp: Option<chrono::DateTime<chrono::Utc>>,
}
// TODO : typed origins / dests
pub enum Origin {
Flow(String),
Custom(String)
}
pub enum Destination {
Flow(String),
Custom(String)
}
impl Transaction {
pub async fn new(
item: &str,
@ -43,14 +59,18 @@ impl Transaction {
origin: Option<&str>,
location: Option<&str>,
note: Option<&str>,
quanta: Option<i64>,
properties: Option<serde_json::Value>
) -> Self {
sqlx::query_as("INSERT INTO transactions (item, variant, price, origin, location, note) VALUES ($1, $2, $3, $4, $5, $6) RETURNING *")
sqlx::query_as("INSERT INTO transactions (item, variant, price, origin, location, note, quanta, properties) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING *")
.bind(item)
.bind(variant)
.bind(price)
.bind(origin)
.bind(location)
.bind(note)
.bind(quanta)
.bind(properties)
.fetch_one(get_pg!()).await.unwrap()
}
@ -207,6 +227,8 @@ impl ToAPI for Transaction {
"consumed": consumed,
"note": self.note,
"expired": self.is_expired().await,
"properties": self.properties,
"quanta": self.quanta
})
}
}

View file

@ -47,6 +47,16 @@ pub struct Variant {
pub barcodes: Option<Vec<i64>>,
/// Variant Need Conditions
pub needs: Option<VariantNeedCondition>,
/// Custom fields as JSON object schema
pub meta: Option<serde_json::Value>,
/// Quantifiable
pub unit: Option<Quanta>
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct Quanta {
pub by: String,
pub conversions: HashMap<String, f64>
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
@ -57,51 +67,8 @@ pub struct VariantNeedCondition {
impl Variant {
/// Create variant from itemdb yaml
pub fn from_yml(json: &serde_yaml::Value, variant: &str, item: &str) -> Self {
Self {
item: item.to_string(),
variant: variant.to_string(),
name: json
.as_mapping()
.unwrap()
.get("name")
.unwrap()
.as_str()
.unwrap()
.to_string(),
min: json
.as_mapping()
.unwrap()
.get("min")
.map(|x| x.as_i64().unwrap()),
expiry: json
.as_mapping()
.unwrap()
.get("expiry")
.map(|x| x.as_i64().unwrap()),
barcodes: json.as_mapping().unwrap().get("barcodes").map(|x| {
x.as_sequence()
.unwrap()
.into_iter()
.map(|x| x.as_i64().unwrap())
.collect()
}),
needs: json.as_mapping().unwrap().get("needs").map(|x| {
let temp_range = x
.as_mapping()
.unwrap()
.get("temperature")
.unwrap()
.as_sequence()
.unwrap();
VariantNeedCondition {
temperature: [
temp_range.get(0).unwrap().as_f64().unwrap(),
temp_range.get(1).unwrap().as_f64().unwrap(),
],
}
}),
}
pub fn from_yml(json: serde_yaml::Value, variant: &str, item: &str) -> Self {
serde_yaml::from_value(json).unwrap()
}
/// Get a API id for this Item Variant.
@ -175,8 +142,10 @@ impl Variant {
origin: Option<&str>,
location: Option<&str>,
note: Option<&str>,
quanta: Option<i64>,
properties: Option<serde_json::Value>
) -> Transaction {
Transaction::new(&self.item, &self.variant, price, origin, location, note).await
Transaction::new(&self.item, &self.variant, price, origin, location, note, quanta, properties).await
}
/// Returns all Transactions of this Item Variant

View file

@ -141,44 +141,41 @@ async fn rocket() -> _ {
integrity::verify_integrity(&config, &flows, &locations, &itemdb).await;
rocket::build()
.mount(
"/",
route![
routes::item::get_items_route,
routes::item::item_route,
routes::item::item_variants_page,
routes::item::supply_log_route,
routes::item::demand_log_route,
routes::item::supply_route,
routes::item::demand_route,
routes::item::transaction_route,
routes::item::inventory_route,
routes::item::inventory_route_variant,
routes::item::variant_stat_route,
routes::item::unique_field_route,
routes::item::location_info,
routes::item::locations_info,
routes::item::locations_list,
routes::item::location_inventory,
routes::flow::flow_info,
routes::flow::flows_list,
routes::item::expired_items_route,
routes::item::min_items_route,
routes::item::variant_price_history_by_origin,
routes::flow::end_flow_route,
routes::flow::continue_flow_route,
routes::flow::create_flow_route,
routes::item::location_condition_warn,
routes::item::move_transaction_route,
routes::item::variant_price_latest_by_origin,
routes::item::item_stat_route,
routes::flow::active_flows_route,
routes::flow::flow_api_route,
routes::flow::create_flow_note_route,
routes::flow::flow_notes_route,
routes::item::item_image_route
],
)
.mount("/", route![
routes::item::get_items_route,
routes::item::item_route,
routes::item::item_variants_page,
routes::item::supply_log_route,
routes::item::demand_log_route,
routes::item::supply_route,
routes::item::demand_route,
routes::item::transaction_route,
routes::item::inventory_route,
routes::item::inventory_route_variant,
routes::item::variant_stat_route,
routes::item::unique_field_route,
routes::item::location_info,
routes::item::locations_info,
routes::item::locations_list,
routes::item::location_inventory,
routes::flow::flow_info,
routes::flow::flows_list,
routes::item::expired_items_route,
routes::item::min_items_route,
routes::item::variant_price_history_by_origin,
routes::flow::end_flow_route,
routes::flow::continue_flow_route,
routes::flow::create_flow_route,
routes::item::location_condition_warn,
routes::item::move_transaction_route,
routes::item::variant_price_latest_by_origin,
routes::item::item_stat_route,
routes::flow::active_flows_route,
routes::flow::flow_api_route,
routes::flow::create_flow_note_route,
routes::flow::flow_notes_route,
routes::item::item_image_route
])
.manage(itemdb)
.manage(locations)
.manage(flows)

View file

@ -21,6 +21,8 @@ pub struct SupplyForm {
pub origin: Option<String>,
pub location: Option<String>,
pub note: Option<String>,
pub quanta: Option<i64>,
pub properties: Option<serde_json::Value>
}
#[post("/supply", data = "<form>")]
@ -39,12 +41,16 @@ pub async fn supply_route(
.variant(&form.variant)
.ok_or_else(variant_does_not_exist_error)?;
// TODO : check properties schema
let transaction = variant
.supply(
form.price,
form.origin.as_deref(),
form.location.as_deref(),
form.note.as_deref(),
form.quanta,
form.properties.clone()
)
.await;