[BACK]Return to pta_import.pl CVS log [TXT][DIR] Up to [cvsweb.bsd.lv] / pta

Annotation of pta/pta_import.pl, Revision 1.10

1.1       schwarze    1: #!/usr/bin/perl
                      2:
                      3: # Copyright (c) 2020 Freda Bundchen
                      4:
                      5: # Permission to use, copy, modify, and distribute this software for any
                      6: # purpose with or without fee is hereby granted, provided that the above
                      7: # copyright notice and this permission notice appear in all copies.
                      8: #
                      9: # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     10: # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     11: # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     12: # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     13: # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     14: # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     15: # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     16:
                     17: use warnings;
                     18: use strict;
                     19:
1.9       schwarze   20: use Getopt::Std qw(getopts);
                     21:
                     22: our ($opt_I);
                     23:
1.1       schwarze   24: # === SUBROUTINES  =====================================================
                     25:
1.10    ! schwarze   26: sub import_account ($$$$$) {
        !            27:        my ($account_name, $accounts_ref, $bookings_ref,
        !            28:            $compiled_ref, $csv_account) = @_;
        !            29:        my ($account, $amount, $booking, $credit, $date, $debit,
        !            30:            $description);
1.5       schwarze   31:        chomp(my $header = <>);
1.2       schwarze   32:        while (<>) {
1.5       schwarze   33:                next if (/^$/);
1.1       schwarze   34:                chomp;
1.3       schwarze   35:                my $line = $_;
1.5       schwarze   36:                foreach my $regex (@$compiled_ref) {
1.3       schwarze   37:                        if ($line =~ /$regex/) {
1.5       schwarze   38:                                $account = %$accounts_ref{$regex};
                     39:                                $booking = %$bookings_ref{$regex};
1.4       schwarze   40:                                last;
1.3       schwarze   41:                        }
                     42:                }
1.10    ! schwarze   43:                if ($account_name eq "chase_credit") {
        !            44:                        ($date, $amount, $debit, $credit,
        !            45:                            $description) =
        !            46:                            import_chase_credit($account,
        !            47:                            $csv_account, $line);
        !            48:                } elsif ($account_name eq "capital_one_credit") {
        !            49:                        ($date, $amount, $debit, $credit,
        !            50:                            $description) =
        !            51:                            import_capital_one_credit($account,
        !            52:                            $csv_account, $line);
        !            53:                } elsif ($account_name eq "optum_hsa") {
        !            54:                        ($date, $amount, $debit, $credit,
        !            55:                            $description) =
        !            56:                            import_optum_hsa($account,
        !            57:                            $csv_account, $line);
        !            58:                } else {
        !            59:                        die "undefined format: $account_name";
        !            60:                }
        !            61:                unless ($date && $booking && $debit && $credit &&
        !            62:                    $amount && $description) {
1.5       schwarze   63:                        die "import parse error: $line";
1.3       schwarze   64:                }
1.10    ! schwarze   65:                $description =~ s/#//g;
        !            66:                print "$date $booking $debit $credit $amount " .
1.1       schwarze   67:                    "$description\n";
                     68:        }
                     69: }
                     70:
