[freeside-commits] freeside/FS/FS/detail_format accountcode_default.pm, NONE, 1.1 basic.pm, NONE, 1.1 default.pm, NONE, 1.1 description_default.pm, NONE, 1.1 simple2.pm, NONE, 1.1 simple.pm, NONE, 1.1 source_default.pm, NONE, 1.1 sum_count.pm, NONE, 1.1 sum_duration.pm, NONE, 1.1 sum_duration_prefix.pm, NONE, 1.1

Mark Wells mark at wavetail.420.am
Tue Jan 3 13:13:35 PST 2012


Update of /home/cvs/cvsroot/freeside/FS/FS/detail_format
In directory wavetail.420.am:/tmp/cvs-serv18734/FS/FS/detail_format

Added Files:
	accountcode_default.pm basic.pm default.pm 
	description_default.pm simple2.pm simple.pm source_default.pm 
	sum_count.pm sum_duration.pm sum_duration_prefix.pm 
Log Message:
detail format refactor, #15535

--- NEW FILE: simple2.pm ---
package FS::detail_format::simple2;

use strict;
use parent qw(FS::detail_format);
use Date::Format qw(time2str);

sub name { 'Simple with source' }

sub header_detail { 'Date,Time,Name,Called From,Destination,Duration,Price' }

sub columns {
  my $self = shift;
  my $cdr = shift;
  (
    time2str($self->date_format, $cdr->startdate),
    time2str('%r', $cdr->startdate),
    $cdr->userfield,
    $cdr->src,
    $cdr->dst,
    $self->duration($cdr),
    $self->price($cdr),
  )
}

1;

--- NEW FILE: accountcode_default.pm ---
package FS::detail_format::accountcode_default;

use strict;
use parent qw(FS::detail_format);
use Date::Format qw(time2str);

sub name { 'Default with accountcode' }

sub header_detail { 'Date,Time,Account,Number,Destination,Duration,Price' }

sub columns {
  my $self = shift;
  my $cdr = shift;
  (
    time2str($self->date_format, $cdr->startdate),
    time2str('%r', $cdr->startdate),
    $cdr->accountcode,
    ($cdr->rated_pretty_dst || $cdr->dst),
    $cdr->rated_regionname,
    $self->duration($cdr),
    $self->price($cdr),
  )
}

1;

--- NEW FILE: default.pm ---
package FS::detail_format::default;

use strict;
use parent qw(FS::detail_format);
use Date::Format qw(time2str);

sub name { 'Default' }

sub header_detail { 'Date,Time,Number,Destination,Duration,Price' }

sub columns {
  my $self = shift;
  my $cdr = shift;
  (
    time2str($self->date_format, $cdr->startdate),
    time2str('%r', $cdr->startdate),
    ($cdr->rated_pretty_dst || $cdr->dst),
    $cdr->rated_regionname,
    $self->duration($cdr),
    $self->price($cdr),
  )
}

1;

--- NEW FILE: basic.pm ---
package FS::detail_format::basic;

use strict;
use parent qw(FS::detail_format);
use Date::Format qw(time2str);

sub name { 'Basic' }

sub header_detail { 'Date/Time,Called Number,Min/Sec,Price' }

sub columns {
  my $self = shift;
  my $cdr = shift;
  (
    time2str('%d %b - %I:%M %p', $cdr->startdate),
    $cdr->dst,
    $self->duration($cdr),
    $self->price($cdr),
  )
}

1;

--- NEW FILE: simple.pm ---
package FS::detail_format::simple;

use strict;
use parent qw(FS::detail_format);
use Date::Format qw(time2str);

sub name { 'Simple' }

sub header_detail { 'Date,Time,Name,Destination,Duration,Price' }

sub columns {
  my $self = shift;
  my $cdr = shift;
  (
    time2str($self->date_format, $cdr->startdate),
    time2str('%r', $cdr->startdate),
    $cdr->userfield,
    $cdr->dst,
    $self->duration($cdr),
    $self->price($cdr),
  )
}

1;

--- NEW FILE: sum_duration.pm ---
package FS::detail_format::sum_duration;

use strict;
use vars qw( $DEBUG );
use parent qw(FS::detail_format);
use FS::Record qw(qsearchs);
use FS::cust_svc;
use FS::svc_Common; # for label

$DEBUG = 0;

sub name { 'Summary, one line per service' };

sub header_detail {
  my $self = shift;
  if ( $self->{inbound} ) {
    'Destination,Calls,Duration,Price'
  }
  else {
    'Source,Calls,Duration,Price'
  }
}

