L<FS::option_Common> - Base class for option sub-classes
+L<FS::class_Common> - Base class for classification classes
+
+L<FS::category_Common> - Base class for category (grooups of classifications) classes
+
L<FS::conf> - Configuration value class
L<FS::payinfo_Mixin> - Mixin class for records in tables that contain payinfo.
L<FS::cust_main_invoice> - Invoice destination class
+L<FS::cust_class> - Customer classification class
+
+L<FS::cust_category> - Customer category class
+
L<FS::cust_main_exemption> - Customer tax exemption class
L<FS::cust_main_note> - Customer note class
'custnum', 'serial', '', '', '', '',
'agentnum', 'int', '', '', '', '',
'agent_custid', 'varchar', 'NULL', $char_d, '', '',
+ 'classnum', 'int', 'NULL', '', '', '',
'custbatch', 'varchar', 'NULL', $char_d, '', '',
# 'titlenum', 'int', 'NULL', '', '', '',
'last', 'varchar', '', $char_d, '', '',
'unique' => [ [ 'agentnum', 'agent_custid' ] ],
#'index' => [ ['last'], ['company'] ],
'index' => [
- [ 'agentnum' ], [ 'refnum' ], [ 'custbatch' ],
+ [ 'agentnum' ], [ 'refnum' ], [ 'classnum' ],
+ [ 'custbatch' ],
[ 'referral_custnum' ],
[ 'payby' ], [ 'paydate' ],
[ 'archived' ],
'index' => [ [ 'custnum' ], [ '_date' ], ],
},
+ 'cust_category' => {
+ 'columns' => [
+ 'categorynum', 'serial', '', '', '', '',
+ 'categoryname', 'varchar', '', $char_d, '', '',
+ 'weight', 'int', 'NULL', '', '', '',
+ 'disabled', 'char', 'NULL', 1, '', '',
+ ],
+ 'primary_key' => 'categorynum',
+ 'unique' => [],
+ 'index' => [ ['disabled'] ],
+ },
+
+ 'cust_class' => {
+ 'columns' => [
+ 'classnum', 'serial', '', '', '', '',
+ 'classname', 'varchar', '', $char_d, '', '',
+ 'categorynum', 'int', 'NULL', '', '', '',
+ 'disabled', 'char', 'NULL', 1, '', '',
+ ],
+ 'primary_key' => 'classnum',
+ 'unique' => [],
+ 'index' => [ ['disabled'] ],
+ },
+
'cust_main_exemption' => {
'columns' => [
'exemptionnum', 'serial', '', '', '', '',
--- /dev/null
+package FS::category_Common;
+
+use strict;
+use base qw( FS::Record );
+use FS::Record qw( qsearch );
+
+=head1 NAME
+
+FS::category_Common - Base class for category (group of classifications) classes
+
+=head1 SYNOPSIS
+
+use base qw( FS::category_Common );
+use FS::class_table; #should use this
+
+#optional for non-standard names
+sub _class_table { 'table_name'; } #default is to replace s/category/class/
+
+=head1 DESCRIPTION
+
+FS::category_Common is a base class for classes which provide a categorization
+(group of classifications) for other classes, such as pkg_category or
+cust_category.
+
+=item delete
+
+Deletes this category from the database. Only categories with no associated
+classifications can be deleted. If there is an error, returns the error,
+otherwise returns false.
+
+=cut
+
+sub delete {
+ my $self = shift;
+
+ return "Can't delete a ". $self->table.
+ " with ". $self->_class_table. " records!"
+ if qsearch( $self->_class_table, { 'categorynum' => $self->categorynum } );
+
+ $self->SUPER::delete;
+}
+
+=item check
+
+Checks all fields to make sure this is a valid package category. If there is an
+error, returns the error, otherwise returns false. Called by the insert and
+replace methods.
+
+=cut
+
+sub check {
+ my $self = shift;
+
+ $self->ut_numbern('categorynum')
+ or $self->ut_text('categoryname')
+ or $self->ut_snumbern('weight')
+ or $self->ut_enum('disabled', [ '', 'Y' ])
+ or $self->SUPER::check;
+
+}
+
+=back
+
+=cut
+
+#defaults
+
+use vars qw( $_class_table );
+sub _class_table {
+ return $_class_table if $_class_table;
+ my $self = shift;
+ $_class_table = $self->table;
+ $_class_table =~ s/category/cclass/ # s/_category$/_class/
+ or die "can't determine an automatic class table for $_class_table";
+ $_class_table;
+}
+
+=head1 BUGS
+
+=head1 SEE ALSO
+
+L<FS::Record>
+
+=cut
+
+1;
+
--- /dev/null
+package FS::class_Common;
+
+use strict;
+use base qw( FS::Record );
+use FS::Record qw( qsearch qsearchs );
+
+=head1 NAME
+
+FS::class_Common - Base class for classification classes
+
+=head1 SYNOPSIS
+
+use base qw( FS::class_Common );
+use FS::category_table; #should use this
+
+#required
+sub _target_table { 'table_name'; }
+
+#optional for non-standard names
+sub _target_column { 'classnum'; } #default is classnum
+sub _category_table { 'table_name'; } #default is to replace s/class/category/
+
+=head1 DESCRIPTION
+
+FS::class_Common is a base class for classes which provide a classification for
+other classes, such as pkg_class or cust_class.
+
+=head1 METHODS
+
+=over 4
+
+=item new HASHREF
+
+Creates a new classification. To add the classfication to the database, see
+L<"insert">.
+
+=cut
+
+=item insert
+
+Adds this classification to the database. If there is an error, returns the
+error, otherwise returns false.
+
+=item delete
+
+Deletes this classification from the database. Only classifications with no
+associated target objects can be deleted. If there is an error, returns
+the error, otherwise returns false.
+
+=cut
+
+sub delete {
+ my $self = shift;
+
+ return "Can't delete a ". $self->table.
+ " with ". $self->_target_table. " records!"
+ if qsearch( $self->_target_table,
+ { $self->_target_column => $self->classnum }
+ );
+
+ $self->SUPER::delete;
+}
+
+=item replace OLD_RECORD
+
+Replaces OLD_RECORD with this one in the database. If there is an error,
+returns the error, otherwise returns false.
+
+=item check
+
+Checks all fields to make sure this is a valid package classification. If
+there is an error, returns the error, otherwise returns false. Called by the
+insert and replace methods.
+
+=cut
+
+sub check {
+ my $self = shift;
+
+ $self->ut_numbern('classnum')
+ or $self->ut_text('classname')
+ or $self->ut_foreign_keyn( 'categorynum',
+ $self->_category_table,
+ 'categorynum',
+ )
+ or $self->ut_enum('disabled', [ '', 'Y' ] )
+ or $self->SUPER::check;
+
+}
+
+=item category
+
+Returns the category record associated with this class, or false if there is
+none.
+
+=cut
+
+sub category {
+ my $self = shift;
+ qsearchs($self->_category_table, { 'categorynum' => $self->categorynum } );
+}
+
+=item categoryname
+
+Returns the category name associated with this class, or false if there
+is none.
+
+=cut
+
+sub categoryname {
+ my $category = shift->category;
+ $category ? $category->categoryname : '';
+}
+
+#required
+sub _target_table {
+ my $self = shift;
+ die "_target_table unspecified for $self";
+}
+
+#defaults
+
+sub _target_column { 'classnum'; }
+
+use vars qw( $_category_table );
+sub _category_table {
+ return $_category_table if $_category_table;
+ my $self = shift;
+ $_category_table = $self->table;
+ $_category_table =~ s/class/category/ # s/_class$/_category/
+ or die "can't determine an automatic category table for $_category_table";
+ $_category_table;
+}
+
+=head1 BUGS
+
+=head1 SEE ALSO
+
+L<FS::category_Common>, L<FS::pkg_class>, L<FS::cust_class>
+
+=cut
+
+1;
--- /dev/null
+package FS::cust_category;
+
+use strict;
+use base qw( FS::category_Common );
+use FS::cust_class;
+
+=head1 NAME
+
+FS::cust_category - Object methods for cust_category records
+
+=head1 SYNOPSIS
+
+ use FS::cust_category;
+
+ $record = new FS::cust_category \%hash;
+ $record = new FS::cust_category { 'column' => 'value' };
+
+ $error = $record->insert;
+
+ $error = $new_record->replace($old_record);
+
+ $error = $record->delete;
+
+ $error = $record->check;
+
+=head1 DESCRIPTION
+
+An FS::cust_category object represents a customer category. Every customer
+class (see L<FS::cust_class>) has, optionally, a customer category.
+FS::cust_category inherits from FS::Record. The following fields are currently
+supported:
+
+=over 4
+
+=item categorynum
+
+primary key
+
+=item categoryname
+
+Text name of this package category
+
+=item weight
+
+Weight
+
+=item disabled
+
+Disabled flag, empty or 'Y'
+
+=back
+
+=head1 METHODS
+
+=over 4
+
+=item new HASHREF
+
+Creates a new customer category. To add the customer category to the database,
+see L<"insert">.
+
+=cut
+
+sub table { 'cust_category'; }
+
+=item insert
+
+Adds this record to the database. If there is an error, returns the error,
+otherwise returns false.
+
+=item delete
+
+Delete this record from the database.
+
+=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.
+
+=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.
+
+=back
+
+=head1 BUGS
+
+=head1 SEE ALSO
+
+L<FS::cust_class>, L<FS::Record>
+
+=cut
+
+1;
+
--- /dev/null
+package FS::cust_class;
+
+use strict;
+use base qw( FS::class_Common );
+use FS::cust_main;
+use FS::cust_category;
+
+=head1 NAME
+
+FS::cust_class - Object methods for cust_class records
+
+=head1 SYNOPSIS
+
+ use FS::cust_class;
+
+ $record = new FS::cust_class \%hash;
+ $record = new FS::cust_class { 'column' => 'value' };
+
+ $error = $record->insert;
+
+ $error = $new_record->replace($old_record);
+
+ $error = $record->delete;
+
+ $error = $record->check;
+
+=head1 DESCRIPTION
+
+An FS::pkg_class object represents an customer class. Every customer (see
+L<FS::cust_main>) has, optionally, a customer class. FS::cust_class inherits
+from FS::Record. The following fields are currently supported:
+
+=over 4
+
+=item classnum
+
+primary key
+
+=item classname
+
+Text name of this customer class
+
+=item categorynum
+
+Number of associated cust_category (see L<FS::cust_category>)
+
+=item disabled
+
+Disabled flag, empty or 'Y'
+
+=back
+
+=head1 METHODS
+
+=over 4
+
+=item new HASHREF
+
+Creates a new customer class. To add the customer class to the database, see
+L<"insert">.
+
+=cut
+
+sub table { 'cust_class'; }
+sub _target_table { 'cust_main'; }
+
+=item insert
+
+Adds this customer class to the database. If there is an error, returns the
+error, otherwise returns false.
+
+=item delete
+
+Delete this customer class from the database. Only customer classes with no
+associated customers can be deleted. If there is an error, returns
+the error, otherwise returns false.
+
+=item replace [ OLD_RECORD ]
+
+Replaces OLD_RECORD with this one in the database. If there is an error,
+returns the error, otherwise returns false.
+
+=item check
+
+Checks all fields to make sure this is a valid customer class. If there is
+an error, returns the error, otherwise returns false. Called by the insert
+and replace methods.
+
+=item cust_category
+
+=item category
+
+Returns the cust_category record associated with this class, or false if there
+is none.
+
+=cut
+
+sub cust_category {
+ my $self = shift;
+ $self->category;
+}
+
+=item categoryname
+
+Returns the category name associated with this class, or false if there
+is none.
+
+=cut
+
+=back
+
+=head1 BUGS
+
+=head1 SEE ALSO
+
+L<FS::cust_main>, L<FS::Record>
+
+=cut
+
+1;
use FS::part_referral;
use FS::cust_main_county;
use FS::cust_location;
+use FS::cust_class;
use FS::cust_main_exemption;
use FS::cust_tax_adjustment;
use FS::tax_rate;
|| $self->ut_number('agentnum')
|| $self->ut_textn('agent_custid')
|| $self->ut_number('refnum')
+ || $self->ut_foreign_keyn('classnum', 'cust_class', 'classnum')
|| $self->ut_textn('custbatch')
|| $self->ut_name('last')
|| $self->ut_name('first')
package FS::pkg_category;
use strict;
+use base qw( FS::category_Common );
use vars qw( @ISA $me $DEBUG );
use FS::Record qw( qsearch dbh );
+use FS::pkg_class;
use FS::part_pkg;
-@ISA = qw( FS::Record );
$DEBUG = 0;
$me = '[FS::pkg_category]';
=over 4
-=item categorynum - primary key (assigned automatically for new package categoryes)
+=item categorynum
-=item categoryname - Text name of this package category
+primary key (assigned automatically for new package categoryes)
-=item disabled - Disabled flag, empty or 'Y'
+=item categoryname
+
+Text name of this package category
+
+=item weight
+
+Weight
+
+=item disabled
+
+Disabled flag, empty or 'Y'
=back
=item new HASHREF
-Creates a new package category. To add the package category to the database, see
-L<"insert">.
+Creates a new package category. To add the package category to the database,
+see L<"insert">.
=cut
=item delete
-Deletes this package category from the database. Only package categoryes with no
-associated package definitions can be deleted. If there is an error, returns
-the error, otherwise returns false.
-
-=cut
-
-sub delete {
- my $self = shift;
-
- return "Can't delete an pkg_category with pkg_class records!"
- if qsearch( 'pkg_class', { 'categorynum' => $self->categorynum } );
-
- $self->SUPER::delete;
-}
+Deletes this package category from the database. Only package categoryes with
+no associated package definitions can be deleted. If there is an error,
+returns the error, otherwise returns false.
-=item replace OLD_RECORD
+=item replace [ OLD_RECORD ]
Replaces OLD_RECORD with this one in the database. If there is an error,
returns the error, otherwise returns false.
error, returns the error, otherwise returns false. Called by the insert and
replace methods.
-=cut
-
-sub check {
- my $self = shift;
-
- $self->ut_numbern('categorynum')
- or $self->ut_text('categoryname')
- or $self->ut_snumber('weight')
- or $self->SUPER::check;
-
-}
-
# _ upgrade_data
#
# Used by FS::Upgrade to migrate to a new database.
=head1 SEE ALSO
-L<FS::Record>, L<FS::part_pkg>, schema.html from the base documentation.
+L<FS::category_Common>, L<FS::Record>
=cut
package FS::pkg_class;
use strict;
-use vars qw( @ISA );
-use FS::Record qw( qsearchs qsearch );
+use FS::class_Common;
+use base qw( FS::class_Common );
use FS::part_pkg;
use FS::pkg_category;
-@ISA = qw( FS::Record );
-
=head1 NAME
FS::pkg_class - Object methods for pkg_class records
=over 4
-=item classnum - primary key (assigned automatically for new package classes)
+=item classnum
+
+primary key (assigned automatically for new package classes)
+
+=item classname
+
+Text name of this package class
-=item classname - Text name of this package class
+=item categorynum
-=item categorynum - Number of associated pkg_category (see L<FS::pkg_category>)
+Number of associated pkg_category (see L<FS::pkg_category>)
-=item disabled - Disabled flag, empty or 'Y'
+=item disabled
+
+Disabled flag, empty or 'Y'
=back
=cut
sub table { 'pkg_class'; }
+sub _target_table { 'part_pkg'; }
=item insert
associated package definitions can be deleted. If there is an error, returns
the error, otherwise returns false.
-=cut
-
-sub delete {
- my $self = shift;
-
- return "Can't delete an pkg_class with part_pkg records!"
- if qsearch( 'part_pkg', { 'classnum' => $self->classnum } );
-
- $self->SUPER::delete;
-}
-
-=item replace OLD_RECORD
+=item replace [ OLD_RECORD ]
Replaces OLD_RECORD with this one in the database. If there is an error,
returns the error, otherwise returns false.
error, returns the error, otherwise returns false. Called by the insert and
replace methods.
-=cut
-
-sub check {
- my $self = shift;
-
- $self->ut_numbern('classnum')
- or $self->ut_text('classname')
- or $self->ut_foreign_keyn('categorynum', 'pkg_category', 'categorynum')
- or $self->SUPER::check;
-
-}
-
=item pkg_category
+=item category
+
Returns the pkg_category record associated with this class, or false if there
is none.
sub pkg_category {
my $self = shift;
- qsearchs('pkg_category', { 'categorynum' => $self->categorynum } );
+ $self->category;
}
=item categoryname
Returns the category name associated with this class, or false if there
is none.
-=cut
-
-sub categoryname {
- my $pkg_category = shift->pkg_category;
- $pkg_category->categoryname if $pkg_category;
-}
-
=back
=head1 BUGS
=head1 SEE ALSO
-L<FS::Record>, L<FS::part_pkg>, schema.html from the base documentation.
+L<FS::part_pkg>, L<FS::Record>
=cut
1;
-
t/cust_attachment.t
FS/cust_statement.pm
t/cust_statement.t
+FS/cust_class.pm
+t/cust_class.t
+FS/cust_category.pm
+t/cust_category.t
--- /dev/null
+BEGIN { $| = 1; print "1..1\n" }
+END {print "not ok 1\n" unless $loaded;}
+use FS::cust_category;
+$loaded=1;
+print "ok 1\n";
--- /dev/null
+BEGIN { $| = 1; print "1..1\n" }
+END {print "not ok 1\n" unless $loaded;}
+use FS::cust_class;
+$loaded=1;
+print "ok 1\n";
--- /dev/null
+<% include( 'elements/browse.html',
+ 'title' => 'Customer categories',
+ 'html_init' => $html_init,
+ 'name' => 'customer categories',
+ 'disableable' => 1,
+ 'disabled_statuspos' => 2,
+ 'query' => { 'table' => 'cust_category',
+ 'hashref' => {},
+ 'extra_sql' => 'ORDER BY categorynum',
+ },
+ 'count_query' => $count_query,
+ 'header' => [ '#', 'Category' ],
+ 'fields' => [ 'categorynum', 'categoryname' ],
+ 'links' => [ $link, $link ],
+ )
+%>
+
+<%init>
+
+die "access denied"
+ unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
+
+my $html_init =
+ qq!<A HREF="${p}browse/cust_class.html">Customer classes</A><BR><BR>!.
+ 'Customer categories define groups of customer classes.<BR><BR>'.
+ qq!<A HREF="${p}edit/cust_category.html"><I>Add a customer category</I></A><BR><BR>!;
+
+my $count_query = 'SELECT COUNT(*) FROM cust_category';
+
+my $link = [ $p.'edit/cust_category.html?', 'categorynum' ];
+
+</%init>
--- /dev/null
+<% include( 'elements/browse.html',
+ 'title' => 'Customer classes',
+ 'html_init' => $html_init,
+ 'name' => 'customer classes',
+ 'disableable' => 1,
+ 'disabled_statuspos' => 2,
+ 'query' => { 'table' => 'cust_class',
+ 'hashref' => {},
+ 'extra_sql' => 'ORDER BY classnum',
+ },
+ 'count_query' => $count_query,
+ 'header' => $header,
+ 'fields' => $fields,
+ 'links' => $links,
+ )
+%>
+<%init>
+
+die "access denied"
+ unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
+
+my $html_init =
+ 'Customer classes define groups of customer for reporting.<BR><BR>'.
+ qq!<A HREF="${p}edit/cust_class.html"><I>Add a customer class</I></A><BR><BR>!;
+
+my $count_query = 'SELECT COUNT(*) FROM cust_class';
+
+my $link = [ $p.'edit/cust_class.html?', 'classnum' ];
+
+my $header = [ '#', 'Class' ];
+my $fields = [ 'classnum', 'classname' ];
+my $links = [ $link, $link ];
+
+my $cat_query = 'SELECT COUNT(*) FROM cust_class where categorynum IS NOT NULL';
+my $sth = dbh->prepare($cat_query)
+ or die "Error preparing $cat_query: ". dbh->errstr;
+$sth->execute
+ or die "Error executing $cat_query: ". $sth->errstr;
+if ($sth->fetchrow_arrayref->[0]) {
+ push @$header, 'Category';
+ push @$fields, 'categoryname';
+ push @$links, $link;
+}
+
+</%init>
unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
my $html_init =
- 'Package optional report classes define groups of packages, for reporting purposes.'.
+ 'Package optional report classes define optional groups of packages for reporting only.'.
qq!<BR><BR><A HREF="${p}edit/part_pkg_report_option.html"><I>Add a class</I></A><BR><BR>!;
my $link = [ $p.'edit/part_pkg_report_option.html?', 'num' ];
my $html_init =
qq!<A HREF="${p}browse/pkg_class.html">Package classes</A><BR><BR>!.
- 'Package categories define groups of package classes, for reporting and '.
- 'convenience purposes.<BR><BR>'.
+ 'Package categories define groups of package classes.<BR><BR>'.
qq!<A HREF="${p}edit/pkg_category.html"><I>Add a package category</I></A><BR><BR>!;
my $count_query = 'SELECT COUNT(*) FROM pkg_category';
unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
my $html_init =
- 'Package classes define groups of packages, for reporting and '.
- 'convenience purposes.<BR><BR>'.
+ 'Package classes define groups of packages, for taxation, ordering '.
+ 'convenience and reporting.<BR><BR>'.
qq!<A HREF="${p}edit/pkg_class.html"><I>Add a package class</I></A><BR><BR>!;
my $count_query = 'SELECT COUNT(*) FROM pkg_class';
--- /dev/null
+<% include( 'elements/category_Common.html',
+ 'name' => 'Customer Category',
+ 'table' => 'cust_category',
+ )
+%>
--- /dev/null
+<% include( 'elements/class_Common.html',
+ 'name' => 'Customer Class',
+ 'table' => 'cust_class',
+ )
+%>
--- /dev/null
+<% include( 'edit.html',
+ 'fields' => [
+ 'categoryname',
+ 'weight',
+ { field=>'disabled', type=>'checkbox', value=>'Y', },
+ ],
+ 'labels' => {
+ 'categorynum' => 'Category number',
+ 'categoryname' => 'Category name',
+ 'weight' => 'Weight',
+ 'disabled' => 'Disable category',
+ },
+ 'viewall_dir' => 'browse',
+ %opt,
+ )
+%>
+<%init>
+
+die "access denied"
+ unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
+
+my %opt = @_;
+
+</%init>
--- /dev/null
+<% include( 'edit.html',
+ 'fields' => [
+ 'classname',
+ (scalar(@category)
+ ? { field=>'categorynum', type=>'select-table', 'empty_label'=>'(none)', 'table'=>'pkg_category', 'name_col'=>'categoryname' }
+ : { field=>'categorynum', type=>'hidden' }
+ ),
+ { field=>'disabled', type=>'checkbox', value=>'Y', },
+ ],
+ 'labels' => {
+ 'classnum' => 'Class number',
+ 'classname' => 'Class name',
+ 'categorynum' => 'Category',
+ 'disabled' => 'Disable class',
+ },
+ 'viewall_dir' => 'browse',
+ %opt,
+ )
+
+%>
+<%init>
+
+die "access denied"
+ unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
+
+my %opt = @_;
+
+my $table = $opt{'table'};
+( my $category_table = $table ) =~ s/class/category/ or die;
+
+my @category = qsearch($category_table, { 'disabled' => '' });
+</%init>
-<% include( 'elements/edit.html',
+<% include( 'elements/category_Common.html',
'name' => 'Package Category',
'table' => 'pkg_category',
- 'fields' => [
- 'categoryname',
- 'weight',
- { field=>'disabled', type=>'checkbox', value=>'Y', },
- ],
- 'labels' => {
- 'categorynum' => 'Category number',
- 'categoryname' => 'Category name',
- 'weight' => 'Weight',
- 'disabled' => 'Disable category',
- },
- 'viewall_dir' => 'browse',
- )
-
+ )
%>
-<%init>
-
-die "access denied"
- unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
-
-</%init>
-<% include( 'elements/edit.html',
+<% include( 'elements/class_Common.html',
'name' => 'Package Class',
'table' => 'pkg_class',
- 'fields' => [
- 'classname',
- (scalar(@category)
- ? { field=>'categorynum', type=>'select-table', 'empty_label'=>'(none)', 'table'=>'pkg_category', 'name_col'=>'categoryname' }
- : { field=>'categorynum', type=>'hidden' }
- ),
- { field=>'disabled', type=>'checkbox', value=>'Y', },
- ],
- 'labels' => {
- 'classnum' => 'Class number',
- 'classname' => 'Class name',
- 'categorynum' => 'Category',
- 'disabled' => 'Disable class',
- },
- 'viewall_dir' => 'browse',
- )
-
+ )
%>
-<%init>
-
-die "access denied"
- unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
-
-my @category = qsearch('pkg_category', { 'disabled' => '' });
-</%init>
--- /dev/null
+<% include( 'elements/process.html',
+ 'table' => 'cust_category',
+ 'viewall_dir' => 'browse',
+ )
+%>
+<%init>
+
+die "access denied"
+ unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
+
+</%init>
--- /dev/null
+<% include( 'elements/process.html',
+ 'table' => 'cust_class',
+ 'viewall_dir' => 'browse',
+ )
+%>
+<%init>
+
+die "access denied"
+ unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
+
+</%init>
if $curuser->access_right('Edit package definitions')
|| $curuser->access_right('Edit global package definitions');
if ( $curuser->access_right('Configuration') ) {
- $config_pkg{'Package categories'} = [ $fsurl.'browse/pkg_category.html', 'Package categories define groups of package classes, for reporting and convenience purposes.' ];
- $config_pkg{'Package tax classes'} = [ $fsurl.'browse/pkg_class.html', 'Package classes define groups of packages, for reporting and convenience purposes.' ];
- $config_pkg{'Package report classes'} = [ $fsurl.'browse/part_pkg_report_option.html', 'Package classes define optional groups of packages for reporting purposes.' ];
- $config_pkg{'Cancel reason types'} = [ $fsurl.'browse/reason_type.html?class=C', 'Cancel reason types define groups of reasons, for reporting and convenience purposes.' ];
+ $config_pkg{'Package classes'} = [ $fsurl.'browse/pkg_class.html', 'Package classes define groups of packages, for taxation, ordering convenience and reporting.' ];
+ $config_pkg{'Package categories'} = [ $fsurl.'browse/pkg_category.html', 'Package categories define groups of package classes.' ];
+ $config_pkg{'Package report classes'} = [ $fsurl.'browse/part_pkg_report_option.html', 'Package classes define optional groups of packages for reporting only.' ];
$config_pkg{'Cancel reasons'} = [ $fsurl.'browse/reason.html?class=C', 'Cancel reasons explain why a service was cancelled.' ];
- $config_pkg{'Suspend reason types'} = [ $fsurl.'browse/reason_type.html?class=S', 'Suspend reason types define groups of reasons, for reporting and convenience purposes.' ];
+ $config_pkg{'Cancel reason types'} = [ $fsurl.'browse/reason_type.html?class=C', 'Cancel reason types define groups of reasons.' ];
$config_pkg{'Suspend reasons'} = [ $fsurl.'browse/reason.html?class=S', 'Suspend reasons explain why a service was suspended.' ];
+ $config_pkg{'Suspend reason types'} = [ $fsurl.'browse/reason_type.html?class=S', 'Suspend reason types define groups of reasons.' ];
}
+tie my %config_cust, 'Tie::IxHash',
+ 'Customer classes' => [ $fsurl.'browse/cust_class.html', 'Customer classes define groups of customers for reporting.' ],
+ 'Customer categories' => [ $fsurl.'browse/cust_category.html', 'Customer categories define groups of customer classes.' ],
+;
+
tie my %config_agent, 'Tie::IxHash',
'Agent types' => [ $fsurl.'browse/agent_type.cgi', 'Agent types define groups of package definitions that you can then assign to particular agents' ],
'Agents' => [ $fsurl.'browse/agent.cgi', 'Agents are resellers of your service. Agents may be limited to a subset of your full offerings (via their type)' ],
tie my %config_billing_rates, 'Tie::IxHash',
'Rate plans' => [ $fsurl.'browse/rate.cgi', 'Manage rate plans' ],
'Regions and prefixes' => [ $fsurl.'browse/rate_region.html', 'Manage regions and prefixes' ],
- 'Usage classes' => [ $fsurl.'browse/usage_class.html', 'Usage classes define groups of usage for taxation purposes.' ],
+ 'Usage classes' => [ $fsurl.'browse/usage_class.html', 'Usage classes define groups of usage for taxation.' ],
'Edit rates with Excel' => [ $fsurl.'misc/rate_edit_excel.html', 'Download and edit rates with Excel, then upload changes.' ], #"Edit with Excel" ?
;
if $conf->exists('enable_taxproducts');
$config_billing{'Tax classes'} = [ $fsurl. 'browse/part_pkg_taxclass.html', 'Tax classes' ];
- $config_billing{'Credit reason types'} = [ $fsurl.'browse/reason_type.html?class=R', 'Credit reason types define groups of reasons, for reporting and convenience purposes.' ];
$config_billing{'Credit reasons'} = [ $fsurl.'browse/reason.html?class=R', 'Credit reasons explain why a credit was issued.' ];
+ $config_billing{'Credit reason types'} = [ $fsurl.'browse/reason_type.html?class=R', 'Credit reason types define groups of reasons.' ];
}
tie my %config_ticketing, 'Tie::IxHash',
;
tie my %config_misc, 'Tie::IxHash';
-$config_misc{'Advertising sources'} = [ $fsurl.'browse/part_referral.html', 'Where a customer heard about your service. Tracked for informational purposes' ]
+$config_misc{'Advertising sources'} = [ $fsurl.'browse/part_referral.html', 'Where a customer heard about your service.' ]
if $curuser->access_right('Edit advertising sources')
|| $curuser->access_right('Edit global advertising sources');
if ( $curuser->access_right('Configuration') ) {
if $curuser->access_right('Configuration' )
|| $curuser->access_right('Edit package definitions')
|| $curuser->access_right('Edit global package definitions');
-$config_menu{'Resellers'} = [ \%config_agent, '' ]
+$config_menu{'Customers'} = [ \%config_cust, '' ]
+ if $curuser->access_right('Configuration');
+$config_menu{'Resellers'} = [ \%config_agent, '' ]
if $curuser->access_right('Configuration');
-$config_menu{'Billing'} = [ \%config_billing, '' ]
+$config_menu{'Billing'} = [ \%config_billing, '' ]
if $curuser->access_right('Edit billing events')
|| $curuser->access_right('Edit global billing events');
$config_menu{'Ticketing'} = [ \%config_ticketing, '' ]
&& FS::TicketSystem->access_right(\%session, 'ShowConfigTab');
$config_menu{'Dialup'} = [ \%config_dialup, '' ]
if ( $curuser->access_right('Dialup configuration') );
-$config_menu{'Fixed (username-less) broadband'} = [ \%config_broadband, '' ]
+$config_menu{'Broadband'} = [ \%config_broadband, '' ]
if ( $curuser->access_right('Broadband configuration') );
$config_menu{'Phone'} = [ \%config_phone, '' ]
if ( $curuser->access_right('Configuration') );