diff options
| -rw-r--r-- | FS/FS/Schema.pm | 1 | ||||
| -rw-r--r-- | FS/FS/cdr.pm | 8 | ||||
| -rw-r--r-- | FS/FS/cust_bill.pm | 16 | ||||
| -rw-r--r-- | FS/FS/cust_bill_pkg.pm | 57 | ||||
| -rw-r--r-- | FS/FS/cust_bill_pkg_detail.pm | 1 | ||||
| -rw-r--r-- | FS/FS/part_pkg/voip_cdr.pm | 20 | ||||
| -rw-r--r-- | conf/invoice_html | 16 | ||||
| -rw-r--r-- | conf/invoice_latex | 13 | 
8 files changed, 100 insertions, 32 deletions
diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index f8dd38b8c..457e5c80d 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -499,6 +499,7 @@ sub tables_hashref {          'detailnum', 'serial', '', '', '', '',           'pkgnum',  'int', '', '', '', '',           'invnum',  'int', '', '', '', '',  +        'format',  'char', 'NULL', 1, '', '',          'detail',  'varchar', '', $char_d, '', '',         ],        'primary_key' => 'detailnum', diff --git a/FS/FS/cdr.pm b/FS/FS/cdr.pm index c10eec053..29bbe0e99 100644 --- a/FS/FS/cdr.pm +++ b/FS/FS/cdr.pm @@ -408,6 +408,14 @@ my %export_formats = (      sub { shift->rated_price ? 'Y' : 'N' }, #RATED      '', #OTHER_INFO    ], +  'voxlinesystems' => [ +    sub { time2str('%D', shift->calldate_unix ) },   #DATE +    sub { time2str('%T', shift->calldate_unix ) },   #TIME +    'userfield',                                     #USER +    'dst',                                           #NUMBER_DIALED +    sub { sprintf('%.2fm', shift->billsec / 60 ) },  #DURATION +    sub { sprintf('%.3f', shift->upstream_price ) }, #PRICE +  ],  );  sub downstream_csv { diff --git a/FS/FS/cust_bill.pm b/FS/FS/cust_bill.pm index f47081317..9b7c4add7 100644 --- a/FS/FS/cust_bill.pm +++ b/FS/FS/cust_bill.pm @@ -2000,6 +2000,7 @@ sub print_generic {      my %options = ();      $options{'section'} = $section if $multisection; +    $options{'format'} = $format;      foreach my $line_item ( $self->_items_pkg(%options) ) {        my $detail = { @@ -2010,9 +2011,7 @@ sub print_generic {        $detail->{'section'} = $section;        $detail->{'description'} = &$escape_function($line_item->{'description'});        if ( exists $line_item->{'ext_description'} ) { -        @{$detail->{'ext_description'}} = map { -          &$escape_function($_); -        } @{$line_item->{'ext_description'}}; +        @{$detail->{'ext_description'}} = @{$line_item->{'ext_description'}};        }        {          my $money = $old_latex ? '' : $money_char; @@ -2528,6 +2527,9 @@ sub _items_tax {  sub _items_cust_bill_pkg {    my $self = shift;    my $cust_bill_pkg = shift; +  my %opt = @_; +  my $format = $opt{format} || ''; +  my $escape_function = $opt{escape_function} || sub { shift };    my @b = ();    foreach my $cust_bill_pkg ( @$cust_bill_pkg ) { @@ -2542,7 +2544,10 @@ sub _items_cust_bill_pkg {          my $description = $desc;          $description .= ' Setup' if $cust_bill_pkg->recur != 0;          my @d = $cust_pkg->h_labels_short($self->_date); -        push @d, $cust_bill_pkg->details if $cust_bill_pkg->recur == 0; +        push @d, $cust_bill_pkg->details( 'format'          => $format, +                                          'escape_function' => $escape_function, +                                        ) +          if $cust_bill_pkg->recur == 0;          push @b, {            description     => $description,            #pkgpart         => $part_pkg->pkgpart, @@ -2569,7 +2574,8 @@ sub _items_cust_bill_pkg {              [ $cust_pkg->h_labels_short( $self->_date ),                                           #$cust_bill_pkg->edate,                                           #$cust_bill_pkg->sdate), -              $cust_bill_pkg->details, +              $cust_bill_pkg->details( 'format'          => $format, +                                       'escape_function' => $escape_function),              ],          };        } diff --git a/FS/FS/cust_bill_pkg.pm b/FS/FS/cust_bill_pkg.pm index 1cb982681..5d60311cf 100644 --- a/FS/FS/cust_bill_pkg.pm +++ b/FS/FS/cust_bill_pkg.pm @@ -112,7 +112,8 @@ sub insert {      my $cust_bill_pkg_detail = new FS::cust_bill_pkg_detail {        'pkgnum' => $self->pkgnum,        'invnum' => $self->invnum, -      'detail' => $detail, +      'format' => (ref($detail) ? $detail->[0] : '' ), +      'detail' => (ref($detail) ? $detail->[1] : $detail ),      };      $error = $cust_bill_pkg_detail->insert;      if ( $error ) { @@ -220,18 +221,62 @@ sub cust_bill {    qsearchs( 'cust_bill', { 'invnum' => $self->invnum } );  } -=item details +=item details [ OPTION => VALUE ... ]  Returns an array of detail information for the invoice line item. +Currently available options are: I<format> I<escape_function> + +If I<format> is set to html or latex then the array members are improved +for tabular appearance in those environments if possible. + +If I<escape_function> is set then the array members are processed by this +function before being returned. +  =cut  sub details { -  my $self = shift; +  my ( $self, %opt ) = @_; +  my $format = $opt{format} || ''; +  my $escape_function = $opt{escape_function} || sub { shift };    return () unless defined dbdef->table('cust_bill_pkg_detail'); -  map { $_->detail } -    qsearch ( 'cust_bill_pkg_detail', { 'pkgnum' => $self->pkgnum, -                                        'invnum' => $self->invnum, } ); + +  eval "use Text::CSV_XS;"; +  die $@ if $@; +  my $csv = new Text::CSV_XS; + +  my $format_sub = sub { my $detail = shift; +                         $csv->parse($detail) or return "can't parse $detail"; +                         join(' - ', map { &$escape_function($_) } +                                     $csv->fields +                             ); +                       }; + +  $format_sub = sub { my $detail = shift; +                      $csv->parse($detail) or return "can't parse $detail"; +                      join('</TD><TD>', map { &$escape_function($_) } +                                        $csv->fields +                          ); +                    } +    if $format eq 'html'; + +  $format_sub = sub { my $detail = shift; +                      $csv->parse($detail) or return "can't parse $detail"; +                      join(' & ', map { &$escape_function($_) } $csv->fields ); +                    } +    if $format eq 'latex'; + +  map { ( $_->format eq 'C' +          ? &{$format_sub}( $_->detail ) +          : &{$escape_function}( $_->detail ) +        ) +      } +    qsearch ({ 'table'    => 'cust_bill_pkg_detail', +               'hashref'  => { 'pkgnum' => $self->pkgnum, +                               'invnum' => $self->invnum, +                             }, +               'order_by' => 'ORDER BY detailnum', +            });      #qsearch ( 'cust_bill_pkg_detail', { 'lineitemnum' => $self->lineitemnum });  } diff --git a/FS/FS/cust_bill_pkg_detail.pm b/FS/FS/cust_bill_pkg_detail.pm index 4156816c8..a69998a42 100644 --- a/FS/FS/cust_bill_pkg_detail.pm +++ b/FS/FS/cust_bill_pkg_detail.pm @@ -104,6 +104,7 @@ sub check {    $self->ut_numbern('detailnum')      || $self->ut_foreign_key('pkgnum', 'cust_pkg', 'pkgnum')      || $self->ut_foreign_key('invnum', 'cust_bill', 'invnum') +    || $self->ut_enum('format', [ '', 'C' ] )      || $self->ut_text('detail')      || $self->SUPER::check      ; diff --git a/FS/FS/part_pkg/voip_cdr.pm b/FS/FS/part_pkg/voip_cdr.pm index c4827c9c5..0f25e15d4 100644 --- a/FS/FS/part_pkg/voip_cdr.pm +++ b/FS/FS/part_pkg/voip_cdr.pm @@ -292,15 +292,7 @@ sub calc_recur {          $charge = sprintf('%.3f', $cdr->upstream_price);          $charges += $charge; -        @call_details = ( -          #time2str("%Y %b %d - %r", $cdr->calldate_unix ), -          time2str("%c", $cdr->calldate_unix),  #XXX this should probably be a config option dropdown so they can select US vs- rest of world dates or whatnot -          sprintf('%.2f', $cdr->billsec / 60 ).'m', -          '$'.$charge, #XXX $money_char -          #$pretty_destnum, -          $cdr->userfield, #$rate_region->regionname, -          $cdr->dst, -        ); +        @call_details = ( $cdr->downstream_csv( 'format' => 'voxlinesystems' ));        } else {          die "don't know how to rate CDRs using method: ". @@ -363,7 +355,12 @@ sub calc_recur {          }          if ( $charge > 0 ) { -          my $call_details = join(' - ', @call_details ); +          my $call_details; +          if ( $self->option('rating_method') eq 'upstream_simple' ) { +            $call_details = [ 'C', $call_details[0] ]; +          }else{ +            $call_details = join(' - ', @call_details ); +          }            warn "  adding details on charge to invoice: $call_details"              if $DEBUG;            push @$details, $call_details; #\@call_details, @@ -382,6 +379,9 @@ sub calc_recur {      } # $cdr +    unshift @$details, [ 'C', "Date,Time,Name,Destination,Duration,Price" ] +      if (@$details && $self->option('rating_method') eq 'upstream_simple' ); +    } # $cust_svc    if ( $spool_cdr && length($downstream_cdr) ) { diff --git a/conf/invoice_html b/conf/invoice_html index 9d97243e4..14b25c671 100644 --- a/conf/invoice_html +++ b/conf/invoice_html @@ -106,13 +106,15 @@                '<td align="right">'. $line->{'amount'}. '</td>'.              '</tr>'            ; -          foreach my $ext_desc ( @{$line->{'ext_description'} } ) { -            $OUT .= -              '<tr class="invoice_extdesc">'. -                '<td></td>'. -                '<td align="left">- '. $ext_desc. '</td>'. -                '<td></td>'. -              '</tr>' +          if ( @{$line->{'ext_description'} } ) { +            $OUT .= '<tr class="invoice_extdesc"><td></td><td><table>'; +            foreach my $ext_desc ( @{$line->{'ext_description'} } ) { +              $OUT .= +                '<tr class="invoice_extdesc">'. +                  '<td align="left">- '. $ext_desc. '</td>'. +                '</tr>' +            } +            $OUT .= '</table></td><td></td></tr>';            }          } diff --git a/conf/invoice_latex b/conf/invoice_latex index 6a81c4c2e..e43fc3eb0 100644 --- a/conf/invoice_latex +++ b/conf/invoice_latex @@ -242,10 +242,15 @@ Terms: [@-- $terms --@]\\        $OUT .= '\FSdesc{' . $line->{'ref'} . '}{' . $line->{'description'} . '}' .
                '{' . $line->{'amount'} . "}${rowbreak}\n";
 -      foreach my $ext_desc (@$ext_description) {
 -        $ext_desc = substr($ext_desc, 0, 80) . '...'
 -          if (length($ext_desc) > 80);
 -        $OUT .= '\FSextdesc{' . $ext_desc . '}' . "${rowbreak}\n";
 +      if (@$ext_description) {
 +        $OUT .= '\multicolumn{1}{l}{\rule{0pt}{1.0ex}} &';
 +        $OUT .= '\multicolumn{2}{l}{\begin{tabular}{lllll}'; %%cheating at 5
 +        foreach my $ext_desc (@$ext_description) {
 +          $ext_desc = substr($ext_desc, 0, 80) . '...'
 +            if (length($ext_desc) > 80);
 +          $OUT .= '\small{' . $ext_desc . '}' . "\\\\${rowbreak}\n";
 +        }
 +        $OUT .="\\end{tabular}}\\\\${rowbreak}\n";
        }
      }
  | 
