From 988ec48fea05902eb7ea22e43a44e86a36eee06a Mon Sep 17 00:00:00 2001 From: jeff Date: Wed, 4 Jun 2008 17:59:42 +0000 Subject: [PATCH] voxline invoice formatting --- FS/FS/Conf.pm | 7 +++++++ FS/FS/Conf_compat17.pm | 7 +++++++ FS/FS/cdr.pm | 45 +++++++++++++++++++++++++++++++++++++++++++++ FS/FS/cust_bill_pkg.pm | 17 +++++++++++++++-- FS/FS/part_pkg/voip_cdr.pm | 20 ++++++++++++++++---- conf/invoice_html | 2 +- conf/invoice_latex | 30 ++++++++++++++++++++++-------- 7 files changed, 113 insertions(+), 15 deletions(-) diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index 16305bf43..1506dde77 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -1875,6 +1875,13 @@ worry that config_items is freeside-specific and icky. }, { + 'key' => 'invoice-unitprice', + 'section' => 'billing', + 'description' => 'This switch enables unit pricing on the invoice.', + 'type' => 'checkbox', + }, + + { 'key' => 'batch-enable', 'section' => 'billing', 'description' => 'Enable credit card and/or ACH batching - leave disabled for real-time installations.', diff --git a/FS/FS/Conf_compat17.pm b/FS/FS/Conf_compat17.pm index 8286431a5..693c02f72 100644 --- a/FS/FS/Conf_compat17.pm +++ b/FS/FS/Conf_compat17.pm @@ -1947,6 +1947,13 @@ httemplate/docs/config.html }, { + 'key' => 'invoice-unitprice', + 'section' => 'billing', + 'description' => 'This switch enables unit pricing on the invoice.', + 'type' => 'checkbox', + }, + + { 'key' => 'batch-enable', 'section' => 'billing', 'description' => 'Enable credit card and/or ACH batching - leave disabled for real-time installations.', diff --git a/FS/FS/cdr.pm b/FS/FS/cdr.pm index 29bbe0e99..adde898e4 100644 --- a/FS/FS/cdr.pm +++ b/FS/FS/cdr.pm @@ -392,6 +392,18 @@ sub _convergent_format { =cut +my %export_names = ( + 'convergent' => {}, + 'voxlinesystems' => { 'name' => 'VoxLineSystems', + 'invoice_header' => + "Date,Time,Name,Destination,Duration,Price", + }, + 'voxlinesystems2' => { 'name' => 'VoxLineSystems with source', + 'invoice_header' => + "Date,Time,Name,Destination,Called From,Duration,Price", + }, +); + my %export_formats = ( 'convergent' => [ 'carriername', #CARRIER @@ -416,6 +428,15 @@ my %export_formats = ( sub { sprintf('%.2fm', shift->billsec / 60 ) }, #DURATION sub { sprintf('%.3f', shift->upstream_price ) }, #PRICE ], + 'voxlinesystems2' => [ + sub { time2str('%D', shift->calldate_unix ) }, #DATE + sub { time2str('%T', shift->calldate_unix ) }, #TIME + 'userfield', #USER + 'dst', #NUMBER_DIALED + 'src', #called from + sub { sprintf('%.2fm', shift->billsec / 60 ) }, #DURATION + sub { sprintf('%.3f', shift->upstream_price ) }, #PRICE + ], ); sub downstream_csv { @@ -448,6 +469,30 @@ sub downstream_csv { =over 4 +=item invoice_formats + +Returns an ordered list of key value pairs containing invoice format names +as keys (for use with part_pkg::voip_cdr) and "pretty" format names as values. + +=cut + +sub invoice_formats { + map { ($_ => $export_names{$_}->{'name'}) } + grep { $export_names{$_}->{'invoice_header'} } + keys %export_names; +} + +=item invoice_header FORMAT + +Returns a scalar containing the CSV column header for invoice format FORMAT. + +=cut + +sub invoice_header { + my $format = shift; + $export_names{$format}->{'invoice_header'}; +} + =item import_formats Returns an ordered list of key value pairs containing import format names diff --git a/FS/FS/cust_bill_pkg.pm b/FS/FS/cust_bill_pkg.pm index d15200e0c..e92c05dc7 100644 --- a/FS/FS/cust_bill_pkg.pm +++ b/FS/FS/cust_bill_pkg.pm @@ -268,8 +268,21 @@ sub details { $format_sub = sub { my $detail = shift; $csv->parse($detail) or return "can't parse $detail"; - join(' & ', map { '\small{'. &$escape_function($_). '}' } - $csv->fields ); + #join(' & ', map { '\small{'. &$escape_function($_). '}' } + # $csv->fields ); + my $result = ''; + my $column = 1; + foreach ($csv->fields) { + $result .= ' & ' if $column > 1; + if ($column > 6) { # KLUDGE ALERT! + $result .= '\multicolumn{1}{l}{\small{'. + &$escape_function($_). '}}'; + }else{ + $result .= '\small{'. &$escape_function($_). '}'; + } + $column++; + } + $result; } if $format eq 'latex'; diff --git a/FS/FS/part_pkg/voip_cdr.pm b/FS/FS/part_pkg/voip_cdr.pm index 0f25e15d4..6a3a2acc2 100644 --- a/FS/FS/part_pkg/voip_cdr.pm +++ b/FS/FS/part_pkg/voip_cdr.pm @@ -7,6 +7,7 @@ use Tie::IxHash; use FS::Conf; use FS::Record qw(qsearchs qsearch); use FS::part_pkg::flat; +use FS::cdr; #use FS::rate; #use FS::rate_prefix; @@ -79,6 +80,11 @@ tie my %rating_method, 'Tie::IxHash', 'type' => 'checkbox', }, + 'output_format' => { 'name' => 'Simple output format', + 'type' => 'select', + 'select_options' => { FS::cdr::invoice_formats() }, + }, + #XXX also have option for an external db # 'cdr_location' => { 'name' => 'CDR database location' # 'type' => 'select', @@ -109,7 +115,7 @@ tie my %rating_method, 'Tie::IxHash', default_prefix disable_src domestic_prefix international_prefix - use_amaflags use_disposition + use_amaflags use_disposition output_format ) ], 'weight' => 40, @@ -136,6 +142,9 @@ sub calc_recur { my $downstream_cdr = ''; + my $output_format = $self->option('output_format', 'Hush!') + || 'voxlinesystems'; + foreach my $cust_svc ( grep { $_->part_svc->svcdb eq 'svc_phone' } $cust_pkg->cust_svc ) { @@ -292,7 +301,7 @@ sub calc_recur { $charge = sprintf('%.3f', $cdr->upstream_price); $charges += $charge; - @call_details = ( $cdr->downstream_csv( 'format' => 'voxlinesystems' )); + @call_details = ($cdr->downstream_csv( 'format' => $output_format )); } else { die "don't know how to rate CDRs using method: ". @@ -362,7 +371,10 @@ sub calc_recur { $call_details = join(' - ', @call_details ); } warn " adding details on charge to invoice: $call_details" - if $DEBUG; + if ( $DEBUG && !ref($call_details) ); + warn " adding details on charge to invoice: [ ". + join(', ', @{$call_details} ). " ]" + if ( $DEBUG && ref($call_details) ); push @$details, $call_details; #\@call_details, } @@ -379,7 +391,7 @@ sub calc_recur { } # $cdr - unshift @$details, [ 'C', "Date,Time,Name,Destination,Duration,Price" ] + unshift @$details, [ 'C', FS::cdr::invoice_header( $output_format) ] if (@$details && $self->option('rating_method') eq 'upstream_simple' ); } # $cust_svc diff --git a/conf/invoice_html b/conf/invoice_html index ae6910dba..a3ab6c0c2 100644 --- a/conf/invoice_html +++ b/conf/invoice_html @@ -117,7 +117,7 @@ '' ; if ( @{$line->{'ext_description'} } ) { - $OUT .= ''; + $OUT .= '
'; foreach my $ext_desc ( @{$line->{'ext_description'} } ) { $OUT .= ''. diff --git a/conf/invoice_latex b/conf/invoice_latex index d17ff8f6d..2acd7102d 100644 --- a/conf/invoice_latex +++ b/conf/invoice_latex @@ -157,16 +157,18 @@ % Commands for freeside description... -\newcommand{\FSdesc}[3]{ +\newcommand{\FSdesc}[5]{ \multicolumn{1}{c}{\rule{0pt}{2.5ex}\textbf{#1}} & - \multicolumn{6}{l}{\textbf{#2}} & - \multicolumn{1}{r}{\textbf{\dollar #3}}\\ + \multicolumn{4}{l}{\textbf{#2}} & + \multicolumn{1}{l}{\textbf{#3}} & + \multicolumn{1}{r}{\textbf{#4}} & + \multicolumn{1}{r}{\textbf{\dollar #5}}\\ } % ...extended description... \newcommand{\FSextdesc}[1]{ \multicolumn{1}{l}{\rule{0pt}{1.0ex}} & %% \multicolumn{2}{l}{\small{~-~#1}}\\ - ~-~#1\\ + ~~~#1\\ } % ...and total line items. \newcommand{\FStotaldesc}[2]{ @@ -238,16 +240,26 @@ Terms: [@-- $terms --@]\\ $OUT .= '\hline'; $OUT .= '\rule{0pt}{2.5ex}'; $OUT .= '\makebox[1.4cm]{\textbf{Ref}} & '; - $OUT .= '\multicolumn{6}{l}{\makebox[12.8cm][l]{\textbf{Description}}} & '; - $OUT .= '\makebox[2.5cm][r]{\textbf{Amount}} \\\\'; + $OUT .= '\makebox[2.0cm][l]{\textbf{Description}}& '; + $OUT .= '\makebox[2.0cm][l]{}& '; + $OUT .= '\makebox[2.0cm][l]{}& '; + $OUT .= '\makebox[2.0cm][l]{}& '; + $OUT .= '\makebox[2.0cm][l]{\textbf{'. ($unitprices ? '~~Unit Price' : ''). '}&'; + $OUT .= '\makebox[2.0cm]{\textbf{'. ($unitprices ? '~Quantity' : ''). '}&'; + $OUT .= '\makebox[2.0cm][r]{\textbf{Amount}} \\\\'; $OUT .= '\hline'; $OUT .= '\endfirsthead'; $OUT .= '\multicolumn{7}{r}{\rule{0pt}{2.5ex}Continued from previous page}\\\\'; $OUT .= '\hline'; $OUT .= '\rule{0pt}{2.5ex}'; $OUT .= '\makebox[1.4cm]{\textbf{Ref}} & '; - $OUT .= '\multicolumn{6}{l}{\makebox[12.8cm][l]{\textbf{Description}}} & '; - $OUT .= '\makebox[2.5cm][r]{\textbf{Amount}} \\\\'; + $OUT .= '\makebox[2.0cm][l]{\textbf{Description}}& '; + $OUT .= '\makebox[2.0cm][l]{}& '; + $OUT .= '\makebox[2.0cm][l]{}& '; + $OUT .= '\makebox[2.0cm][l]{}& '; + $OUT .= '\makebox[2.0cm][l]{\textbf{'. ($unitprices ? '~~Unit Price' : ''). '}&'; + $OUT .= '\makebox[2.0cm]{\textbf{'. ($unitprices ? '~Quantity' : ''). '}&'; + $OUT .= '\makebox[2.0cm][r]{\textbf{Amount}} \\\\'; $OUT .= '\hline'; $OUT .= '\endhead'; $OUT .= '\multicolumn{7}{r}{\rule{0pt}{2.5ex}Continued on next page...}\\\\'; @@ -283,6 +295,8 @@ Terms: [@-- $terms --@]\\ $OUT .= "\\hline\n"; $OUT .= '\FSdesc{' . $line->{'ref'} . '}{' . $line->{'description'} . '}' . + '{' . ( $unitprices ? $line->{'unit_amount'} : '' ) . '}'. + '{' . ( $unitprices ? $line->{'quantity'} : '' ) . '}' . '{' . $line->{'amount'} . "}${rowbreak}\n"; foreach my $ext_desc (@$ext_description) { -- 2.11.0