Skip to content

Commit 2e48195

Browse files
authored
Merge pull request #11333 from msupply-foundation/11288-ancillary-item-graphql
#11288 Ancillary item service + GraphQL layers
2 parents 7ad96f1 + e352c74 commit 2e48195

21 files changed

Lines changed: 1148 additions & 2 deletions

File tree

server/Cargo.lock

Lines changed: 19 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

server/graphql/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ graphql_asset_catalogue = { path = "asset_catalogue" }
2222
graphql_inventory_adjustment = { path = "inventory_adjustment" }
2323
graphql_item_variant = { path = "item_variant" }
2424
graphql_item_bundle = { path = "item_bundle" }
25+
graphql_ancillary_item = { path = "ancillary_item" }
2526
graphql_invoice = { path = "invoice" }
2627
graphql_invoice_line = { path = "invoice_line" }
2728
graphql_vaccine_course = { path = "vaccine_course" }
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
[package]
2+
name = "graphql_ancillary_item"
3+
version = "0.1.0"
4+
edition = "2018"
5+
6+
[lib]
7+
path = "src/lib.rs"
8+
doctest = false
9+
10+
[dependencies]
11+
12+
repository = { path = "../../repository" }
13+
service = { path = "../../service" }
14+
graphql_core = { path = "../core" }
15+
graphql_types = { path = "../types" }
16+
17+
actix-web = { workspace = true }
18+
async-graphql = { workspace = true }
19+
async-graphql-actix-web = { workspace = true }
20+
async-trait = { workspace = true }
21+
22+
[dev-dependencies]
23+
actix-rt = { workspace = true }
24+
assert-json-diff = { workspace = true }
25+
serde = { workspace = true }
26+
serde_json = { workspace = true }
27+
28+
[features]
29+
default = ["sqlite"]
30+
sqlite = ["repository/sqlite"]
31+
postgres = ["repository/postgres"]
32+
33+
[lints]
34+
workspace = true
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
use async_graphql::*;
2+
3+
mod mutations;
4+
use self::mutations::*;
5+
6+
#[derive(Default, Clone)]
7+
pub struct AncillaryItemMutations;
8+
9+
#[Object]
10+
impl AncillaryItemMutations {
11+
async fn upsert_ancillary_item(
12+
&self,
13+
ctx: &Context<'_>,
14+
store_id: String,
15+
input: UpsertAncillaryItemInput,
16+
) -> Result<UpsertAncillaryItemResponse> {
17+
upsert_ancillary_item(ctx, store_id, input)
18+
}
19+
20+
async fn delete_ancillary_item(
21+
&self,
22+
ctx: &Context<'_>,
23+
store_id: String,
24+
input: DeleteAncillaryItemInput,
25+
) -> Result<DeleteAncillaryItemResponse> {
26+
delete_ancillary_item(ctx, store_id, input)
27+
}
28+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
use async_graphql::*;
2+
use graphql_core::{
3+
standard_graphql_error::{validate_auth, StandardGraphqlError},
4+
ContextExt,
5+
};
6+
use graphql_types::types::DeleteResponse;
7+
use service::{
8+
auth::{Resource, ResourceAccessRequest},
9+
item::ancillary_item::{DeleteAncillaryItem, DeleteAncillaryItemError},
10+
};
11+
12+
#[derive(InputObject)]
13+
pub struct DeleteAncillaryItemInput {
14+
pub id: String,
15+
}
16+
17+
#[derive(Union)]
18+
pub enum DeleteAncillaryItemResponse {
19+
Response(DeleteResponse),
20+
}
21+
22+
pub fn delete_ancillary_item(
23+
ctx: &Context<'_>,
24+
store_id: String,
25+
input: DeleteAncillaryItemInput,
26+
) -> Result<DeleteAncillaryItemResponse> {
27+
validate_auth(
28+
ctx,
29+
&ResourceAccessRequest {
30+
resource: Resource::MutateItemNamesCodesAndUnits,
31+
store_id: Some(store_id.to_string()),
32+
},
33+
)?;
34+
35+
let service_provider = ctx.service_provider();
36+
let service_context = service_provider.basic_context()?;
37+
38+
let result = service_provider
39+
.item_service
40+
.delete_ancillary_item(&service_context, input.to_domain());
41+
42+
map_response(result)
43+
}
44+
45+
impl DeleteAncillaryItemInput {
46+
pub fn to_domain(self) -> DeleteAncillaryItem {
47+
let DeleteAncillaryItemInput { id } = self;
48+
DeleteAncillaryItem { id }
49+
}
50+
}
51+
52+
fn map_response(
53+
from: Result<String, DeleteAncillaryItemError>,
54+
) -> Result<DeleteAncillaryItemResponse> {
55+
match from {
56+
Ok(result) => Ok(DeleteAncillaryItemResponse::Response(DeleteResponse(result))),
57+
Err(error) => {
58+
let formatted_error = format!("{error:#?}");
59+
60+
let graphql_error = match error {
61+
DeleteAncillaryItemError::NotCentralServer => {
62+
StandardGraphqlError::Forbidden(formatted_error)
63+
}
64+
DeleteAncillaryItemError::DatabaseError(_) => {
65+
StandardGraphqlError::InternalError(formatted_error)
66+
}
67+
};
68+
69+
Err(graphql_error.extend())
70+
}
71+
}
72+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
mod upsert;
2+
pub use upsert::*;
3+
4+
mod delete;
5+
pub use delete::*;
6+
7+
#[cfg(test)]
8+
mod test;

0 commit comments

Comments
 (0)