sub append {
  my $self = shift;
  my $svcnums = ($self->{svcnums} ||= {});
  foreach my $cdr (@_) {
    my $object = $self->{inbound} ? $cdr->cdr_termination(1) : $cdr;
    my $svcnum = $object->svcnum; # yes, $object->svcnum.

    my $subtotal = ($svcnums->{$svcnum} ||=
      { count => 0, duration => 0, amount => 0 });
    $subtotal->{count}++;
    $subtotal->{duration} += $object->rated_seconds;
    $subtotal->{amount} += $object->rated_price;
  }
}

sub finish {
  my $self = shift;
  my $svcnums = $self->{svcnums};
  my $buffer = $self->{buffer};
  foreach my $svcnum (keys %$svcnums) {

    my $cust_svc = qsearchs('cust_svc', { svcnum => $svcnum })
      or die "svcnum #$svcnum not found";
    my $phonenum = $cust_svc->svc_x->label;
    warn "processing $phonenum\n" if $DEBUG;

    my $subtotal = $svcnums->{$svcnum};

    $self->csv->combine(
      $phonenum,
      $subtotal->{count},
      int($subtotal->{duration}/60) . ' min',
      $self->money_char . sprintf('%.02f',$subtotal->{amount}),
    );

    warn "adding detail: ".$self->csv->string."\n" if $DEBUG;

    push @$buffer, FS::cust_bill_pkg_detail->new({
        amount      => $subtotal->{amount},
        format      => 'C',
        classnum    => '', #ignored in this format
        duration    => $subtotal->{duration},
        phonenum    => $phonenum,
        accountcode => '', #ignored in this format
        startdate   => '', #could use the earliest startdate in the bunch?
        regionname  => '', #no, we're using prefix instead
        detail      => $self->csv->string,
    });
  } #foreach $svcnum

  # supposedly the compiler is smart enough to do this in place
  @$buffer = sort { $a->{Hash}->{phonenum} cmp $b->{Hash}->{phonenum} } 
              @$buffer;
}

1;

--- NEW FILE: sum_count.pm ---
package FS::detail_format::sum_count;

use strict;
use vars qw( $DEBUG );
use parent qw(FS::detail_format);
use FS::Record qw(qsearchs);
use FS::cust_svc;
use FS::svc_Common; # for label

$DEBUG = 0;

sub name { 'Number of calls, one line per service' };

sub header_detail {
  my $self = shift;
  if ( $self->{inbound} ) {
    'Destination,Messages,Price'
  }
  else {
    'Source,Messages,Price'
  }
}

sub append {
  my $self = shift;
  my $svcnums = ($self->{svcnums} ||= {});
  foreach my $cdr (@_) {
    my $object = $self->{inbound} ? $cdr->cdr_termination(1) : $cdr;
    my $svcnum = $object->svcnum; # yes, $object->svcnum.

    my $subtotal = ($svcnums->{$svcnum} ||=
      { count => 0, duration => 0, amount => 0 });
    $subtotal->{count}++;
    $subtotal->{amount} += $object->rated_price;
  }
}

sub finish {
  my $self = shift;
  my $svcnums = $self->{svcnums};
  my $buffer = $self->{buffer};
  foreach my $svcnum (keys %$svcnums) {

    my $cust_svc = qsearchs('cust_svc', { svcnum => $svcnum })
      or die "svcnum #$svcnum not found";
    my $phonenum = $cust_svc->svc_x->label;
    warn "processing $phonenum\n" if $DEBUG;

    my $subtotal = $svcnums->{$svcnum};

    $self->csv->combine(
      $phonenum,
      $subtotal->{count},
      $self->money_char . sprintf('%.02f',$subtotal->{amount}),
    );

    warn "adding detail: ".$self->csv->string."\n" if $DEBUG;

    push @$buffer, FS::cust_bill_pkg_detail->new({
        amount      => $subtotal->{amount},
        format      => 'C',
        classnum    => '', #ignored in this format
        duration    => '',
        phonenum    => $phonenum,
        accountcode => '', #ignored in this format
        startdate   => '', #could use the earliest startdate in the bunch?
        regionname  => '', #no, we're using prefix instead
        detail      => $self->csv->string,
    });
  } #foreach $svcnum

  # supposedly the compiler is smart enough to do this in place
  @$buffer = sort { $a->{Hash}->{phonenum} cmp $b->{Hash}->{phonenum} } 
              @$buffer;
}

1;

--- NEW FILE: sum_duration_prefix.pm ---
package FS::detail_format::sum_duration_prefix;

use strict;
use vars qw( $DEBUG );
use parent qw(FS::detail_format);
use List::Util qw(sum);

