Stock almost done
This commit is contained in:
parent
bc80d1329b
commit
e5fb90ae0e
251
Cargo.lock
generated
251
Cargo.lock
generated
@ -103,7 +103,7 @@ dependencies = [
|
||||
"mime",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"rand",
|
||||
"rand 0.8.5",
|
||||
"sha1",
|
||||
"smallvec",
|
||||
"tracing",
|
||||
@ -347,7 +347,7 @@ version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b88d82667eca772c4aa12f0f1348b3ae643424c8876448f3f7bd5787032e234c"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"autocfg 1.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -367,6 +367,15 @@ dependencies = [
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78"
|
||||
dependencies = [
|
||||
"autocfg 1.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
@ -585,6 +594,15 @@ dependencies = [
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cloudabi"
|
||||
version = "0.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "codespan-reporting"
|
||||
version = "0.11.1"
|
||||
@ -649,7 +667,7 @@ dependencies = [
|
||||
"base64",
|
||||
"hmac",
|
||||
"percent-encoding",
|
||||
"rand",
|
||||
"rand 0.8.5",
|
||||
"sha2",
|
||||
"subtle",
|
||||
"time 0.3.16",
|
||||
@ -732,7 +750,7 @@ version = "0.9.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f916dfc5d356b0ed9dae65f1db9fc9770aa2851d2662b988ccf4fe3516e86348"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"autocfg 1.1.0",
|
||||
"cfg-if 1.0.0",
|
||||
"crossbeam-utils",
|
||||
"memoffset",
|
||||
@ -866,7 +884,7 @@ dependencies = [
|
||||
"itertools",
|
||||
"model",
|
||||
"pretty_env_logger",
|
||||
"rand",
|
||||
"rand 0.8.5",
|
||||
"rumqttc",
|
||||
"serde",
|
||||
"sqlx",
|
||||
@ -1090,10 +1108,23 @@ dependencies = [
|
||||
"chrono",
|
||||
"dummy",
|
||||
"http",
|
||||
"rand",
|
||||
"rand 0.8.5",
|
||||
"uuid 1.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fakeit"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "853c484c6a2a2a7e7d5f0d7863b4a64b90875b60cea1ccab68cc4da21c785656"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"libmath",
|
||||
"rand 0.6.5",
|
||||
"simplerand",
|
||||
"uuid 0.8.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "1.8.0"
|
||||
@ -1264,6 +1295,12 @@ dependencies = [
|
||||
"uuid 1.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-cprng"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-zircon"
|
||||
version = "0.3.3"
|
||||
@ -1726,7 +1763,7 @@ version = "1.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"autocfg 1.1.0",
|
||||
"hashbrown",
|
||||
"serde",
|
||||
]
|
||||
@ -1909,6 +1946,15 @@ dependencies = [
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libmath"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dfd3416934a853ae80d5c3b006f632dfcbaf320300c5167e88a469e9ac214502"
|
||||
dependencies = [
|
||||
"rand 0.3.23",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libz-sys"
|
||||
version = "1.1.8"
|
||||
@ -1960,7 +2006,7 @@ version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"autocfg 1.1.0",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
@ -2019,7 +2065,7 @@ version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"autocfg 1.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2105,8 +2151,8 @@ dependencies = [
|
||||
"derive_more",
|
||||
"fake",
|
||||
"password-hash",
|
||||
"rand",
|
||||
"rand_core",
|
||||
"rand 0.8.5",
|
||||
"rand_core 0.6.4",
|
||||
"serde",
|
||||
"sqlx",
|
||||
"sqlx-core",
|
||||
@ -2205,7 +2251,7 @@ version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"autocfg 1.1.0",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
@ -2216,7 +2262,7 @@ version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"autocfg 1.1.0",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
@ -2226,7 +2272,7 @@ version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"autocfg 1.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2303,7 +2349,7 @@ version = "0.9.77"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b03b84c3b2d099b81f0953422b4d4ad58761589d0229b5506356afca05a3670a"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"autocfg 1.1.0",
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
@ -2325,7 +2371,7 @@ dependencies = [
|
||||
"lazy_static",
|
||||
"percent-encoding",
|
||||
"pin-project",
|
||||
"rand",
|
||||
"rand 0.8.5",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
@ -2393,7 +2439,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"opentelemetry_api",
|
||||
"percent-encoding",
|
||||
"rand",
|
||||
"rand 0.8.5",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
@ -2442,7 +2488,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700"
|
||||
dependencies = [
|
||||
"base64ct",
|
||||
"rand_core",
|
||||
"rand_core 0.6.4",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
@ -2626,6 +2672,48 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.3.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand 0.4.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293"
|
||||
dependencies = [
|
||||
"fuchsia-cprng",
|
||||
"libc",
|
||||
"rand_core 0.3.1",
|
||||
"rdrand",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
|
||||
dependencies = [
|
||||
"autocfg 0.1.8",
|
||||
"libc",
|
||||
"rand_chacha 0.1.1",
|
||||
"rand_core 0.4.2",
|
||||
"rand_hc",
|
||||
"rand_isaac",
|
||||
"rand_jitter",
|
||||
"rand_os",
|
||||
"rand_pcg",
|
||||
"rand_xorshift",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
@ -2633,8 +2721,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
"rand_chacha 0.3.1",
|
||||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
|
||||
dependencies = [
|
||||
"autocfg 0.1.8",
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2644,9 +2742,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
|
||||
dependencies = [
|
||||
"rand_core 0.4.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
@ -2656,13 +2769,75 @@ dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_isaac"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_jitter"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_core 0.4.2",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_os"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
|
||||
dependencies = [
|
||||
"cloudabi",
|
||||
"fuchsia-cprng",
|
||||
"libc",
|
||||
"rand_core 0.4.2",
|
||||
"rdrand",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_pcg"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
|
||||
dependencies = [
|
||||
"autocfg 0.1.8",
|
||||
"rand_core 0.4.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_xorshift"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"autocfg 1.1.0",
|
||||
"crossbeam-deque",
|
||||
"either",
|
||||
"rayon-core",
|
||||
@ -2680,6 +2855,15 @@ dependencies = [
|
||||
"num_cpus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rdrand"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.16"
|
||||
@ -3014,7 +3198,7 @@ dependencies = [
|
||||
"gloo-utils",
|
||||
"indexmap",
|
||||
"js-sys",
|
||||
"rand",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"uuid 1.2.1",
|
||||
@ -3171,13 +3355,22 @@ version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62ac7f900db32bf3fd12e0117dd3dc4da74bc52ebaac97f39668446d89694803"
|
||||
|
||||
[[package]]
|
||||
name = "simplerand"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70455a0a21cb984df0f86033ca19f37cced497deb779603e7fa7b032f5b8897b"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"autocfg 1.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3297,7 +3490,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"paste",
|
||||
"percent-encoding",
|
||||
"rand",
|
||||
"rand 0.8.5",
|
||||
"rust_decimal",
|
||||
"rustls",
|
||||
"rustls-pemfile 1.0.1",
|
||||
@ -3365,7 +3558,7 @@ dependencies = [
|
||||
"db-utils",
|
||||
"derive_more",
|
||||
"dotenv",
|
||||
"fake",
|
||||
"fakeit",
|
||||
"futures 0.3.25",
|
||||
"insta",
|
||||
"model",
|
||||
@ -3431,7 +3624,7 @@ dependencies = [
|
||||
"humantime 2.1.0",
|
||||
"opentelemetry 0.17.0",
|
||||
"pin-project",
|
||||
"rand",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"static_assertions",
|
||||
"tarpc-plugins",
|
||||
@ -3636,7 +3829,7 @@ dependencies = [
|
||||
"parking_lot",
|
||||
"password-hash",
|
||||
"pretty_env_logger",
|
||||
"rand_core",
|
||||
"rand_core 0.6.4",
|
||||
"rumqttc",
|
||||
"serde",
|
||||
"sha2",
|
||||
@ -3653,7 +3846,7 @@ version = "1.21.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"autocfg 1.1.0",
|
||||
"bytes",
|
||||
"libc",
|
||||
"memchr",
|
||||
|
@ -36,8 +36,18 @@ pub enum Error {
|
||||
DeleteProduct(ProductId),
|
||||
#[error("Failed to create variant of product {0:?}")]
|
||||
CreateProductVariant(ProductId),
|
||||
#[error("Failed to update variant {0:?}")]
|
||||
UpdateProductVariant(ProductVariantId),
|
||||
#[error("Failed to create stock of variant {0:?}")]
|
||||
CreateVariantStock(ProductVariantId),
|
||||
#[error("Failed to add photo to variant {0:?}")]
|
||||
AddProductPhoto(ProductVariantId),
|
||||
#[error("Failed to delete photo for variant {0:?}")]
|
||||
DeleteProductPhoto(ProductVariantId),
|
||||
#[error("Failed to create stock for variant {0:?}")]
|
||||
CreateProductStock(ProductVariantId),
|
||||
#[error("Failed to update stock for variant {0:?}")]
|
||||
UpdateProductStock(ProductVariantId),
|
||||
}
|
||||
|
||||
pub mod rpc {
|
||||
|
@ -5,6 +5,7 @@ pub mod add_product_photo {
|
||||
|
||||
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub struct Input {
|
||||
pub product_variant_id: ProductVariantId,
|
||||
pub local_path: LocalPath,
|
||||
pub file_name: FileName,
|
||||
pub unique_name: UniqueName,
|
||||
|
@ -1,3 +1,8 @@
|
||||
use model::v2::{ProductVariant, ProductVariantId};
|
||||
use rumqttc::QoS;
|
||||
|
||||
use crate::AsyncClient;
|
||||
|
||||
pub mod create_product_variant {
|
||||
use model::v2::*;
|
||||
|
||||
@ -29,7 +34,7 @@ pub mod update_product_variant {
|
||||
pub struct Input {
|
||||
pub id: ProductVariantId,
|
||||
pub product_id: ProductId,
|
||||
pub name: ProductName,
|
||||
pub name: ProductVariantName,
|
||||
pub short_description: ProductShortDesc,
|
||||
pub long_description: ProductLongDesc,
|
||||
pub price: Price,
|
||||
@ -62,3 +67,57 @@ pub mod delete_product_variant {
|
||||
|
||||
pub type Output = Result<Details, Error>;
|
||||
}
|
||||
|
||||
pub enum Topic {
|
||||
ProductVariantCreated,
|
||||
ProductVariantUpdated,
|
||||
ProductVariantDeleted,
|
||||
}
|
||||
|
||||
impl Topic {
|
||||
pub fn to_str(&self) -> &str {
|
||||
match self {
|
||||
Topic::ProductVariantCreated => "product-variant/created",
|
||||
Topic::ProductVariantUpdated => "product-variant/updated",
|
||||
Topic::ProductVariantDeleted => "product-variant/deleted",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<String> for Topic {
|
||||
fn into(self) -> String {
|
||||
self.to_str().into()
|
||||
}
|
||||
}
|
||||
|
||||
impl AsyncClient {
|
||||
pub async fn emit_product_variant_created(&self, product: &ProductVariant) {
|
||||
self.publish_or_log(
|
||||
Topic::ProductVariantCreated,
|
||||
QoS::AtLeastOnce,
|
||||
true,
|
||||
product,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn emit_product_variant_updated(&self, product: &ProductVariant) {
|
||||
self.publish_or_log(
|
||||
Topic::ProductVariantUpdated,
|
||||
QoS::AtLeastOnce,
|
||||
true,
|
||||
product,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn emit_product_variant_deleted(&self, product: &ProductVariantId) {
|
||||
self.publish_or_log(
|
||||
Topic::ProductVariantDeleted,
|
||||
QoS::AtLeastOnce,
|
||||
true,
|
||||
product,
|
||||
)
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
@ -32,6 +32,6 @@ tracing-subscriber = { version = "0.3.16", features = ["env-filter"] }
|
||||
uuid = { version = "1.2.1", features = ['v4'] }
|
||||
|
||||
[dev-dependencies]
|
||||
fake = { version = "2.5.0" }
|
||||
testx = { path = "../testx" }
|
||||
insta = { version = "1.21.0" }
|
||||
fakeit = { version = "1.1.1" }
|
||||
|
@ -106,7 +106,7 @@ async fn inner_detailed_products(
|
||||
let stocks = match dbm.run(&mut *t).await {
|
||||
Ok(stocks) => stocks,
|
||||
Err(e) => {
|
||||
tracing::error!("{}", e);
|
||||
tracing::warn!("{}", e);
|
||||
return Err(Error::VariantStocks(
|
||||
variants.into_iter().map(|p| p.id).collect(),
|
||||
));
|
||||
@ -118,7 +118,7 @@ async fn inner_detailed_products(
|
||||
let photos = match dbm.run(t).await {
|
||||
Ok(photos) => photos,
|
||||
Err(e) => {
|
||||
tracing::error!("{}", e);
|
||||
tracing::warn!("{}", e);
|
||||
return Err(Error::VariantPhotos(
|
||||
variants.into_iter().map(|p| p.id).collect(),
|
||||
));
|
||||
|
@ -15,7 +15,7 @@ macro_rules! begin_t {
|
||||
($db: ident, $err: expr) => {
|
||||
match $db.pool().begin().await {
|
||||
Err(e) => {
|
||||
tracing::error!("{}", e);
|
||||
tracing::warn!("{}", e);
|
||||
return Err($err);
|
||||
}
|
||||
Ok(t) => t,
|
||||
@ -29,7 +29,7 @@ macro_rules! dbm_run {
|
||||
match $dbm.run($t).await {
|
||||
Ok(res) => res,
|
||||
Err(e) => {
|
||||
tracing::error!("{}", e);
|
||||
tracing::warn!("{}", e);
|
||||
return Err($err);
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ pub async fn create_product(
|
||||
match inner_create_product(input, &mut t).await {
|
||||
Ok(res) => {
|
||||
if let Err(e) = t.commit().await {
|
||||
tracing::error!("{}", e);
|
||||
tracing::warn!("{}", e);
|
||||
Err(Error::InternalServerError)
|
||||
} else {
|
||||
mqtt.emit_product_created(&res.product).await;
|
||||
@ -26,7 +26,7 @@ pub async fn create_product(
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!("{}", e);
|
||||
tracing::warn!("{}", e);
|
||||
t.rollback().await.ok();
|
||||
Err(e)
|
||||
}
|
||||
@ -47,7 +47,7 @@ async fn inner_create_product(
|
||||
let product = match dbm.run(&mut *t).await {
|
||||
Ok(product) => product,
|
||||
Err(e) => {
|
||||
tracing::error!("{}", e);
|
||||
tracing::warn!("{}", e);
|
||||
return Err(Error::CreateProduct);
|
||||
}
|
||||
};
|
||||
@ -115,7 +115,7 @@ pub async fn update_product(
|
||||
match res {
|
||||
Ok(res) => {
|
||||
t.commit().await.map_err(|e| {
|
||||
tracing::error!("{}", e);
|
||||
tracing::warn!("{}", e);
|
||||
Error::InternalServerError
|
||||
})?;
|
||||
|
||||
@ -126,7 +126,7 @@ pub async fn update_product(
|
||||
Err(e) => {
|
||||
tracing::warn!("{}", e);
|
||||
t.rollback().await.map_err(|e| {
|
||||
tracing::error!("{}", e);
|
||||
tracing::warn!("{}", e);
|
||||
Error::InternalServerError
|
||||
})?;
|
||||
Err(e)
|
||||
@ -167,16 +167,16 @@ pub async fn delete_product(
|
||||
match res {
|
||||
Ok((product_id, _maybe_product)) => {
|
||||
if let Err(e) = t.commit().await {
|
||||
tracing::error!("{}", e);
|
||||
tracing::warn!("{}", e);
|
||||
return Err(Error::InternalServerError);
|
||||
}
|
||||
mqtt.emit_product_deleted(&product_id).await;
|
||||
Ok(delete_product::Details { product_id })
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!("{}", e);
|
||||
tracing::warn!("{}", e);
|
||||
t.rollback().await.map_err(|e| {
|
||||
tracing::error!("{}", e);
|
||||
tracing::warn!("{}", e);
|
||||
Error::InternalServerError
|
||||
})?;
|
||||
Err(Error::DeleteProduct(product_id))
|
||||
|
@ -1,23 +1,225 @@
|
||||
use channels::stocks::{add_product_photo, delete_product_photo};
|
||||
use channels::stocks::{add_product_photo, delete_product_photo, Error};
|
||||
use channels::AsyncClient;
|
||||
use config::SharedAppConfig;
|
||||
use db_utils::PgT;
|
||||
|
||||
use crate::begin_t;
|
||||
use crate::db::Database;
|
||||
|
||||
pub async fn add_product_photo(
|
||||
_input: add_product_photo::Input,
|
||||
_db: Database,
|
||||
input: add_product_photo::Input,
|
||||
db: Database,
|
||||
_mqtt: AsyncClient,
|
||||
_config: SharedAppConfig,
|
||||
) -> add_product_photo::Output {
|
||||
todo!()
|
||||
let id = input.product_variant_id;
|
||||
let mut t = begin_t!(db, Error::InternalServerError);
|
||||
let res = inner_add_product_photo(input, &mut t).await;
|
||||
|
||||
match res {
|
||||
Ok(details) => {
|
||||
if let Err(e) = t.commit().await {
|
||||
tracing::warn!("{}", e);
|
||||
Err(Error::AddProductPhoto(id))
|
||||
} else {
|
||||
Ok(details)
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
t.rollback().await.ok();
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn inner_add_product_photo(
|
||||
input: add_product_photo::Input,
|
||||
t: &mut PgT<'_>,
|
||||
) -> add_product_photo::Output {
|
||||
let dbm = crate::db::CreatePhoto {
|
||||
local_path: input.local_path,
|
||||
file_name: input.file_name,
|
||||
unique_name: input.unique_name,
|
||||
};
|
||||
let photo = match dbm.run(&mut *t).await {
|
||||
Ok(res) => res,
|
||||
Err(e) => {
|
||||
tracing::warn!("{}", e);
|
||||
return Err(Error::AddProductPhoto(input.product_variant_id));
|
||||
}
|
||||
};
|
||||
|
||||
let dbm = crate::db::CreateProductPhoto {
|
||||
product_variant_id: input.product_variant_id,
|
||||
photo_id: photo.id,
|
||||
};
|
||||
match dbm.run(&mut *t).await {
|
||||
Ok(res) => Ok(add_product_photo::Details {
|
||||
photo_id: res.id,
|
||||
product_variant_id: res.product_variant_id,
|
||||
local_path: photo.local_path,
|
||||
file_name: photo.file_name,
|
||||
unique_name: photo.unique_name,
|
||||
}),
|
||||
Err(e) => {
|
||||
tracing::warn!("{}", e);
|
||||
Err(Error::AddProductPhoto(input.product_variant_id))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn delete_product_photo(
|
||||
_input: delete_product_photo::Input,
|
||||
_db: Database,
|
||||
input: delete_product_photo::Input,
|
||||
db: Database,
|
||||
_mqtt: AsyncClient,
|
||||
_config: SharedAppConfig,
|
||||
) -> delete_product_photo::Output {
|
||||
todo!()
|
||||
let id = input.product_variant_id;
|
||||
let mut t = begin_t!(db, Error::InternalServerError);
|
||||
let res = inner_delete_product_photo(input, &mut t).await;
|
||||
|
||||
match res {
|
||||
Ok(details) => {
|
||||
if let Err(e) = t.commit().await {
|
||||
tracing::warn!("{}", e);
|
||||
Err(Error::DeleteProductPhoto(id))
|
||||
} else {
|
||||
Ok(details)
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
t.rollback().await.ok();
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn inner_delete_product_photo(
|
||||
input: delete_product_photo::Input,
|
||||
t: &mut PgT<'_>,
|
||||
) -> delete_product_photo::Output {
|
||||
let dbm = crate::db::DeleteProductPhoto { id: input.photo_id };
|
||||
|
||||
match dbm.run(t).await {
|
||||
Ok(_details) => Ok(delete_product_photo::Details {
|
||||
photo_id: input.photo_id,
|
||||
product_variant_id: input.product_variant_id,
|
||||
}),
|
||||
Err(e) => {
|
||||
tracing::warn!("{}", e);
|
||||
Err(Error::DeleteProductPhoto(input.product_variant_id))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use channels::stocks::{add_product_photo, delete_product_photo};
|
||||
use config::UpdateConfig;
|
||||
use db_utils::PgT;
|
||||
use model::v2::*;
|
||||
|
||||
use crate::actions::product_photo::{inner_add_product_photo, inner_delete_product_photo};
|
||||
use crate::db::Database;
|
||||
|
||||
struct NoOpts;
|
||||
impl UpdateConfig for NoOpts {}
|
||||
|
||||
async fn test_product(t: &mut PgT<'_>) -> Product {
|
||||
crate::db::CreateProduct {
|
||||
name: ProductName::new(format!("{}", uuid::Uuid::new_v4())),
|
||||
category: None,
|
||||
deliver_days_flag: Days(vec![]),
|
||||
}
|
||||
.run(t)
|
||||
.await
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
async fn test_product_variant(product_id: ProductId, t: &mut PgT<'_>) -> ProductVariant {
|
||||
crate::db::CreateProductVariant {
|
||||
product_id,
|
||||
name: ProductVariantName::new(format!("{}", uuid::Uuid::new_v4())),
|
||||
short_description: ProductShortDesc::new(fakeit::words::sentence(4)),
|
||||
long_description: ProductLongDesc::new(fakeit::words::sentence(16)),
|
||||
price: Price::from_u32(650),
|
||||
}
|
||||
.run(t)
|
||||
.await
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
async fn test_photo(t: &mut PgT<'_>) -> Photo {
|
||||
crate::db::CreatePhoto {
|
||||
local_path: LocalPath::new(format!("{}", uuid::Uuid::new_v4())),
|
||||
file_name: FileName::new(format!("{}", uuid::Uuid::new_v4())),
|
||||
unique_name: UniqueName::new(format!("{}", uuid::Uuid::new_v4())),
|
||||
}
|
||||
.run(t)
|
||||
.await
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
async fn test_product_photo(
|
||||
product_variant_id: ProductVariantId,
|
||||
photo_id: PhotoId,
|
||||
t: &mut PgT<'_>,
|
||||
) -> ProductPhoto {
|
||||
crate::db::CreateProductPhoto {
|
||||
product_variant_id,
|
||||
photo_id,
|
||||
}
|
||||
.run(t)
|
||||
.await
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn add_product_photo() {
|
||||
testx::db_t_ref!(t);
|
||||
|
||||
let product = test_product(&mut t).await;
|
||||
let variant = test_product_variant(product.id, &mut t).await;
|
||||
|
||||
let res = inner_add_product_photo(
|
||||
add_product_photo::Input {
|
||||
product_variant_id: variant.id,
|
||||
local_path: LocalPath::new(format!("{}", uuid::Uuid::new_v4())),
|
||||
file_name: FileName::new(format!("{}", uuid::Uuid::new_v4())),
|
||||
unique_name: UniqueName::new(format!("{}", uuid::Uuid::new_v4())),
|
||||
},
|
||||
&mut t,
|
||||
)
|
||||
.await;
|
||||
|
||||
testx::db_rollback!(t);
|
||||
|
||||
let _res = res.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn delete_product_photo() {
|
||||
testx::db_t_ref!(t);
|
||||
|
||||
let product = test_product(&mut t).await;
|
||||
let variant = test_product_variant(product.id, &mut t).await;
|
||||
let photo = test_photo(&mut t).await;
|
||||
let product_photo = test_product_photo(variant.id, photo.id, &mut t).await;
|
||||
|
||||
let res = inner_delete_product_photo(
|
||||
delete_product_photo::Input {
|
||||
photo_id: product_photo.id,
|
||||
product_variant_id: variant.id,
|
||||
},
|
||||
&mut t,
|
||||
)
|
||||
.await;
|
||||
|
||||
testx::db_rollback!(t);
|
||||
|
||||
let res = res.unwrap();
|
||||
|
||||
assert_eq!(res.photo_id, product_photo.id);
|
||||
assert_eq!(res.product_variant_id, variant.id);
|
||||
}
|
||||
}
|
||||
|
@ -1,23 +1,203 @@
|
||||
use channels::stocks::{create_product_stock, update_product_stock};
|
||||
use channels::stocks::{create_product_stock, update_product_stock, Error};
|
||||
use channels::AsyncClient;
|
||||
use config::SharedAppConfig;
|
||||
use db_utils::PgT;
|
||||
|
||||
use crate::begin_t;
|
||||
use crate::db::Database;
|
||||
|
||||
pub async fn create_product_stock(
|
||||
_input: create_product_stock::Input,
|
||||
_db: Database,
|
||||
input: create_product_stock::Input,
|
||||
db: Database,
|
||||
_mqtt: AsyncClient,
|
||||
_config: SharedAppConfig,
|
||||
) -> create_product_stock::Output {
|
||||
todo!()
|
||||
let product_variant_id = input.product_variant_id;
|
||||
let mut t = begin_t!(db, Error::InternalServerError);
|
||||
let res = inner_create_product_stock(input, &mut t).await;
|
||||
match res {
|
||||
Ok(details) => {
|
||||
if let Err(e) = t.commit().await {
|
||||
tracing::warn!("{}", e);
|
||||
Err(Error::CreateProductStock(product_variant_id))
|
||||
} else {
|
||||
Ok(details)
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
if let Err(e) = t.rollback().await {
|
||||
tracing::warn!("{}", e);
|
||||
}
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn inner_create_product_stock(
|
||||
input: create_product_stock::Input,
|
||||
t: &mut PgT<'_>,
|
||||
) -> create_product_stock::Output {
|
||||
let dbm = crate::db::CreateStock {
|
||||
product_variant_id: input.product_variant_id,
|
||||
quantity: input.quantity,
|
||||
quantity_unit: input.quantity_unit,
|
||||
};
|
||||
match dbm.run(t).await {
|
||||
Ok(product_stock) => Ok(create_product_stock::Details { product_stock }),
|
||||
Err(e) => {
|
||||
tracing::warn!("{}", e);
|
||||
Err(Error::CreateVariantStock(input.product_variant_id))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn update_product_stock(
|
||||
_input: update_product_stock::Input,
|
||||
_db: Database,
|
||||
input: update_product_stock::Input,
|
||||
db: Database,
|
||||
_mqtt: AsyncClient,
|
||||
_config: SharedAppConfig,
|
||||
) -> update_product_stock::Output {
|
||||
todo!()
|
||||
let product_variant_id = input.product_variant_id;
|
||||
let mut t = begin_t!(db, Error::InternalServerError);
|
||||
let res = inner_update_product_stock(input, &mut t).await;
|
||||
match res {
|
||||
Ok(details) => {
|
||||
if let Err(e) = t.commit().await {
|
||||
tracing::warn!("{}", e);
|
||||
Err(Error::UpdateProductStock(product_variant_id))
|
||||
} else {
|
||||
Ok(details)
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
if let Err(e) = t.rollback().await {
|
||||
tracing::warn!("{}", e);
|
||||
}
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn inner_update_product_stock(
|
||||
input: update_product_stock::Input,
|
||||
t: &mut PgT<'_>,
|
||||
) -> update_product_stock::Output {
|
||||
let dbm = crate::db::UpdateStock {
|
||||
id: input.id,
|
||||
product_variant_id: input.product_variant_id,
|
||||
quantity: input.quantity,
|
||||
quantity_unit: input.quantity_unit,
|
||||
};
|
||||
match dbm.run(t).await {
|
||||
Ok(product_stock) => Ok(update_product_stock::Details { product_stock }),
|
||||
Err(e) => {
|
||||
tracing::warn!("{}", e);
|
||||
Err(Error::CreateVariantStock(input.product_variant_id))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use channels::stocks::{
|
||||
add_product_photo, create_product_stock, delete_product_photo, update_product_stock,
|
||||
};
|
||||
use config::UpdateConfig;
|
||||
use db_utils::PgT;
|
||||
use model::v2::*;
|
||||
|
||||
use crate::actions::product_stock::{inner_create_product_stock, inner_update_product_stock};
|
||||
use crate::db::Database;
|
||||
|
||||
struct NoOpts;
|
||||
impl UpdateConfig for NoOpts {}
|
||||
|
||||
async fn test_product(t: &mut PgT<'_>) -> Product {
|
||||
crate::db::CreateProduct {
|
||||
name: ProductName::new(format!("{}", uuid::Uuid::new_v4())),
|
||||
category: None,
|
||||
deliver_days_flag: Days(vec![]),
|
||||
}
|
||||
.run(t)
|
||||
.await
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
async fn test_product_variant(product_id: ProductId, t: &mut PgT<'_>) -> ProductVariant {
|
||||
crate::db::CreateProductVariant {
|
||||
product_id,
|
||||
name: ProductVariantName::new(format!("{}", uuid::Uuid::new_v4())),
|
||||
short_description: ProductShortDesc::new(fakeit::words::sentence(4)),
|
||||
long_description: ProductLongDesc::new(fakeit::words::sentence(16)),
|
||||
price: Price::from_u32(650),
|
||||
}
|
||||
.run(t)
|
||||
.await
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
async fn test_stock(product_variant_id: ProductVariantId, t: &mut PgT<'_>) -> Stock {
|
||||
crate::db::CreateStock {
|
||||
product_variant_id,
|
||||
quantity: Quantity::from_u32(1056),
|
||||
quantity_unit: QuantityUnit::Gram,
|
||||
}
|
||||
.run(t)
|
||||
.await
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn create_stock() {
|
||||
testx::db_t_ref!(t);
|
||||
|
||||
let product = test_product(&mut t).await;
|
||||
let variant = test_product_variant(product.id, &mut t).await;
|
||||
|
||||
let res = inner_create_product_stock(
|
||||
create_product_stock::Input {
|
||||
product_variant_id: variant.id,
|
||||
quantity: Quantity::from_u32(4684),
|
||||
quantity_unit: QuantityUnit::Gram,
|
||||
},
|
||||
&mut t,
|
||||
)
|
||||
.await;
|
||||
|
||||
testx::db_rollback!(t);
|
||||
|
||||
let res = res.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn delete_stock() {
|
||||
testx::db_t_ref!(t);
|
||||
|
||||
let product = test_product(&mut t).await;
|
||||
let variant = test_product_variant(product.id, &mut t).await;
|
||||
let stock = test_stock(variant.id, &mut t).await;
|
||||
|
||||
let quantity = Quantity::from_u32(6699);
|
||||
let quantity_unit = QuantityUnit::Kilogram;
|
||||
|
||||
let res = inner_update_product_stock(
|
||||
update_product_stock::Input {
|
||||
id: stock.id,
|
||||
product_variant_id: variant.id,
|
||||
quantity,
|
||||
quantity_unit,
|
||||
},
|
||||
&mut t,
|
||||
)
|
||||
.await;
|
||||
|
||||
testx::db_rollback!(t);
|
||||
|
||||
let res = res.unwrap();
|
||||
|
||||
assert_eq!(res.product_stock.id, stock.id);
|
||||
assert_eq!(res.product_stock.product_variant_id, variant.id);
|
||||
assert_eq!(res.product_stock.quantity, quantity);
|
||||
assert_eq!(res.product_stock.quantity_unit, quantity_unit);
|
||||
}
|
||||
}
|
||||
|
@ -11,21 +11,24 @@ use crate::db::Database;
|
||||
pub async fn create_product_variant(
|
||||
input: create_product_variant::Input,
|
||||
db: Database,
|
||||
_mqtt: AsyncClient,
|
||||
mqtt: AsyncClient,
|
||||
_config: SharedAppConfig,
|
||||
) -> create_product_variant::Output {
|
||||
let mut t = begin_t!(db, Error::InternalServerError);
|
||||
match inner_create_product_variant(input, &mut t).await {
|
||||
Ok(res) => {
|
||||
Ok(details) => {
|
||||
if let Err(e) = t.commit().await {
|
||||
tracing::error!("{}", e);
|
||||
return Err(Error::InternalServerError);
|
||||
tracing::warn!("{}", e);
|
||||
Err(Error::InternalServerError)
|
||||
} else {
|
||||
mqtt.emit_product_variant_created(&details.product_variant)
|
||||
.await;
|
||||
Ok(details)
|
||||
}
|
||||
Ok(res)
|
||||
}
|
||||
Err(e) => {
|
||||
t.rollback().await.map_err(|e| {
|
||||
tracing::error!("{}", e);
|
||||
tracing::warn!("{}", e);
|
||||
Error::InternalServerError
|
||||
})?;
|
||||
Err(e)
|
||||
@ -49,38 +52,117 @@ async fn inner_create_product_variant(
|
||||
product_variant: variant,
|
||||
}),
|
||||
Err(e) => {
|
||||
tracing::error!("{}", e);
|
||||
tracing::warn!("{}", e);
|
||||
Err(Error::CreateProductVariant(input.product_id))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn update_product_variant(
|
||||
_input: update_product_variant::Input,
|
||||
_db: Database,
|
||||
_mqtt: AsyncClient,
|
||||
input: update_product_variant::Input,
|
||||
db: Database,
|
||||
mqtt: AsyncClient,
|
||||
_config: SharedAppConfig,
|
||||
) -> update_product_variant::Output {
|
||||
todo!()
|
||||
let id = input.id;
|
||||
let mut t = begin_t!(db, Error::InternalServerError);
|
||||
match inner_update_product_variant(input, &mut t).await {
|
||||
Ok(details) => {
|
||||
if let Err(e) = t.commit().await {
|
||||
tracing::warn!("{}", e);
|
||||
Err(Error::UpdateProductVariant(id))
|
||||
} else {
|
||||
mqtt.emit_product_variant_updated(&details.product_variant)
|
||||
.await;
|
||||
Ok(details)
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
t.rollback().await.ok();
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn inner_update_product_variant(
|
||||
input: update_product_variant::Input,
|
||||
t: &mut PgT<'_>,
|
||||
) -> update_product_variant::Output {
|
||||
let dbm = crate::db::UpdateProductVariant {
|
||||
product_variant_id: input.id,
|
||||
product_id: input.product_id,
|
||||
name: input.name,
|
||||
short_description: input.short_description,
|
||||
long_description: input.long_description,
|
||||
price: input.price,
|
||||
};
|
||||
match dbm.run(t).await {
|
||||
Ok(product_variant) => Ok(update_product_variant::Details { product_variant }),
|
||||
Err(e) => {
|
||||
tracing::warn!("{}", e);
|
||||
Err(Error::UpdateProductVariant(input.id))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn delete_product_variant(
|
||||
_input: delete_product_variant::Input,
|
||||
_db: Database,
|
||||
_mqtt: AsyncClient,
|
||||
input: delete_product_variant::Input,
|
||||
db: Database,
|
||||
mqtt: AsyncClient,
|
||||
_config: SharedAppConfig,
|
||||
) -> delete_product_variant::Output {
|
||||
todo!()
|
||||
let id = input.product_variant_id;
|
||||
let mut t = begin_t!(db, Error::InternalServerError);
|
||||
match inner_delete_product_variant(input, &mut t).await {
|
||||
Ok(details) => {
|
||||
if let Err(e) = t.commit().await {
|
||||
tracing::warn!("{}", e);
|
||||
Err(Error::UpdateProductVariant(id))
|
||||
} else {
|
||||
mqtt.emit_product_variant_deleted(&details.product_variant_id)
|
||||
.await;
|
||||
Ok(details)
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
t.rollback().await.ok();
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn inner_delete_product_variant(
|
||||
input: delete_product_variant::Input,
|
||||
t: &mut PgT<'_>,
|
||||
) -> delete_product_variant::Output {
|
||||
let dbm = crate::db::DeleteProductVariant {
|
||||
product_variant_id: input.product_variant_id,
|
||||
};
|
||||
|
||||
match dbm.run(t).await {
|
||||
Ok(_product_variant) => Ok(delete_product_variant::Details {
|
||||
product_id: input.product_id,
|
||||
product_variant_id: input.product_variant_id,
|
||||
}),
|
||||
Err(e) => {
|
||||
tracing::warn!("{}", e);
|
||||
Err(Error::UpdateProductVariant(input.product_variant_id))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use channels::stocks::create_product_variant;
|
||||
use channels::stocks::{
|
||||
create_product_variant, delete_product_variant, update_product_variant,
|
||||
};
|
||||
use config::UpdateConfig;
|
||||
use db_utils::PgT;
|
||||
use model::v2::*;
|
||||
|
||||
use crate::actions::product_variant::inner_create_product_variant;
|
||||
use crate::actions::product_variant::{
|
||||
inner_create_product_variant, inner_delete_product_variant, inner_update_product_variant,
|
||||
};
|
||||
use crate::db::Database;
|
||||
|
||||
struct NoOpts;
|
||||
@ -97,6 +179,22 @@ mod test {
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
async fn test_product_variant(product_id: ProductId, t: &mut PgT<'_>) -> ProductVariant {
|
||||
inner_create_product_variant(
|
||||
create_product_variant::Input {
|
||||
product_id,
|
||||
name: ProductVariantName::new(format!("{}", uuid::Uuid::new_v4())),
|
||||
short_description: ProductShortDesc::new(fakeit::words::sentence(4)),
|
||||
long_description: ProductLongDesc::new(fakeit::words::sentence(16)),
|
||||
price: Price::from_u32(650),
|
||||
},
|
||||
t,
|
||||
)
|
||||
.await
|
||||
.unwrap()
|
||||
.product_variant
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn create_product_variant() {
|
||||
testx::db_t_ref!(t);
|
||||
@ -129,4 +227,70 @@ mod test {
|
||||
assert_eq!(variant.long_description, long_description);
|
||||
assert_eq!(variant.price, price);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn update_product_variant() {
|
||||
testx::db_t_ref!(t);
|
||||
|
||||
let product = test_product(&mut t).await;
|
||||
let variant = test_product_variant(product.id, &mut t).await;
|
||||
|
||||
let id = variant.id;
|
||||
let product_id = product.id;
|
||||
let name = ProductVariantName::new(format!("{}", uuid::Uuid::new_v4()));
|
||||
let short_description = ProductShortDesc::new(format!("{}", uuid::Uuid::new_v4()));
|
||||
let long_description = ProductLongDesc::new(format!("{}", uuid::Uuid::new_v4()));
|
||||
let price = Price::from_u32(234234);
|
||||
|
||||
let res = inner_update_product_variant(
|
||||
update_product_variant::Input {
|
||||
id,
|
||||
product_id,
|
||||
name: name.clone(),
|
||||
short_description: short_description.clone(),
|
||||
long_description: long_description.clone(),
|
||||
price,
|
||||
},
|
||||
&mut t,
|
||||
)
|
||||
.await;
|
||||
|
||||
testx::db_rollback!(t);
|
||||
|
||||
let res = res.unwrap();
|
||||
|
||||
let expected = ProductVariant {
|
||||
id,
|
||||
product_id,
|
||||
name,
|
||||
short_description,
|
||||
long_description,
|
||||
price,
|
||||
};
|
||||
assert_eq!(res.product_variant, expected);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn delete_product_variant() {
|
||||
testx::db_t_ref!(t);
|
||||
|
||||
let product = test_product(&mut t).await;
|
||||
let variant = test_product_variant(product.id, &mut t).await;
|
||||
|
||||
let res = inner_delete_product_variant(
|
||||
delete_product_variant::Input {
|
||||
product_id: product.id,
|
||||
product_variant_id: variant.id,
|
||||
},
|
||||
&mut t,
|
||||
)
|
||||
.await;
|
||||
|
||||
testx::db_rollback!(t);
|
||||
|
||||
let res = res.unwrap();
|
||||
|
||||
assert_eq!(res.product_id, product.id);
|
||||
assert_eq!(res.product_variant_id, variant.id);
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ LIMIT $1 OFFSET $2
|
||||
.fetch_all(t)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("{e:?}");
|
||||
tracing::warn!("{e:?}");
|
||||
Error::All
|
||||
})
|
||||
}
|
||||
@ -64,7 +64,7 @@ RETURNING id, local_path, file_name, unique_name
|
||||
.fetch_one(pool)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("{e:?}");
|
||||
tracing::warn!("{e:?}");
|
||||
Error::Create
|
||||
})
|
||||
}
|
||||
@ -104,7 +104,7 @@ WHERE
|
||||
self.product_variant_ids.len(),
|
||||
self.product_variant_ids.into_iter().map(|id| *id),
|
||||
|e| {
|
||||
tracing::error!("{}", e);
|
||||
tracing::warn!("{}", e);
|
||||
dbg!(e);
|
||||
Error::PhotosForProductVariants
|
||||
},
|
||||
|
@ -34,7 +34,7 @@ LIMIT $1 OFFSET $2
|
||||
.fetch_all(pool)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("{e:?}");
|
||||
tracing::warn!("{e:?}");
|
||||
Error::All
|
||||
})
|
||||
}
|
||||
@ -60,7 +60,7 @@ RETURNING id, product_variant_id, photo_id
|
||||
.fetch_one(pool)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("{:?}", e);
|
||||
tracing::warn!("{:?}", e);
|
||||
Error::Create
|
||||
})
|
||||
}
|
||||
@ -84,7 +84,7 @@ RETURNING id, product_variant_id, photo_id
|
||||
.fetch_optional(pool)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("{:?}", e);
|
||||
tracing::warn!("{:?}", e);
|
||||
Error::Delete(self.id)
|
||||
})
|
||||
}
|
||||
|
@ -49,7 +49,52 @@ RETURNING id,
|
||||
.fetch_one(pool)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("{}", e);
|
||||
tracing::warn!("{}", e);
|
||||
dbg!(e);
|
||||
Error::CreateProductVariant
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct UpdateProductVariant {
|
||||
pub product_variant_id: ProductVariantId,
|
||||
pub product_id: ProductId,
|
||||
pub name: ProductVariantName,
|
||||
pub short_description: ProductShortDesc,
|
||||
pub long_description: ProductLongDesc,
|
||||
pub price: Price,
|
||||
}
|
||||
|
||||
impl UpdateProductVariant {
|
||||
pub async fn run(self, pool: &mut PgT<'_>) -> Result<ProductVariant> {
|
||||
sqlx::query_as(
|
||||
r#"
|
||||
UPDATE product_variants
|
||||
SET product_id = $2,
|
||||
name = $3,
|
||||
short_description = $4,
|
||||
long_description = $5,
|
||||
price = $6
|
||||
WHERE id = $1
|
||||
RETURNING id,
|
||||
product_id,
|
||||
name,
|
||||
short_description,
|
||||
long_description,
|
||||
price
|
||||
"#,
|
||||
)
|
||||
.bind(self.product_variant_id)
|
||||
.bind(self.product_id)
|
||||
.bind(self.name)
|
||||
.bind(self.short_description)
|
||||
.bind(self.long_description)
|
||||
.bind(self.price)
|
||||
.fetch_one(pool)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::warn!("{}", e);
|
||||
dbg!(e);
|
||||
Error::CreateProductVariant
|
||||
})
|
||||
@ -91,7 +136,7 @@ WHERE
|
||||
self.product_ids.len(),
|
||||
self.product_ids.iter().copied().map(|id| *id),
|
||||
|e| {
|
||||
tracing::error!("{}", e);
|
||||
tracing::warn!("{}", e);
|
||||
Error::ProductsVariants(self.product_ids.clone())
|
||||
},
|
||||
)
|
||||
|
@ -49,7 +49,7 @@ LIMIT $1 OFFSET $2
|
||||
.fetch_all(pool)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("{e:?}");
|
||||
tracing::warn!("{e:?}");
|
||||
Error::All
|
||||
})
|
||||
}
|
||||
@ -79,7 +79,7 @@ WHERE id = $1
|
||||
.fetch_one(pool)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("{e:?}");
|
||||
tracing::warn!("{e:?}");
|
||||
Error::Single(self.product_id)
|
||||
})
|
||||
}
|
||||
@ -113,7 +113,7 @@ RETURNING id,
|
||||
.fetch_one(pool)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("{e:?}");
|
||||
tracing::warn!("{e:?}");
|
||||
dbg!(e);
|
||||
Error::Create
|
||||
})
|
||||
@ -153,7 +153,7 @@ RETURNING id,
|
||||
.fetch_one(pool)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("{e:?}");
|
||||
tracing::warn!("{e:?}");
|
||||
dbg!(e);
|
||||
Error::Update(self.id)
|
||||
})
|
||||
@ -184,7 +184,7 @@ RETURNING id,
|
||||
.fetch_optional(pool)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("{e:?}");
|
||||
tracing::warn!("{e:?}");
|
||||
eprintln!("{e:?}");
|
||||
Error::Delete(self.product_id)
|
||||
})
|
||||
@ -219,7 +219,7 @@ LIMIT $2 OFFSET $3
|
||||
.fetch_all(t)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("{e:?}");
|
||||
tracing::warn!("{e:?}");
|
||||
Error::ShoppingCartProducts(self.shopping_cart_id)
|
||||
})
|
||||
}
|
||||
@ -253,7 +253,7 @@ WHERE
|
||||
self.product_ids.len(),
|
||||
self.product_ids.into_iter().map(|id| *id),
|
||||
|e| {
|
||||
tracing::error!("{e:?}");
|
||||
tracing::warn!("{e:?}");
|
||||
Error::FindProducts
|
||||
},
|
||||
)
|
||||
|
@ -41,7 +41,7 @@ LIMIT $1 OFFSET $2
|
||||
.fetch_all(pool)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("{e:?}");
|
||||
tracing::warn!("{e:?}");
|
||||
Error::All
|
||||
})
|
||||
}
|
||||
@ -65,7 +65,7 @@ WHERE id = $1
|
||||
.fetch_one(pool)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("{e:?}");
|
||||
tracing::warn!("{e:?}");
|
||||
dbg!(e);
|
||||
Error::NotFound(self.id)
|
||||
})
|
||||
@ -94,7 +94,7 @@ RETURNING id, product_variant_id, quantity, quantity_unit
|
||||
.fetch_one(pool)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("{e:?}");
|
||||
tracing::warn!("{e:?}");
|
||||
dbg!(e);
|
||||
Error::Create
|
||||
})
|
||||
@ -128,7 +128,7 @@ RETURNING id, product_variant_id, quantity, quantity_unit
|
||||
.fetch_one(pool)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("{e:?}");
|
||||
tracing::warn!("{e:?}");
|
||||
Error::Update(self.id)
|
||||
})
|
||||
}
|
||||
@ -155,7 +155,7 @@ RETURNING id, product_variant_id, quantity, quantity_unit
|
||||
.fetch_optional(pool)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("{e:?}");
|
||||
tracing::warn!("{e:?}");
|
||||
Error::Delete(self.stock_id)
|
||||
})
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ pub async fn start(config: SharedAppConfig, _db: Database) -> channels::AsyncCli
|
||||
Ok(Event::Incoming(_incoming)) => {}
|
||||
Ok(Event::Outgoing(_outgoing)) => {}
|
||||
Err(e) => {
|
||||
tracing::error!("{}", e);
|
||||
tracing::warn!("{}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user