Accept CSV file path as command line argument
Output is now written to the same directory as the input file.
This commit is contained in:
64
src/main.rs
64
src/main.rs
@@ -1,11 +1,12 @@
|
||||
use askama::Template;
|
||||
use chrono::Utc;
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
mod invoice_generator;
|
||||
|
||||
use invoice_generator::{group_by_customer, read_csv_file, Batch, Customer};
|
||||
use invoice_generator::{group_by_customer, read_csv_file, Customer};
|
||||
|
||||
fn fmt(v: f64) -> String {
|
||||
format!("{:.2}", v)
|
||||
@@ -101,40 +102,35 @@ struct CustomerTemplate {
|
||||
}
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let data_dir = Path::new("input");
|
||||
let output_dir = Path::new("output");
|
||||
let args: Vec<String> = env::args().collect();
|
||||
|
||||
if args.len() != 2 {
|
||||
eprintln!("Usage: {} <csv-file>", args[0]);
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
let input_path = Path::new(&args[1]);
|
||||
|
||||
if !input_path.exists() {
|
||||
eprintln!("Error: File not found: {:?}", input_path);
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
let output_dir = input_path.parent().unwrap_or(Path::new("."));
|
||||
|
||||
if !output_dir.exists() {
|
||||
fs::create_dir_all(output_dir)?;
|
||||
}
|
||||
|
||||
let mut batches: Vec<Batch> = Vec::new();
|
||||
let batch = read_csv_file(input_path)?;
|
||||
println!(
|
||||
"Loaded {} transactions from {}",
|
||||
batch.transactions.len(),
|
||||
batch.filename
|
||||
);
|
||||
|
||||
for entry in fs::read_dir(data_dir)? {
|
||||
let entry = entry?;
|
||||
let path = entry.path();
|
||||
if path.extension().and_then(|s| s.to_str()) == Some("csv") {
|
||||
match read_csv_file(&path) {
|
||||
Ok(batch) => {
|
||||
println!(
|
||||
"Loaded {} transactions from {}",
|
||||
batch.transactions.len(),
|
||||
batch.filename
|
||||
);
|
||||
batches.push(batch);
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("Error reading {:?}: {}", path, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
batches.sort_by(|a, b| a.filename.cmp(&b.filename));
|
||||
|
||||
let batch_filenames: Vec<String> = batches.iter().map(|b| b.filename.clone()).collect();
|
||||
|
||||
let customers = group_by_customer(&batches);
|
||||
let batch_filename = batch.filename.clone();
|
||||
let customers = group_by_customer(&[batch]);
|
||||
|
||||
let index_customers: Vec<(String, usize)> = customers
|
||||
.iter()
|
||||
@@ -142,8 +138,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
.collect();
|
||||
|
||||
let html = IndexTemplate {
|
||||
customers: index_customers,
|
||||
batches: batch_filenames.clone(),
|
||||
customers: index_customers.clone(),
|
||||
batches: vec![batch_filename.clone()],
|
||||
}
|
||||
.render()
|
||||
.unwrap();
|
||||
@@ -156,7 +152,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let prepared = PreparedCustomer::from_customer(customer);
|
||||
let customer_html = CustomerTemplate {
|
||||
customer: prepared,
|
||||
batches: batch_filenames.clone(),
|
||||
batches: vec![batch_filename.clone()],
|
||||
generated_date: generated_date.clone(),
|
||||
}
|
||||
.render()
|
||||
@@ -167,8 +163,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
}
|
||||
|
||||
println!(
|
||||
"\nGenerated {} customer invoices in output/",
|
||||
customer_count
|
||||
"\nGenerated {} customer invoices in {:?}",
|
||||
customer_count, output_dir
|
||||
);
|
||||
|
||||
Ok(())
|
||||
|
||||
Reference in New Issue
Block a user