summary refs log tree commit diff stats
path: root/src/api
diff options
context:
space:
mode:
authorBenedikt Peetz <benedikt.peetz@b-peetz.de>2025-10-25 02:15:31 +0200
committerBenedikt Peetz <benedikt.peetz@b-peetz.de>2025-10-25 02:15:31 +0200
commit3a0e91bda1e93afa33dd182c2e820c94b3e94593 (patch)
tree436fb1b1e1b0bbe450436ccb5e105b8bea8db17f /src/api
parentfeat(treewide): Make usage more intuitive (diff)
downloadweb-client-3a0e91bda1e93afa33dd182c2e820c94b3e94593.zip
feat(treewide): Add further buttons
The register product > associate barcode > buy barcode workflow is now
usable.

The only missing features for an MVP are unit and unit property
creation.
Diffstat (limited to 'src/api')
-rw-r--r--src/api/mod.rs171
1 files changed, 89 insertions, 82 deletions
diff --git a/src/api/mod.rs b/src/api/mod.rs
index bc800fb..3bc870c 100644
--- a/src/api/mod.rs
+++ b/src/api/mod.rs
@@ -1,103 +1,110 @@
-use leptos::{
-    error::Error,
-    prelude::{Read, expect_context},
-};
-use reactive_stores::Store;
+use leptos::error::Error;
 use rocie_client::{
     apis::{
         api_get_inventory_api::amount_by_id,
         api_get_product_api::{
-            product_by_id, product_by_name, product_suggestion_by_name, products,
+            product_by_id, product_by_name, product_suggestion_by_name, products_in_storage,
+            products_registered,
         },
         api_get_unit_api::unit_by_id,
-        api_get_unit_property_api::unit_property_by_id,
+        api_get_unit_property_api::{unit_properties, unit_property_by_id},
         api_set_barcode_api::buy_barcode,
+        api_set_product_api::{associate_barcode, register_product},
         configuration::Configuration,
     },
     models::{
-        BarcodeId, Product, ProductAmount, ProductId, Unit, UnitId, UnitProperty, UnitPropertyId,
+        Barcode, BarcodeId, Product, ProductAmount, ProductId, ProductStub, Unit, UnitId,
+        UnitProperty, UnitPropertyId,
     },
 };
 