1.10    ! schwarze   71: sub import_chase_credit ($$$) {
        !            72:        my ($account, $csv_account, $line) = @_;
        !            73:        my ($trans_date, $post_date, $description, $category,
        !            74:            $type, $amount) = split /,/, $line;
        !            75:        my ($debit, $credit);
        !            76:        $post_date =~ s#(\d+)/(\d+)/(\d+)#$3$1$2#;
        !            77:        ($amount, $debit, $credit) =
        !            78:            get_accounts_by_amount_sign($amount, $account,
        !            79:            $csv_account);
        !            80:        return ($post_date, $amount, $debit, $credit, $description);
        !            81: }
        !            82:
        !            83: sub import_capital_one_credit ($$$) {
        !            84:        my ($account, $csv_account, $line) = @_;
        !            85:        my ($trans_date, $post_date, $card_num,
        !            86:            $description, $category, $csv_debit,
        !            87:            $csv_credit) = split /,/, $line;
        !            88:        $post_date =~ s/(\d+)-(\d+)-(\d+)/$1$2$3/;
        !            89:        my ($amount, $debit, $credit) =
        !            90:            get_accounts_by_csv_col($account, $csv_account,
        !            91:            $csv_debit, $csv_credit);
        !            92:        return ($post_date, $amount, $debit, $credit, $description);
        !            93: }
        !            94:
        !            95: sub import_optum_hsa ($$$) {
        !            96:         my ($account, $csv_account, $line) = @_;
        !            97:         my ($date, $description, $amount,
        !            98:             $type) = split /,/, $line;
        !            99:        my ($debit, $credit);
        !           100:        $date =~ s/(\d+)-(\d+)-(\d+)/$1$2$3/;
        !           101:        $amount =~ s/\$//;
        !           102:        ($amount, $debit, $credit) =
        !           103:            get_accounts_by_amount_sign($amount, $account,
        !           104:            $csv_account);
        !           105:        return ($date, $amount, $debit, $credit, $description);
        !           106: }
        !           107:
        !           108: sub get_accounts_by_amount_sign ($$$) {
        !           109:        my ($amount, $account, $csv_account) = @_;
        !           110:        my ($debit, $credit);
        !           111:        if ($amount <= 0) {
        !           112:                $amount = substr $amount, 1;
        !           113:                $credit = $csv_account;
        !           114:                $debit = $account;
        !           115:        } else {
        !           116:                $debit = $csv_account;
        !           117:                $credit = $account;
1.5       schwarze  118:        }
1.10    ! schwarze  119:        return ($amount, $debit, $credit);
1.5       schwarze  120: }
1.9       schwarze  121:
1.10    ! schwarze  122: sub get_accounts_by_csv_col ($$$$) {
        !           123:        my ($account, $csv_account, $csv_debit, $csv_credit) = @_;
        !           124:        my ($amount, $debit, $credit);
        !           125:        if ($csv_debit eq "") {
        !           126:                $amount = $csv_credit;
        !           127:                $credit = $account;
        !           128:                $debit = $csv_account;
        !           129:        } else {
        !           130:                $amount = $csv_debit;
        !           131:                $credit = $csv_account;
        !           132:                $debit = $account;
        !           133:        }
        !           134:        return ($amount, $debit, $credit);
1.9       schwarze  135: }
                    136:
                    137: sub usage () {
1.10    ! schwarze  138:        printf STDERR "usage: %s -I accountname csvfilename\n", $0;
1.9       schwarze  139:        exit 1;
                    140: }
                    141:
1.1       schwarze  142: # === MAIN PROGRAM =====================================================
                    143:
1.10    ! schwarze  144: my ($csv_account, $fn, $in, $account_name, %accounts, %bookings, @compiled);
1.9       schwarze  145: getopts 'I:' or usage;
                    146: if ($opt_I) {
1.10    ! schwarze  147:        $account_name = $opt_I;
        !           148:        $fn = "import_" . $account_name . ".txt";
1.9       schwarze  149:        open $in, $fn or die "$fn: $!";
1.1       schwarze  150: } else {
1.9       schwarze  151:        usage;
                    152: }
                    153: while (<$in>) {
                    154:        chomp;
                    155:        next if /^(?:#|$)/;
                    156:        my $line = $_;
                    157:        if (/^ACCOUNT\s+(\d+)$/) {
                    158:                $csv_account and die "duplicate ACCOUNT line: $1";
                    159:                $csv_account = $1;
                    160:                next;
                    161:        }
                    162:        s/^(.*),\s+(\d+)\s+(\S+)// or
                    163:            die "$fn import parse error: $line";
                    164:        my ($reg, $account, $booking) = ($1, $2, $3);
                    165:        $reg =~ s/(?:^|(?<=,))(?:$|(?=,))/[^,]*/g;
                    166:        $reg = qr/$reg/;
                    167:        push @compiled, $reg;
                    168:        $bookings{$reg} = $booking;
                    169:        $accounts{$reg} = $account;
1.1       schwarze  170: }
1.9       schwarze  171: close $in;
                    172: $csv_account or die "no ACCOUNT line in $fn";
1.10    ! schwarze  173: import_account($account_name, \%accounts, \%bookings,
        !           174:     \@compiled, $csv_account);

CVSweb