rust_woocommerce/controllers/
product_variations.rs

1use chrono::NaiveDateTime;
2use serde::{Deserialize, Serialize};
3use serde_with::skip_serializing_none;
4
5use crate::{BackordersStatus, Dimensions, MetaData, ProductStatus, StockStatus, TaxStatus};
6
7use super::products::{DefaultAttributeDTO, DownloadDTO, ImageDTO};
8
9#[skip_serializing_none]
10#[derive(Debug, Clone, Serialize, Deserialize)]
11pub struct ProductVariationModify {
12    id: Option<i32>,
13    description: Option<String>,
14    sku: Option<String>,
15    regular_price: Option<String>,
16    sale_price: Option<String>,
17    date_on_sale_from: Option<NaiveDateTime>,
18    date_on_sale_to: Option<NaiveDateTime>,
19    status: Option<ProductStatus>,
20    #[serde(rename = "virtual")]
21    is_virtual: Option<bool>,
22    downloadable: Option<bool>,
23    downloads: Option<Vec<DownloadDTO>>,
24    download_limit: Option<i32>,
25    download_expiry: Option<i32>,
26    tax_status: Option<TaxStatus>,
27    tax_class: Option<String>,
28    manage_stock: Option<bool>,
29    stock_quantity: Option<i32>,
30    stock_status: Option<StockStatus>,
31    backorders: Option<BackordersStatus>,
32    weight: Option<String>,
33    dimensions: Option<Dimensions>,
34    shipping_class: Option<String>,
35    image: Option<ImageDTO>,
36    attributes: Option<Vec<DefaultAttributeDTO>>,
37    menu_order: Option<i32>,
38    meta_data: Option<Vec<MetaData>>,
39}
40#[derive(Default)]
41pub struct ProductVariationModifyBuilder {
42    id: Option<i32>,
43    description: Option<String>,
44    sku: Option<String>,
45    regular_price: Option<String>,
46    sale_price: Option<String>,
47    date_on_sale_from: Option<NaiveDateTime>,
48    date_on_sale_to: Option<NaiveDateTime>,
49    status: Option<ProductStatus>,
50    is_virtual: Option<bool>,
51    downloadable: Option<bool>,
52    downloads: Option<Vec<DownloadDTO>>,
53    download_limit: Option<i32>,
54    download_expiry: Option<i32>,
55    tax_status: Option<TaxStatus>,
56    tax_class: Option<String>,
57    manage_stock: Option<bool>,
58    stock_quantity: Option<i32>,
59    stock_status: Option<StockStatus>,
60    backorders: Option<BackordersStatus>,
61    weight: Option<String>,
62    dimensions: Option<Dimensions>,
63    shipping_class: Option<String>,
64    image: Option<ImageDTO>,
65    attributes: Option<Vec<DefaultAttributeDTO>>,
66    menu_order: Option<i32>,
67    meta_data: Option<Vec<MetaData>>,
68}
69impl ProductVariationModifyBuilder {
70    /// Unique identifier for the resource.
71    pub fn id(&mut self, id: i32) -> &mut Self {
72        let _ = self.id.insert(id);
73        self
74    }
75    /// Variation description.
76    pub fn description(&mut self, description: impl Into<String>) -> &mut Self {
77        let _ = self.description.insert(description.into());
78        self
79    }
80    /// Unique identifier.
81    pub fn sku(&mut self, sku: impl Into<String>) -> &mut Self {
82        let _ = self.sku.insert(sku.into());
83        self
84    }
85    /// Variation regular price.
86    pub fn regular_price(&mut self, regular_price: impl Into<String>) -> &mut Self {
87        let _ = self.regular_price.insert(regular_price.into());
88        self
89    }
90    /// Variation sale price.
91    pub fn sale_price(&mut self, sale_price: impl Into<String>) -> &mut Self {
92        let _ = self.sale_price.insert(sale_price.into());
93        self
94    }
95    /// Start date of sale price, in the site's timezone.
96    pub fn date_on_sale_from(&mut self, year: i32, month: u32, day: u32) -> &mut Self {
97        let dt = chrono::NaiveDate::from_ymd_opt(year, month, day)
98            .unwrap()
99            .and_hms_opt(0, 0, 0)
100            .unwrap();
101        let _ = self.date_on_sale_from.insert(dt);
102        self
103    }
104    /// End date of sale price, in the site's timezone.
105    pub fn date_on_sale_to(&mut self, year: i32, month: u32, day: u32) -> &mut Self {
106        let dt = chrono::NaiveDate::from_ymd_opt(year, month, day)
107            .unwrap()
108            .and_hms_opt(0, 0, 0)
109            .unwrap();
110        let _ = self.date_on_sale_to.insert(dt);
111        self
112    }
113    /// Variation status. Options: draft, pending, private and publish. Default is publish.
114    pub fn status(&mut self, status: ProductStatus) -> &mut Self {
115        let _ = self.status.insert(status);
116        self
117    }
118    /// If the variation is virtual. Default is false.
119    pub fn set_virtual(&mut self) -> &mut Self {
120        let _ = self.is_virtual.insert(true);
121        self
122    }
123    /// If the variation is downloadable. Default is false.
124    pub fn downloadable(&mut self) -> &mut Self {
125        let _ = self.downloadable.insert(true);
126        self
127    }
128    /// List of downloadable files.
129    pub fn downloads(&mut self, file_src: impl Into<String>) -> &mut Self {
130        let f = DownloadDTO {
131            file: file_src.into(),
132        };
133        self.downloads.get_or_insert(vec![]).push(f);
134        self
135    }
136    /// Number of times downloadable files can be downloaded after purchase. Default is -1.
137    pub fn download_limit(&mut self, download_limit: i32) -> &mut Self {
138        let _ = self.download_limit.insert(download_limit);
139        self
140    }
141    /// Number of days until access to downloadable files expires. Default is -1.
142    pub fn download_expiry(&mut self, download_expiry: i32) -> &mut Self {
143        let _ = self.download_expiry.insert(download_expiry);
144        self
145    }
146    /// Tax status. Options: taxable, shipping and none. Default is taxable.
147    pub fn tax_status(&mut self, tax_status: TaxStatus) -> &mut Self {
148        let _ = self.tax_status.insert(tax_status);
149        self
150    }
151    /// Tax class.
152    pub fn tax_class(&mut self, tax_class: impl Into<String>) -> &mut Self {
153        let _ = self.tax_class.insert(tax_class.into());
154        self
155    }
156    /// Stock management at variation level. Default is false.
157    pub fn manage_stock(&mut self) -> &mut Self {
158        let _ = self.manage_stock.insert(true);
159        self
160    }
161    /// Stock quantity.
162    pub fn stock_quantity(&mut self, stock_quantity: i32) -> &mut Self {
163        let _ = self.stock_quantity.insert(stock_quantity);
164        self
165    }
166    /// Controls the stock status of the product. Options: instock, outofstock, onbackorder. Default is instock.
167    pub fn stock_status(&mut self, stock_status: StockStatus) -> &mut Self {
168        let _ = self.stock_status.insert(stock_status);
169        self
170    }
171    /// If managing stock, this controls if backorders are allowed. Options: no, notify and yes. Default is no.
172    pub fn backorders(&mut self, backorders: BackordersStatus) -> &mut Self {
173        let _ = self.backorders.insert(backorders);
174        self
175    }
176    /// Variation weight.
177    pub fn weight(&mut self, weight: impl Into<String>) -> &mut Self {
178        let _ = self.weight.insert(weight.into());
179        self
180    }
181    /// Variation dimensions. See Product variation - Dimensions properties
182    pub fn dimensions(
183        &mut self,
184        length: impl Into<String>,
185        width: impl Into<String>,
186        height: impl Into<String>,
187    ) -> &mut Self {
188        let d = Dimensions {
189            length: length.into(),
190            width: width.into(),
191            height: height.into(),
192        };
193        let _ = self.dimensions.insert(d);
194        self
195    }
196    /// Shipping class slug.
197    pub fn shipping_class(&mut self, shipping_class: impl Into<String>) -> &mut Self {
198        let _ = self.shipping_class.insert(shipping_class.into());
199        self
200    }
201    /// Variation image data.
202    pub fn image(&mut self, img_src: impl Into<String>) -> &mut Self {
203        let _ = self.image.insert(ImageDTO {
204            src: img_src.into(),
205        });
206        self
207    }
208    /// List of attributes.
209    pub fn attribute(
210        &mut self,
211        id: Option<i32>,
212        name: impl Into<String>,
213        option: impl Into<String>,
214    ) -> &mut Self {
215        self.attributes
216            .get_or_insert(vec![])
217            .push(DefaultAttributeDTO {
218                id,
219                name: name.into(),
220                option: option.into(),
221            });
222        self
223    }
224    /// Menu order, used to custom sort products.
225    pub fn menu_order(&mut self, menu_order: i32) -> &mut Self {
226        let _ = self.menu_order.insert(menu_order);
227        self
228    }
229    /// Meta data.
230    pub fn meta_data(&mut self, key: impl Into<String>, value: impl Serialize) -> &mut Self {
231        self.meta_data.get_or_insert(vec![]).push(MetaData {
232            id: None,
233            key: key.into(),
234            value: serde_json::json!(value),
235        });
236        self
237    }
238    pub fn build(&self) -> ProductVariationModify {
239        ProductVariationModify {
240            id: self.id,
241            description: self.description.to_owned(),
242            sku: self.sku.to_owned(),
243            regular_price: self.regular_price.to_owned(),
244            sale_price: self.sale_price.to_owned(),
245            date_on_sale_from: self.date_on_sale_from,
246            date_on_sale_to: self.date_on_sale_to,
247            status: self.status.to_owned(),
248            is_virtual: self.is_virtual,
249            downloadable: self.downloadable,
250            downloads: self.downloads.to_owned(),
251            download_limit: self.download_limit,
252            download_expiry: self.download_expiry,
253            tax_status: self.tax_status.to_owned(),
254            tax_class: self.tax_class.to_owned(),
255            manage_stock: self.manage_stock,
256            stock_quantity: self.stock_quantity,
257            stock_status: self.stock_status.to_owned(),
258            backorders: self.backorders.to_owned(),
259            weight: self.weight.to_owned(),
260            dimensions: self.dimensions.to_owned(),
261            shipping_class: self.shipping_class.to_owned(),
262            image: self.image.to_owned(),
263            attributes: self.attributes.to_owned(),
264            menu_order: self.menu_order,
265            meta_data: self.meta_data.to_owned(),
266        }
267    }
268}