psdn-tacsvs/src/main.rs

128 lines
3.8 KiB
Rust
Raw Normal View History

2019-12-22 21:30:26 +00:00
/// simple typed helper enums
mod simple_enums;
2019-12-22 21:18:45 +00:00
mod transaction;
2019-12-22 21:18:45 +00:00
2019-12-22 16:55:38 +00:00
fn main() {
2019-12-22 23:39:00 +00:00
use chrono::Datelike;
2019-12-22 16:55:38 +00:00
use encoding::types::Encoding;
use prettytable::{cell, format, row, Cell, Row, Table};
2019-12-22 23:39:00 +00:00
use std::collections::BTreeMap;
2019-12-22 16:55:38 +00:00
for i in std::env::args().skip(1) {
println!("F = {}", i);
let fh = readfilez::read_from_file(std::fs::File::open(i)).expect("unable to open file");
let dat = encoding::all::ISO_8859_1
.decode(&*fh, encoding::types::DecoderTrap::Replace)
.expect("got invalid latin-1 data");
2019-12-22 21:18:45 +00:00
std::mem::drop(fh);
2019-12-22 16:55:38 +00:00
let mut rdr = csv::ReaderBuilder::new()
.delimiter(b';')
.flexible(true)
.has_headers(false)
.from_reader(dat.as_bytes());
2019-12-22 21:18:45 +00:00
let mut recsit = rdr.records().skip(8);
2019-12-22 21:30:26 +00:00
assert_eq!(
recsit.next().unwrap().unwrap(),
vec![
"Buchungstag",
"Valuta",
"Auftraggeber/Zahlungsempfänger",
"Empfänger/Zahlungspflichtiger",
"Konto-Nr.",
"IBAN",
"BLZ",
"BIC",
"Vorgang/Verwendungszweck",
"Kundenreferenz",
"Währung",
"Umsatz",
" "
]
);
2019-12-22 21:18:45 +00:00
let mut tmp = transaction::TransactionColl::new();
2019-12-22 21:18:45 +00:00
for result in recsit {
2019-12-22 16:55:38 +00:00
let record = result.expect("got invalid line");
let record_bak = record.clone();
let pres: Result<transaction::TransactionLine, _> =
std::convert::TryInto::try_into(record);
match pres {
Ok(tl) => tmp.push(tl),
Err(transaction::ParseError::Finalizer) => break,
Err(x) => panic!("got error '{}' @ {:?}", x, record_bak),
}
}
let dat = tmp.finish();
2019-12-22 23:39:00 +00:00
let mut accu = BTreeMap::<
(i32, bool, string_cache::DefaultAtom),
(usize, transaction::TransactionValue),
>::new();
let mut i_skipped = 0usize;
for i in dat {
if i.direction != simple_enums::TransactionDirection::Haben
|| i.waehrung != simple_enums::Waehrung::EUR
|| i.p_other.is_empty()
|| i.p_other.find(" ZINS BIS ").is_some()
{
i_skipped += 1;
continue;
2019-12-22 21:18:45 +00:00
}
2019-12-22 23:39:00 +00:00
let mut ent = accu
.entry((
i.d_buchungs.year(),
i.d_buchungs.month() > 6,
i.p_other.clone(),
))
.or_default();
ent.0 += 1;
ent.1 += i.umsatz;
}
println!("skipped {} entries", i_skipped);
2019-12-22 21:18:45 +00:00
if accu.is_empty() {
continue;
2019-12-22 16:55:38 +00:00
}
let mut table = Table::new();
table.set_format(
format::FormatBuilder::new()
.column_separator('│')
.borders('│')
.separator(
format::LinePosition::Top,
format::LineSeparator::new('─', '┬', '┌', '┐'),
)
.separator(
format::LinePosition::Bottom,
format::LineSeparator::new('─', '┴', '└', '┘'),
)
.padding(1, 1)
.build(),
);
2019-12-22 23:39:00 +00:00
table.add_row(row!["Jahr", "Einzahler", "Zahlungen", "Summe"]);
for (k, v) in accu {
table.add_row(Row::new(vec![
2019-12-22 23:39:00 +00:00
Cell::new(&format!("{} {}.", k.0, if k.1 { 2 } else { 1 })),
Cell::new(&k.2),
Cell::new(&v.0.to_string()),
Cell::new(&v.1.to_string()),
]));
}
table.printstd();
2019-12-22 16:55:38 +00:00
}
}