From: Mark Wells Date: Thu, 10 Sep 2015 23:27:43 +0000 (-0700) Subject: improve usage_class_summary with number of calls and total minutes, #37122 X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=commitdiff_plain;h=9896275b96170e2a97e313e64c7aa5bfaf12a087 improve usage_class_summary with number of calls and total minutes, #37122 --- diff --git a/FS/FS/Template_Mixin.pm b/FS/FS/Template_Mixin.pm index e9b60a86c..206c03cde 100644 --- a/FS/FS/Template_Mixin.pm +++ b/FS/FS/Template_Mixin.pm @@ -1519,7 +1519,7 @@ sub print_generic { # usage subtotals if ( $conf->exists('usage_class_summary') and $self->can('_items_usage_class_summary') ) { - my @usage_subtotals = $self->_items_usage_class_summary(escape => $escape_function); + my @usage_subtotals = $self->_items_usage_class_summary(escape => $escape_function, 'money_char' => $other_money_char); if ( @usage_subtotals ) { unshift @sections, $usage_subtotals[0]->{section}; # do not summarize unshift @detail_items, @usage_subtotals; diff --git a/FS/FS/cust_bill.pm b/FS/FS/cust_bill.pm index 410fa7bf7..09424ba52 100644 --- a/FS/FS/cust_bill.pm +++ b/FS/FS/cust_bill.pm @@ -2661,10 +2661,12 @@ sub _items_usage_class_summary { my %opt = @_; my $escape = $opt{escape} || sub { $_[0] }; + my $money_char = $opt{money_char}; my $invnum = $self->invnum; my @classes = qsearch({ 'table' => 'usage_class', - 'select' => 'classnum, classname, SUM(amount) AS amount', + 'select' => 'classnum, classname, SUM(amount) AS amount,'. + ' COUNT(*) AS calls, SUM(duration) AS duration', 'addl_from' => ' LEFT JOIN cust_bill_pkg_detail USING (classnum)' . ' LEFT JOIN cust_bill_pkg USING (billpkgnum)', 'extra_sql' => " WHERE cust_bill_pkg.invnum = $invnum". @@ -2675,17 +2677,21 @@ sub _items_usage_class_summary { my @l; my $section = { description => &{$escape}($self->mt('Usage Summary')), - no_subtotal => 1, usage_section => 1, + subtotal => 0, }; foreach my $class (@classes) { + $section->{subtotal} += $class->get('amount'); push @l, { 'description' => &{$escape}($class->classname), - 'amount' => sprintf('%.2f', $class->amount), + 'amount' => $money_char.sprintf('%.2f', $class->get('amount')), + 'quantity' => $class->get('calls'), + 'duration' => $class->get('duration'), 'usage_classnum' => $class->classnum, 'section' => $section, }; } + $section->{subtotal} = $money_char.sprintf('%.2f', $section->{subtotal}); return @l; } diff --git a/conf/invoice_html b/conf/invoice_html index dfd87c79b..e1af70703 100644 --- a/conf/invoice_html +++ b/conf/invoice_html @@ -176,15 +176,28 @@ $OUT .= $header; $columncount = scalar(my @array = split /<\/th>' . emt('Description') . ''. - ( $unitprices - ? '' . emt('Unit Price') . ''. - '' . emt('Quantity') . '' - : '' ). - '' . emt('Amount') . ''; + my @headings = ( '', 'Description', 'Amount' ); + my @aligns = ( 'center', 'left', 'right' ); + if ( $unitprices ) { + splice @headings, 2, 0, 'Unit Price', 'Quantity'; + splice @aligns, 2, 0, 'right', 'right'; + } + if ( $section->{usage_section} ) { + @headings = ( '', 'Description', 'Calls', 'Duration', 'Amount' ); + @aligns = ( '', 'left', 'right', 'right', 'right' ); + $columncount = 5; + } + + while ( @headings ) { + my $heading = shift @headings; + $heading = emt($heading) if $heading; + my $align = shift @aligns; + $OUT .= ' + ' . $heading . ''; + } } - $OUT .= ''; + + $OUT .= ''; my $lastref = 0; foreach my $line ( @@ -197,6 +210,17 @@ if ( $section->{description_generator} ) { $OUT .= ' + + ' . $line->{'description'} . ' + ' . $line->{'quantity'} . ' + ' . $minutes . 'm ' . $seconds . 's' . ' + ' . $line->{'amount'} . ' + '; } else { my $class = 'invoice_desc_more'; if ( ($line->{'ref'} || 0) ne $lastref ) { @@ -257,7 +281,7 @@ } $OUT .= ''; } - } + } # if !$section->{summarized} if ($section->{'posttotal'}) { $OUT .= ''; $OUT .= diff --git a/conf/invoice_latex b/conf/invoice_latex index c7c696b5d..4df858d22 100644 --- a/conf/invoice_latex +++ b/conf/invoice_latex @@ -196,7 +196,20 @@ \hline } -% ...description... +\newcommand{\FSusagehead}{ + \hline + \rule{0pt}{2.5ex} + \makebox[1.4cm]{} & + \multicolumn{4}{l}{ + \makebox[\FSdescriptionlength][l]{\textbf{[@-- emt('Description') --@]}} + } & + \textbf{~~[@-- emt('Calls') --@]} & + \textbf{~~[@-- emt('Duration') --@]} & + \textbf{~~[@-- emt('Amount') --@]} \\ + \hline +} + +}% ...description... \newcommand{\FSdesc}[5]{ \multicolumn{1}{c}{\rule{0pt}{2.5ex}\textbf{#1}} & \multicolumn{[@-- $unitprices ? '4' : '6' --@]}{l}{\textbf{#2}} & @@ -217,6 +230,15 @@ & \multicolumn{6}{l}{#1} & #2\\ } +% ...usage class summary +\newcommand{\FSusagedesc}[4]{ + \multicolumn{1}{c}{\rule{0pt}{2.5ex}} & + \multicolumn{4}{l}{\textbf{#1}} & + \multicolumn{1}{r}{\textbf{#2}} & + \multicolumn{1}{r}{\textbf{#3}} & + \multicolumn{1}{r}{\textbf{#4}} + \\ +} \begin{document} % Headers and footers defined for the first page @@ -289,6 +311,8 @@ $OUT .= '}\\\\'; if ($section->{header_generator}) { $OUT .= &{$section->{header_generator}}(); + } elsif ( $section->{usage_section} ) { + $OUT .= '\FSusagehead'; } else { $OUT .= '\FShead'; } @@ -296,6 +320,8 @@ $OUT .= '\multicolumn{7}{r}{\rule{0pt}{2.5ex}'.emt('Continued from previous page').'}\\\\'; if ($section->{header_generator}) { $OUT .= &{$section->{header_generator}}(); + } elsif ( $section->{usage_section} ) { + $OUT .= '\FSusagehead'; } else { $OUT .= '\FShead'; } @@ -343,6 +369,14 @@ $OUT .= "\\hline\n" if (($line->{'ref'} || 0) ne $lastref); if ($section->{description_generator}) { $OUT .= &{$section->{description_generator}}($line); + } elsif ($section->{usage_section}) { + my $minutes = sprintf('%d', $line->{'duration'} / 60); + my $seconds = $line->{'duration'} % 60; + $OUT .= '\FSusagedesc + {' . $line->{'description'} . '} + {' . $line->{'quantity'} . '} + {' . $minutes . 'm ' . $seconds . 's' . '} + {' . '\dollar' . $line->{'amount'} . '}'; } else { $OUT .= '\FSdesc'. '{}'.