=================================================================== RCS file: /cvs/pta/pta.pl,v retrieving revision 1.3 retrieving revision 1.7 diff -u -p -r1.3 -r1.7 --- pta/pta.pl 2020/10/18 23:47:35 1.3 +++ pta/pta.pl 2020/11/18 12:55:44 1.7 @@ -18,6 +18,7 @@ use warnings; use strict; use Getopt::Std qw(getopts); +use Time::Local qw(timegm); our ($opt_a, $opt_b, $opt_c, $opt_L, $opt_n, $opt_p, $opt_s); @@ -40,6 +41,7 @@ my %atypes = ( ); my $translations = { + en => {}, de => { 'Account list' => 'Kontenblatt', 'Assets' => 'Aktiva', @@ -71,13 +73,13 @@ my $translations = { sub translate ($) { my $en = shift; - return $translations ? $translations->{$en} : $en; + return $translations->{$en} || $en; } sub translate_type ($) { my $type = shift; - my $en = $atypes{substr $type, 0, 1} || '?'; - return translate $en || $type; + my $en = $atypes{substr $type, 0, 1}; + return $en ? translate $en : $type; } # Handles account entries (not journal entries) with respect to @@ -145,14 +147,8 @@ sub usage () { getopts 'abcL:nps' or usage; $opt_a = $opt_b = $opt_c = $opt_p = $opt_s = 1 unless $opt_a || $opt_b || $opt_c || $opt_n || $opt_p || $opt_s; -$opt_L ||= 'en'; -if ($opt_L eq 'de') { - $translations = $translations->{$opt_L}; -} elsif ($opt_L eq 'en') { - undef $opt_L; - undef $translations; -} else { - printf STDERR "unsupported language %s\n", $opt_L; +unless ($translations = $translations->{$opt_L || 'en'}) { + printf STDERR "unsupported language: -L %s\n", $opt_L; usage; } @@ -190,6 +186,10 @@ while (<$in>) { my ($amount, $text) = ($1, $2); my $cc = $1 if $text =~ s/\[(.*?)\] *//; $accounts{$ano} or die "unknown account $ano: $line"; + ($accounts{$ano}{type} =~ /S/) == + ($accounts{$entry{contra}}{type} =~ /S/) + or die "statistical vs. non-statistical account: " . + "$entry{contra} split $line"; $amount *= $entry{amount} < 0 ? -1 : +1; # Combine the text on the split side. @@ -231,7 +231,7 @@ while (<$in>) { s/^(\d{4})(\d{2})(\d{2}) +// or die "$fn date parse error: $line"; my ($year, $month, $day) = ($1, $2, $3); - s/^([A-Z]+(?:\d+\/\d+)?) +// or die "$fn ID parse error: $line"; + s/^(\S+) +// or die "$fn ID parse error: $line"; my $id = $1; s/^(\d+) +// or die "$fn debit account number parse error: $line"; my $debit = $1; @@ -258,7 +258,7 @@ while (<$in>) { month => $month, day => $day, date => "$year-$month-$day", - days => ($month - 1) * 30 + ($day - 1), + days => (timegm 0,0,0, $day, $month-1, $year) / 86400, price => $newpc * $amount, }; $prices{$cc} = $new unless $prices{$cc} && $oldpc == $newpc; @@ -284,8 +284,7 @@ while (<$in>) { if ($old) { # Record a gain or loss in this period. $newprofit->{olddate} = $old->{date}; - $newprofit->{days} = $new->{days} - $old->{days} + - ($new->{year} - $old->{year}) * 360; + $newprofit->{days} = $new->{days} - $old->{days}; $newprofit->{text} .= sprintf " %s %s (%dd)", (translate 'since'), $old->{date}, $newprofit->{days}; @@ -322,23 +321,28 @@ while (<$in>) { ); if ($debit) { $accounts{$debit} or die "unknown debit account $debit: $line"; + # The credit side may or may not be split. my %newentry = (%entry, contra => $credit, amount => $amount); make_entry %newentry, $debit; } else { $credit or die "splitting both sides: $line"; - # Remember a credit side split. + # The debit side is split, remember the entry. $entry{contra} = $credit; $entry{amount} = $amount; } if ($credit) { $accounts{$credit} or die "unknown credit account $credit: $line"; + $debit && ($accounts{$debit}{type} =~ /S/) != + ($accounts{$credit}{type} =~ /S/) + and die "statistical vs. non-statistical account: $line"; + # The debit side may or may not be split. my %newentry = (%entry, contra => $debit, amount => -$amount); make_entry %newentry, $credit; # This entry is not split: clear it after processing. %entry = () if $debit; } else { - # Remember a debit side split. + # The credit side is split, remember the entry. $entry{contra} = $debit; $entry{amount} = -$amount; } @@ -520,7 +524,7 @@ for my $cc (sort keys %cclist) { 100.0 * $entry->{rel}, $entry->{old}; if ($entry->{days}) { printf "%5.1f%% p.a.", - 36000.0 * $entry->{rel} / $entry->{days}; + 36524.5 * $entry->{rel} / $entry->{days}; } else { printf "%11s", ''; }