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 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 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 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 pub fn description(mut self, description: impl Into<String>) -> Self {
161 let _ = self.description.insert(description.into());
162 self
163 }
164 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 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 pub fn individual_use(mut self) -> Self {
176 self.individual_use = true;
177 self
178 }
179 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 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 pub fn usage_limit(mut self, usage_limit: i32) -> Self {
193 let _ = self.usage_limit.insert(usage_limit);
194 self
195 }
196 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 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 pub fn free_shipping(mut self) -> Self {
208 self.free_shipping = true;
209 self
210 }
211 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 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 pub fn exclude_sale_items(mut self) -> Self {
227 self.exclude_sale_items = true;
228 self
229 }
230 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 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 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 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 pub fn id(&mut self, id: i32) -> &mut Self {
340 let _ = self.id.insert(id);
341 self
342 }
343 pub fn code(&mut self, code: impl Into<String>) -> &mut Self {
345 let _ = self.code.insert(code.into());
346 self
347 }
348 pub fn discount_type(&mut self, discount_type: DiscountType) -> &mut Self {
350 let _ = self.discount_type.insert(discount_type);
351 self
352 }
353 pub fn amount(&mut self, amount: impl Into<String>) -> &mut Self {
355 let _ = self.amount.insert(amount.into());
356 self
357 }
358 pub fn description(&mut self, description: impl Into<String>) -> &mut Self {
360 let _ = self.description.insert(description.into());
361 self
362 }
363 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 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 pub fn individual_use(&mut self, individual_use: bool) -> &mut Self {
375 let _ = self.individual_use.insert(individual_use);
376 self
377 }
378 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 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 pub fn usage_limit(&mut self, usage_limit: i32) -> &mut Self {
392 let _ = self.usage_limit.insert(usage_limit);
393 self
394 }
395 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 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 pub fn free_shipping(&mut self, free_shipping: bool) -> &mut Self {
407 let _ = self.free_shipping.insert(free_shipping);
408 self
409 }
410 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 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 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 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 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 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 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}