quickbooks_types/reports/
types.rs

1use std::borrow::Cow;
2
3use super::params::{
4    AccountId, AccountingMethod, AgingMethod, ArPaid, AttachmentType, Cleared, CustomerId,
5    DateMacro, HasValue, ItemId, Printed, SortOrder, SummarizeColumnBy, TermId, VendorId,
6};
7use chrono::NaiveDate;
8
9/// Represents parameters for `QuickBooks` reports.
10pub trait QBReportParams {
11    fn params(&self) -> impl Iterator<Item = (&'static str, Cow<'_, str>)>;
12    fn to_query_string(&self) -> String {
13        self.params()
14            .map(|(name, value)| format!("{name}={value}"))
15            .collect::<Vec<_>>()
16            .join("&")
17    }
18}
19
20/// Represents a type of `QuickBooks` report.
21pub trait QBReportType {
22    type QueryParams: QBReportParams;
23    fn url_name(&self) -> &'static str;
24}
25
26use paste::paste;
27
28macro_rules! impl_report_type {
29  ($(
30    $report_ty:ident, $url_name:expr, [$($param:tt),* $(,)?]; $(($doc:expr))?
31  )*
32  $(;)?) => {
33    $(
34
35    paste! {
36      #[doc = "Type to represent the `" $report_ty "` report in quickbooks:\n\nAPI Reference:\n<https://developer.intuit.com/app/developer/qbo/docs/api/accounting/report-entities/" [<$report_ty:lower>] ">\n\n" $($doc)?]
37      pub struct $report_ty;
38
39      impl QBReportType for $report_ty {
40        type QueryParams = [<$report_ty Params>];
41        fn url_name(&self) -> &'static str {
42          $url_name
43        }
44      }
45
46      #[derive(Debug, Default)]
47      #[allow(non_snake_case)]
48      #[doc = "Parameters for the `" $report_ty "` report.\n\n" $($doc)?]
49      pub struct [<$report_ty Params>] {
50        $(
51        pub $param: Option<impl_report_type!(@param_type $param)>,
52        )*
53      }
54
55      impl [<$report_ty Params>] {
56        #[must_use]
57        pub fn new() -> Self {
58          Self {
59            $(
60            $param: None,
61            )*
62          }
63        }
64
65        $(
66          impl_report_type!(@param_method $param);
67        )*
68
69        fn iter_params(&self) -> impl Iterator<Item = (&'static str, Option<Cow<'_, str>>)> {
70          [
71            $(
72              (stringify!($param), self.$param.as_ref().map(|p| p.value())),
73            )*
74          ]
75          .into_iter()
76        }
77      }
78
79      impl QBReportParams for [<$report_ty Params>] {
80        fn params(&self) -> impl Iterator<Item = (&'static str, Cow<'_, str>)> {
81          self.iter_params().filter_map(|(name, value)| {
82            value.map(|v| (name, v))
83          })
84        }
85      }
86    }
87    )+
88  };
89
90  // Generic handler for vector parameters
91  (@param_method_vec $param:tt, $id_type:ty) => {
92    #[must_use]
93    pub fn $param(mut self, param: impl Into<$id_type>) -> Self {
94      if let Some(ref mut vec) = self.$param {
95        vec.push(param.into());
96      } else {
97        self.$param = Some(vec![param.into()]);
98      }
99      self
100    }
101
102    paste! {
103      #[must_use]
104      pub fn [<$param s>](mut self, params: Vec<$id_type>) -> Self {
105        self.$param = Some(params);
106        self
107      }
108    }
109  };
110
111  // Apply vector method for each vector parameter
112  (@param_method vendor) => { impl_report_type!(@param_method_vec vendor, VendorId); };
113  (@param_method customer) => { impl_report_type!(@param_method_vec customer, CustomerId); };
114  (@param_method term) => { impl_report_type!(@param_method_vec term, TermId); };
115  (@param_method item) => { impl_report_type!(@param_method_vec item, ItemId); };
116  (@param_method account) => { impl_report_type!(@param_method_vec account, AccountId); };
117  (@param_method source_account) => { impl_report_type!(@param_method_vec source_account, AccountId); };
118  // Special case for columns as it ends with an 's' yet is also a vector
119  (@param_method columns) => {
120    #[must_use]
121    pub fn columns(mut self, params: Vec<String>) -> Self {
122      self.columns = Some(params);
123      self
124    }
125
126    #[must_use]
127    pub fn column(mut self, param: impl Into<String>) -> Self {
128      if let Some(ref mut vec) = self.columns {
129        vec.push(param.into());
130      } else {
131        self.columns = Some(vec![param.into()]);
132      }
133      self
134    }
135  };
136
137  // Simple setter for non-vector parameters
138  (@param_method $param:tt) => {
139    #[must_use]
140    pub fn $param(mut self, param: impl Into<impl_report_type!(@param_type $param)>) -> Self {
141      self.$param = Some(param.into());
142      self
143    }
144  };
145
146  // Helper macro to map parameter names to appropriate types
147  (@param_type vendor) => { Vec<VendorId> };
148  (@param_type customer) => { Vec<CustomerId> };
149  (@param_type term) => { Vec<TermId> };
150  (@param_type item) => { Vec<ItemId> };
151  (@param_type account) => { Vec<AccountId> };
152  (@param_type columns) => { Vec<String> };
153  (@param_type source_account) => { Vec<AccountId> };
154  (@param_type accounting_method) => { AccountingMethod };
155  (@param_type date_macro) => { DateMacro };
156  (@param_type start_date) => { NaiveDate };
157  (@param_type end_date) => { NaiveDate };
158  (@param_type summarize_column_by) => { SummarizeColumnBy };
159  (@param_type as_of_date) => { NaiveDate };
160  (@param_type aging_method) => { AgingMethod };
161  (@param_type arpaid) => { ArPaid };
162  (@param_type qzurl) => { String };
163  (@param_type department) => { String };
164  (@param_type report_date) => { NaiveDate };
165  (@param_type sort_order) => { SortOrder };
166  (@param_type shipvia) => { String };
167  (@param_type end_duedate) => { NaiveDate };
168  (@param_type start_duedate) => { NaiveDate };
169  (@param_type custom1) => { String };
170  (@param_type custom2) => { String };
171  (@param_type custom3) => { String };
172  (@param_type num_periods) => { u32 };
173  (@param_type past_due) => { String };
174  (@param_type aging_period) => { String };
175  (@param_type adjusted_gain_loss) => { String };
176  (@param_type class) => { String };
177  (@param_type sort_by) => { String };
178  (@param_type attachment_type) => { AttachmentType };
179  (@param_type with_qbo_identifier) => { bool };
180  (@param_type add_due_date) => { String };
181  (@param_type account_type) => { String };
182  (@param_type end_svcdate) => { NaiveDate };
183  (@param_type svcdate_macro) => { DateMacro };
184  (@param_type start_svcdate) => { NaiveDate };
185  (@param_type group_by) => { String };
186  (@param_type payment_method) => { String };
187  (@param_type employee) => { String };
188  (@param_type agency_id) => { String };
189  (@param_type duedate_macro) => { DateMacro };
190  (@param_type bothamount) => { String };
191  (@param_type transaction_type) => { String };
192  (@param_type docnum) => { String };
193  (@param_type start_moddate) => { NaiveDate };
194  (@param_type source_account_type) => { String };
195  (@param_type start_createdate) => { NaiveDate };
196  (@param_type memo) => { String };
197  (@param_type appaid) => { String };
198  (@param_type moddate_macro) => { String };
199  (@param_type printed) => { Printed };
200  (@param_type createdate_macro) => { String };
201  (@param_type cleared) => { Cleared };
202  (@param_type end_createdate) => { NaiveDate };
203  (@param_type name) => { String };
204  (@param_type end_moddate) => { NaiveDate };
205
206  (@param_type $param:tt) => { compile_error!(
207    "Unsupported parameter type for report"
208  ) };
209
210  () => {}
211}
212
213impl_report_type!(
214  AccountListDetail, "AccountList", [
215      accounting_method,
216      date_macro,
217      start_date,
218      end_date,
219      summarize_column_by,
220  ]; ("List of accounts with details")
221
222  APAgingDetail, "AgedPayableDetail", [
223    as_of_date,
224    aging_method,
225    vendor,
226    columns
227  ];
228
229  APAgingSummary, "AgedPayables", [
230    customer,
231    qzurl,
232    vendor,
233    date_macro,
234    department,
235    report_date,
236    sort_order,
237    aging_method
238  ];
239
240  ARAgingDetail, "AgedReceivableDetail", [
241    customer,
242    shipvia,
243    term,
244    end_duedate,
245    start_duedate,
246    custom1,
247    custom2,
248    custom3,
249    report_date,
250    num_periods,
251    aging_method,
252    past_due,
253    aging_period,
254    columns
255  ];
256
257  ARAgingSummary, "AgedReceivables", [
258    customer,
259    qzurl,
260    date_macro,
261    aging_method,
262    report_date,
263    sort_order,
264    department
265  ];
266
267  BalanceSheet, "BalanceSheet", [
268    customer,
269    qzurl,
270    end_date,
271    accounting_method,
272    date_macro,
273    adjusted_gain_loss,
274    class,
275    item,
276    sort_order,
277    summarize_column_by,
278    department,
279    vendor,
280    start_date
281  ];
282
283  CashFlow, "CashFlow", [
284    customer,
285    vendor,
286    end_date,
287    date_macro,
288    class,
289    item,
290    sort_order,
291    summarize_column_by,
292    department,
293    start_date
294  ];
295
296  CustomerBalance, "CustomerBalance", [
297    customer,
298    accounting_method,
299    date_macro,
300    arpaid,
301    report_date,
302    sort_order,
303    summarize_column_by,
304    department
305  ];
306
307  CustomerBalanceDetail, "CustomerBalanceDetail", [
308    customer,
309    shipvia,
310    term,
311    end_duedate,
312    start_duedate,
313    custom1,
314    custom2,
315    custom3,
316    arpaid,
317    report_date,
318    sort_order,
319    aging_method,
320    department
321  ];
322
323  CustomerIncome, "CustomerIncome", [
324    customer,
325    term,
326    accounting_method,
327    end_date,
328    date_macro,
329    class,
330    sort_order,
331    summarize_column_by,
332    department,
333    start_date,
334    vendor
335  ];
336
337  FECReport, "FECReport", [
338    attachment_type,
339    with_qbo_identifier,
340    start_date,
341    end_date,
342    add_due_date
343  ];
344
345  GeneralLedger, "GeneralLedger", [
346    customer,
347    account,
348    accounting_method,
349    source_account,
350    end_date,
351    date_macro,
352    account_type,
353    sort_by,
354    sort_order,
355    start_date,
356    summarize_column_by,
357    class,
358    item,
359    department,
360    vendor,
361    columns
362  ];
363
364  GeneralLedgerFR, "GeneralLedgerFR", [
365    customer,
366    account,
367    accounting_method,
368    source_account,
369    end_date,
370    date_macro,
371    account_type,
372    sort_by,
373    sort_order,
374    start_date,
375    summarize_column_by,
376    class,
377    vendor
378  ];
379
380  InventoryValuationDetail, "InventoryValuationDetail", [
381    end_date,
382    end_svcdate,
383    date_macro,
384    svcdate_macro,
385    start_svcdate,
386    group_by,
387    start_date,
388    columns
389  ];
390
391  InventoryValuationSummary, "InventoryValuationSummary", [
392    qzurl,
393    date_macro,
394    item,
395    report_date,
396    sort_order,
397    summarize_column_by
398  ];
399
400  JournalReport, "JournalReport", [
401    end_date,
402    date_macro,
403    sort_by,
404    sort_order,
405    start_date,
406    columns
407  ];
408
409  ProfitAndLoss, "ProfitAndLoss", [
410    customer,
411    qzurl,
412    accounting_method,
413    end_date,
414    date_macro,
415    adjusted_gain_loss,
416    class,
417    item,
418    sort_order,
419    summarize_column_by,
420    department,
421    vendor,
422    start_date
423  ];
424
425  ProfitAndLossDetail, "ProfitAndLossDetail", [
426    customer,
427    account,
428    accounting_method,
429    end_date,
430    date_macro,
431    adjusted_gain_loss,
432    class,
433    sort_by,
434    payment_method,
435    sort_order,
436    employee,
437    department,
438    vendor,
439    account_type,
440    start_date,
441    columns
442  ];
443
444  SalesByClassSummary, "ClassSales", [
445    customer,
446    accounting_method,
447    end_date,
448    date_macro,
449    class,
450    item,
451    summarize_column_by,
452    department,
453    start_date
454  ];
455
456  SalesByCustomer, "CustomerSales", [
457    customer,
458    qzurl,
459    accounting_method,
460    end_date,
461    date_macro,
462    class,
463    item,
464    sort_order,
465    summarize_column_by,
466    department,
467    start_date
468  ];
469
470  SalesByDepartment, "DepartmentSales", [
471    customer,
472    accounting_method,
473    end_date,
474    date_macro,
475    class,
476    item,
477    sort_order,
478    summarize_column_by,
479    department,
480    start_date
481  ];
482
483  SalesByProduct, "ItemSales", [
484    customer,
485    end_duedate,
486    accounting_method,
487    end_date,
488    date_macro,
489    start_duedate,
490    class,
491    item,
492    sort_order,
493    summarize_column_by,
494    department,
495    start_date
496  ];
497
498  TaxSummary, "TaxSummary", [
499    agency_id,
500    accounting_method,
501    end_date,
502    date_macro,
503    sort_order,
504    start_date
505  ];
506
507  TransactionList, "TransactionList", [
508    date_macro,
509    payment_method,
510    duedate_macro,
511    arpaid,
512    bothamount,
513    transaction_type,
514    docnum,
515    start_moddate,
516    source_account_type,
517    group_by,
518    start_date,
519    department,
520    start_duedate,
521    columns,
522    end_duedate,
523    vendor,
524    end_date,
525    memo,
526    appaid,
527    moddate_macro,
528    printed,
529    createdate_macro,
530    cleared,
531    customer,
532    qzurl,
533    term,
534    end_createdate,
535    name,
536    sort_by,
537    sort_order,
538    start_createdate,
539    end_moddate
540  ];
541
542  TransactionListByCustomer, "TransactionListByCustomer", [
543    date_macro,
544    payment_method,
545    duedate_macro,
546    arpaid,
547    bothamount,
548    transaction_type,
549    docnum,
550    start_moddate,
551    source_account_type,
552    group_by,
553    start_date,
554    department,
555    start_duedate,
556    columns,
557    end_duedate,
558    end_date,
559    memo,
560    appaid,
561    moddate_macro,
562    printed,
563    createdate_macro,
564    cleared,
565    customer,
566    qzurl,
567    term,
568    end_createdate,
569    name,
570    sort_by,
571    sort_order,
572    start_createdate,
573    end_moddate
574  ];
575
576  TransactionListByVendor, "TransactionListByVendor", [
577    date_macro,
578    payment_method,
579    duedate_macro,
580    arpaid,
581    bothamount,
582    transaction_type,
583    docnum,
584    start_moddate,
585    source_account_type,
586    group_by,
587    start_date,
588    department,
589    start_duedate,
590    columns,
591    end_duedate,
592    vendor,
593    end_date,
594    memo,
595    appaid,
596    moddate_macro,
597    printed,
598    createdate_macro,
599    cleared,
600    qzurl,
601    term,
602    end_createdate,
603    name,
604    sort_by,
605    sort_order,
606    start_createdate,
607    end_moddate
608  ];
609
610  TransactionListWithSplits, "TransactionListWithSplits", [
611    docnum,
612    name,
613    end_date,
614    date_macro,
615    payment_method,
616    source_account_type,
617    transaction_type,
618    group_by,
619    sort_by,
620    sort_order,
621    start_date,
622    columns
623  ];
624
625  TrialBalance, "TrialBalance", [
626    accounting_method,
627    end_date,
628    date_macro,
629    sort_order,
630    summarize_column_by,
631    start_date
632  ];
633
634  VendorBalance, "VendorBalance", [
635    qzurl,
636    accounting_method,
637    date_macro,
638    appaid,
639    report_date,
640    sort_order,
641    summarize_column_by,
642    department,
643    vendor
644  ];
645
646  VendorBalanceDetail, "VendorBalanceDetail", [
647    term,
648    accounting_method,
649    date_macro,
650    appaid,
651    report_date,
652    sort_order,
653    summarize_column_by,
654    department,
655    vendor,
656    columns,
657    duedate_macro,
658    start_duedate,
659    end_duedate
660  ];
661
662  VendorExpenses, "VendorExpenses", [
663    customer,
664    vendor,
665    end_date,
666    date_macro,
667    class,
668    sort_order,
669    summarize_column_by,
670    department,
671    accounting_method,
672    start_date
673  ];
674);