use askama::Template; use askama_derive::Filter; use chrono::Utc; use std::collections::BTreeMap; use invoice_generator::{group_by_customer, read_csv_file, Customer, Transaction}; #[derive(Template)] #[template(path = "index.html")] pub struct IndexTemplate { pub customers: Vec<(String, Customer)>, pub batches: Vec, } #[derive(Template)] #[template(path = "customer.html")] pub struct CustomerTemplate { pub customer: &Customer, pub batches: Vec, } pub fn calculate_card_totals(transactions: &[Transaction]) -> (f64, f64) { let total_amount: f64 = transactions.iter().map(|t| t.amount).sum(); let total_volume: f64 = transactions.iter().map(|t| t.volume).sum(); (total_amount, total_volume) } pub fn calculate_grand_total(customer: &Customer) -> f64 { customer .cards .values() .flat_map(|t| t.iter()) .map(|t| t.amount) .sum() } pub fn format_amount(amount: f64) -> String { format!("{:.2}", amount) } pub fn format_volume(volume: f64) -> String { format!("{:.2}", volume) } pub fn format_date(date: &chrono::NaiveDateTime) -> String { date.format("%Y-%m-%d %H:%M").to_string() } pub fn now_string() -> String { Utc::now().format("%Y-%m-%d %H:%M").to_string() }