rust_woocommerce/controllers/
coupons.rs

1use serde_with::skip_serializing_none;
2
3use crate::{DiscountType, MetaData};
4#[skip_serializing_none]
5#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Default)]
6pub struct CreateCoupon {
7    code: String,
8    discount_type: DiscountType,
9    amount: String,
10    description: Option<String>,
11    date_expires: Option<String>,
12    date_expires_gmt: Option<String>,
13    individual_use: bool,
14    product_ids: Option<Vec<i32>>,
15    excluded_product_ids: Option<Vec<i32>>,
16    usage_limit: Option<i32>,
17    usage_limit_per_user: Option<i32>,
18    limit_usage_to_x_items: Option<i32>,
19    free_shipping: bool,
20    product_categories: Option<Vec<i32>>,
21    excluded_product_categories: Option<Vec<i32>>,
22    exclude_sale_items: bool,
23    minimum_amount: Option<String>,
24    maximum_amount: Option<String>,
25    email_restrictions: Option<Vec<String>>,
26    meta_data: Option<Vec<MetaData>>,
27}
28impl CreateCoupon {
29    pub fn new(
30        code: impl Into<String>,
31        discount_type: DiscountType,
32        amount: impl Into<String>,
33    ) -> Self {
34        Self {
35            code: code.into(),
36            discount_type,
37            amount: amount.into(),
38            ..Default::default()
39        }
40    }
41    pub fn builder() -> CreateCouponBuilder<NoCode, NoDiscountType, NoAmount> {
42        CreateCouponBuilder::default()
43    }
44}
45#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Default)]
46pub struct CreateCouponBuilder<C, D, A> {
47    code: C,
48    discount_type: D,
49    amount: A,
50    description: Option<String>,
51    date_expires: Option<String>,
52    date_expires_gmt: Option<String>,
53    individual_use: bool,
54    product_ids: Option<Vec<i32>>,
55    excluded_product_ids: Option<Vec<i32>>,
56    usage_limit: Option<i32>,
57    usage_limit_per_user: Option<i32>,
58    limit_usage_to_x_items: Option<i32>,
59    free_shipping: bool,
60    product_categories: Option<Vec<i32>>,
61    excluded_product_categories: Option<Vec<i32>>,
62    exclude_sale_items: bool,
63    minimum_amount: Option<String>,
64    maximum_amount: Option<String>,
65    email_restrictions: Option<Vec<String>>,
66    meta_data: Option<Vec<MetaData>>,
67}
68#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Default)]
69pub struct NoCode;
70#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Default)]
71pub struct NoDiscountType;
72#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Default)]
73pub struct NoAmount;
74#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Default)]
75pub struct WithCode(String);
76#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Default)]
77pub struct WithDiscountType(DiscountType);
78#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Default)]
79pub struct WithAmount(String);
80impl<C, D, A> CreateCouponBuilder<C, D, A> {
81    /// Coupon code.
82    pub fn code(self, code: impl Into<String>) -> CreateCouponBuilder<WithCode, D, A> {
83        CreateCouponBuilder {
84            code: WithCode(code.into()),
85            discount_type: self.discount_type,
86            amount: self.amount,
87            description: self.description,
88            date_expires: self.date_expires,
89            date_expires_gmt: self.date_expires_gmt,
90            individual_use: self.individual_use,
91            product_ids: self.product_ids,
92            excluded_product_ids: self.excluded_product_ids,
93            usage_limit: self.usage_limit,
94            usage_limit_per_user: self.usage_limit_per_user,
95            limit_usage_to_x_items: self.limit_usage_to_x_items,
96            free_shipping: self.free_shipping,
97            product_categories: self.product_categories,
98            excluded_product_categories: self.excluded_product_categories,
99            exclude_sale_items: self.exclude_sale_items,
100            minimum_amount: self.minimum_amount,
101            maximum_amount: self.maximum_amount,
102            email_restrictions: self.email_restrictions,
103            meta_data: self.meta_data,
104        }
105    }
106    /// Determines the type of discount that will be applied.
107    pub fn discount_type(
108        self,
109        discount_type: DiscountType,
110    ) -> CreateCouponBuilder<C, WithDiscountType, A> {
111        CreateCouponBuilder {
112            code: self.code,
113            discount_type: WithDiscountType(discount_type),
114            amount: self.amount,
115            description: self.description,
116            date_expires: self.date_expires,
117            date_expires_gmt: self.date_expires_gmt,
118            individual_use: self.individual_use,
119            product_ids: self.product_ids,
120            excluded_product_ids: self.excluded_product_ids,
121            usage_limit: self.usage_limit,
122            usage_limit_per_user: self.usage_limit_per_user,
123            limit_usage_to_x_items: self.limit_usage_to_x_items,
124            free_shipping: self.free_shipping,
125            product_categories: self.product_categories,
126            excluded_product_categories: self.excluded_product_categories,
127            exclude_sale_items: self.exclude_sale_items,
128            minimum_amount: self.minimum_amount,
129            maximum_amount: self.maximum_amount,
130            email_restrictions: self.email_restrictions,
131            meta_data: self.meta_data,
132        }
133    }
134    /// The amount of discount. Should always be numeric, even if setting a percentage.
135    pub fn amount(self, amount: impl Into<String>) -> CreateCouponBuilder<C, D, WithAmount> {
136        CreateCouponBuilder {
137            code: self.code,
138            discount_type: self.discount_type,
139            amount: WithAmount(amount.into()),
140            description: self.description,
141            date_expires: self.date_expires,
142            date_expires_gmt: self.date_expires_gmt,
143            individual_use: self.individual_use,
144            product_ids: self.product_ids,
145            excluded_product_ids: self.excluded_product_ids,
146            usage_limit: self.usage_limit,
147            usage_limit_per_user: self.usage_limit_per_user,
148            limit_usage_to_x_items: self.limit_usage_to_x_items,
149            free_shipping: self.free_shipping,
150            product_categories: self.product_categories,
151            excluded_product_categories: self.excluded_product_categories,
152            exclude_sale_items: self.exclude_sale_items,
153            minimum_amount: self.minimum_amount,
154            maximum_amount: self.maximum_amount,
155            email_restrictions: self.email_restrictions,
156            meta_data: self.meta_data,
157        }
158    }
159    /// Coupon description.
160    pub fn description(mut self, description: impl Into<String>) -> Self {
161        let _ = self.description.insert(description.into());
162        self
163    }
164    /// The date the coupon expires, in the site's timezone. Format: YEAR-MONTH-DAY. Example: "2024-01-31"
165    pub fn date_expires(mut self, date_expires: impl Into<String>) -> Self {
166        let _ = self.date_expires.insert(date_expires.into());
167        self
168    }
169    /// The date the coupon expires, as GMT.Format: YEAR-MONTH-DAY. Example: "2024-01-31"
170    pub fn date_expires_gmt(mut self, date_expires_gmt: impl Into<String>) -> Self {
171        let _ = self.date_expires_gmt.insert(date_expires_gmt.into());
172        self
173    }
174    /// If true, the coupon can only be used individually. Other applied coupons will be removed from the cart. Default is false.
175    pub fn individual_use(mut self) -> Self {
176        self.individual_use = true;
177        self
178    }
179    /// List of product IDs the coupon can be used on.
180    pub fn product_id(mut self, product_id: i32) -> Self {
181        self.product_ids.get_or_insert(vec![]).push(product_id);
182        self
183    }
184    /// List of product IDs the coupon cannot be used on.
185    pub fn excluded_product_id(mut self, excluded_product_id: i32) -> Self {
186        self.excluded_product_ids
187            .get_or_insert(vec![])
188            .push(excluded_product_id);
189        self
190    }
191    /// How many times the coupon can be used in total.
192    pub fn usage_limit(mut self, usage_limit: i32) -> Self {
193        let _ = self.usage_limit.insert(usage_limit);
194        self
195    }
196    /// How many times the coupon can be used per customer.
197    pub fn usage_limit_per_user(mut self, usage_limit_per_user: i32) -> Self {
198        let _ = self.usage_limit_per_user.insert(usage_limit_per_user);
199        self
200    }
201    /// Max number of items in the cart the coupon can be applied to.
202    pub fn limit_usage_to_x_items(mut self, limit_usage_to_x_items: i32) -> Self {
203        let _ = self.limit_usage_to_x_items.insert(limit_usage_to_x_items);
204        self
205    }
206    /// If true and if the free shipping method requires a coupon, this coupon will enable free shipping. Default is false.
207    pub fn free_shipping(mut self) -> Self {
208        self.free_shipping = true;
209        self
210    }
211    /// List of category IDs the coupon applies to.
212    pub fn product_category(mut self, category_id: i32) -> Self {
213        self.product_categories
214            .get_or_insert(vec![])
215            .push(category_id);
216        self
217    }
218    /// List of category IDs the coupon does not apply to.
219    pub fn excluded_product_category(mut self, exclude_product_category_id: i32) -> Self {
220        self.excluded_product_categories
221            .get_or_insert(vec![])
222            .push(exclude_product_category_id);
223        self
224    }
225    /// If true, this coupon will not be applied to items that have sale prices. Default is false.
226    pub fn exclude_sale_items(mut self) -> Self {
227        self.exclude_sale_items = true;
228        self
229    }
230    /// Minimum order amount that needs to be in the cart before coupon applies.
231    pub fn minimum_amount(mut self, minimum_amount: impl Into<String>) -> Self {
232        let _ = self.minimum_amount.insert(minimum_amount.into());
233        self
234    }
235    /// Maximum order amount allowed when using the coupon.
236    pub fn maximum_amount(mut self, maximum_amount: impl Into<String>) -> Self {
237        let _ = self.maximum_amount.insert(maximum_amount.into());
238        self
239    }
240    /// List of email addresses that can use this coupon.
241    pub fn email_restriction(mut self, email: impl Into<String>) -> Self {
242        self.email_restrictions
243            .get_or_insert(vec![])
244            .push(email.into());
245        self
246    }
247    /// Meta data.
248    pub fn meta_data(mut self, key: impl Into<String>, value: impl serde::Serialize) -> Self {
249        self.meta_data.get_or_insert(vec![]).push(MetaData {
250            id: None,
251            key: key.into(),
252            value: serde_json::json!(value),
253        });
254        self
255    }
256}
257impl CreateCouponBuilder<WithCode, WithDiscountType, WithAmount> {
258    pub fn build(self) -> CreateCoupon {
259        CreateCoupon {
260            code: self.code.0,
261            discount_type: self.discount_type.0,
262            amount: self.amount.0,
263            description: self.description,
264            date_expires: self.date_expires,
265            date_expires_gmt: self.date_expires_gmt,
266            individual_use: self.individual_use,
267            product_ids: self.product_ids,
268            excluded_product_ids: self.excluded_product_ids,
269            usage_limit: self.usage_limit,
270            usage_limit_per_user: self.usage_limit_per_user,
271            limit_usage_to_x_items: self.limit_usage_to_x_items,
272            free_shipping: self.free_shipping,
273            product_categories: self.product_categories,
274            excluded_product_categories: self.excluded_product_categories,
275            exclude_sale_items: self.exclude_sale_items,
276            minimum_amount: self.minimum_amount,
277            maximum_amount: self.maximum_amount,
278            email_restrictions: self.email_restrictions,
279            meta_data: self.meta_data,
280        }
281    }
282}
283#[skip_serializing_none]
284#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Default)]
285pub struct UpdateCoupon {
286    id: Option<i32>,
287    code: Option<String>,
288    discount_type: Option<DiscountType>,
289    amount: Option<String>,
290    description: Option<String>,
291    date_expires: Option<String>,
292    date_expires_gmt: Option<String>,
293    individual_use: Option<bool>,
294    product_ids: Option<Vec<i32>>,
295    excluded_product_ids: Option<Vec<i32>>,
296    usage_limit: Option<i32>,
297    usage_limit_per_user: Option<i32>,
298    limit_usage_to_x_items: Option<i32>,
299    free_shipping: Option<bool>,
300    product_categories: Option<Vec<i32>>,
301    excluded_product_categories: Option<Vec<i32>>,
302    exclude_sale_items: Option<bool>,
303    minimum_amount: Option<String>,
304    maximum_amount: Option<String>,
305    email_restrictions: Option<Vec<String>>,
306    meta_data: Option<Vec<MetaData>>,
307}
308impl UpdateCoupon {
309    pub fn builder() -> UpdateCouponBuilder {
310        UpdateCouponBuilder::default()
311    }
312}
313#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Default)]
314pub struct UpdateCouponBuilder {
315    id: Option<i32>,
316    code: Option<String>,
317    discount_type: Option<DiscountType>,
318    amount: Option<String>,
319    description: Option<String>,
320    date_expires: Option<String>,
321    date_expires_gmt: Option<String>,
322    individual_use: Option<bool>,
323    product_ids: Option<Vec<i32>>,
324    excluded_product_ids: Option<Vec<i32>>,
325    usage_limit: Option<i32>,
326    usage_limit_per_user: Option<i32>,
327    limit_usage_to_x_items: Option<i32>,
328    free_shipping: Option<bool>,
329    product_categories: Option<Vec<i32>>,
330    excluded_product_categories: Option<Vec<i32>>,
331    exclude_sale_items: Option<bool>,
332    minimum_amount: Option<String>,
333    maximum_amount: Option<String>,
334    email_restrictions: Option<Vec<String>>,
335    meta_data: Option<Vec<MetaData>>,
336}
337impl UpdateCouponBuilder {
338    /// Unique identifier for the object.
339    pub fn id(&mut self, id: i32) -> &mut Self {
340        let _ = self.id.insert(id);
341        self
342    }
343    /// Coupon code.
344    pub fn code(&mut self, code: impl Into<String>) -> &mut Self {
345        let _ = self.code.insert(code.into());
346        self
347    }
348    /// Determines the type of discount that will be applied.
349    pub fn discount_type(&mut self, discount_type: DiscountType) -> &mut Self {
350        let _ = self.discount_type.insert(discount_type);
351        self
352    }
353    /// The amount of discount. Should always be numeric, even if setting a percentage.
354    pub fn amount(&mut self, amount: impl Into<String>) -> &mut Self {
355        let _ = self.amount.insert(amount.into());
356        self
357    }
358    /// Coupon description.
359    pub fn description(&mut self, description: impl Into<String>) -> &mut Self {
360        let _ = self.description.insert(description.into());
361        self
362    }
363    /// The date the coupon expires, in the site's timezone. Format: YEAR-MONTH-DAY. Example: "2024-01-31"
364    pub fn date_expires(&mut self, date_expires: impl Into<String>) -> &mut Self {
365        let _ = self.date_expires.insert(date_expires.into());
366        self
367    }
368    /// The date the coupon expires, as GMT.Format: YEAR-MONTH-DAY. Example: "2024-01-31"
369    pub fn date_expires_gmt(&mut self, date_expires_gmt: impl Into<String>) -> &mut Self {
370        let _ = self.date_expires_gmt.insert(date_expires_gmt.into());
371        self
372    }
373    /// If true, the coupon can only be used individually. Other applied coupons will be removed from the cart. Default is false.
374    pub fn individual_use(&mut self, individual_use: bool) -> &mut Self {
375        let _ = self.individual_use.insert(individual_use);
376        self
377    }
378    /// List of product IDs the coupon can be used on.
379    pub fn product_id(&mut self, product_id: i32) -> &mut Self {
380        self.product_ids.get_or_insert(vec![]).push(product_id);
381        self
382    }
383    /// List of product IDs the coupon cannot be used on.
384    pub fn excluded_product_id(&mut self, excluded_product_id: i32) -> &mut Self {
385        self.excluded_product_ids
386            .get_or_insert(vec![])
387            .push(excluded_product_id);
388        self
389    }
390    /// How many times the coupon can be used in total.
391    pub fn usage_limit(&mut self, usage_limit: i32) -> &mut Self {
392        let _ = self.usage_limit.insert(usage_limit);
393        self
394    }
395    /// How many times the coupon can be used per customer.
396    pub fn usage_limit_per_user(&mut self, usage_limit_per_user: i32) -> &mut Self {
397        let _ = self.usage_limit_per_user.insert(usage_limit_per_user);
398        self
399    }
400    /// Max number of items in the cart the coupon can be applied to.
401    pub fn limit_usage_to_x_items(&mut self, limit_usage_to_x_items: i32) -> &mut Self {
402        let _ = self.limit_usage_to_x_items.insert(limit_usage_to_x_items);
403        self
404    }
405    /// If true and if the free shipping method requires a coupon, this coupon will enable free shipping. Default is false.
406    pub fn free_shipping(&mut self, free_shipping: bool) -> &mut Self {
407        let _ = self.free_shipping.insert(free_shipping);
408        self
409    }
410    /// List of category IDs the coupon applies to.
411    pub fn product_category(&mut self, category_id: i32) -> &mut Self {
412        self.product_categories
413            .get_or_insert(vec![])
414            .push(category_id);
415        self
416    }
417    /// List of category IDs the coupon does not apply to.
418    pub fn excluded_product_category(&mut self, exclude_product_category_id: i32) -> &mut Self {
419        self.excluded_product_categories
420            .get_or_insert(vec![])
421            .push(exclude_product_category_id);
422        self
423    }
424    /// If true, this coupon will not be applied to items that have sale prices. Default is false.
425    pub fn exclude_sale_items(&mut self, exclude_sale_items: bool) -> &mut Self {
426        let _ = self.exclude_sale_items.insert(exclude_sale_items);
427        self
428    }
429    /// Minimum order amount that needs to be in the cart before coupon applies.
430    pub fn minimum_amount(&mut self, minimum_amount: impl Into<String>) -> &mut Self {
431        let _ = self.minimum_amount.insert(minimum_amount.into());
432        self
433    }
434    /// Maximum order amount allowed when using the coupon.
435    pub fn maximum_amount(&mut self, maximum_amount: impl Into<String>) -> &mut Self {
436        let _ = self.maximum_amount.insert(maximum_amount.into());
437        self
438    }
439    /// List of email addresses that can use this coupon.
440    pub fn email_restriction(&mut self, email: impl Into<String>) -> &mut Self {
441        self.email_restrictions
442            .get_or_insert(vec![])
443            .push(email.into());
444        self
445    }
446    /// Meta data.
447    pub fn meta_data(&mut self, key: impl Into<String>, value: impl serde::Serialize) -> &mut Self {
448        self.meta_data.get_or_insert(vec![]).push(MetaData {
449            id: None,
450            key: key.into(),
451            value: serde_json::json!(value),
452        });
453        self
454    }
455    pub fn build(&self) -> UpdateCoupon {
456        UpdateCoupon {
457            id: self.id,
458            code: self.code.clone(),
459            discount_type: self.discount_type.clone(),
460            amount: self.amount.clone(),
461            description: self.description.clone(),
462            date_expires: self.date_expires.clone(),
463            date_expires_gmt: self.date_expires_gmt.clone(),
464            individual_use: self.individual_use,
465            product_ids: self.product_ids.clone(),
466            excluded_product_ids: self.excluded_product_ids.clone(),
467            usage_limit: self.usage_limit,
468            usage_limit_per_user: self.usage_limit_per_user,
469            limit_usage_to_x_items: self.limit_usage_to_x_items,
470            free_shipping: self.free_shipping,
471            product_categories: self.product_categories.clone(),
472            excluded_product_categories: self.excluded_product_categories.clone(),
473            exclude_sale_items: self.exclude_sale_items,
474            minimum_amount: self.minimum_amount.clone(),
475            maximum_amount: self.maximum_amount.clone(),
476            email_restrictions: self.email_restrictions.clone(),
477            meta_data: self.meta_data.clone(),
478        }
479    }
480}