diff options
Diffstat (limited to 'apps/koffice/invoice')
-rw-r--r-- | apps/koffice/invoice/Cargo.toml | 13 | ||||
-rw-r--r-- | apps/koffice/invoice/src/base.rs | 20 | ||||
-rw-r--r-- | apps/koffice/invoice/src/cli.rs | 76 | ||||
-rw-r--r-- | apps/koffice/invoice/src/main.rs | 41 | ||||
-rw-r--r-- | apps/koffice/invoice/src/pfile.rs | 33 |
5 files changed, 183 insertions, 0 deletions
diff --git a/apps/koffice/invoice/Cargo.toml b/apps/koffice/invoice/Cargo.toml new file mode 100644 index 000000000000..15bb8e7e90c6 --- /dev/null +++ b/apps/koffice/invoice/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "invoice" +version = "0.2.0" +authors = ["Katharina Fey <kookie@spacekookie.de>"] +edition = "2018" + +[dependencies] +chrono = { version = "0.4", features = [ "serde" ] } +clap = { version = "2.0", features = [ "wrap_help", "color", "suggestions" ] } +libko = { path = "../libko", version = "*" } +serde = { version = "1.0", features = [ "derive" ] } +env_logger = "0.8" +log = "0.4"
\ No newline at end of file diff --git a/apps/koffice/invoice/src/base.rs b/apps/koffice/invoice/src/base.rs new file mode 100644 index 000000000000..a29af6480bf8 --- /dev/null +++ b/apps/koffice/invoice/src/base.rs @@ -0,0 +1,20 @@ +//! Basing application initialisation + +use libko::*; +use std::path::PathBuf; + +pub fn init(pid: Option<&str>, tf: Option<&str>, t: Option<&str>, rev: Option<&str>) -> Meta { + let mut meta = initialise(); + + meta.project_id = pid.map(Into::into); + + if let Some(tfpath) = tf { + meta.load_timefile(tfpath); + } + + if let Some(template) = t { + meta.template = Some(PathBuf::new().join(template)); + } + + dbg!(meta) +} diff --git a/apps/koffice/invoice/src/cli.rs b/apps/koffice/invoice/src/cli.rs new file mode 100644 index 000000000000..cbf27efe6cc4 --- /dev/null +++ b/apps/koffice/invoice/src/cli.rs @@ -0,0 +1,76 @@ +use crate::Meta; +use clap::{App, AppSettings, Arg, SubCommand}; + +pub struct AppState { + pub meta: Meta, + pub cmd: Command, +} + +pub enum Command { + Init, + Generate, + Install, +} + +pub fn parse() -> AppState { + let project_id = + Arg::with_name("project id").help("The project identifier. Format: [client/]<project>"); + + let timefile = Arg::with_name("timefile") + .help("Location of the project's time file") + .takes_value(true) + .long("file") + .short("f") + .default_value("./time.cass"); + + let template = Arg::with_name("template") + .help("Override the default application template") + .long("templ") + .short("t") + .takes_value(true) + .default_value("$XDG_CONFIG_HOME/k-office/template.tex"); + + let revision = Arg::with_name("revision") + .help("Override the default revision system") + .long("rev") + .short("r") + .takes_value(true); + + let app = App::new("invoice") + .version(env!("CARGO_PKG_VERSION")) + .about("A k-office tool to generate and manage invoices") + .settings(&[ + AppSettings::SubcommandRequired, + AppSettings::GlobalVersion, + AppSettings::ColoredHelp, + AppSettings::DontCollapseArgsInUsage, + ]) + .subcommand( + SubCommand::with_name("init") + .about("Initialise a new invoice config") + .arg(timefile) + .arg(revision.clone()), + ) + .subcommand( + SubCommand::with_name("generate") + .about("Generate an invoice PDF for a client/ project based on a template") + .arg(revision) + .arg(template), + ); + + let matches = app.get_matches(); + + let project_id = matches.value_of("project id"); + let timefile = matches.value_of("timefile"); + let template = matches.value_of("template"); + let revision = matches.value_of("revision"); + + AppState { + meta: crate::base::init(project_id, timefile, template, revision), + cmd: match matches.subcommand() { + ("init", _) => Command::Init, + ("generate", _) => Command::Generate, + _ => unreachable!(), + }, + } +} diff --git a/apps/koffice/invoice/src/main.rs b/apps/koffice/invoice/src/main.rs new file mode 100644 index 000000000000..742b74be0b0a --- /dev/null +++ b/apps/koffice/invoice/src/main.rs @@ -0,0 +1,41 @@ + +mod base; +mod cli; +mod pfile; + +pub(crate) use base::*; +pub(crate) use cli::*; +pub(crate) use pfile::*; + +use libko::*; +use std::{io::Write, fs::OpenOptions as Oo}; + +fn main() { + let AppState { meta, cmd } = cli::parse(); + + match cmd { + Command::Init => init(meta), + Command::Generate => generate(meta), + Command::Install => todo!(), + } +} + +fn init(meta: Meta) { + let pid = meta.project_id.as_ref().unwrap_or_else(|| { + meta.timefile + .as_ref() + .expect("No project id given, with no timefile available") + .client() + .as_ref() + .unwrap() + }); + + let path = meta.invoice_dir.join(pid); + let mut f = Oo::new().write(true).truncate(true).open(path).unwrap(); + f.write_all(pfile::data_templ().as_bytes()).unwrap(); + + // let pid = meta.project_id.as_ref().unwrap_or_else(|| + // let f = meta.invoice_dir.join(meta.project_id); +} + +fn generate(meta: Meta) {} diff --git a/apps/koffice/invoice/src/pfile.rs b/apps/koffice/invoice/src/pfile.rs new file mode 100644 index 000000000000..ec99e5ab3049 --- /dev/null +++ b/apps/koffice/invoice/src/pfile.rs @@ -0,0 +1,33 @@ +use crate::{Account, Address, Worker, InvoiceId}; +use chrono::NaiveDate; +use serde::{Serialize, Deserialize}; + +/// Describes invoice metadata +#[derive(Serialize, Deserialize)] +pub struct InvoiceFile { + invoice_id: InvoiceId, + date: NaiveDate, + author: Worker, + account: Account, + client: Address, + vat: u8, + service: Vec<ServiceEntry>, + currency: String, + lang: String, +} + +/// A service description +#[derive(Serialize, Deserialize)] +pub enum ServiceEntry { + Line(String), + Hash { + description: String, + price: usize, + details: Vec<String>, + } +} + +pub fn data_templ() -> String { + + todo!() +} |