summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FS/FS/Template_Mixin.pm2
-rw-r--r--FS/FS/cust_bill.pm12
-rw-r--r--conf/invoice_html42
-rw-r--r--conf/invoice_latex36
4 files changed, 78 insertions, 14 deletions
diff --git a/FS/FS/Template_Mixin.pm b/FS/FS/Template_Mixin.pm
index e9b60a8..206c03c 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 dee8a8f..54488f9 100644
--- a/FS/FS/cust_bill.pm
+++ b/FS/FS/cust_bill.pm
@@ -2658,10 +2658,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".
@@ -2672,17 +2674,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 dfd87c7..e1af707 100644
--- a/conf/invoice_html
+++ b/conf/invoice_html
@@ -176,15 +176,28 @@
$OUT .= $header;
$columncount = scalar(my @array = split /<\/th><th/i, $header);
} else {
- $OUT .= '<th align="center"></th>'.
- '<th align="left">' . emt('Description') . '</th>'.
- ( $unitprices
- ? '<th align="right">' . emt('Unit Price') . '</th>'.
- '<th align="right">' . emt('Quantity') . '</th>'
- : '' ).
- '<th align="right">' . emt('Amount') . '</th>';
+ 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 .= '
+ <th align="' . $align . '">' . $heading . '</th>';
+ }
}
- $OUT .= '</tr>';
+
+ $OUT .= '</tr>';
my $lastref = 0;
foreach my $line (
@@ -197,6 +210,17 @@
if ( $section->{description_generator} ) {
$OUT .= '<tr class="invoice_desc' .
&{$section->{description_generator}}($line);
+ } elsif ( $section->{usage_section} ) {
+ my $minutes = sprintf('%d', $line->{'duration'} / 60);
+ my $seconds = $line->{'duration'} % 60;
+ $OUT .= '
+ <tr class="invoice_desc_more">
+ <td></td>
+ <td align="left">' . $line->{'description'} . '</td>
+ <td align="right">' . $line->{'quantity'} . '</td>
+ <td align="right">' . $minutes . 'm ' . $seconds . 's' . '</td>
+ <td align="right">' . $line->{'amount'} . '</td>
+ </tr>';
} else {
my $class = 'invoice_desc_more';
if ( ($line->{'ref'} || 0) ne $lastref ) {
@@ -257,7 +281,7 @@
}
$OUT .= '</tr>';
}
- }
+ } # if !$section->{summarized}
if ($section->{'posttotal'}) {
$OUT .= '<tr><td align="right" colspan='. $columncount. '>';
$OUT .=
diff --git a/conf/invoice_latex b/conf/invoice_latex
index c7c696b..4df858d 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'.
'{}'.