$DEBUG = 0;

my $me = '[sum_duration_prefix]';

sub name { 'Summary, one line per destination prefix' };
# and also..."rate group"?  what do you call the interstate/intrastate rate 
# distinction?

sub header_detail {
  'Destination NPA-NXX,Interstate Calls,Duration,Intrastate Calls,Duration,Price';
}

my $prefix_length = 6;
# possibly should use rate_prefix for this, but interstate/intrastate uses 
# them in a strange way and we are following along

sub append {
  my $self = shift;
  my $prefixes = ($self->{prefixes} ||= {});
  foreach my $cdr (@_) {
    my $phonenum = $self->{inbound} ? $cdr->src : $cdr->dst;
    $phonenum =~ /^(\d{$prefix_length})/;
    my $prefix = $1 || 'other';
    warn "$me appending ".$cdr->dst." to $prefix\n" if $DEBUG;

    # XXX hardcoded ratenames, not the worst of evils
    $prefixes->{$prefix} ||= { 
      Interstate => { count => 0, duration => 0, amount => 0 }, 
      Intrastate => { count => 0, duration => 0, amount => 0 }, 
    };
    my $object = $self->{inbound} ? $cdr->cdr_termination(1) : $cdr;
    # XXX using $cdr's rated_ratename instead of $object because 
    # cdr_termination doesn't have one...
    # but interstate-ness should be symmetric, yes?  if A places an
    # interstate call to B, then B receives an interstate call from A.
    my $subtotal = $prefixes->{$prefix}{$cdr->rated_ratename}
      or die "unknown rated_ratename '" .$cdr->rated_ratename.
             "' in CDR #".$cdr->acctid."\n";
    $subtotal->{count}++;
    $subtotal->{duration} += $object->rated_seconds;
    $subtotal->{amount} += $object->rated_price;
  }
}

sub finish {
  my $self = shift;
  my $prefixes = $self->{prefixes};
  foreach my $prefix (sort { $a cmp $b } keys %$prefixes) {

    warn "processing $prefix\n" if $DEBUG;

    my $ratenames = $prefixes->{$prefix};
    my @subtotals = ($ratenames->{'Interstate'}, $ratenames->{'Intrastate'});
    my $total_amount   = sum( map { $_->{'amount'} } @subtotals );
    my $total_duration = sum( map { $_->{'duration'} } @subtotals );
    $prefix =~ s/(...)(...)/$1 - $2/;

    $self->csv->combine(
      $prefix,
      map({ 
          ($_->{count} || ''), 
          ($_->{duration} ? int($_->{duration}/60) . ' min' : '')
        } @subtotals ),
      $self->money_char . sprintf('%.02f',$total_amount),
    );

    warn "adding detail: ".$self->csv->string."\n" if $DEBUG;

    push @{ $self->{buffer} }, FS::cust_bill_pkg_detail->new({
        amount      => $total_amount,
        format      => 'C',
        classnum    => '', #ignored in this format
        duration    => $total_duration,
        phonenum    => '', # not divided up per service
        accountcode => '', #ignored in this format
        startdate   => '', #could use the earliest startdate in the bunch?
        regionname  => '', #no, we're using prefix instead
        detail      => $self->csv->string,
    });
  } #foreach $prefix
}

1;

--- NEW FILE: source_default.pm ---
package FS::detail_format::source_default;

use strict;
use parent qw(FS::detail_format);
use Date::Format qw(time2str);

sub name { 'Default with source' }

sub header_detail { 'Caller,Date,Time,Number,Destination,Duration,Price' }

sub columns {
  my $self = shift;
  my $cdr = shift;
  (
    $cdr->src,
    time2str($self->date_format, $cdr->startdate),
    time2str('%r', $cdr->startdate),
    ($cdr->rated_pretty_dst || $cdr->dst),
    $cdr->rated_regionname,
    $self->duration($cdr),
    $self->price($cdr),
  )
}

1;

--- NEW FILE: description_default.pm ---
package FS::detail_format::description_default;

use strict;
use parent qw(FS::detail_format);
use Date::Format qw(time2str);

sub name { 'Default with description field as destination' }

sub header_detail { 'Caller,Date,Time,Number,Destination,Duration,Price' }

sub columns {
  my $self = shift;
  my $cdr = shift;
  (
    $cdr->src,
    time2str($self->date_format, $cdr->startdate),
    time2str('%r', $cdr->startdate),
    ($cdr->rated_pretty_dst || $cdr->dst),
    $cdr->description,
    $self->duration($cdr),
    $self->price($cdr),
  )
}

1;



More information about the freeside-commits mailing list