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