♻️ refactor + location conditions
This commit is contained in:
parent
ce9cdc4256
commit
3076ebe6a0
19 changed files with 1228 additions and 520 deletions
|
@ -1,19 +1,19 @@
|
|||
use rocket::{get, post, serde::json::Json, State};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::json;
|
||||
use std::{collections::HashMap, str::FromStr};
|
||||
|
||||
use crate::{
|
||||
check_auth,
|
||||
config::Config,
|
||||
flow::{Flow, FlowInfo, FlowNote},
|
||||
get_pg,
|
||||
json_store::JSONStore,
|
||||
routes::{api_error, vec_to_api, FallibleApiResponse, ToAPI, Token},
|
||||
routes::{FallibleApiResponse, Token, api_error},
|
||||
transaction::Transaction,
|
||||
};
|
||||
use based::request::api::{ToAPI, vec_to_api};
|
||||
use rocket::{State, get, post, serde::json::Json};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::json;
|
||||
use std::{collections::HashMap, str::FromStr};
|
||||
|
||||
use super::{item::SupplyForm, ApiError};
|
||||
use super::{ApiError, item::SupplyForm};
|
||||
|
||||
#[get("/flow/<id>/info")]
|
||||
pub async fn flow_info(
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
use std::str::FromStr;
|
||||
|
||||
use rocket::serde::json::Json;
|
||||
use rocket::{get, post, State};
|
||||
use serde::Deserialize;
|
||||
use serde_json::json;
|
||||
|
||||
use crate::config::{Config, Webhook};
|
||||
use crate::routes::{ToAPI, Token};
|
||||
use crate::routes::Token;
|
||||
use crate::variant::Variant;
|
||||
use crate::{check_auth, get_itemdb};
|
||||
use crate::{
|
||||
db::ItemDB,
|
||||
routes::{api_error, FallibleApiResponse},
|
||||
routes::{FallibleApiResponse, api_error},
|
||||
};
|
||||
use based::request::api::ToAPI;
|
||||
use rocket::serde::json::Json;
|
||||
use rocket::{State, get, post};
|
||||
use serde::Deserialize;
|
||||
use serde_json::json;
|
||||
|
||||
use super::{item_does_not_exist_error, variant_does_not_exist_error};
|
||||
|
||||
|
@ -23,8 +23,8 @@ pub struct DemandForm {
|
|||
price: f64,
|
||||
}
|
||||
|
||||
/// Consumes a Transaction with Price and Destination
|
||||
#[post("/demand", data = "<f>")]
|
||||
/// Consumes a Transaction with Price and Destination
|
||||
pub async fn demand_route(f: Json<DemandForm>, t: Token, c: &State<Config>) -> FallibleApiResponse {
|
||||
check_auth!(t, c);
|
||||
|
||||
|
@ -66,8 +66,8 @@ pub async fn demand_route(f: Json<DemandForm>, t: Token, c: &State<Config>) -> F
|
|||
Ok(json!({"ok": 1}))
|
||||
}
|
||||
|
||||
/// Returns all consumed transactions for Item Variant
|
||||
#[get("/item/<item_id>/<variant_id>/demand?<destination>")]
|
||||
/// Returns all consumed transactions for Item Variant
|
||||
pub async fn demand_log_route(
|
||||
item_id: &str,
|
||||
variant_id: &str,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::routes::{api_error, ApiError};
|
||||
use crate::routes::{ApiError, api_error};
|
||||
|
||||
pub fn item_does_not_exist_error() -> ApiError {
|
||||
api_error("The item does not exist")
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use rocket::{get, State};
|
||||
use serde_json::json;
|
||||
|
||||
use crate::{
|
||||
check_auth,
|
||||
config::Config,
|
||||
json_store::JSONStore,
|
||||
location::Location,
|
||||
routes::{api_error, vec_to_api, FallibleApiResponse, ToAPI, Token},
|
||||
routes::{FallibleApiResponse, Token, api_error},
|
||||
transaction::Transaction,
|
||||
};
|
||||
use based::request::api::{ToAPI, vec_to_api};
|
||||
use rocket::{State, get};
|
||||
use serde_json::json;
|
||||
|
||||
#[get("/location/<id>")]
|
||||
pub async fn location_info(
|
||||
|
@ -27,6 +27,42 @@ pub async fn location_info(
|
|||
Ok(loc.api().await)
|
||||
}
|
||||
|
||||
#[get("/location/<id>/warn")]
|
||||
/// API route returning affected items on a condition mismatch
|
||||
pub async fn location_condition_warn(
|
||||
id: &str,
|
||||
locations: &State<JSONStore<Location>>,
|
||||
t: Token,
|
||||
c: &State<Config>,
|
||||
) -> FallibleApiResponse {
|
||||
check_auth!(t, c);
|
||||
|
||||
let loc = locations
|
||||
.get(id)
|
||||
.ok_or_else(|| api_error("No location with that ID"))?;
|
||||
|
||||
let transactions = Transaction::in_location(&loc.id).await;
|
||||
|
||||
let mut ret = Vec::new();
|
||||
|
||||
for t in transactions {
|
||||
if let Some(item) = t.item_variant().await {
|
||||
if !item
|
||||
.satisfy_condition(
|
||||
loc.conditions
|
||||
.as_ref()
|
||||
.ok_or(api_error("Location has no conditions"))?,
|
||||
)
|
||||
.await
|
||||
{
|
||||
ret.push(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(json!(vec_to_api(&ret).await))
|
||||
}
|
||||
|
||||
/// Resolve locations children recursively
|
||||
async fn location_api_resolve(
|
||||
id: &str,
|
||||
|
|
|
@ -6,6 +6,7 @@ mod supply;
|
|||
|
||||
use std::str::FromStr;
|
||||
|
||||
use based::request::api::ToAPI;
|
||||
pub use demand::*;
|
||||
pub use error::*;
|
||||
pub use location::*;
|
||||
|
@ -17,25 +18,24 @@ use serde::Serialize;
|
|||
pub use stat::*;
|
||||
pub use supply::*;
|
||||
|
||||
use rocket::get;
|
||||
use rocket::State;
|
||||
use rocket::get;
|
||||
use serde_json::json;
|
||||
|
||||
use crate::check_auth;
|
||||
use crate::config::Config;
|
||||
use crate::db::get_items_without_min_satisfied;
|
||||
use crate::db::ItemDB;
|
||||
use crate::db::get_items_without_min_satisfied;
|
||||
use crate::get_locations;
|
||||
use crate::get_pg;
|
||||
use crate::routes::ToAPI;
|
||||
use crate::routes::Token;
|
||||
use crate::transaction::Transaction;
|
||||
|
||||
use super::api_error;
|
||||
use crate::routes::FallibleApiResponse;
|
||||
|
||||
/// Returns a JSON response with all items in the database.
|
||||
#[get("/items")]
|
||||
/// Returns a JSON response with all items in the database.
|
||||
pub fn get_items_route(itemdb: &State<ItemDB>, t: Token, c: &State<Config>) -> FallibleApiResponse {
|
||||
check_auth!(t, c);
|
||||
|
||||
|
@ -47,8 +47,8 @@ pub fn get_items_route(itemdb: &State<ItemDB>, t: Token, c: &State<Config>) -> F
|
|||
Ok(json!({"items": items}))
|
||||
}
|
||||
|
||||
/// Return an API Response for an `Item`
|
||||
#[get("/item/<item_id>")]
|
||||
/// Return an API Response for an `Item`
|
||||
pub fn item_route(
|
||||
item_id: &str,
|
||||
itemdb: &State<ItemDB>,
|
||||
|
@ -74,8 +74,8 @@ pub async fn item_image_route(item_id: &str, itemdb: &State<ItemDB>) -> Option<N
|
|||
None
|
||||
}
|
||||
|
||||
/// Returns all variants of an Item
|
||||
#[get("/item/<item_id>/variants")]
|
||||
/// Returns all variants of an Item
|
||||
pub fn item_variants_page(
|
||||
item_id: &str,
|
||||
itemdb: &State<ItemDB>,
|
||||
|
@ -112,8 +112,8 @@ pub async fn transaction_route(
|
|||
Ok(t.api().await)
|
||||
}
|
||||
|
||||
/// Returns unique values for a field
|
||||
#[get("/item/<item_id>/<variant_id>/unique?<field>")]
|
||||
/// Returns unique values for a field
|
||||
pub async fn unique_field_route(
|
||||
item_id: &str,
|
||||
variant_id: &str,
|
||||
|
@ -131,23 +131,28 @@ pub async fn unique_field_route(
|
|||
.ok_or_else(variant_does_not_exist_error)?;
|
||||
|
||||
match field {
|
||||
"origin" => Ok(json!(variant
|
||||
.get_unique_origins()
|
||||
.await
|
||||
.into_iter()
|
||||
.filter(|x| !x.starts_with("flow::"))
|
||||
.collect::<Vec<_>>())),
|
||||
"destination" => Ok(json!(variant
|
||||
.get_unique_destinations()
|
||||
.await
|
||||
.into_iter()
|
||||
.filter(|x| !x.starts_with("flow::"))
|
||||
.collect::<Vec<_>>())),
|
||||
"origin" => Ok(json!(
|
||||
variant
|
||||
.get_unique_origins()
|
||||
.await
|
||||
.into_iter()
|
||||
.filter(|x| !x.starts_with("flow::"))
|
||||
.collect::<Vec<_>>()
|
||||
)),
|
||||
"destination" => Ok(json!(
|
||||
variant
|
||||
.get_unique_destinations()
|
||||
.await
|
||||
.into_iter()
|
||||
.filter(|x| !x.starts_with("flow::"))
|
||||
.collect::<Vec<_>>()
|
||||
)),
|
||||
_ => Err(api_error("Unknown field")),
|
||||
}
|
||||
}
|
||||
|
||||
#[get("/items/expired?<days>")]
|
||||
/// Get all expired transactions
|
||||
pub async fn expired_items_route(
|
||||
days: Option<&str>,
|
||||
t: Token,
|
||||
|
@ -169,6 +174,7 @@ pub async fn expired_items_route(
|
|||
}
|
||||
|
||||
#[get("/items/min")]
|
||||
/// Return all items without minimum satisfied
|
||||
pub async fn min_items_route(
|
||||
itemdb: &State<ItemDB>,
|
||||
t: Token,
|
||||
|
@ -197,6 +203,7 @@ pub struct MoveTransaction {
|
|||
}
|
||||
|
||||
#[post("/transaction/<id>/move", data = "<form>")]
|
||||
/// Move a transaction to a new location
|
||||
pub async fn move_transaction_route(id: &str, form: Json<MoveTransaction>) -> FallibleApiResponse {
|
||||
let new_loc = &form.to;
|
||||
let locations = get_locations!();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rocket::{get, State};
|
||||
use rocket::{State, get};
|
||||
use serde_json::json;
|
||||
|
||||
use crate::check_auth;
|
||||
|
@ -6,7 +6,7 @@ use crate::config::Config;
|
|||
use crate::routes::Token;
|
||||
use crate::{
|
||||
db::ItemDB,
|
||||
routes::{api_error, FallibleApiResponse},
|
||||
routes::{FallibleApiResponse, api_error},
|
||||
};
|
||||
|
||||
use super::{item_does_not_exist_error, variant_does_not_exist_error};
|
||||
|
@ -48,11 +48,13 @@ pub async fn variant_price_latest_by_origin(
|
|||
.variant(variant_id)
|
||||
.ok_or_else(variant_does_not_exist_error)?;
|
||||
|
||||
Ok(json!(variant
|
||||
.price_history_by_origin(origin, Some(1))
|
||||
.await
|
||||
.first()
|
||||
.unwrap()))
|
||||
Ok(json!(
|
||||
variant
|
||||
.price_history_by_origin(origin, Some(1))
|
||||
.await
|
||||
.first()
|
||||
.unwrap()
|
||||
))
|
||||
}
|
||||
|
||||
#[get("/items/stat")]
|
||||
|
@ -73,7 +75,7 @@ pub async fn item_stat_route(
|
|||
let item_var = itemdb.get_item(&item).unwrap().variant(var).unwrap();
|
||||
for t in item_var.inventory().await {
|
||||
transaction_count += 1;
|
||||
total_price += t.price;
|
||||
total_price += t.price.unwrap_or_default();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
use rocket::serde::json::Json;
|
||||
use rocket::{get, post, State};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::json;
|
||||
|
||||
use crate::check_auth;
|
||||
use crate::config::{Config, Webhook};
|
||||
use crate::routes::{vec_to_api, ToAPI, Token};
|
||||
use crate::routes::Token;
|
||||
use crate::{
|
||||
db::ItemDB,
|
||||
routes::{api_error, FallibleApiResponse},
|
||||
routes::{FallibleApiResponse, api_error},
|
||||
};
|
||||
use based::request::api::{ToAPI, vec_to_api};
|
||||
use rocket::serde::json::Json;
|
||||
use rocket::{State, get, post};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::json;
|
||||
|
||||
use super::{item_does_not_exist_error, variant_does_not_exist_error};
|
||||
|
||||
|
@ -23,8 +23,8 @@ pub struct SupplyForm {
|
|||
pub note: Option<String>,
|
||||
}
|
||||
|
||||
/// Route for supply action. Creates a new Transaction for the specified Item Variant.
|
||||
#[post("/supply", data = "<form>")]
|
||||
/// Route for supply action. Creates a new Transaction for the specified Item Variant.
|
||||
pub async fn supply_route(
|
||||
form: Json<SupplyForm>,
|
||||
itemdb: &State<ItemDB>,
|
||||
|
@ -57,8 +57,8 @@ pub async fn supply_route(
|
|||
Ok(json!({"uuid": transaction.id}))
|
||||
}
|
||||
|
||||
/// Returns a list of Transaction UUIDs for the Item Variant
|
||||
#[get("/item/<item_id>/<variant_id>/supply")]
|
||||
/// Returns a list of Transaction UUIDs for the Item Variant
|
||||
pub async fn supply_log_route(
|
||||
item_id: &str,
|
||||
variant_id: &str,
|
||||
|
@ -79,8 +79,8 @@ pub async fn supply_log_route(
|
|||
Ok(json!(transactions))
|
||||
}
|
||||
|
||||
/// Returns current active Transactions for Item
|
||||
#[get("/item/<item_id>/inventory?<origin>")]
|
||||
/// Returns current active Transactions for Item
|
||||
pub async fn inventory_route(
|
||||
item_id: &str,
|
||||
itemdb: &State<ItemDB>,
|
||||
|
@ -103,8 +103,8 @@ pub async fn inventory_route(
|
|||
Ok(json!(vec_to_api(&transactions).await))
|
||||
}
|
||||
|
||||
/// Returns current active Transactions for Item Variant
|
||||
#[get("/item/<item_id>/<variant_id>/inventory")]
|
||||
/// Returns current active Transactions for Item Variant
|
||||
pub async fn inventory_route_variant(
|
||||
item_id: &str,
|
||||
variant_id: &str,
|
||||
|
@ -125,8 +125,8 @@ pub async fn inventory_route_variant(
|
|||
Ok(json!(vec_to_api(&transactions).await))
|
||||
}
|
||||
|
||||
/// Returns statistics for the Item Variant
|
||||
#[get("/item/<item_id>/<variant_id>/stat?<full>")]
|
||||
/// Returns statistics for the Item Variant
|
||||
pub async fn variant_stat_route(
|
||||
item_id: &str,
|
||||
variant_id: &str,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use rocket::{
|
||||
http::Status, outcome::Outcome, request::FromRequest, response::status::BadRequest, Request,
|
||||
Request, http::Status, outcome::Outcome, request::FromRequest, response::status::BadRequest,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
|
@ -37,20 +37,3 @@ impl<'r> FromRequest<'r> for Token {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A trait to generate a Model API representation in JSON format.
|
||||
pub trait ToAPI: Sized {
|
||||
/// Generate public API JSON
|
||||
fn api(&self) -> impl std::future::Future<Output = serde_json::Value>;
|
||||
}
|
||||
|
||||
/// Converts a slice of items implementing the `ToAPI` trait into a `Vec` of JSON values.
|
||||
pub async fn vec_to_api(items: &[impl ToAPI]) -> Vec<serde_json::Value> {
|
||||
let mut ret = Vec::with_capacity(items.len());
|
||||
|
||||
for e in items {
|
||||
ret.push(e.api().await);
|
||||
}
|
||||
|
||||
ret
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue