1use crate::cli::setup_domain;
2use crate::client::accounting_info::AccountingInfoClient;
3use crate::client::sales::SalesClient;
4use crate::config::Config;
5use crate::error::YukiError;
6use crate::output::{
7 ListOptions, OutputFormat, apply_pagination, format_json, format_table, is_tty,
8};
9
10pub async fn list(
11 config: &Config,
12 admin: Option<&str>,
13 _period: Option<&str>,
14 invoice_type: Option<&str>,
15 format: Option<&str>,
16 opts: ListOptions<'_>,
17) -> Result<(), YukiError> {
18 let fmt = OutputFormat::from_flag(format, is_tty());
19
20 match invoice_type {
21 Some("purchase") | Some("creditor") => {
22 let (client, entry) = setup_domain(config, admin).await?;
23 let items = client.outstanding_creditor_items(&entry.admin_id).await?;
24
25 let headers = vec![
26 "Contact".into(),
27 "Description".into(),
28 "Date".into(),
29 "Amount".into(),
30 "Open".into(),
31 ];
32 let mut rows: Vec<Vec<String>> = items
33 .iter()
34 .map(|i| {
35 vec![
36 i.contact_name.clone(),
37 i.description.clone(),
38 i.date.clone(),
39 i.amount.clone(),
40 i.open_amount.clone(),
41 ]
42 })
43 .collect();
44 apply_pagination(&mut rows, &opts);
45
46 match fmt {
47 OutputFormat::Table => println!("{}", format_table(&headers, &rows)),
48 OutputFormat::Json => println!("{}", format_json(&headers, &rows)),
49 }
50 }
51
52 _ => {
54 let mut client = SalesClient::new();
55 client.authenticate(&config.api_key).await?;
56 let items = client.get_sales_items().await?;
57
58 let headers = vec!["ID".into(), "Description".into()];
59 let mut rows: Vec<Vec<String>> = items
60 .iter()
61 .map(|i| vec![i.id.clone(), i.description.clone()])
62 .collect();
63 apply_pagination(&mut rows, &opts);
64
65 match fmt {
66 OutputFormat::Table => println!("{}", format_table(&headers, &rows)),
67 OutputFormat::Json => println!("{}", format_json(&headers, &rows)),
68 }
69 }
70 }
71
72 Ok(())
73}
74
75pub async fn document(
76 config: &Config,
77 admin: Option<&str>,
78 id: &str,
79 format: Option<&str>,
80) -> Result<(), YukiError> {
81 let entry = config.resolve_admin(admin)?;
82 let mut client = AccountingInfoClient::new();
83 client.authenticate(&config.api_key).await?;
84 let xml = client.get_transaction_document(&entry.admin_id, id).await?;
85
86 let result = crate::client::soap_client::SoapClient::parse_single_result(
87 &xml,
88 "GetTransactionDocumentResult",
89 )
90 .unwrap_or(xml);
91
92 let headers = vec!["Transaction".into(), "Document".into()];
93 let rows = vec![vec![id.to_string(), result]];
94
95 let fmt = OutputFormat::from_flag(format, is_tty());
96 match fmt {
97 OutputFormat::Table => println!("{}", format_table(&headers, &rows)),
98 OutputFormat::Json => println!("{}", format_json(&headers, &rows)),
99 }
100 Ok(())
101}
102
103pub async fn show(
104 config: &Config,
105 _admin: Option<&str>,
106 id: &str,
107 format: Option<&str>,
108) -> Result<(), YukiError> {
109 let mut client = AccountingInfoClient::new();
110 client.authenticate(&config.api_key).await?;
111 let details = client.get_transaction_details(id).await?;
112
113 let headers = vec![
114 "ID".into(),
115 "Date".into(),
116 "Amount".into(),
117 "Currency".into(),
118 "GL Account".into(),
119 "Description".into(),
120 ];
121 let rows: Vec<Vec<String>> = details
122 .iter()
123 .map(|d| {
124 vec![
125 d.id.clone(),
126 d.date.clone(),
127 d.amount.clone(),
128 d.currency.clone(),
129 d.gl_account_code.clone(),
130 d.description.clone(),
131 ]
132 })
133 .collect();
134
135 let fmt = OutputFormat::from_flag(format, is_tty());
136 match fmt {
137 OutputFormat::Table => println!("{}", format_table(&headers, &rows)),
138 OutputFormat::Json => println!("{}", format_json(&headers, &rows)),
139 }
140 Ok(())
141}