summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjeff <jeff>2008-08-23 21:59:46 +0000
committerjeff <jeff>2008-08-23 21:59:46 +0000
commitef0d8db38d1ee28a65a7ecdc6e11c7a82c0a741b (patch)
tree78518afc3aa8623211251caedf78459167cd0877
parent8381e7232f90ac22b3f655cdccd0d39e2bde1d63 (diff)
add usage classes to rate details
-rw-r--r--FS/FS.pm2
-rw-r--r--FS/FS/Mason.pm2
-rw-r--r--FS/FS/Schema.pm12
-rw-r--r--FS/FS/Setup.pm4
-rw-r--r--FS/FS/Upgrade.pm3
-rw-r--r--FS/FS/rate_detail.pm17
-rw-r--r--FS/FS/usage_class.pm143
-rw-r--r--FS/MANIFEST2
-rw-r--r--FS/t/usage_class.t5
-rw-r--r--httemplate/browse/rate_detail.html8
-rw-r--r--httemplate/browse/usage_class.html28
-rw-r--r--httemplate/edit/elements/edit.html12
-rwxr-xr-xhttemplate/edit/process/rate_region.cgi2
-rw-r--r--httemplate/edit/process/usage_class.html11
-rw-r--r--httemplate/edit/rate_detail.html8
-rw-r--r--httemplate/edit/rate_region.cgi16
-rw-r--r--httemplate/edit/usage_class.html25
-rw-r--r--httemplate/elements/menu.html1
18 files changed, 293 insertions, 8 deletions
diff --git a/FS/FS.pm b/FS/FS.pm
index e3580f5..a2f72bc 100644
--- a/FS/FS.pm
+++ b/FS/FS.pm
@@ -190,6 +190,8 @@ L<FS::rate_prefix> - Rate region prefixes for call billing
L<FS::rate_detail> - Rate plan detail for call billing
+L<FS::usage_class> - Usage class class
+
L<FS::agent> - Agent (reseller) class
L<FS::agent_type> - Agent type class
diff --git a/FS/FS/Mason.pm b/FS/FS/Mason.pm
index 77ff668..cfb12e4 100644
--- a/FS/FS/Mason.pm
+++ b/FS/FS/Mason.pm
@@ -145,6 +145,8 @@ Initializes the Mason environment, loads all Freeside and RT libraries, etc.
use FS::rate;
use FS::rate_region;
use FS::rate_prefix;
+ use FS::rate_detail;
+ use FS::usage_class;
use FS::payment_gateway;
use FS::agent_payment_gateway;
use FS::XMLRPC;
diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm
index 86cf4a3..530f632 100644
--- a/FS/FS/Schema.pm
+++ b/FS/FS/Schema.pm
@@ -1671,6 +1671,7 @@ sub tables_hashref {
'min_charge', 'decimal', '', '10,5', '', '',
'sec_granularity', 'int', '', '', '', '',
#time period (link to table of periods)?
+ 'classnum', 'int', 'NULL', '', '', '',
],
'primary_key' => 'ratedetailnum',
'unique' => [ [ 'ratenum', 'orig_regionnum', 'dest_regionnum' ] ],
@@ -1700,6 +1701,17 @@ sub tables_hashref {
'index' => [ [ 'countrycode' ], [ 'regionnum' ] ],
},
+ 'usage_class' => {
+ 'columns' => [
+ 'classnum', 'serial', '', '', '', '',
+ 'classname', 'varchar', '', $char_d, '', '',
+ 'disabled', 'char', 'NULL', 1, '', '',
+ ],
+ 'primary_key' => 'classnum',
+ 'unique' => [],
+ 'index' => [ ['disabled'] ],
+ },
+
'reg_code' => {
'columns' => [
'codenum', 'serial', '', '', '', '',
diff --git a/FS/FS/Setup.pm b/FS/FS/Setup.pm
index d265d93..2b392e5 100644
--- a/FS/FS/Setup.pm
+++ b/FS/FS/Setup.pm
@@ -341,6 +341,10 @@ sub initial_data {
#not yet....
#)
+
+ #usage classes
+ 'usage_class' => [],
+
;
\%hash;
diff --git a/FS/FS/Upgrade.pm b/FS/FS/Upgrade.pm
index b4c79ea..fd62f64 100644
--- a/FS/FS/Upgrade.pm
+++ b/FS/FS/Upgrade.pm
@@ -106,6 +106,9 @@ sub upgrade_data {
#replace invnum and pkgnum with billpkgnum
'cust_bill_pkg_detail' => [],
+ #usage_classes if we have none
+ 'usage_class' => [],
+
;
\%hash;
diff --git a/FS/FS/rate_detail.pm b/FS/FS/rate_detail.pm
index 533fb1e..a78ea82 100644
--- a/FS/FS/rate_detail.pm
+++ b/FS/FS/rate_detail.pm
@@ -49,6 +49,8 @@ inherits from FS::Record. The following fields are currently supported:
=item sec_granularity - granularity in seconds, i.e. 6 or 60; 0 for per-call
+=item classnum - usage class (see L<FS::usage_class) if any for this rate
+
=back
=head1 METHODS
@@ -121,6 +123,8 @@ sub check {
|| $self->ut_float('min_charge')
|| $self->ut_number('sec_granularity')
+
+ || $self->ut_foreign_keyn('classnum', 'usage_class', 'classnum' )
;
return $error if $error;
@@ -187,6 +191,19 @@ sub dest_prefixes_short {
$self->dest_region->prefixes_short;
}
+=item classname
+
+Returns the name of the usage class (see L<FS::usage_class>) associated with
+this call plan rate.
+
+=cut
+
+sub classname {
+ my $self = shift;
+ my $usage_class = qsearchs('usage_class', { classnum => $self->classnum });
+ $usage_class ? $usage_class->classname : '';
+}
+
=back
diff --git a/FS/FS/usage_class.pm b/FS/FS/usage_class.pm
new file mode 100644
index 0000000..053d398
--- /dev/null
+++ b/FS/FS/usage_class.pm
@@ -0,0 +1,143 @@
+package FS::usage_class;
+
+use strict;
+use vars qw( @ISA );
+use FS::Record qw( qsearch qsearchs );
+
+@ISA = qw(FS::Record);
+
+=head1 NAME
+
+FS::usage_class - Object methods for usage_class records
+
+=head1 SYNOPSIS
+
+ use FS::usage_class;
+
+ $record = new FS::usage_class \%hash;
+ $record = new FS::usage_class { 'column' => 'value' };
+
+ $error = $record->insert;
+
+ $error = $new_record->replace($old_record);
+
+ $error = $record->delete;
+
+ $error = $record->check;
+
+=head1 DESCRIPTION
+
+An FS::usage_class object represents a usage class. Every rate detail
+(see L<FS::rate_detail) has, optionally, a usage class. FS::usage_class
+inherits from FS::Record. The following fields are currently supported:
+
+=over 4
+
+=item classnum
+
+Primary key (assigned automatically for new usage classes)
+
+=item classname
+
+Text name of this usage class
+
+=item disabled
+
+Disabled flag, empty or 'Y'
+
+
+=back
+
+=head1 METHODS
+
+=over 4
+
+=item new HASHREF
+
+Creates a new usage class. To add the usage class 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
+
+sub table { 'usage_class'; }
+
+=item insert
+
+Adds this record to the database. If there is an error, returns the error,
+otherwise returns false.
+
+=cut
+
+=item delete
+
+Delete this record from the database.
+
+=cut
+
+=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
+
+=item check
+
+Checks all fields to make sure this is a valid usage class. 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('classnum')
+ || $self->ut_text('classname')
+ || $self->ut_enum('disabled', [ '', 'Y' ])
+ ;
+ return $error if $error;
+
+ $self->SUPER::check;
+}
+
+sub _populate_initial_data {
+ my ($class, %opts) = @_;
+
+ foreach ("Intrastate", "Interstate", "International") {
+ my $object = $class->new( { 'classname' => $_ } );
+ my $error = $object->insert;
+ die "error inserting $class into database: $error\n"
+ if $error;
+ }
+
+ '';
+
+}
+
+sub _upgrade_data {
+ my $class = shift;
+
+ return $class->_populate_initial_data(@_)
+ unless scalar( qsearch( 'usage_class', {} ) );
+
+ '';
+
+}
+
+=back
+
+=head1 BUGS
+
+=head1 SEE ALSO
+
+L<FS::Record>, schema.html from the base documentation.
+
+=cut
+
+1;
+
diff --git a/FS/MANIFEST b/FS/MANIFEST
index 5dcd696..a6fe219 100644
--- a/FS/MANIFEST
+++ b/FS/MANIFEST
@@ -420,3 +420,5 @@ t/phone_avail.t
FS/Yori.pm
FS/cust_svc_option.pm
t/cust_svc_option.t
+FS/usage_class.pm
+t/usage_class.t
diff --git a/FS/t/usage_class.t b/FS/t/usage_class.t
new file mode 100644
index 0000000..64fe98e
--- /dev/null
+++ b/FS/t/usage_class.t
@@ -0,0 +1,5 @@
+BEGIN { $| = 1; print "1..1\n" }
+END {print "not ok 1\n" unless $loaded;}
+use FS::usage_class;
+$loaded=1;
+print "ok 1\n";
diff --git a/httemplate/browse/rate_detail.html b/httemplate/browse/rate_detail.html
index 36e808f..23bc23f 100644
--- a/httemplate/browse/rate_detail.html
+++ b/httemplate/browse/rate_detail.html
@@ -17,6 +17,7 @@
'Included<BR>minutes',
'Charge per<BR>minute',
'Granularity',
+ 'Usage class',
],
'fields' => [
'regionname',
@@ -28,10 +29,11 @@
'&nbsp;<FONT SIZE="-1">(edit)</FONT>';
},
sub { $granularity{ shift->sec_granularity } },
+ 'classname',
],
- 'links' => [ '', '', $edit_link, $edit_link, '' ],
- 'link_onclicks' => [ '', '', $edit_onclick, $edit_onclick, '' ],
- 'align' => 'llrrc',
+ 'links' => [ '', '', $edit_link, $edit_link, '', '' ],
+ 'link_onclicks' => [ '', '', $edit_onclick, $edit_onclick, '', '' ],
+ 'align' => 'llrrcc',
)
%>
<%once>
diff --git a/httemplate/browse/usage_class.html b/httemplate/browse/usage_class.html
new file mode 100644
index 0000000..63fd2c5
--- /dev/null
+++ b/httemplate/browse/usage_class.html
@@ -0,0 +1,28 @@
+<% include( 'elements/browse.html',
+ 'title' => 'Usage classes',
+ 'html_init' => $html_init,
+ 'name' => 'usage classes',
+ 'disableable' => 1,
+ 'disabled_statuspos' => 2,
+ 'query' => { 'table' => 'usage_class',
+ 'hashref' => {},
+ 'extra_sql' => 'ORDER BY classnum',
+ },
+ 'count_query' => 'SELECT COUNT(*) FROM usage_class',
+ 'header' => [ '#', 'Class' ],
+ 'fields' => [ 'classnum', 'classname' ],
+ 'links' => [ $link, $link ],
+ )
+%>
+<%init>
+
+die "access denied"
+ unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
+
+my $html_init =
+ 'Usage classes define groups of usage for taxation purposes.<BR><BR>'.
+ qq!<A HREF="${p}edit/usage_class.html"><I>Add a usage class</I></A><BR><BR>!;
+
+my $link = [ $p.'edit/usage_class.html?', 'classnum' ];
+
+</%init>
diff --git a/httemplate/edit/elements/edit.html b/httemplate/edit/elements/edit.html
index 47b2464..3896f17 100644
--- a/httemplate/edit/elements/edit.html
+++ b/httemplate/edit/elements/edit.html
@@ -3,8 +3,12 @@
Example:
include( 'elements/edit.html',
- 'name' =>
- 'table' =>
+ 'name_singular' => #singular name for the record
+ # (preferred, will be pluralized automatically)
+ 'name' => #name for the record
+ # (deprecated, will be pluralized simplistically)
+ 'table' =>
+
#? 'primary_key' => #required when the dbdef doesn't know...???
'labels' => {
'column' => 'Label',
@@ -616,9 +620,9 @@ my @menubar = ();
if ( $opt{'menubar'} ) {
@menubar = @{ $opt{'menubar'} };
} else {
+ my $items = $opt{'name'} ? $opt{'name'}.'s' : PL($opt{'name_singular'});
@menubar = (
- #eventually use Lingua::bs to pluralize
- "View all $opt{'name'}s" => $viewall_url,
+ "View all $items" => $viewall_url,
);
}
diff --git a/httemplate/edit/process/rate_region.cgi b/httemplate/edit/process/rate_region.cgi
index d839406..861a6dc 100755
--- a/httemplate/edit/process/rate_region.cgi
+++ b/httemplate/edit/process/rate_region.cgi
@@ -37,7 +37,7 @@ my @dest_detail = map {
new FS::rate_detail {
'ratenum' => $ratenum,
map { $_ => $cgi->param("$_$ratenum") }
- qw( min_included min_charge sec_granularity )
+ qw( min_included min_charge sec_granularity classnum )
};
} qsearch('rate', {} );
diff --git a/httemplate/edit/process/usage_class.html b/httemplate/edit/process/usage_class.html
new file mode 100644
index 0000000..cf50cb7
--- /dev/null
+++ b/httemplate/edit/process/usage_class.html
@@ -0,0 +1,11 @@
+<% include( 'elements/process.html',
+ 'table' => 'usage_class',
+ 'viewall_dir' => 'browse',
+ )
+%>
+<%init>
+
+die "access denied"
+ unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
+
+</%init>
diff --git a/httemplate/edit/rate_detail.html b/httemplate/edit/rate_detail.html
index 73d2d9b..4860593 100644
--- a/httemplate/edit/rate_detail.html
+++ b/httemplate/edit/rate_detail.html
@@ -8,6 +8,7 @@
'min_included' => 'Included minutes',
'min_charge' => 'Charge per minute',
'sec_granularity' => 'Granularity',
+ 'classnum' => 'Usage class',
},
'fields' => [
{ field=>'ratenum', type=>'hidden', },
@@ -23,6 +24,13 @@
labels => \%granularity,
disable_empty => 1,
},
+ { field =>'classnum',
+ type =>'select-table',
+ table =>'usage_class',
+ name_col =>'classname',
+ empty_label =>'(default)',
+ hashref =>{ disabled => '' },
+ },
],
)
diff --git a/httemplate/edit/rate_region.cgi b/httemplate/edit/rate_region.cgi
index 496e054..f24b9d6 100644
--- a/httemplate/edit/rate_region.cgi
+++ b/httemplate/edit/rate_region.cgi
@@ -57,6 +57,9 @@
<TH CLASS="grid" BGCOLOR="#cccccc">
<FONT SIZE=-1>Granularity</FONT>
</TH>
+ <TH CLASS="grid" BGCOLOR="#cccccc">
+ <FONT SIZE=-1>Usage class</FONT>
+ </TH>
</TR>
% foreach my $rate ( qsearch('rate', {}) ) {
@@ -96,6 +99,19 @@
</SELECT>
</TD>
+ <TD CLASS="grid" BGCOLOR="<% $bgcolor %>">
+ <% include( '/elements/select-table.html',
+ 'element_name' => "classnum$n",
+ 'table' => 'usage_class',
+ 'name_col' => 'classname',
+ 'empty_label' => '(default)',
+ 'hashref' => { disabled => '' },
+ 'curr_value' => ( $cgi->param("classnum$n") ||
+ $rate_detail->classnum ),
+ )
+ %>
+ </TD>
+
</TR>
% }
diff --git a/httemplate/edit/usage_class.html b/httemplate/edit/usage_class.html
new file mode 100644
index 0000000..ef4b1ff
--- /dev/null
+++ b/httemplate/edit/usage_class.html
@@ -0,0 +1,25 @@
+<% include( 'elements/edit.html',
+ 'name_singular' => 'Usage Class',
+ 'table' => 'usage_class',
+ 'fields' => [
+ 'classname',
+ { field=>'disabled',
+ type=>'checkbox',
+ value=>'Y',
+ },
+ ],
+ 'labels' => {
+ 'classnum' => 'Class number',
+ 'classname' => 'Class name',
+ 'disabled' => 'Disable class',
+ },
+ 'viewall_dir' => 'browse',
+ )
+
+%>
+<%init>
+
+die "access denied"
+ unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
+
+</%init>
diff --git a/httemplate/elements/menu.html b/httemplate/elements/menu.html
index 321927e..d476e30 100644
--- a/httemplate/elements/menu.html
+++ b/httemplate/elements/menu.html
@@ -279,6 +279,7 @@ tie my %config_agent, 'Tie::IxHash',
tie my %config_billing_rates, 'Tie::IxHash',
'View/Edit rate plans' => [ $fsurl.'browse/rate.cgi', 'Manage rate plans' ],
'View/Edit regions and prefixes' => [ $fsurl.'browse/rate_region.html', 'Manage regions and prefixes' ],
+ 'View/Edit usage classes' => [ $fsurl.'browse/usage_class.html', 'Usage classes define groups of usage for taxation purposes.' ],
;
tie my %config_billing, 'Tie::IxHash';