Skip to main content

lago_types/requests/
plan.rs

1use serde::{Deserialize, Serialize};
2
3use crate::filters::common::ListFilters;
4use crate::filters::plan::PlanFilters;
5use crate::models::{ChargeModel, PaginationParams, PlanInterval};
6
7/// Request parameters for listing plans.
8#[derive(Debug, Clone)]
9pub struct ListPlansRequest {
10    pub pagination: PaginationParams,
11    pub filters: PlanFilters,
12}
13
14impl ListPlansRequest {
15    /// Creates a new empty list plans request.
16    pub fn new() -> Self {
17        Self {
18            pagination: PaginationParams::default(),
19            filters: PlanFilters::default(),
20        }
21    }
22
23    /// Sets the pagination parameters for the request.
24    pub fn with_pagination(mut self, pagination: PaginationParams) -> Self {
25        self.pagination = pagination;
26        self
27    }
28
29    /// Sets the plan filters for the request.
30    pub fn with_filters(mut self, filters: PlanFilters) -> Self {
31        self.filters = filters;
32        self
33    }
34
35    /// Converts the request parameters into HTTP query parameters.
36    pub fn to_query_params(&self) -> Vec<(&str, String)> {
37        let mut params = self.pagination.to_query_params();
38        params.extend(self.filters.to_query_params());
39        params
40    }
41}
42
43impl Default for ListPlansRequest {
44    fn default() -> Self {
45        Self::new()
46    }
47}
48
49/// Request parameters for retrieving a specific plan.
50#[derive(Debug, Clone)]
51pub struct GetPlanRequest {
52    /// The unique code of the plan.
53    pub code: String,
54}
55
56impl GetPlanRequest {
57    /// Creates a new get plan request.
58    pub fn new(code: String) -> Self {
59        Self { code }
60    }
61}
62
63/// Input data for creating a plan charge.
64#[derive(Debug, Clone, Serialize, Deserialize)]
65pub struct CreatePlanChargeInput {
66    /// The billable metric ID to reference.
67    pub billable_metric_id: String,
68    /// The charge model to use.
69    pub charge_model: ChargeModel,
70    /// Whether the charge is invoiceable.
71    #[serde(skip_serializing_if = "Option::is_none")]
72    pub invoiceable: Option<bool>,
73    /// Display name for the charge on invoices.
74    #[serde(skip_serializing_if = "Option::is_none")]
75    pub invoice_display_name: Option<String>,
76    /// Whether the charge is billed in advance.
77    #[serde(skip_serializing_if = "Option::is_none")]
78    pub pay_in_advance: Option<bool>,
79    /// Whether the charge is prorated.
80    #[serde(skip_serializing_if = "Option::is_none")]
81    pub prorated: Option<bool>,
82    /// Minimum amount in cents for this charge.
83    #[serde(skip_serializing_if = "Option::is_none")]
84    pub min_amount_cents: Option<i64>,
85    /// Charge properties (model-specific configuration).
86    #[serde(skip_serializing_if = "Option::is_none")]
87    pub properties: Option<serde_json::Value>,
88    /// Tax codes for this charge.
89    #[serde(skip_serializing_if = "Option::is_none")]
90    pub tax_codes: Option<Vec<String>>,
91    /// Filters for differentiated pricing.
92    #[serde(skip_serializing_if = "Option::is_none")]
93    pub filters: Option<Vec<CreateChargeFilterInput>>,
94    /// The regroup paid fees option.
95    #[serde(skip_serializing_if = "Option::is_none")]
96    pub regroup_paid_fees: Option<String>,
97}
98
99impl CreatePlanChargeInput {
100    /// Creates a new plan charge input.
101    pub fn new(billable_metric_id: String, charge_model: ChargeModel) -> Self {
102        Self {
103            billable_metric_id,
104            charge_model,
105            invoiceable: None,
106            invoice_display_name: None,
107            pay_in_advance: None,
108            prorated: None,
109            min_amount_cents: None,
110            properties: None,
111            tax_codes: None,
112            filters: None,
113            regroup_paid_fees: None,
114        }
115    }
116
117    /// Sets the invoiceable flag.
118    pub fn with_invoiceable(mut self, invoiceable: bool) -> Self {
119        self.invoiceable = Some(invoiceable);
120        self
121    }
122
123    /// Sets the invoice display name.
124    pub fn with_invoice_display_name(mut self, name: String) -> Self {
125        self.invoice_display_name = Some(name);
126        self
127    }
128
129    /// Sets the pay in advance flag.
130    pub fn with_pay_in_advance(mut self, pay_in_advance: bool) -> Self {
131        self.pay_in_advance = Some(pay_in_advance);
132        self
133    }
134
135    /// Sets the prorated flag.
136    pub fn with_prorated(mut self, prorated: bool) -> Self {
137        self.prorated = Some(prorated);
138        self
139    }
140
141    /// Sets the minimum amount in cents.
142    pub fn with_min_amount_cents(mut self, min_amount_cents: i64) -> Self {
143        self.min_amount_cents = Some(min_amount_cents);
144        self
145    }
146
147    /// Sets the charge properties.
148    pub fn with_properties(mut self, properties: serde_json::Value) -> Self {
149        self.properties = Some(properties);
150        self
151    }
152
153    /// Sets the tax codes.
154    pub fn with_tax_codes(mut self, tax_codes: Vec<String>) -> Self {
155        self.tax_codes = Some(tax_codes);
156        self
157    }
158
159    /// Sets the filters.
160    pub fn with_filters(mut self, filters: Vec<CreateChargeFilterInput>) -> Self {
161        self.filters = Some(filters);
162        self
163    }
164}
165
166/// Input data for creating a charge filter.
167#[derive(Debug, Clone, Serialize, Deserialize)]
168pub struct CreateChargeFilterInput {
169    /// Invoice display name for this filter.
170    #[serde(skip_serializing_if = "Option::is_none")]
171    pub invoice_display_name: Option<String>,
172    /// Filter properties.
173    #[serde(skip_serializing_if = "Option::is_none")]
174    pub properties: Option<serde_json::Value>,
175    /// Filter values mapping.
176    #[serde(skip_serializing_if = "Option::is_none")]
177    pub values: Option<serde_json::Value>,
178}
179
180/// Input data for creating a minimum commitment.
181#[derive(Debug, Clone, Serialize, Deserialize)]
182pub struct CreateMinimumCommitmentInput {
183    /// Minimum commitment amount in cents.
184    pub amount_cents: i64,
185    /// Invoice display name for the minimum commitment.
186    #[serde(skip_serializing_if = "Option::is_none")]
187    pub invoice_display_name: Option<String>,
188    /// Tax codes for the minimum commitment.
189    #[serde(skip_serializing_if = "Option::is_none")]
190    pub tax_codes: Option<Vec<String>>,
191}
192
193impl CreateMinimumCommitmentInput {
194    /// Creates a new minimum commitment input.
195    pub fn new(amount_cents: i64) -> Self {
196        Self {
197            amount_cents,
198            invoice_display_name: None,
199            tax_codes: None,
200        }
201    }
202
203    /// Sets the invoice display name.
204    pub fn with_invoice_display_name(mut self, name: String) -> Self {
205        self.invoice_display_name = Some(name);
206        self
207    }
208
209    /// Sets the tax codes.
210    pub fn with_tax_codes(mut self, tax_codes: Vec<String>) -> Self {
211        self.tax_codes = Some(tax_codes);
212        self
213    }
214}
215
216/// Input data for creating a usage threshold.
217#[derive(Debug, Clone, Serialize, Deserialize)]
218pub struct CreateUsageThresholdInput {
219    /// Threshold amount in cents.
220    pub amount_cents: i64,
221    /// Display name for the threshold.
222    #[serde(skip_serializing_if = "Option::is_none")]
223    pub threshold_display_name: Option<String>,
224    /// Whether the threshold is recurring.
225    #[serde(skip_serializing_if = "Option::is_none")]
226    pub recurring: Option<bool>,
227}
228
229impl CreateUsageThresholdInput {
230    /// Creates a new usage threshold input.
231    pub fn new(amount_cents: i64) -> Self {
232        Self {
233            amount_cents,
234            threshold_display_name: None,
235            recurring: None,
236        }
237    }
238
239    /// Sets the threshold display name.
240    pub fn with_threshold_display_name(mut self, name: String) -> Self {
241        self.threshold_display_name = Some(name);
242        self
243    }
244
245    /// Sets the recurring flag.
246    pub fn with_recurring(mut self, recurring: bool) -> Self {
247        self.recurring = Some(recurring);
248        self
249    }
250}
251
252/// Input data for creating a plan.
253#[derive(Debug, Clone, Serialize, Deserialize)]
254pub struct CreatePlanInput {
255    /// Name of the plan.
256    pub name: String,
257    /// Unique code for the plan.
258    pub code: String,
259    /// Billing interval.
260    pub interval: PlanInterval,
261    /// Base amount in cents.
262    pub amount_cents: i64,
263    /// Currency for the amount.
264    pub amount_currency: String,
265    /// Display name for invoices.
266    #[serde(skip_serializing_if = "Option::is_none")]
267    pub invoice_display_name: Option<String>,
268    /// Description of the plan.
269    #[serde(skip_serializing_if = "Option::is_none")]
270    pub description: Option<String>,
271    /// Trial period in days.
272    #[serde(skip_serializing_if = "Option::is_none")]
273    pub trial_period: Option<f64>,
274    /// Whether the plan is billed in advance.
275    #[serde(skip_serializing_if = "Option::is_none")]
276    pub pay_in_advance: Option<bool>,
277    /// Whether charges are billed monthly for yearly plans.
278    #[serde(skip_serializing_if = "Option::is_none")]
279    pub bill_charges_monthly: Option<bool>,
280    /// Tax codes for this plan.
281    #[serde(skip_serializing_if = "Option::is_none")]
282    pub tax_codes: Option<Vec<String>>,
283    /// Charges for this plan.
284    #[serde(skip_serializing_if = "Option::is_none")]
285    pub charges: Option<Vec<CreatePlanChargeInput>>,
286    /// Minimum commitment for this plan.
287    #[serde(skip_serializing_if = "Option::is_none")]
288    pub minimum_commitment: Option<CreateMinimumCommitmentInput>,
289    /// Usage thresholds for progressive billing.
290    #[serde(skip_serializing_if = "Option::is_none")]
291    pub usage_thresholds: Option<Vec<CreateUsageThresholdInput>>,
292}
293
294impl CreatePlanInput {
295    /// Creates a new plan input with required fields.
296    pub fn new(
297        name: String,
298        code: String,
299        interval: PlanInterval,
300        amount_cents: i64,
301        amount_currency: String,
302    ) -> Self {
303        Self {
304            name,
305            code,
306            interval,
307            amount_cents,
308            amount_currency,
309            invoice_display_name: None,
310            description: None,
311            trial_period: None,
312            pay_in_advance: None,
313            bill_charges_monthly: None,
314            tax_codes: None,
315            charges: None,
316            minimum_commitment: None,
317            usage_thresholds: None,
318        }
319    }
320
321    /// Sets the invoice display name.
322    pub fn with_invoice_display_name(mut self, name: String) -> Self {
323        self.invoice_display_name = Some(name);
324        self
325    }
326
327    /// Sets the description.
328    pub fn with_description(mut self, description: String) -> Self {
329        self.description = Some(description);
330        self
331    }
332
333    /// Sets the trial period in days.
334    pub fn with_trial_period(mut self, days: f64) -> Self {
335        self.trial_period = Some(days);
336        self
337    }
338
339    /// Sets whether the plan is billed in advance.
340    pub fn with_pay_in_advance(mut self, pay_in_advance: bool) -> Self {
341        self.pay_in_advance = Some(pay_in_advance);
342        self
343    }
344
345    /// Sets whether charges are billed monthly.
346    pub fn with_bill_charges_monthly(mut self, bill_charges_monthly: bool) -> Self {
347        self.bill_charges_monthly = Some(bill_charges_monthly);
348        self
349    }
350
351    /// Sets the tax codes.
352    pub fn with_tax_codes(mut self, tax_codes: Vec<String>) -> Self {
353        self.tax_codes = Some(tax_codes);
354        self
355    }
356
357    /// Sets the charges.
358    pub fn with_charges(mut self, charges: Vec<CreatePlanChargeInput>) -> Self {
359        self.charges = Some(charges);
360        self
361    }
362
363    /// Sets the minimum commitment.
364    pub fn with_minimum_commitment(
365        mut self,
366        minimum_commitment: CreateMinimumCommitmentInput,
367    ) -> Self {
368        self.minimum_commitment = Some(minimum_commitment);
369        self
370    }
371
372    /// Sets the usage thresholds.
373    pub fn with_usage_thresholds(
374        mut self,
375        usage_thresholds: Vec<CreateUsageThresholdInput>,
376    ) -> Self {
377        self.usage_thresholds = Some(usage_thresholds);
378        self
379    }
380}
381
382/// Request for creating a plan.
383#[derive(Debug, Clone, Serialize)]
384pub struct CreatePlanRequest {
385    pub plan: CreatePlanInput,
386}
387
388impl CreatePlanRequest {
389    /// Creates a new create plan request.
390    pub fn new(input: CreatePlanInput) -> Self {
391        Self { plan: input }
392    }
393}
394
395/// Input data for updating a plan.
396#[derive(Debug, Clone, Serialize, Deserialize)]
397pub struct UpdatePlanInput {
398    /// Name of the plan.
399    #[serde(skip_serializing_if = "Option::is_none")]
400    pub name: Option<String>,
401    /// Unique code for the plan.
402    #[serde(skip_serializing_if = "Option::is_none")]
403    pub code: Option<String>,
404    /// Billing interval.
405    #[serde(skip_serializing_if = "Option::is_none")]
406    pub interval: Option<PlanInterval>,
407    /// Base amount in cents.
408    #[serde(skip_serializing_if = "Option::is_none")]
409    pub amount_cents: Option<i64>,
410    /// Currency for the amount.
411    #[serde(skip_serializing_if = "Option::is_none")]
412    pub amount_currency: Option<String>,
413    /// Display name for invoices.
414    #[serde(skip_serializing_if = "Option::is_none")]
415    pub invoice_display_name: Option<String>,
416    /// Description of the plan.
417    #[serde(skip_serializing_if = "Option::is_none")]
418    pub description: Option<String>,
419    /// Trial period in days.
420    #[serde(skip_serializing_if = "Option::is_none")]
421    pub trial_period: Option<f64>,
422    /// Whether the plan is billed in advance.
423    #[serde(skip_serializing_if = "Option::is_none")]
424    pub pay_in_advance: Option<bool>,
425    /// Whether charges are billed monthly for yearly plans.
426    #[serde(skip_serializing_if = "Option::is_none")]
427    pub bill_charges_monthly: Option<bool>,
428    /// Tax codes for this plan.
429    #[serde(skip_serializing_if = "Option::is_none")]
430    pub tax_codes: Option<Vec<String>>,
431    /// Charges for this plan.
432    #[serde(skip_serializing_if = "Option::is_none")]
433    pub charges: Option<Vec<CreatePlanChargeInput>>,
434    /// Minimum commitment for this plan.
435    #[serde(skip_serializing_if = "Option::is_none")]
436    pub minimum_commitment: Option<CreateMinimumCommitmentInput>,
437    /// Usage thresholds for progressive billing.
438    #[serde(skip_serializing_if = "Option::is_none")]
439    pub usage_thresholds: Option<Vec<CreateUsageThresholdInput>>,
440    /// Whether to cascade updates to existing subscriptions.
441    #[serde(skip_serializing_if = "Option::is_none")]
442    pub cascade_updates: Option<bool>,
443}
444
445impl UpdatePlanInput {
446    /// Creates a new empty update plan input.
447    pub fn new() -> Self {
448        Self {
449            name: None,
450            code: None,
451            interval: None,
452            amount_cents: None,
453            amount_currency: None,
454            invoice_display_name: None,
455            description: None,
456            trial_period: None,
457            pay_in_advance: None,
458            bill_charges_monthly: None,
459            tax_codes: None,
460            charges: None,
461            minimum_commitment: None,
462            usage_thresholds: None,
463            cascade_updates: None,
464        }
465    }
466
467    /// Sets the name.
468    pub fn with_name(mut self, name: String) -> Self {
469        self.name = Some(name);
470        self
471    }
472
473    /// Sets the code.
474    pub fn with_code(mut self, code: String) -> Self {
475        self.code = Some(code);
476        self
477    }
478
479    /// Sets the interval.
480    pub fn with_interval(mut self, interval: PlanInterval) -> Self {
481        self.interval = Some(interval);
482        self
483    }
484
485    /// Sets the amount in cents.
486    pub fn with_amount_cents(mut self, amount_cents: i64) -> Self {
487        self.amount_cents = Some(amount_cents);
488        self
489    }
490
491    /// Sets the currency.
492    pub fn with_amount_currency(mut self, currency: String) -> Self {
493        self.amount_currency = Some(currency);
494        self
495    }
496
497    /// Sets the invoice display name.
498    pub fn with_invoice_display_name(mut self, name: String) -> Self {
499        self.invoice_display_name = Some(name);
500        self
501    }
502
503    /// Sets the description.
504    pub fn with_description(mut self, description: String) -> Self {
505        self.description = Some(description);
506        self
507    }
508
509    /// Sets the trial period in days.
510    pub fn with_trial_period(mut self, days: f64) -> Self {
511        self.trial_period = Some(days);
512        self
513    }
514
515    /// Sets whether the plan is billed in advance.
516    pub fn with_pay_in_advance(mut self, pay_in_advance: bool) -> Self {
517        self.pay_in_advance = Some(pay_in_advance);
518        self
519    }
520
521    /// Sets whether charges are billed monthly.
522    pub fn with_bill_charges_monthly(mut self, bill_charges_monthly: bool) -> Self {
523        self.bill_charges_monthly = Some(bill_charges_monthly);
524        self
525    }
526
527    /// Sets the tax codes.
528    pub fn with_tax_codes(mut self, tax_codes: Vec<String>) -> Self {
529        self.tax_codes = Some(tax_codes);
530        self
531    }
532
533    /// Sets the charges.
534    pub fn with_charges(mut self, charges: Vec<CreatePlanChargeInput>) -> Self {
535        self.charges = Some(charges);
536        self
537    }
538
539    /// Sets the minimum commitment.
540    pub fn with_minimum_commitment(
541        mut self,
542        minimum_commitment: CreateMinimumCommitmentInput,
543    ) -> Self {
544        self.minimum_commitment = Some(minimum_commitment);
545        self
546    }
547
548    /// Sets the usage thresholds.
549    pub fn with_usage_thresholds(
550        mut self,
551        usage_thresholds: Vec<CreateUsageThresholdInput>,
552    ) -> Self {
553        self.usage_thresholds = Some(usage_thresholds);
554        self
555    }
556
557    /// Sets whether to cascade updates to existing subscriptions.
558    pub fn with_cascade_updates(mut self, cascade_updates: bool) -> Self {
559        self.cascade_updates = Some(cascade_updates);
560        self
561    }
562}
563
564impl Default for UpdatePlanInput {
565    fn default() -> Self {
566        Self::new()
567    }
568}
569
570/// Request for updating a plan.
571#[derive(Debug, Clone, Serialize)]
572pub struct UpdatePlanRequest {
573    /// The code of the plan to update.
574    #[serde(skip)]
575    pub code: String,
576    /// The plan update data.
577    pub plan: UpdatePlanInput,
578}
579
580impl UpdatePlanRequest {
581    /// Creates a new update plan request.
582    pub fn new(code: String, input: UpdatePlanInput) -> Self {
583        Self { code, plan: input }
584    }
585}
586
587/// Request for deleting a plan.
588#[derive(Debug, Clone)]
589pub struct DeletePlanRequest {
590    /// The code of the plan to delete.
591    pub code: String,
592}
593
594impl DeletePlanRequest {
595    /// Creates a new delete plan request.
596    pub fn new(code: String) -> Self {
597        Self { code }
598    }
599}