Skip to main content

contract_cli/commands/
clients.rs

1use crate::cli::ClientCmd;
2use crate::db::{self, Client};
3use crate::error::Result;
4use crate::output::{print_success, Ctx};
5
6use super::split_multiline_arg;
7
8pub fn run(cmd: ClientCmd, ctx: Ctx) -> Result<()> {
9    let conn = db::open()?;
10    match cmd {
11        ClientCmd::Add {
12            slug,
13            name,
14            legal_name,
15            company_no,
16            jurisdiction,
17            attn,
18            country,
19            address,
20            email,
21            notes,
22        } => {
23            let c = Client {
24                id: 0,
25                slug,
26                name,
27                legal_name,
28                company_no,
29                legal_jurisdiction: jurisdiction,
30                attn,
31                country,
32                tax_id: None,
33                address: split_multiline_arg(&address),
34                email,
35                notes,
36                default_issuer_slug: None,
37                default_template: None,
38            };
39            let id = db::client_create(&conn, &c)?;
40            let mut saved = c;
41            saved.id = id;
42            print_success(ctx, &saved, |c| println!("added client '{}' (#{})", c.slug, c.id));
43            Ok(())
44        }
45        ClientCmd::Edit {
46            slug,
47            name,
48            legal_name,
49            company_no,
50            jurisdiction,
51            attn,
52            country,
53            address,
54            email,
55            notes,
56        } => {
57            let mut existing = db::client_by_slug(&conn, &slug)?;
58            if let Some(v) = name { existing.name = v; }
59            if let Some(v) = legal_name { existing.legal_name = Some(v); }
60            if let Some(v) = company_no { existing.company_no = Some(v); }
61            if let Some(v) = jurisdiction { existing.legal_jurisdiction = Some(v); }
62            if let Some(v) = attn { existing.attn = Some(v); }
63            if let Some(v) = country { existing.country = Some(v); }
64            if let Some(v) = address { existing.address = split_multiline_arg(&v); }
65            if let Some(v) = email { existing.email = Some(v); }
66            if let Some(v) = notes { existing.notes = Some(v); }
67            db::client_update(&conn, &existing)?;
68            print_success(ctx, &existing, |c| println!("updated client '{}'", c.slug));
69            Ok(())
70        }
71        ClientCmd::List => {
72            let list = db::client_list(&conn)?;
73            print_success(ctx, &list, |rows| {
74                if rows.is_empty() {
75                    println!("(no clients — add one with: contract clients add <slug> --name X --address ...)");
76                } else {
77                    for c in rows {
78                        println!(
79                            "  {:<14} {:<28} {}",
80                            c.slug,
81                            c.name,
82                            c.legal_name.clone().unwrap_or_default()
83                        );
84                    }
85                }
86            });
87            Ok(())
88        }
89        ClientCmd::Show { slug } => {
90            let c = db::client_by_slug(&conn, &slug)?;
91            print_success(ctx, &c, |c| println!("{:#?}", c));
92            Ok(())
93        }
94        ClientCmd::Delete { slug } => {
95            db::client_delete(&conn, &slug)?;
96            print_success(ctx, &slug, |s| println!("deleted client '{s}'"));
97            Ok(())
98        }
99    }
100}