[freeside-commits] freeside/FS/FS rate_time.pm, NONE, 1.1 rate_time_interval.pm, NONE, 1.1 Mason.pm, 1.42, 1.43 Schema.pm, 1.221, 1.222 rate.pm, 1.12, 1.13 rate_detail.pm, 1.12, 1.13

Mark Wells mark at wavetail.420.am
Wed Jun 30 18:53:52 PDT 2010


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

Modified Files:
	Mason.pm Schema.pm rate.pm rate_detail.pm 
Added Files:
	rate_time.pm rate_time_interval.pm 
Log Message:
voip_cdr call rating by day and time, RT#4763

Index: Mason.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/Mason.pm,v
retrieving revision 1.42
retrieving revision 1.43
diff -u -w -d -r1.42 -r1.43
--- Mason.pm	30 Jun 2010 07:09:42 -0000	1.42
+++ Mason.pm	1 Jul 2010 01:53:49 -0000	1.43
@@ -244,6 +244,8 @@
   use FS::cgp_rule_action;
   use FS::bill_batch;
   use FS::cust_bill_batch;
+  use FS::rate_time;
+  use FS::rate_time_interval;
   # Sammath Naur
 
   if ( $FS::Mason::addl_handler_use ) {

Index: rate_detail.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/rate_detail.pm,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -w -d -r1.12 -r1.13
--- rate_detail.pm	21 Mar 2010 23:13:24 -0000	1.12
+++ rate_detail.pm	1 Jul 2010 01:53:49 -0000	1.13
@@ -5,6 +5,7 @@
 use FS::Record qw( qsearch qsearchs dbh );
 use FS::rate;
 use FS::rate_region;
+use FS::rate_time;
 use Tie::IxHash;
 
 @ISA = qw(FS::Record);
@@ -54,6 +55,8 @@
 
 =item classnum - usage class (see L<FS::usage_class>) if any for this rate
 
+=item ratetimenum - rating time period (see L<FS::rate_time) if any
+
 =back
 
 =head1 METHODS
@@ -194,6 +197,30 @@
   $self->dest_region->prefixes_short;
 }
 
+=item rate_time
+
+Returns the L<FS::rate_time> object associated with this call 
+plan rate, if there is one.
+
+=cut
+
+sub rate_time {
+  my $self = shift;
+  $self->ratetimenum ? FS::rate_time->by_key($self->ratetimenum) : ();
+}
+
+=item rate_time_name
+
+Returns the I<ratetimename> field of the L<FS::rate_time> object
+associated with this rate plan.
+
+=cut
+
+sub rate_time_name {
+  my $self = shift;
+  $self->ratetimenum ? $self->rate_time->ratetimename : '(default)';
+}
+
 =item classname
 
 Returns the name of the usage class (see L<FS::usage_class>) associated with

--- NEW FILE: rate_time_interval.pm ---
package FS::rate_time_interval;

use strict;
use base qw( FS::Record );
use FS::Record qw( qsearch qsearchs );

=head1 NAME

FS::rate_time_interval - Object methods for rate_time_interval records

=head1 SYNOPSIS

  use FS::rate_time_interval;

  $record = new FS::rate_time_interval \%hash;
  $record = new FS::rate_time_interval { 'column' => 'value' };

  $error = $record->insert;

  $error = $new_record->replace($old_record);

  $error = $record->delete;

  $error = $record->check;

=head1 DESCRIPTION

An FS::rate_time_interval object represents an interval of clock time during 
the week, such as "Monday, 7 AM to 8 PM".  FS::rate_time_interval inherits 
from FS::Record.  The following fields are currently supported:

=over 4

=item intervalnum

primary key

=item stime

Start of the interval, in seconds from midnight on Sunday.

=item etime

End of the interval.

=item ratetimenum

A foreign key to an L<FS::rate_time> object representing the set of intervals 
to which this belongs.


=back

=head1 METHODS

=over 4

=item new HASHREF

Creates a new example.  To add the example to the database, see L<"insert">.

Note that this stores the hash reference, not a distinct copy of the hash it
points to.  You can ask the object for a copy with the I<hash> method.

=cut

# the new method can be inherited from FS::Record, if a table method is defined

sub table { 'rate_time_interval'; }

=item insert

Adds this record to the database.  If there is an error, returns the error,
otherwise returns false.

=cut

# the insert method can be inherited from FS::Record

