Parse-PayPal-TxFinderReport

 view release on metacpan or  search on metacpan

lib/Parse/PayPal/TxFinderReport.pm  view on Meta::CPAN

Dates will be converted into Unix timestamps.

_
    args => {
        file => {
            schema => ['filename*'],
            description => <<'_',

File can be in tab-separated or comma-separated (CSV) format.

_
            pos => 0,
        },
        string => {
            schema => ['str*'],
            description => <<'_',

Instead of `files`, you can alternatively provide the file contents in
`strings`.

_
        },
        format => {
            schema => ['str*', in=>[qw/tsv csv/]],
            description => <<'_',

If unspecified, will be deduced from the filename's extension (/csv/i for
CSV, or /txt|tsv|tab/i for tab-separated).

_
        },
        date_format => {
            schema => ['str*', in=>['MM/DD/YYYY', 'DD/MM/YYYY']],
            default => 'MM/DD/YYYY',
        },
        thousands_sep => {
            schema => ['str*', in=>['.', '', ',']],
            default => ',',
        },
        decimal_point => {
            schema => ['str*', in=>['.', ',']],
            default => '.',
        },
    },
    args_rels => {
        req_one => ['file', 'string'],
    },
};
sub parse_paypal_txfinder_report {
    my %args = @_;

    my $format = $args{format};
    my $date_format   = $args{date_format}   // 'MM/DD/YYYY';
    my $thousands_sep = $args{thousands_sep} // ',';
    my $decimal_point = $args{decimal_point} // '.';

    my $handle;
    my $file;
    if (defined(my $str0 = $args{string})) {
        require IO::Scalar;
        require String::BOM;

        if (!$format) {
            $format = $str0 =~ /\t/ ? 'tsv' : 'csv';
        }
        my $str = String::BOM::strip_bom_from_string($str0);
        $handle = IO::Scalar->new(\$str);
        $file = "(string)";
    } elsif (defined(my $file = $args{file})) {
        require File::BOM;

        if (!$format) {
            $format = $file =~ /\.(csv)\z/i ? 'csv' : 'tsv';
        }
        open $handle, "<:encoding(utf8):via(File::BOM)", $file
            or return [500, "Can't open file '$file': $!"];
    } else {
        return [400, "Please specify files (or strings)"];
    }

    my $res = [200, "OK", {
        format => "txfinder",
        transactions => [],
    }];

    my $column_names;
    my $variant; # STR="Search Transaction Results", TF="Transaction Finder"
    my $state;   # header, data, postamble
    my $code_parse_row = sub {
        my ($row, $rownum) = @_;
        if ($rownum == 1) {
            return [412, "There are no rows"] unless @$row;
            if ($row->[0] eq 'Search Transactions Results') {
                $variant = 'STR';
            } elsif ($row->[0] eq 'Transaction Finder') {
                $variant = 'TF';
            } else {
                return [400, "Doesn't find signature in first row"];
            }
            $state = 'header';
            return;
        }
        if ($state eq 'postamble') {
            return $res;
        }
        if (!@$row || @$row == 1 && $row->[0] eq '') {
            if ($state eq 'header') {
                $state = 'data';
            } elsif ($state eq 'data') {
                $state = 'postamble';
            }
            return;
        }
        if ($state eq 'header') {
            # set column names as the last row in header
            $column_names = $row;
            return;
        }
        if ($state eq 'data') {
            return if $row->[0] eq 'Total';
            my $hash = {};
            for (0..@$row) {
                my $key = $column_names->[$_] // "";
                last unless length $key;
                my $v;
                if ($key =~ /^Date$/) {
                    $v = _parse_date($date_format, $row->[$_]);
                } elsif ($key =~ /Amount|Fee/) {
                    $v = _parse_num($thousands_sep, $decimal_point, $row->[$_]);
                } else {
                    $v = $row->[$_];
                }
                $hash->{$key} = $v;
            }
            push @{ $res->[2]{transactions} }, $hash;



( run in 2.145 seconds using v1.01-cache-2.11-cpan-c966e8aa7e8 )