2019-12-22 21:30:26 +00:00
|
|
|
/// simple typed helper enums
|
|
|
|
mod simple_enums;
|
2019-12-22 21:18:45 +00:00
|
|
|
|
2019-12-22 23:21:09 +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;
|
2019-12-22 23:21:09 +00:00
|
|
|
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
|
|
|
|
2019-12-22 23:21:09 +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");
|
2019-12-22 23:21:09 +00:00
|
|
|
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();
|
2019-12-22 23:21:09 +00:00
|
|
|
|
|
|
|
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();
|
2019-12-22 23:21:09 +00:00
|
|
|
ent.0 += 1;
|
|
|
|
ent.1 += i.umsatz;
|
|
|
|
}
|
|
|
|
|
|
|
|
println!("skipped {} entries", i_skipped);
|
2019-12-22 21:18:45 +00:00
|
|
|
|
2019-12-22 23:21:09 +00:00
|
|
|
if accu.is_empty() {
|
|
|
|
continue;
|
2019-12-22 16:55:38 +00:00
|
|
|
}
|
2019-12-22 23:21:09 +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"]);
|
2019-12-22 23:21:09 +00:00
|
|
|
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),
|
2019-12-22 23:21:09 +00:00
|
|
|
Cell::new(&v.0.to_string()),
|
|
|
|
Cell::new(&v.1.to_string()),
|
|
|
|
]));
|
|
|
|
}
|
|
|
|
|
|
|
|
table.printstd();
|
2019-12-22 16:55:38 +00:00
|
|
|
}
|
|
|
|
}
|