shopify_client/admin/order/
remote.rs1use reqwest::header::{HeaderMap, HeaderValue, CONTENT_TYPE};
2
3use crate::{
4 common::{
5 http::{execute_graphql, http_client},
6 types::APIError,
7 utils::parse_response_from_text,
8 ServiceContext,
9 },
10 types::order::{
11 GetOrderResp, OrderDiscountsAndTransactionsResp, OrderQueryResp, PatchOrderRequest,
12 },
13};
14
15pub async fn patch_order(
16 ctx: &ServiceContext,
17 order_id: &String,
18 patch_request: &PatchOrderRequest,
19) -> Result<GetOrderResp, APIError> {
20 let endpoint = format!(
21 "{}/admin/api/{}/orders/{}.json",
22 ctx.shop_url.trim_end_matches('/'),
23 ctx.version,
24 order_id
25 );
26
27 let body_str = serde_json::to_string(&patch_request).unwrap_or_default();
28
29 let mut callback_headers = HeaderMap::new();
30 callback_headers.insert(CONTENT_TYPE, HeaderValue::from_static("application/json"));
31
32 ctx.callbacks
33 .call_before(&endpoint, Some(&body_str), &callback_headers);
34
35 let response = http_client()
36 .put(&endpoint)
37 .header("X-Shopify-Access-Token", &*ctx.access_token)
38 .header("Content-Type", "application/json")
39 .json(&patch_request)
40 .send()
41 .await;
42
43 match response {
44 Ok(resp) => {
45 let response_headers = resp.headers().clone();
46 let response_text = match resp.text().await {
47 Ok(text) => text,
48 Err(e) => {
49 let error_msg = format!("<failed to read response body: {}>", e);
50 ctx.callbacks
51 .call_after(&endpoint, &error_msg, &response_headers);
52 return Err(APIError::FailedToParse);
53 }
54 };
55
56 ctx.callbacks
57 .call_after(&endpoint, &response_text, &response_headers);
58
59 parse_response_from_text::<GetOrderResp>(&response_text)
60 }
61 Err(e) => {
62 let error_msg = format!("<network error: {}>", e);
63 ctx.callbacks
64 .call_after(&endpoint, &error_msg, &HeaderMap::new());
65 Err(APIError::NetworkError)
66 }
67 }
68}
69
70pub async fn get_order_with_name(
71 ctx: &ServiceContext,
72 order_name: &String,
73) -> Result<OrderQueryResp, APIError> {
74 let endpoint = format!(
75 "{}/admin/api/{}/orders.json?query=name:%23{}&status=any",
76 ctx.shop_url.trim_end_matches('/'),
77 ctx.version,
78 order_name
79 );
80
81 let callback_headers = HeaderMap::new();
82
83 ctx.callbacks
84 .call_before(&endpoint, None, &callback_headers);
85
86 let response = http_client()
87 .get(&endpoint)
88 .header("X-Shopify-Access-Token", &*ctx.access_token)
89 .send()
90 .await;
91
92 match response {
93 Ok(resp) => {
94 let response_headers = resp.headers().clone();
95 let response_text = match resp.text().await {
96 Ok(text) => text,
97 Err(e) => {
98 let error_msg = format!("<failed to read response body: {}>", e);
99 ctx.callbacks
100 .call_after(&endpoint, &error_msg, &response_headers);
101 return Err(APIError::FailedToParse);
102 }
103 };
104
105 ctx.callbacks
106 .call_after(&endpoint, &response_text, &response_headers);
107
108 parse_response_from_text::<OrderQueryResp>(&response_text)
109 }
110 Err(e) => {
111 let error_msg = format!("<network error: {}>", e);
112 ctx.callbacks
113 .call_after(&endpoint, &error_msg, &HeaderMap::new());
114 Err(APIError::NetworkError)
115 }
116 }
117}
118
119pub async fn get_order_with_id(
120 ctx: &ServiceContext,
121 order_id: &String,
122) -> Result<GetOrderResp, APIError> {
123 let endpoint = format!(
124 "{}/admin/api/{}/orders/{}.json",
125 ctx.shop_url.trim_end_matches('/'),
126 ctx.version,
127 order_id
128 );
129
130 let callback_headers = HeaderMap::new();
131
132 ctx.callbacks
133 .call_before(&endpoint, None, &callback_headers);
134
135 let response = http_client()
136 .get(&endpoint)
137 .header("X-Shopify-Access-Token", &*ctx.access_token)
138 .send()
139 .await;
140
141 match response {
142 Ok(resp) => {
143 let response_headers = resp.headers().clone();
144 let response_text = match resp.text().await {
145 Ok(text) => text,
146 Err(e) => {
147 let error_msg = format!("<failed to read response body: {}>", e);
148 ctx.callbacks
149 .call_after(&endpoint, &error_msg, &response_headers);
150 return Err(APIError::FailedToParse);
151 }
152 };
153
154 ctx.callbacks
155 .call_after(&endpoint, &response_text, &response_headers);
156
157 parse_response_from_text::<GetOrderResp>(&response_text)
158 }
159 Err(e) => {
160 let error_msg = format!("<network error: {}>", e);
161 ctx.callbacks
162 .call_after(&endpoint, &error_msg, &HeaderMap::new());
163 Err(APIError::NetworkError)
164 }
165 }
166}
167
168pub async fn get_order_discounts_and_transactions(
169 ctx: &ServiceContext,
170 order_gid: &str,
171 lines: u32,
172) -> Result<OrderDiscountsAndTransactionsResp, APIError> {
173 let query = r#"
174 query orderDiscountsAndTransactions($id: ID!, $lines: Int!) {
175 order(id: $id) {
176 discountCodes
177 transactions {
178 gateway
179 kind
180 status
181 amountSet { shopMoney { amount currencyCode } }
182 }
183 lineItems(first: $lines) {
184 nodes {
185 id
186 discountAllocations {
187 allocatedAmountSet { shopMoney { amount currencyCode } }
188 }
189 }
190 pageInfo { hasNextPage }
191 }
192 cartDiscountAmountSet { shopMoney { amount currencyCode } }
193 }
194 }
195 "#;
196
197 let variables = serde_json::json!({ "id": order_gid, "lines": lines });
198
199 execute_graphql(ctx, query, variables).await
200}