#!/usr/bin/perl -w

use utf8;
use strict;
use warnings;

BEGIN {
    unshift @INC, ( $ENV{POPHOME} || '@POPHOME@' ) . '/lib'
      unless $ENV{KUNDE_NO_PERLPATH};
}

use Dbase::Getopt qw(:DEFAULT :kunden getopt_date);
use Dbase::Help qw(DoSelect in_list);
use noris::CSV;
use Umlaut qw(textmodus);

sub getopt_day {
    my ($option) = @_;
    my @l = localtime( my $time = &getopt_date );
    die "Bei -$option sind nur tagesgenaue Angaben möglich.\n"
      if grep $_, @l[ 0 .. 2 ];
    $time;
}

sub time2jjmm_tt($) {
    my ( $y, $m, $d ) = ( localtime shift )[ 5, 4, 3 ];
    sprintf( '%d%02d', $y + 1900, $m + 1 ), $d;
}

my ( $WithNewlines, $ZeitSeit, $ZeitVor );
GetOptions(
    'csv-option=s' => \my %CSV_Options,
    'einzeilig'    => sub { $WithNewlines = '' },
    'mehrzeilig'   => sub { $WithNewlines = 1 },
    'seit=s'       => sub { $ZeitSeit = &getopt_day },
    'vor=s'        => sub { $ZeitVor = &getopt_day },
);

my @where = (
    in_list( 'acct.kunde', '', @Kunden ),
    in_list( 'acct.kunde', NOT => @OhneKunden )
);

if ( defined $ZeitSeit ) {
    my ( $jjmm, $tt ) = time2jjmm_tt($ZeitSeit);
    push @where, $tt == 1
      ? "acct.jjmm >= $jjmm"
      : "( acct.jjmm > $jjmm OR acct.jjmm = $jjmm AND acct.tt >= $tt )";
}
if ( defined $ZeitVor ) {
    my ( $jjmm, $tt ) = time2jjmm_tt($ZeitVor);
    push @where, $tt == 1
      ? "acct.jjmm < $jjmm"
      : "( acct.jjmm < $jjmm OR acct.jjmm = $jjmm AND acct.tt < $tt )";
}

textmodus( \*STDOUT );
my $csv = noris::CSV->new( \%CSV_Options );

print $csv->as_decoded_string(
    qw(Kunde Ticket Acct-ID Datum Dienst Minuten Text));

DoSelect {
    $_[-1] =~ s/\n/ /g unless $WithNewlines;
    print $csv->as_decoded_string(@_);
}
<<'1' . join( '', map <<2, @where ) . <<'3';
	SELECT    kunde.name,
	          rt_billing.ticket,
                  CONCAT( acct.`hash`, '-', acct.seq ),
	          CONCAT_WS( '-',
	                     LEFT( acct.jjmm, CHAR_LENGTH(acct.jjmm)-2 ),
	                     RIGHT( acct.jjmm, 2 ), acct.tt
	                   ),
	          IF( dienst.rechnungstext IS NULL,
	              IF( dienst.info IS NULL,
	                  IF( dienst.name IS NULL,
	                      CONCAT('#',dienst.id),
	                      dienst.name
	                    ),
	              dienst.info
	            ),
	            dienst.rechnungstext
	          ),
	          ROUND(acct.bytes/60),
	          acctassoc.info
	FROM      ( acct, dienst, kunde, rt_billing )
	
	LEFT JOIN acctassoc
	       ON acct.`hash` = acctassoc.`hash` AND acct.seq = acctassoc.seq
	WHERE     acct.`hash` = rt_billing.`hash`
	      AND acct.seq    = rt_billing.seq
	      AND acct.kunde  = kunde.id
	      AND acct.dienst = dienst.id
1
	      AND $_
2
	ORDER BY  acct.jjmm, acct.tt, rt_billing.ticket, acct.hash, acct.seq
3

__END__

=encoding utf8

=head1 NAME

arbeitszeit-acct - auf Tickets gebuchte Accounting-Datensätze ausgeben

=head1 SYNOPSE

    arbeitszeit-acct -kunde-und-unterkunden quelle-contact -seit 2009-01-01

=head1 BESCHREIBUNG

Gibt eine CSV-Liste von Accounting-Datensätzen aus.

=head1 OPTIONEN

=over 4

=item -ap-technik Person

=item -ap-vertrieb Person

=item -kunde Kunde

=item -kunde-und-unterkunden Kunde

=item -ohne-ap-technik Person

=item -ohne-ap-vertrieb Person

=item -ohne-kunde Kunde

=item -ohne-kunde-und-unterkunden Kunde

Per Default werden Datensätze aller Kunden ausgewertet.
Dies lässt sich vermittels dieser Optionen modifizieren.
Details dazu siehe L<Dbase::Getopt/:kunden>.

=item -seit Tag

Nur Accounting-Datensätze ausgeben, die nicht älter sind als das (tagesgenau)
angegebene Datum.

=item -vor Tag

Nur Accounting-Datensätze ausgeben, die älter sind als das (tagesgenau)
angegebene Datum.

=item -csv-option Name=Wert

Optionen für L<Text::CSV_XS>, s. Dokumentation dieses Moduls

=item -einzeilig

Zeilenumbrüche in den Rechnungstexten durch Leerzeichen ersetzen
(voreingestellt)

=item -mehrzeilig

Zeilenumbrüche in den Rechnungstexten erhalten;
führt beim Import in MS-Excel erfahrungsgemäß zu Problemen

=item -help

=item -?

um (nur) diese Dokumentation anzeigen zu lassen

=back

