1use reqwest::{Method, Response};
2use serde_json::{json, Value};
3use crate::general::{Client, CountryMarketplace};
4use strum_macros;
5use crate::error_handling::Errors;
6
7pub struct Listings;
8#[allow(non_camel_case_types)]
9#[derive(strum_macros::Display)]
10pub enum IncludedData {
11 summaries,
12 issues,
13 attributes,
14 offers,
15 fulfillmentAvailability,
16 procurement,
17 relationships,
18 productTypes,
19}
20impl Listings {
21 pub async fn get_listings_item(
22 client: &mut Client,
23 seller_id: &str,
24 sku: &str,
25 country_marketplace: CountryMarketplace,
26 included_data: Vec<IncludedData>,
27
28 ) -> Result<Response, Errors> {
29 let url = format!("/listings/2021-08-01/items/{}/{}", seller_id, sku);
30 let parameters = vec![("marketplaceIds", country_marketplace.details().0.to_string()), ("includedData", included_data.iter().map(|b| b.to_string()).collect::<Vec<String>>().join(","))];
31
32 client.make_request(&url, Method::GET, Some(parameters)).await
33 }
34 pub async fn put_listings_item() {}
35
36 pub async fn patch_listings_item(
37 client: &mut Client,
38 seller_id: &str,
39 sku: &str,
40 country_marketplace: CountryMarketplace,
41 validation_preview: bool,
42 body: &str
43 ) -> Result<Response, Errors> {
44 let url = format!("/listings/2021-08-01/items/{}/{}", seller_id, sku);
45 let mut parameters = vec![("marketplaceIds", country_marketplace.details().0)];
46 if validation_preview {
47 parameters.push(("mode", "VALIDATION_PREVIEW"))
48 }
49
50 client.make_request_w_body(&url, Method::PATCH, Some(parameters), body.parse().unwrap()).await
51
52 }
53 pub async fn wrapped_patch_listings_item(
55 client: &mut Client,
56 seller_id: &str,
57 sku: &str,
58 country_marketplace: CountryMarketplace,
59 validation_preview: bool,
60 new_price: f64
61
62 ) -> Result<Response, Errors> {
63 let item_data: Value = Self::get_listings_item(client, seller_id, sku ,CountryMarketplace::SaudiArabia, vec![IncludedData::productTypes, IncludedData::attributes]).await?.json().await?;
64 let item_type = &item_data["productTypes"][0]["productType"];
65 let mut offers = item_data["attributes"]["purchasable_offer"].clone();
66
67 offers[0]["our_price"][0]["schedule"][0]["value_with_tax"] = Value::from(new_price);
68 let final_body = json!({
69 "productType": item_type,
70 "patches": [{
71 "op":"replace",
72 "path":"/attributes/purchasable_offer",
73 "value":offers
74 }]
75 });
76 Self::patch_listings_item(client, seller_id, sku, country_marketplace, validation_preview, &*final_body.to_string()).await
77
78 }
79 pub async fn search_listings_items(
106 client: &mut Client,
107 seller_id: String,
108 marketplace: CountryMarketplace,
109 issue_locale: Option<String>,
110 included_data: Option<Vec<String>>,
111 identifiers: Option<Vec<String>>,
112 identifiers_type: Option<String>,
113 variation_parent_sku: Option<String>,
114 package_hierarchy_sku: Option<String>,
115 created_after: Option<String>,
116 created_before: Option<String>,
117 last_updated_after: Option<String>,
118 last_updated_before: Option<String>,
119 with_issue_severity: Option<Vec<String>>,
120 with_status: Option<Vec<String>>,
121 without_status: Option<Vec<String>>,
122 sort_by: Option<String>,
123 sort_order: Option<String>,
124 page_size: Option<u32>,
125 page_token: Option<String>,
126 ) -> Result<Response, Errors> {
127 let uri = format!("/listings/2021-08-01/items/{}", seller_id);
128
129 if identifiers.is_some() && (variation_parent_sku.is_some() || package_hierarchy_sku.is_some()) {
131 return Err(Errors::CustomError(
132 "Cannot use identifiers with variationParentSku or packageHierarchySku".to_string()
133 ));
134 }
135
136 if variation_parent_sku.is_some() && package_hierarchy_sku.is_some() {
137 return Err(Errors::CustomError(
138 "Cannot use both variationParentSku and packageHierarchySku".to_string()
139 ));
140 }
141
142 if let Some(ids) = &identifiers {
144 if ids.len() > 20 {
145 return Err(Errors::CustomError("Maximum 20 identifiers allowed".to_string()));
146 }
147 }
148
149 if let Some(size) = page_size {
151 if size > 20 {
152 return Err(Errors::CustomError("Maximum page size is 20".to_string()));
153 }
154 }
155
156 let mut params: Vec<(String, String)> = Vec::new();
157
158 params.push(("marketplaceIds".to_string(), marketplace.details().0.to_string()));
160 params.push(("sellerId".to_string(), seller_id));
161
162 if let Some(locale) = issue_locale {
164 params.push(("issueLocale".to_string(), locale));
165 }
166 if let Some(data) = included_data {
167 params.push(("includedData".to_string(), data.join(",")));
168 }
169 if let Some(ids) = identifiers {
170 params.push(("identifiers".to_string(), ids.join(",")));
171 }
172 if let Some(id_type) = identifiers_type {
173 params.push(("identifiersType".to_string(), format!("{:?}", id_type)));
174 }
175 if let Some(sku) = variation_parent_sku {
176 params.push(("variationParentSku".to_string(), sku));
177 }
178 if let Some(sku) = package_hierarchy_sku {
179 params.push(("packageHierarchySku".to_string(), sku));
180 }
181 if let Some(date) = created_after {
182 params.push(("createdAfter".to_string(), date));
183 }
184 if let Some(date) = created_before {
185 params.push(("createdBefore".to_string(), date));
186 }
187 if let Some(date) = last_updated_after {
188 params.push(("lastUpdatedAfter".to_string(), date));
189 }
190 if let Some(date) = last_updated_before {
191 params.push(("lastUpdatedBefore".to_string(), date));
192 }
193 if let Some(severities) = with_issue_severity {
194 params.push(("withIssueSeverity".to_string(),
195 severities.iter().map(|s| format!("{:?}", s)).collect::<Vec<_>>().join(",")));
196 }
197 if let Some(statuses) = with_status {
198 params.push(("withStatus".to_string(),
199 statuses.iter().map(|s| format!("{:?}", s)).collect::<Vec<_>>().join(",")));
200 }
201 if let Some(statuses) = without_status {
202 params.push(("withoutStatus".to_string(),
203 statuses.iter().map(|s| format!("{:?}", s)).collect::<Vec<_>>().join(",")));
204 }
205 if let Some(sort) = sort_by {
206 params.push(("sortBy".to_string(), format!("{:?}", sort)));
207 }
208 if let Some(order) = sort_order {
209 params.push(("sortOrder".to_string(), format!("{:?}", order)));
210 }
211 if let Some(size) = page_size {
212 params.push(("pageSize".to_string(), size.to_string()));
213 }
214 if let Some(token) = page_token {
215 params.push(("pageToken".to_string(), token));
216 }
217 client.make_request(&uri, Method::GET, Some(params)).await
218 }
219}