=item delete

Delete this record from the database.

=cut

# the delete method can be inherited from FS::Record

=item replace OLD_RECORD

Replaces the OLD_RECORD with this one in the database.  If there is an error,
returns the error, otherwise returns false.

=cut

# the replace method can be inherited from FS::Record

=item check

Checks all fields to make sure this is a valid example.  If there is
an error, returns the error, otherwise returns false.  Called by the insert
and replace methods.

=cut

sub check {
  my $self = shift;

  my $error = 
    $self->ut_numbern('intervalnum')
    || $self->ut_number('stime')
    || $self->ut_number('etime')
    || $self->ut_number('ratetimenum')
  ;
  return $error if $error;

  $self->SUPER::check;
}

=item rate_time

Returns the L<FS::rate_time> comprising this interval.

=cut

sub rate_time {
  my $self = shift;
  FS::rate_time->by_key($self->ratetimenum);
}

=item description

Returns two strings containing stime and etime, formatted 
"Day HH:MM:SS AM/PM".  Example: "Mon 5:00 AM".

=cut

my @days = qw(Sun Mon Tue Wed Thu Fri Sat);

sub description {
  my $self = shift;
  return map { 
            sprintf('%s %02d:%02d:%02d %s',
            $days[int($_/86400) % 7],
            int($_/3600) % 12,
            int($_/60) % 60,
            $_ % 60,
            (($_/3600) % 24 < 12) ? 'AM' : 'PM' )
       } ( $self->stime, $self->etime );
}

=back

=head1 BUGS

=head1 SEE ALSO

L<FS::rate_time>, L<FS::Record>, schema.html from the base documentation.

=cut

1;


Index: rate.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/rate.pm,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -w -d -r1.12 -r1.13
--- rate.pm	14 May 2010 02:16:30 -0000	1.12
+++ rate.pm	1 Jul 2010 01:53:49 -0000	1.13
@@ -279,16 +279,22 @@
 (see L<FS::rate_detail>), or as a hashref with two keys: I<countrycode>
 and I<phonenum>.
 
