1use clap::{Parser, Subcommand};
2
3#[derive(Parser, Debug)]
4#[command(name = "invoice", version, about = "Beautiful invoices from the CLI")]
5pub struct Cli {
6 #[arg(long, global = true)]
8 pub json: bool,
9 #[arg(long, global = true)]
11 pub quiet: bool,
12 #[command(subcommand)]
13 pub command: Commands,
14}
15
16#[derive(Subcommand, Debug)]
17pub enum Commands {
18 #[command(visible_alias = "issuer", subcommand)]
20 Issuers(IssuerCmd),
21
22 #[command(subcommand)]
24 Clients(ClientCmd),
25
26 #[command(subcommand)]
28 Products(ProductCmd),
29
30 #[command(subcommand)]
32 Invoices(InvoiceCmd),
33
34 #[command(subcommand)]
36 Template(TemplateCmd),
37
38 #[command(subcommand)]
40 Config(ConfigCmd),
41
42 #[command(alias = "info")]
44 AgentInfo,
45
46 #[command(subcommand)]
48 Skill(SkillCmd),
49
50 Doctor,
52
53 Update {
55 #[arg(long)]
57 check: bool,
58 },
59}
60
61#[derive(Subcommand, Debug)]
62pub enum IssuerCmd {
63 #[command(alias = "new")]
65 Add {
66 slug: String,
67 #[arg(long)]
68 name: String,
69 #[arg(long)]
70 legal_name: Option<String>,
71 #[arg(long, default_value = "sg")]
72 jurisdiction: String,
73 #[arg(long)]
74 tax_registered: bool,
75 #[arg(long)]
76 tax_id: Option<String>,
77 #[arg(long)]
78 company_no: Option<String>,
79 #[arg(long)]
80 address: String,
81 #[arg(long)]
82 email: Option<String>,
83 #[arg(long)]
84 phone: Option<String>,
85 #[arg(long = "bank-line")]
91 bank_line: Vec<String>,
92 #[arg(long, default_value = "vienna")]
93 template: String,
94 #[arg(long)]
96 logo: Option<String>,
97 #[arg(long)]
101 output_dir: Option<String>,
102 #[arg(long)]
106 notes: Option<String>,
107 #[arg(long)]
110 number_format: Option<String>,
111 },
112 Edit {
114 slug: String,
115 #[arg(long)]
116 name: Option<String>,
117 #[arg(long)]
118 legal_name: Option<String>,
119 #[arg(long)]
120 jurisdiction: Option<String>,
121 #[arg(long)]
122 tax_registered: Option<bool>,
123 #[arg(long)]
124 tax_id: Option<String>,
125 #[arg(long)]
126 company_no: Option<String>,
127 #[arg(long)]
128 tagline: Option<String>,
129 #[arg(long)]
130 address: Option<String>,
131 #[arg(long)]
132 email: Option<String>,
133 #[arg(long)]
134 phone: Option<String>,
135 #[arg(long = "bank-line")]
139 bank_line: Vec<String>,
140 #[arg(long)]
142 bank_clear: bool,
143 #[arg(long)]
144 template: Option<String>,
145 #[arg(long)]
146 currency: Option<String>,
147 #[arg(long)]
148 symbol: Option<String>,
149 #[arg(long)]
152 number_format: Option<String>,
153 #[arg(long)]
154 logo: Option<String>,
155 #[arg(long)]
157 logo_clear: bool,
158 #[arg(long)]
161 output_dir: Option<String>,
162 #[arg(long)]
164 notes: Option<String>,
165 },
166 SetTemplate { slug: String, template: String },
168 #[command(alias = "ls")]
169 List,
170 #[command(alias = "get")]
171 Show { slug: String },
172 #[command(alias = "rm")]
173 Delete { slug: String },
174}
175
176#[derive(Subcommand, Debug)]
177pub enum ClientCmd {
178 #[command(alias = "new")]
179 Add {
180 slug: String,
181 #[arg(long)]
182 name: String,
183 #[arg(long)]
184 attn: Option<String>,
185 #[arg(long)]
186 country: Option<String>,
187 #[arg(long)]
188 tax_id: Option<String>,
189 #[arg(long)]
190 address: String,
191 #[arg(long)]
192 email: Option<String>,
193 #[arg(long)]
194 notes: Option<String>,
195 #[arg(long)]
197 default_issuer: Option<String>,
198 #[arg(long)]
200 default_template: Option<String>,
201 },
202 Edit {
204 slug: String,
205 #[arg(long)]
206 name: Option<String>,
207 #[arg(long)]
208 attn: Option<String>,
209 #[arg(long)]
210 country: Option<String>,
211 #[arg(long)]
212 tax_id: Option<String>,
213 #[arg(long)]
214 address: Option<String>,
215 #[arg(long)]
216 email: Option<String>,
217 #[arg(long)]
218 notes: Option<String>,
219 #[arg(long)]
220 default_issuer: Option<String>,
221 #[arg(long)]
222 default_template: Option<String>,
223 },
224 SetIssuer { slug: String, issuer_slug: String },
226 SetTemplate { slug: String, template: String },
228 #[command(alias = "ls")]
229 List,
230 #[command(alias = "get")]
231 Show { slug: String },
232 #[command(alias = "rm")]
233 Delete { slug: String },
234}
235
236#[derive(Subcommand, Debug)]
237pub enum ProductCmd {
238 #[command(alias = "new")]
239 Add {
240 slug: String,
241 #[arg(long)]
242 description: String,
243 #[arg(long)]
244 subtitle: Option<String>,
245 #[arg(long, default_value = "unit")]
246 unit: String,
247 #[arg(long)]
249 price: String,
250 #[arg(long)]
251 currency: String,
252 #[arg(long, default_value = "0")]
253 tax_rate: String,
254 },
255 Edit {
257 slug: String,
258 #[arg(long)]
259 description: Option<String>,
260 #[arg(long)]
261 subtitle: Option<String>,
262 #[arg(long)]
263 unit: Option<String>,
264 #[arg(long)]
265 price: Option<String>,
266 #[arg(long)]
267 currency: Option<String>,
268 #[arg(long)]
269 tax_rate: Option<String>,
270 },
271 #[command(alias = "ls")]
272 List,
273 #[command(alias = "get")]
274 Show { slug: String },
275 #[command(alias = "rm")]
276 Delete { slug: String },
277}
278
279#[derive(Subcommand, Debug)]
280pub enum InvoiceCmd {
281 New {
283 #[arg(long)]
286 r#as: Option<String>,
287 #[arg(long)]
289 client: String,
290 #[arg(long = "item")]
292 items: Vec<String>,
293 #[arg(long, default_value = "7d")]
296 due: String,
297 #[arg(long, default_value = "Pay in full")]
299 terms: String,
300 #[arg(long)]
301 notes: Option<String>,
302 #[arg(long)]
304 currency: Option<String>,
305 #[arg(long)]
307 reverse_charge: bool,
308 #[arg(long)]
310 pay_link: Option<String>,
311 #[arg(long)]
313 discount_rate: Option<String>,
314 #[arg(long)]
316 discount_fixed: Option<String>,
317 },
318 Edit {
321 number: String,
322 #[arg(long)]
323 client: Option<String>,
324 #[arg(long)]
325 due: Option<String>,
326 #[arg(long)]
327 terms: Option<String>,
328 #[arg(long)]
329 notes: Option<String>,
330 #[arg(long)]
331 currency: Option<String>,
332 #[arg(long)]
333 pay_link: Option<String>,
334 #[arg(long)]
335 reverse_charge: Option<bool>,
336 #[arg(long)]
337 discount_rate: Option<String>,
338 #[arg(long)]
339 discount_fixed: Option<String>,
340 },
341 #[command(subcommand)]
343 Items(InvoiceItemCmd),
344 CreditNote {
346 number: String,
348 #[arg(long, conflicts_with = "items")]
351 full: bool,
352 #[arg(long = "item")]
356 items: Vec<String>,
357 #[arg(long)]
358 notes: Option<String>,
359 #[arg(long)]
360 pay_link: Option<String>,
361 },
362 Aging {
364 #[arg(long = "as")]
365 issuer: Option<String>,
366 },
367 Export {
369 #[arg(long)]
371 from: Option<String>,
372 #[arg(long)]
374 to: Option<String>,
375 #[arg(long, default_value = "csv")]
377 format: String,
378 #[arg(long, short)]
380 out: Option<String>,
381 #[arg(long = "as")]
382 issuer: Option<String>,
383 },
384 Duplicate {
387 number: String,
388 #[arg(long)]
390 client: Option<String>,
391 #[arg(long = "as")]
393 r#as: Option<String>,
394 #[arg(long, default_value = "7d")]
396 due: String,
397 },
398 #[command(alias = "ls")]
399 List {
400 #[arg(long)]
401 status: Option<String>,
402 #[arg(long = "as")]
403 issuer: Option<String>,
404 #[arg(long)]
406 overdue: bool,
407 },
408 #[command(alias = "get")]
409 Show { number: String },
410 Render {
412 number: String,
413 #[arg(long)]
415 template: Option<String>,
416 #[arg(long, short)]
418 out: Option<String>,
419 #[arg(long)]
421 open: bool,
422 },
423 Mark { number: String, status: String },
425 #[command(alias = "rm")]
426 Delete {
427 number: String,
428 #[arg(long)]
431 force: bool,
432 },
433}
434
435#[derive(Subcommand, Debug)]
436pub enum InvoiceItemCmd {
437 Add {
439 number: String,
440 spec: String,
442 #[arg(long)]
443 subtitle: Option<String>,
444 #[arg(long)]
445 discount_rate: Option<String>,
446 #[arg(long)]
447 discount_fixed: Option<String>,
448 },
449 #[command(alias = "rm")]
451 Remove { number: String, position: i64 },
452 Edit {
454 number: String,
455 position: i64,
456 #[arg(long)]
457 description: Option<String>,
458 #[arg(long)]
459 subtitle: Option<String>,
460 #[arg(long)]
461 qty: Option<String>,
462 #[arg(long)]
463 unit: Option<String>,
464 #[arg(long)]
465 price: Option<String>,
466 #[arg(long)]
467 tax_rate: Option<String>,
468 #[arg(long)]
469 discount_rate: Option<String>,
470 #[arg(long)]
471 discount_fixed: Option<String>,
472 },
473}
474
475#[derive(Subcommand, Debug)]
476pub enum TemplateCmd {
477 #[command(alias = "ls")]
478 List,
479 Preview {
481 name: String,
482 #[arg(long, short)]
483 out: Option<String>,
484 },
485}
486
487#[derive(Subcommand, Debug)]
488pub enum ConfigCmd {
489 Show,
490 Path,
491 Set { key: String, value: String },
492}
493
494#[derive(Subcommand, Debug)]
495pub enum SkillCmd {
496 Install,
497}