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:
54
src/main.rs
54
src/main.rs
@@ -1,11 +1,12 @@
|
|||||||
use askama::Template;
|
use askama::Template;
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
|
use std::env;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
mod invoice_generator;
|
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 {
|
fn fmt(v: f64) -> String {
|
||||||
format!("{:.2}", v)
|
format!("{:.2}", v)
|
||||||
@@ -101,40 +102,35 @@ struct CustomerTemplate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let data_dir = Path::new("input");
|
let args: Vec<String> = env::args().collect();
|
||||||
let output_dir = Path::new("output");
|
|
||||||
|
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() {
|
if !output_dir.exists() {
|
||||||
fs::create_dir_all(output_dir)?;
|
fs::create_dir_all(output_dir)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut batches: Vec<Batch> = Vec::new();
|
let batch = read_csv_file(input_path)?;
|
||||||
|
|
||||||
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!(
|
println!(
|
||||||
"Loaded {} transactions from {}",
|
"Loaded {} transactions from {}",
|
||||||
batch.transactions.len(),
|
batch.transactions.len(),
|
||||||
batch.filename
|
batch.filename
|
||||||
);
|
);
|
||||||
batches.push(batch);
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
eprintln!("Error reading {:?}: {}", path, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
batches.sort_by(|a, b| a.filename.cmp(&b.filename));
|
let batch_filename = batch.filename.clone();
|
||||||
|
let customers = group_by_customer(&[batch]);
|
||||||
let batch_filenames: Vec<String> = batches.iter().map(|b| b.filename.clone()).collect();
|
|
||||||
|
|
||||||
let customers = group_by_customer(&batches);
|
|
||||||
|
|
||||||
let index_customers: Vec<(String, usize)> = customers
|
let index_customers: Vec<(String, usize)> = customers
|
||||||
.iter()
|
.iter()
|
||||||
@@ -142,8 +138,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let html = IndexTemplate {
|
let html = IndexTemplate {
|
||||||
customers: index_customers,
|
customers: index_customers.clone(),
|
||||||
batches: batch_filenames.clone(),
|
batches: vec![batch_filename.clone()],
|
||||||
}
|
}
|
||||||
.render()
|
.render()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@@ -156,7 +152,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
let prepared = PreparedCustomer::from_customer(customer);
|
let prepared = PreparedCustomer::from_customer(customer);
|
||||||
let customer_html = CustomerTemplate {
|
let customer_html = CustomerTemplate {
|
||||||
customer: prepared,
|
customer: prepared,
|
||||||
batches: batch_filenames.clone(),
|
batches: vec![batch_filename.clone()],
|
||||||
generated_date: generated_date.clone(),
|
generated_date: generated_date.clone(),
|
||||||
}
|
}
|
||||||
.render()
|
.render()
|
||||||
@@ -167,8 +163,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
println!(
|
println!(
|
||||||
"\nGenerated {} customer invoices in output/",
|
"\nGenerated {} customer invoices in {:?}",
|
||||||
customer_count
|
customer_count, output_dir
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
Reference in New Issue
Block a user