+An optional third key, I<weektime>, will return a timed rate (one with 
+a non-null I<ratetimenum>) if one exists for a call at that time.  If 
+no matching timed rate exists, the non-timed rate will be returned.
+
 =cut
 
 sub dest_detail {
   my $self = shift;
 
   my $regionnum;
+  my $weektime;
   if ( ref($_[0]) eq 'HASH' ) {
 
     my $countrycode = $_[0]->{'countrycode'};
     my $phonenum    = $_[0]->{'phonenum'};
+    $weektime       = $_[0]->{'weektime'};
 
     #find a rate prefix, first look at most specific, then fewer digits,
     # finally trying the country code only
@@ -315,8 +321,30 @@
     $regionnum = ref($_[0]) ? shift->regionnum : shift;
   }
 
-  qsearchs( 'rate_detail', { 'ratenum'        => $self->ratenum,
+  if(!defined($weektime)) {
+    return qsearchs( 'rate_detail', 
+                            { 'ratenum'        => $self->ratenum,
+                              'dest_regionnum' => $regionnum,
+                              'ratetimenum'    => '',
+                            } );
+  }
+  else {
+    my @details = grep { my $rate_time = $_->rate_time;
+                            $rate_time && $rate_time->contains($weektime) }
+                       qsearch( 'rate_detail',
+                                    { 'ratenum'        => $self->ratenum,
                              'dest_regionnum' => $regionnum,     } );
+    if(!@details) {
+      # this may change at some point
+      return $self->dest_detail($regionnum);
+    }
+    elsif(@details == 1) {
+      return $details[0];
+    }
+    else {
+      die "overlapping rate_detail times (region $regionnum, time $weektime)\n";
+    }
+  }
 }
 
 =item rate_detail

--- NEW FILE: rate_time.pm ---
package FS::rate_time;

use strict;
use base qw( FS::Record );
use FS::Record qw( qsearch qsearchs );
use FS::rate_time_interval;

=head1 NAME

FS::rate_time - Object methods for rate_time records

=head1 SYNOPSIS

  use FS::rate_time;

  $record = new FS::rate_time \%hash;
  $record = new FS::rate_time { 'column' => 'value' };

  $error = $record->insert;

  $error = $new_record->replace($old_record);

  $error = $record->delete;

  $error = $record->check;

=head1 DESCRIPTION

An FS::rate_time object represents a time period for selection of CDR billing 
rates.  FS::rate_time inherits from FS::Record.  The following fields are 
currently supported:

=over 4

=item ratetimenum

primary key

=item ratetimename

A label (like "Daytime" or "Weekend").

=back

=head1 METHODS

=over 4

=item new HASHREF

Creates a new example.  To add the example to the database, see L<"insert">.

Note that this stores the hash reference, not a distinct copy of the hash it
points to.  You can ask the object for a copy with the I<hash> method.

=cut

# the new method can be inherited from FS::Record, if a table method is defined

sub table { 'rate_time'; }

=item insert

Adds this record to the database.  If there is an error, returns the error,
otherwise returns false.

=cut

# the insert method can be inherited from FS::Record

=item delete

Delete this record from the database.

=cut

# the delete method can be inherited from FS::Record

=item replace OLD_RECORD

Replaces the OLD_RECORD with this one in the database.  If there is an error,
returns the error, otherwise returns false.

=cut

# the replace method can be inherited from FS::Record

=item check

Checks all fields to make sure this is a valid example.  If there is
an error, returns the error, otherwise returns false.  Called by the insert
and replace methods.

=cut

sub check {
  my $self = shift;

  my $error = 
    $self->ut_numbern('ratetimenum')
    || $self->ut_text('ratetimename')
  ;
  return $error if $error;

  $self->SUPER::check;
}

=item intervals

Return the L<FS::rate_time_interval> objects included in this rating period.

=cut

sub intervals {
  my $self = shift;
  return qsearch({ table    => 'rate_time_interval', 
                   hashref  => { ratetimenum => $self->ratetimenum },
                   order_by => 'ORDER BY stime ASC',
  });
}

=item contains TIME

Return the L<FS::rate_time_interval> object that contains the specified 
time-of-week (in seconds from the start of Sunday).  The primary use of 
this is to test whether that time falls within this rating period.

=cut

sub contains {
  my $self = shift;
  my $weektime = shift;
  return qsearchs('rate_time_interval', { ratetimenum => $self->ratetimenum,
                                          stime => { op    => '<=', 
                                                     value => $weektime },
                                          etime => { op    => '>',
                                                     value => $weektime },
                                        } );
}

=item description

Returns a list of arrayrefs containing the starting and 
ending times of each interval in this period, in a readable
format.

=cut

sub description {
  my $self = shift;
  return map { [ $_->description ] } $self->intervals;
}


=back

=head1 BUGS

To be seen.

=head1 SEE ALSO

L<FS::Record>, schema.html from the base documentation.

=cut

1;


Index: Schema.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/Schema.pm,v
retrieving revision 1.221
retrieving revision 1.222
diff -u -w -d -r1.221 -r1.222
--- Schema.pm	26 Jun 2010 09:34:09 -0000	1.221
+++ Schema.pm	1 Jul 2010 01:53:49 -0000	1.222
@@ -2229,6 +2229,7 @@
         'conn_sec',        'int',     '',     '', '0', '',
         'min_charge',      'decimal', '', '10,5', '', '', #@money_type, '', '', 
         'sec_granularity', 'int',     '',     '', '', '', 
+        'ratetimenum',     'int', 'NULL',     '', '', '',
         #time period (link to table of periods)?
         'classnum',        'int', 'NULL',     '', '', '', 
       ],
@@ -2260,6 +2261,28 @@
       'index'       => [ [ 'countrycode' ], [ 'npa' ], [ 'regionnum' ] ],
     },
 
+    'rate_time' => {
+      'columns' => [
+        'ratetimenum', 'serial',      '',      '', '', '',
+        'ratetimename',   'varchar',      '', $char_d, '', '',
+      ],
+      'primary_key' => 'ratetimenum',
+      'unique'      => [],
+      'index'       => [],
+    },
+
+    'rate_time_interval' => {
+      'columns' => [
+        'intervalnum', 'serial', '', '', '', '',
+        'stime',          'int', '', '', '', '',
+        'etime',          'int', '', '', '', '',
+        'ratetimenum',    'int', '', '', '', '',
+      ],
+      'primary_key' => 'intervalnum',
+      'unique'      => [],
+      'index'       => [],
+    },
+
     'usage_class' => {
       'columns' => [
         'classnum',    'serial',      '',      '', '', '', 



More information about the freeside-commits mailing list