-use crate::{ConfigState, ConfigStateStoreFields};
+macro_rules! get_config {
+    () => {{
+        use crate::ConfigStateStoreFields;
+        use leptos::prelude::Read;
 
-pub(crate) async fn get_amount_by_id(product_id: ProductId) -> Result<ProductAmount, Error> {
-    let config = expect_context::<Store<ConfigState>>();
-    amount_by_id(&config.config().read(), product_id)
-        .await
-        .map_err(Into::<Error>::into)
-}
-pub(crate) async fn get_product_by_id(product_id: ProductId) -> Result<Product, Error> {
-    let config = expect_context::<Store<ConfigState>>();
-    product_by_id(&config.config().read(), product_id)
-        .await
-        .map_err(Into::<Error>::into)
-}
-pub(crate) async fn get_product_by_name(
-    name: String,
-) -> Result<
-    Product,
-    rocie_client::apis::Error<rocie_client::apis::api_get_product_api::ProductByNameError>,
-> {
-    let config = expect_context::<Store<ConfigState>>();
-    product_by_name(&config.config().read(), &name).await
-}
-pub(crate) async fn get_products_by_part_name(part_name: String) -> Result<Vec<Product>, Error> {
-    let config = expect_context::<Store<ConfigState>>();
-    product_suggestion_by_name(&config.config().read(), &part_name)
-        .await
-        .map_err(Into::<Error>::into)
-}
-pub(crate) async fn get_unit_by_id(unit_id: UnitId) -> Result<Unit, Error> {
-    let config = expect_context::<Store<ConfigState>>();
-    unit_by_id(&config.config().read(), unit_id)
-        .await
-        .map_err(Into::<Error>::into)
-}
-pub(crate) async fn get_unit_property_by_id(
-    unit_id: UnitPropertyId,
-) -> Result<UnitProperty, Error> {
-    let config = expect_context::<Store<ConfigState>>();
-    unit_property_by_id(&config.config().read(), unit_id)
-        .await
-        .map_err(Into::<Error>::into)
+        let config =
+            leptos::prelude::expect_context::<reactive_stores::Store<crate::ConfigState>>();
+        config.config().read()
+    }};
 }
 
-pub(crate) async fn get_full_product_by_id(
-    id: ProductId,
-) -> Result<(Product, ProductAmount, Unit), Error> {
-    let amount = get_amount_by_id(id).await?;
-    let product = get_product_by_id(id).await?;
-    let unit = get_unit_by_id(amount.amount.unit).await?;
+pub(crate) use get_config;
 
-    Ok::<_, Error>((product, amount, unit))
-}
-pub(crate) async fn get_product_unit_by_id(
-    id: ProductId,
-) -> Result<(Product, UnitProperty), Error> {
-    let product = get_product_by_id(id).await?;
-    let unit = get_unit_property_by_id(product.unit_property).await?;
+macro_rules! mk_wrapper {
+    (
+        $orig:ident($($arg_name:ident : $arg_type:ty),*) -> $output_type:ty
+        as $new_name:ident
+    ) => {
+        pub(crate) async fn $new_name(
+            $($arg_name : $arg_type),*
+        ) -> Result<$output_type, Error> {
+            let config = get_config!();
 
-    Ok::<_, Error>((product, unit))
-}
+            $orig(&config, $($arg_name),*)
+                .await
+                .map_err(Into::<Error>::into)
+        }
+    };
 
-pub(crate) async fn get_products() -> Result<Vec<Product>, Error> {
-    let config = expect_context::<Store<ConfigState>>();
-    products(&config.config().read())
-        .await
-        .map_err(Into::<Error>::into)
-}
+    (
+        @treat_404_as_None
+        $orig:ident($($arg_name:ident : $arg_type:ty),*) -> Option<$output_type:ty>
+        as $new_name:ident
+    ) => {
+        pub(crate) async fn $new_name(
+            $($arg_name : $arg_type),*
+        ) -> Result<Option<$output_type>, Error> {
+            let config = get_config!();
 
-pub(crate) async fn buy_barcode_wrapper(
-    config: &Configuration,
-    barcode_number: u32,
-) -> Result<(), Error> {
-    buy_barcode(
-        config,
-        BarcodeId {
-            value: barcode_number,
-        },
-    )
-    .await
-    .map_err(Into::<Error>::into)
+            match $orig(&config, $($arg_name),*).await
+            {
+                Ok(ok) => Ok::<_, leptos::error::Error>(Some(ok)),
+                Err(err) => match err {
+                    rocie_client::apis::Error::ResponseError(ref response_content) => {
+                        match response_content.status.as_u16() {
+                            404 => Ok(None),
+                            _ => Err(err.into()),
+                        }
+                    }
+                    err => Err(err.into()),
+                },
+            }
+        }
+    };
+
+    (
+        @external_config
+        $orig:ident(&config, $($arg_name:ident : $arg_type:ty),*) -> $output_type:ty
+        as $new_name:ident
+    ) => {
+        pub(crate) async fn $new_name(
+            config: &Configuration,
+            $($arg_name : $arg_type),*
+        ) -> Result<$output_type, Error> {
+            $orig(config, $($arg_name),*)
+                .await
+                .map_err(Into::<Error>::into)
+        }
+    }
 }
+
+mk_wrapper!(product_by_id(product_id: ProductId) -> Product as product_by_id_wrapped);
+
+mk_wrapper!(@treat_404_as_None product_by_name(name: &str) -> Option<Product> as product_by_name_404_wrapped);
+mk_wrapper!(@external_config product_by_name(&config, name: &str) -> Product as product_by_name_external_wrapped);
+
+mk_wrapper!(product_suggestion_by_name(part_name: &str) -> Vec<Product> as product_suggestion_by_name_wrapped);
+
+mk_wrapper!(unit_by_id(unit_id: UnitId) -> Unit as unit_by_id_wrapped);
+mk_wrapper!(unit_property_by_id(unit_id: UnitPropertyId) -> UnitProperty as unit_property_by_id_wrapped);
+mk_wrapper!(unit_properties() -> Vec<UnitProperty> as unit_properties_wrapped);
+
+mk_wrapper!(amount_by_id(product_id: ProductId) -> ProductAmount as amount_by_id_wrapped);
+
+mk_wrapper!(products_registered() -> Vec<Product> as products_registered_wrapped);
+mk_wrapper!(products_in_storage() -> Vec<Product> as products_in_storage_wrapped);
+
+mk_wrapper!(@external_config buy_barcode(&config, barcode_number: BarcodeId, times: u32) -> () as buy_barcode_external_wrapped);
+mk_wrapper!(@external_config register_product(&config, product_stub: ProductStub) -> ProductId as register_product_external_wrapped);
+mk_wrapper!(@external_config associate_barcode(&config, id: ProductId, barcode: Barcode) -> () as associate_barcode_external_wrapped);