仕訳データを取り込むの続き(前編)

消耗品の場合は、摘要の内容も入力したいので、
少しばかり修正することにした。

use v5.14;
use strict;
use warnings;
use utf8;
use FindBin;

my $yyyy = 2013;
my $data_dir = $FindBin::Bin . '/' . $yyyy;

# debtor: 借方
# creditor: 貸方
# summary: 摘要
# tax_class: 税区分
my $template = 'date,debtor_id,,price,tax_class,creditor_id,,price,,summary';

write_data( 'import/01_book.csv', {
    file => 'book.txt',
    debtor_id => 241, tax_class => 3,
    creditor_id => 100,
    summary => "書籍代"
} );

sub load_csv {
    my $file = shift;

    my $in_file = $data_dir . '/' . $file;
    open(my $fh, $in_file) or die $! . " : cannot open $in_file";

    my @data = ();
    while (<$fh>) {
        chomp;
        my @tmp = split /,/, $_;

        my $h = {};
        if ( my ($MM, $dd) = $tmp[0] =~ /(1?\d)\/([1-3]?\d)/ ) {
            $h->{date} = sprintf( "%04d/%02d/%02d", $yyyy, $MM, $dd );
        }
        else {
            say $_, ' <<< date is wrong!', " ($.)";
        }

        if ( my ($price) = $tmp[1] =~ /(\d{2,6})/ ) {
            $h->{price} = $price;
        }
        else {
            say $_, ' <<< price is wrong!', " ($.)";
        }

        if ( 3 <= scalar(@tmp) ) {
            $h->{summary} = $tmp[2];
        }

        push @data, $h;
    }

    close $fh;

    return \@data;
}

sub write_data {
    my $out_file = shift;
    my $arg_ref = shift;

    my $data_ref = load_csv( $arg_ref->{file} );
    my $replaced = $template
        =~ s/debtor_id/$arg_ref->{debtor_id}/r
        =~ s/tax_class/$arg_ref->{tax_class}/r
        =~ s/creditor_id/$arg_ref->{creditor_id}/r;
    my $summary = '';
    $summary = $arg_ref->{summary} if exists $arg_ref->{summary};

    local $\ = "\r";
    open my $fh, '>:encoding(utf-8)', $out_file or die $! . " : cannot open $out_file";
    foreach (sort { $a->{date} cmp $b->{date} } @{$data_ref}) {
        my $date = $_->{date};
        my $price = $_->{price};
        $summary = $_->{summary} if exists $_->{summary};
        print $fh $replaced =~ s/price/$price/gr =~ s/date/$date/gr =~ s/summary/$summary/gr;
    }
    close $fh;
}

これだと、入力するデータの3つ目を摘要として扱える。
ただ、たいぶ不格好なスクリプトになってしまったのと、
出力順を固定にするためにテンプレートを置換をするのはアレなので、
リファクタリングを継続しようと思う。

作戦としては、読み込みを行うタイミングでデフォルト値を渡して、
出力する側が、順番のみ担保する感じしようと思う。

でもって、もっと大切なことは、データを入力すること・・・。

おしまい。

Leave a Comment