package RTI::Config; use strict; use warnings; use 5.010; use YAML::XS qw/ LoadFile Dump Load /; use File::Spec; sub new { my ( $class, $args ) = @_; my $self = { file => '', }; bless $self, $class; my $file = $args->{file} || $self->_find_config; $self->read_config($file); return $self; } sub _find_config { my ($self) = @_; # XXX This needs to be better foreach my $file (qw/ rt_invoice.conf rt_invoice.cfg .rt_invoicerc /) { foreach my $dir ( '.', $ENV{HOME} . '/.rt_invoicing', $ENV{HOME} ) { my $path = join '/', $dir, $file; return $path if -e $path; } } return; } sub read_config { my ( $self, $file ) = @_; $file ||= $self->{file}; die "$file: no such file\n" unless -e $file; my $c = LoadFile($file) or die "Unable to load $file\n"; $c->{customers} ||= []; if ( $c->{default} ) { foreach my $cust ( @{ $c->{customers} } ) { foreach my $k ( keys %{ $c->{default} } ) { $cust->{$k} //= Load( Dump( $c->{default}->{$k} ) ); } } } $self->{_config} = $c; $self->{file} = $file; } sub get { my ( $self, $key ) = @_; my $value = Load( Dump( $self->{_config}->{$key} ) ); my ( $volume, $directories, $file ) = File::Spec->splitpath( File::Spec->rel2abs( $self->{file} ) ); given ($key) { when ('state') { if (!$value) { $value = $self->{file}; $value =~ s/(?:\.[^.]+)?$/\.state/; } } when ('invoice_dir') { $value //= File::Spec->catdir( $volume, $directories, 'invoices' ); } when ('template_dir') { $value //= File::Spec->catdir( $volume, $directories ); } when ('invoice_template') { $value //= 'invoice.tex.tt'; } when ('logo') { $value //= File::Spec->catfile( $volume, $directories, 'Logo.pdf' ); } when ('customers') { $value = $self->_customers($value); } } return $value; } sub _customers { my ( $self, $customers ) = @_; my $default_cust = $self->new_customer; foreach my $cust ( @{$customers} ) { foreach (keys %{ $default_cust }) { $cust->{$_} = $default_cust->{$_} unless exists $cust->{$_} } } return $customers; } sub new_customer { my ($self) = @_; my $cust = $self->get('default'); return { day => 0, per => 'week', frequency => 1, hours => { default => 0 }, rates => {}, %{$cust} }; } 1;