summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FS/FS.pm6
-rw-r--r--FS/FS/AccessRight.pm1
-rw-r--r--FS/FS/Schema.pm55
-rw-r--r--FS/FS/access_right.pm1
-rw-r--r--FS/FS/conferencing_quality.pm113
-rw-r--r--FS/FS/conferencing_type.pm113
-rw-r--r--FS/FS/svc_conferencing.pm260
-rw-r--r--FS/MANIFEST6
-rw-r--r--FS/t/conferencing_quality.t5
-rw-r--r--FS/t/conferencing_type.t5
-rw-r--r--FS/t/svc_conferencing.t5
-rw-r--r--httemplate/browse/conferencing_quality.html32
-rw-r--r--httemplate/browse/conferencing_type.html32
-rw-r--r--httemplate/edit/conferencing_quality.html21
-rw-r--r--httemplate/edit/conferencing_type.html21
-rw-r--r--httemplate/edit/process/conferencing_quality.html10
-rw-r--r--httemplate/edit/process/conferencing_type.html10
-rw-r--r--httemplate/elements/duration.html74
-rw-r--r--httemplate/elements/menu.html7
-rw-r--r--httemplate/elements/select-conferencing_quality.html7
-rw-r--r--httemplate/elements/select-conferencing_type.html7
-rw-r--r--httemplate/elements/tr-duration.html30
-rw-r--r--httemplate/elements/tr-select-conferencing_quality.html6
-rw-r--r--httemplate/elements/tr-select-conferencing_type.html6
-rw-r--r--httemplate/view/elements/svc_Common.html4
25 files changed, 834 insertions, 3 deletions
diff --git a/FS/FS.pm b/FS/FS.pm
index 485792a..6f770da 100644
--- a/FS/FS.pm
+++ b/FS/FS.pm
@@ -222,6 +222,12 @@ L<FS::alarm_type> - Alarm type (inputs and outputs) class
L<FS::alarm_station> - Alarm central station class
+L<FS::svc_conferencing> - Conferencing service class
+
+L<FS::conferencing_type> - Conferencing type class
+
+L<FS::conferencing_quality> - Conferencing quality class
+
L<FS::inventory_class> - Inventory classes
L<FS::inventory_item> - Inventory items
diff --git a/FS/FS/AccessRight.pm b/FS/FS/AccessRight.pm
index 41ca954..35994de 100644
--- a/FS/FS/AccessRight.pm
+++ b/FS/FS/AccessRight.pm
@@ -295,6 +295,7 @@ tie my %rights, 'Tie::IxHash',
'Services: Wireless broadband services: Advanced search',
'Services: DSLs',
'Services: Cable subscribers',
+ 'Services: Conferencing',
'Services: Dish services',
'Services: Hardware',
'Services: Hardware: Advanced search',
diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm
index 862e40a..07da81d 100644
--- a/FS/FS/Schema.pm
+++ b/FS/FS/Schema.pm
@@ -6055,6 +6055,61 @@ sub tables_hashref {
'index' => [],
},
+ 'svc_conferencing' => {
+ 'columns' => [
+ 'svcnum', 'int', '', '', '', '',
+ 'conf_id', 'int', 'NULL', '', '', '', #"system assigned"
+ 'conf_name', 'varchar', '', $char_d, '', '',
+ 'conf_password', 'varchar', '', $char_d, '', '',
+ 'access_code', 'varchar', '', 16, '', '',
+ 'duration', 'int', '', '', '', '',
+ 'participants', 'int', '', '', '', '',
+ 'conftypenum', 'int', '', '', '', '',
+ 'confqualitynum', 'int', '', '', '', '',
+ 'opt_recording', 'char', 'NULL', 1, '', '',
+ 'opt_sip', 'char', 'NULL', 1, '', '',
+ 'opt_phone', 'char', 'NULL', 1, '', '',
+ ],
+ 'primary_key' => 'svcnum',
+ 'unique' => [],
+ 'index' => [],
+ 'foreign_keys' => [
+ { columns => [ 'svcnum' ],
+ table => 'cust_svc',
+ },
+ { columns => [ 'conftypenum' ],
+ table => 'conferencing_type',
+ },
+ { columns => [ 'confqualitynum' ],
+ table => 'conferencing_quality',
+ },
+ ],
+ },
+
+ 'conferencing_type' => {
+ 'columns' => [
+ 'conftypenum', 'int', '', '', '', '',
+ 'typeid' , 'int', '', '', '', '',
+ 'typename', 'varchar', '', $char_d, '', '',
+ 'disabled', 'char', 'NULL', 1, '', '',
+ ],
+ 'primary_key' => 'conftypenum',
+ 'unique' => [ [ 'typeid', 'disabled' ], [ 'typename', 'disabled' ] ],
+ 'index' => [],
+ },
+
+ 'conferencing_quality' => {
+ 'columns' => [
+ 'confqualitynum', 'int', '', '', '', '',
+ 'qualityid' , 'int', '', '', '', '',
+ 'qualityname', 'varchar', '', $char_d, '', '',
+ 'disabled', 'char', 'NULL', 1, '', '',
+ ],
+ 'primary_key' => 'confqualitynum',
+ 'unique' => [ [ 'qualityid', 'disabled' ], [ 'qualityname', 'disabled' ] ],
+ 'index' => [],
+ },
+
'vend_main' => {
'columns' => [
'vendnum', 'serial', '', '', '', '',
diff --git a/FS/FS/access_right.pm b/FS/FS/access_right.pm
index 4931c7f..61e5b7c 100644
--- a/FS/FS/access_right.pm
+++ b/FS/FS/access_right.pm
@@ -240,6 +240,7 @@ sub _upgrade_data { # class method
'Bulk change customer packages' => 'Bulk move customer services',
'Configuration' => 'Edit sales people',
'Configuration' => 'Alarm global configuration',
+ 'Services: Accounts' => 'Services: Conferencing',
);
# foreach my $old_acl ( keys %onetime ) {
diff --git a/FS/FS/conferencing_quality.pm b/FS/FS/conferencing_quality.pm
new file mode 100644
index 0000000..78b1e0e
--- /dev/null
+++ b/FS/FS/conferencing_quality.pm
@@ -0,0 +1,113 @@
+package FS::conferencing_quality;
+use base qw( FS::Record );
+
+use strict;
+
+=head1 NAME
+
+FS::conferencing_quality - Object methods for conferencing_quality records
+
+=head1 SYNOPSIS
+
+ use FS::conferencing_quality;
+
+ $record = new FS::conferencing_quality \%hash;
+ $record = new FS::conferencing_quality { 'column' => 'value' };
+
+ $error = $record->insert;
+
+ $error = $new_record->replace($old_record);
+
+ $error = $record->delete;
+
+ $error = $record->check;
+
+=head1 DESCRIPTION
+
+An FS::conferencing_quality object represents a conferencing quality level.
+FS::conferencing_quality inherits from FS::Record. The following fields are
+currently supported:
+
+=over 4
+
+=item confqualitynum
+
+primary key
+
+=item qualityid
+
+Numeric (vendor) ID for this quality
+
+=item qualityname
+
+Name for this quality
+
+=item disabled
+
+Empty or 'Y'
+
+=back
+
+=head1 METHODS
+
+=over 4
+
+=item new HASHREF
+
+Creates a new record. To add the record 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 { 'conferencing_quality'; }
+
+=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 record. 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('confqualitynum')
+ || $self->ut_number('qualityid')
+ || $self->ut_text('qualityname')
+ || $self->ut_enum('disabled', [ '', 'Y' ] )
+ ;
+ return $error if $error;
+
+ $self->SUPER::check;
+}
+
+=back
+
+=head1 BUGS
+
+=head1 SEE ALSO
+
+L<FS::svc_conferencing>, L<FS::Record>
+
+=cut
+
+1;
+
diff --git a/FS/FS/conferencing_type.pm b/FS/FS/conferencing_type.pm
new file mode 100644
index 0000000..3df8913
--- /dev/null
+++ b/FS/FS/conferencing_type.pm
@@ -0,0 +1,113 @@
+package FS::conferencing_type;
+use base qw( FS::Record );
+
+use strict;
+
+=head1 NAME
+
+FS::conferencing_type - Object methods for conferencing_type records
+
+=head1 SYNOPSIS
+
+ use FS::conferencing_type;
+
+ $record = new FS::conferencing_type \%hash;
+ $record = new FS::conferencing_type { 'column' => 'value' };
+
+ $error = $record->insert;
+
+ $error = $new_record->replace($old_record);
+
+ $error = $record->delete;
+
+ $error = $record->check;
+
+=head1 DESCRIPTION
+
+An FS::conferencing_type object represents a conferencing type.
+FS::conferencing_type inherits from FS::Record. The following fields are
+currently supported:
+
+=over 4
+
+=item conftypenum
+
+primary key
+
+=item typeid
+
+Numeric (vendor) ID for type type
+
+=item typename
+
+Name for this type
+
+=item disabled
+
+Empty or 'Y'
+
+=back
+
+=head1 METHODS
+
+=over 4
+
+=item new HASHREF
+
+Creates a new record. To add the record 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 { 'conferencing_type'; }
+
+=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 record. 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('conftypenum')
+ || $self->ut_number('typeid')
+ || $self->ut_text('typename')
+ || $self->ut_enum('disabled', [ '', 'Y' ] )
+ ;
+ return $error if $error;
+
+ $self->SUPER::check;
+}
+
+=back
+
+=head1 BUGS
+
+=head1 SEE ALSO
+
+L<FS::svc_conferencing>, L<FS::Record>
+
+=cut
+
+1;
+
diff --git a/FS/FS/svc_conferencing.pm b/FS/FS/svc_conferencing.pm
new file mode 100644
index 0000000..cae6112
--- /dev/null
+++ b/FS/FS/svc_conferencing.pm
@@ -0,0 +1,260 @@
+package FS::svc_conferencing;
+use base qw( FS::svc_Common );
+
+use strict;
+use Tie::IxHash;
+#use FS::Record qw( qsearch qsearchs );
+
+=head1 NAME
+
+FS::svc_conferencing - Object methods for svc_conferencing records
+
+=head1 SYNOPSIS
+
+ use FS::svc_conferencing;
+
+ $record = new FS::svc_conferencing \%hash;
+ $record = new FS::svc_conferencing { 'column' => 'value' };
+
+ $error = $record->insert;
+
+ $error = $new_record->replace($old_record);
+
+ $error = $record->delete;
+
+ $error = $record->check;
+
+=head1 DESCRIPTION
+
+An FS::svc_conferencing object represents a conferencing service.
+FS::svc_conferencing inherits from FS::Record. The following fields are
+currently supported:
+
+=over 4
+
+=item svcnum
+
+primary key
+
+=item conf_id
+
+conf_id
+
+=item conf_name
+
+conf_name
+
+=item conf_password
+
+conf_password
+
+=item access_code
+
+access_code
+
+=item duration
+
+duration
+
+=item participants
+
+participants
+
+=item conftypenum
+
+conftypenum
+
+=item confqualitynum
+
+confqualitynum
+
+=item opt_recording
+
+opt_recording
+
+=item opt_sip
+
+opt_sip
+
+=item opt_phone
+
+opt_phone
+
+
+=back
+
+=head1 METHODS
+
+=over 4
+
+=item new HASHREF
+
+Creates a new record. To add the record 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 { 'svc_conferencing'; }
+
+sub table_info {
+
+ my %opts = ( 'type' => 'text',
+ 'disable_select' => 1,
+ 'disable_inventory' => 1,
+ );
+
+ tie my %fields, 'Tie::IxHash',
+ 'svcnum' => { label => 'Service' },
+ 'conf_id' => { label => 'Conference ID', %opts, },
+ 'conf_name' => { label => 'Conference Name',
+ size => 31,
+ maxlength => 30,
+ %opts,
+ },
+ 'conf_password' => { label => 'Password',
+ size => 31,
+ maxlength => 30,
+ %opts,
+ },
+ 'access_code' => { label => 'Access code' ,
+ size => 17,
+ maxlength => 16,
+ %opts,
+ },
+ 'duration' => { label => 'Duration',
+ type => 'duration',
+ disable_select => 1,
+ disable_inventory => 1,
+ value_callback => sub {
+ my $min = shift->duration;
+ int($min/60)."h".
+ sprintf("%02d",$min%60)."m";
+ },
+ },
+ 'participants' => { label => 'Num. participants', size=>5, %opts },
+ 'conftypenum' => { label => 'Conference type',
+ type => 'select-conferencing_type',
+ disable_select => 1,
+ disable_inventory => 1,
+ value_callback => sub {
+ shift->conferencing_type->typename;
+ },
+ },
+ 'confqualitynum' => { label => 'Quality',
+ type => 'select-conferencing_quality',
+ disable_select => 1,
+ disable_inventory => 1,
+ value_callback => sub {
+ shift->conferencing_quality->qualityname;
+ },
+ },
+ 'opt_recording' => { label => 'Recording',
+ type => 'checkbox',
+ value => 'Y',
+ disable_select => 1,
+ disable_inventory => 1,
+ },
+ 'opt_sip' => { label => 'SIP participation',
+ type => 'checkbox',
+ value => 'Y',
+ disable_select => 1,
+ disable_inventory => 1,
+ },
+ 'opt_phone' => { label => 'Phone participation',
+ type => 'checkbox',
+ value => 'Y',
+ disable_select => 1,
+ disable_inventory => 1,
+ },
+ ;
+
+ {
+ 'name' => 'Conferencing', # service',
+ #'name_plural' => '', #optional,
+ #'longname_plural' => '', #optional
+ 'fields' => \%fields,
+ 'addl_process_fields' => [ 'duration_units' ],
+ 'sorts' => [ 'conf_id', 'conf_name' ],
+ 'display_weight' => 57,
+ 'cancel_weight' => 70, #? no deps, so
+ };
+
+}
+
+sub label {
+ my $self = shift;
+ $self->conf_id.': '. $self->conf_name;
+}
+
+=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 record. If there is
+an error, returns the error, otherwise returns false. Called by the insert
+and replace methods.
+
+=cut
+
+sub check {
+ my $self = shift;
+
+ if ( $self->duration_units && $self->duration_units > 1 ) {
+ $self->duration( int( ($self->duration * $self->duration_units) + .5) );
+
+ $self->duration_units(1);
+ }
+
+ my $error =
+ $self->ut_numbern('svcnum')
+ || $self->ut_numbern('conf_id')
+ || $self->ut_text('conf_name')
+ || $self->ut_text('conf_password')
+ || $self->ut_text('access_code')
+ || $self->ut_number('duration')
+ || $self->ut_number('participants')
+ || $self->ut_number('conftypenum')
+ || $self->ut_number('confqualitynum')
+ || $self->ut_enum('opt_recording', [ '', 'Y' ])
+ || $self->ut_enum('opt_sip', [ '', 'Y' ])
+ || $self->ut_enum('opt_phone', [ '', 'Y' ])
+ ;
+ return $error if $error;
+
+ return 'Meeting name must be at least 4 characters'
+ unless length($self->conf_name) >= 4;
+ return 'Password must be at least 4 characters'
+ unless length($self->conf_password) >= 4;
+ return 'Access code must be at least 4 digits'
+ unless length($self->access_code) >= 4;
+
+
+ $self->SUPER::check;
+}
+
+=back
+
+=head1 BUGS
+
+=head1 SEE ALSO
+
+L<FS::Record>
+
+=cut
+
+1;
+
diff --git a/FS/MANIFEST b/FS/MANIFEST
index 1f2dfcc..bfc47c6 100644
--- a/FS/MANIFEST
+++ b/FS/MANIFEST
@@ -737,3 +737,9 @@ FS/alarm_station.pm
t/alarm_station.t
FS/addr_range.pm
t/addr_range.t
+FS/svc_conferencing.pm
+t/svc_conferencing.t
+FS/conferencing_type.pm
+t/conferencing_type.t
+FS/conferencing_quality.pm
+t/conferencing_quality.t
diff --git a/FS/t/conferencing_quality.t b/FS/t/conferencing_quality.t
new file mode 100644
index 0000000..987ec87
--- /dev/null
+++ b/FS/t/conferencing_quality.t
@@ -0,0 +1,5 @@
+BEGIN { $| = 1; print "1..1\n" }
+END {print "not ok 1\n" unless $loaded;}
+use FS::conferencing_quality;
+$loaded=1;
+print "ok 1\n";
diff --git a/FS/t/conferencing_type.t b/FS/t/conferencing_type.t
new file mode 100644
index 0000000..2bcd688
--- /dev/null
+++ b/FS/t/conferencing_type.t
@@ -0,0 +1,5 @@
+BEGIN { $| = 1; print "1..1\n" }
+END {print "not ok 1\n" unless $loaded;}
+use FS::conferencing_type;
+$loaded=1;
+print "ok 1\n";
diff --git a/FS/t/svc_conferencing.t b/FS/t/svc_conferencing.t
new file mode 100644
index 0000000..e480c67
--- /dev/null
+++ b/FS/t/svc_conferencing.t
@@ -0,0 +1,5 @@
+BEGIN { $| = 1; print "1..1\n" }
+END {print "not ok 1\n" unless $loaded;}
+use FS::svc_conferencing;
+$loaded=1;
+print "ok 1\n";
diff --git a/httemplate/browse/conferencing_quality.html b/httemplate/browse/conferencing_quality.html
new file mode 100644
index 0000000..8854559
--- /dev/null
+++ b/httemplate/browse/conferencing_quality.html
@@ -0,0 +1,32 @@
+<& elements/browse.html,
+ 'title' => 'Conferencing quality levels',
+ 'html_init' => $html_init,
+ 'name_singular' => 'quality',
+ 'disableable' => 1,
+ 'disabled_statuspos' => 1,
+ 'query' => { 'table' => 'conferencing_quality',
+ 'hashref' => {},
+ 'order_by' => 'ORDER BY qualityid',
+ },
+ 'count_query' => $count_query,
+ 'header' => $header,
+ 'fields' => $fields,
+ 'links' => $links,
+&>
+<%init>
+
+die "access denied"
+ unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
+
+my $html_init =
+ qq!<A HREF="${p}edit/conferencing_quality.html"><I>Add a conferencing quality</I></A><BR><BR>!;
+
+my $count_query = 'SELECT COUNT(*) FROM conferencing_quality';
+
+my $link = [ $p.'edit/conferencing_quality.html?', 'confqualitynum' ];
+
+my $header = [ 'ID', 'Quality' ];
+my $fields = [ 'qualityid', 'qualityname' ];
+my $links = [ $link, $link ];
+
+</%init>
diff --git a/httemplate/browse/conferencing_type.html b/httemplate/browse/conferencing_type.html
new file mode 100644
index 0000000..176b6a2
--- /dev/null
+++ b/httemplate/browse/conferencing_type.html
@@ -0,0 +1,32 @@
+<& elements/browse.html,
+ 'title' => 'Conferencing types',
+ 'html_init' => $html_init,
+ 'name_singular' => 'type',
+ 'disableable' => 1,
+ 'disabled_statuspos' => 1,
+ 'query' => { 'table' => 'conferencing_type',
+ 'hashref' => {},
+ 'order_by' => 'ORDER BY typeid',
+ },
+ 'count_query' => $count_query,
+ 'header' => $header,
+ 'fields' => $fields,
+ 'links' => $links,
+&>
+<%init>
+
+die "access denied"
+ unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
+
+my $html_init =
+ qq!<A HREF="${p}edit/conferencing_type.html"><I>Add a conferencing type</I></A><BR><BR>!;
+
+my $count_query = 'SELECT COUNT(*) FROM conferencing_type';
+
+my $link = [ $p.'edit/conferencing_type.html?', 'conftypenum' ];
+
+my $header = [ 'ID', 'Type' ];
+my $fields = [ 'typeid', 'typename' ];
+my $links = [ $link, $link ];
+
+</%init>
diff --git a/httemplate/edit/conferencing_quality.html b/httemplate/edit/conferencing_quality.html
new file mode 100644
index 0000000..4d93dee
--- /dev/null
+++ b/httemplate/edit/conferencing_quality.html
@@ -0,0 +1,21 @@
+<& elements/edit.html,
+ 'table' => 'conferencing_quality',
+ 'name_singular' => 'quality',
+ 'fields' => [
+ { field=>'qualityid', type=>'text', size=>4 },
+ { field=>'qualityname', type=>'text', },
+ { field=>'disabled', type=>'checkbox', value=>'Y'},
+ ],
+ 'labels' => { 'confqualitynum' => 'Type',
+ 'qualityid' => 'ID',
+ 'qualityname' => 'Name',
+ 'disabled' => 'Disabled',
+ },
+ 'viewall_dir' => 'browse',
+&>
+<%init>
+
+die "access denied"
+ unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
+
+</%init>
diff --git a/httemplate/edit/conferencing_type.html b/httemplate/edit/conferencing_type.html
new file mode 100644
index 0000000..964a560
--- /dev/null
+++ b/httemplate/edit/conferencing_type.html
@@ -0,0 +1,21 @@
+<& elements/edit.html,
+ 'table' => 'conferencing_type',
+ 'name_singular' => 'type',
+ 'fields' => [
+ { field=>'typeid', type=>'text', size=>4 },
+ { field=>'typename', type=>'text', },
+ { field=>'disabled', type=>'checkbox', value=>'Y'},
+ ],
+ 'labels' => { 'conftypenum' => 'Type',
+ 'typeid' => 'ID',
+ 'typename' => 'Name',
+ 'disabled' => 'Disabled',
+ },
+ 'viewall_dir' => 'browse',
+&>
+<%init>
+
+die "access denied"
+ unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
+
+</%init>
diff --git a/httemplate/edit/process/conferencing_quality.html b/httemplate/edit/process/conferencing_quality.html
new file mode 100644
index 0000000..e68b4ea
--- /dev/null
+++ b/httemplate/edit/process/conferencing_quality.html
@@ -0,0 +1,10 @@
+<& elements/process.html,
+ 'table' => 'conferencing_quality',
+ 'viewall_dir' => 'browse',
+&>
+<%init>
+
+die "access denied"
+ unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
+
+</%init>
diff --git a/httemplate/edit/process/conferencing_type.html b/httemplate/edit/process/conferencing_type.html
new file mode 100644
index 0000000..a67d779
--- /dev/null
+++ b/httemplate/edit/process/conferencing_type.html
@@ -0,0 +1,10 @@
+<& elements/process.html,
+ 'table' => 'conferencing_type',
+ 'viewall_dir' => 'browse',
+&>
+<%init>
+
+die "access denied"
+ unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
+
+</%init>
diff --git a/httemplate/elements/duration.html b/httemplate/elements/duration.html
new file mode 100644
index 0000000..106e56b
--- /dev/null
+++ b/httemplate/elements/duration.html
@@ -0,0 +1,74 @@
+<% $opt{'prefix'} %><INPUT TYPE = "text"
+ NAME = "<% $opt{field} %>"
+ ID = "<% $opt{id} %>"
+ VALUE = "<% $value |h %>"
+ <% $size %>
+ <% $maxlength %>
+ <% $style %>
+ <% $opt{autocomplete} ? 'autocomplete="off"' : '' %>
+ <% $opt{disabled} %>
+ <% $onchange %>
+ ><SELECT NAME = "<% $opt{field} %>_units"
+ ID = "<% $opt{id} %>_units"
+ onChange = "<% $opt{field} %>_units_changed(this)"
+ >
+ <OPTION VALUE="1">minutes</OPTION>
+ <OPTION SELECTED VALUE="60">hours</OPTION>
+ </SELECT><% $opt{'postfix'} %>
+<SCRIPT TYPE="text/javascript">
+ function <% $opt{field} %>_units_changed(what) {
+ var units = what.options[what.selectedIndex].value;
+ if ( units == 60 ) { // changed from minutes to hours, so /60
+
+ var value = what.form.<% $opt{field} %>.value;
+ value = value / 60;
+ what.form.<% $opt{field} %>.value = value;
+
+ } else if ( units == 1 ) { // changed from hours to minutes, so *60
+
+ var value = what.form.<% $opt{field} %>.value;
+ value = Math.round(value * 60);
+ what.form.<% $opt{field} %>.value = value;
+
+ }
+ }
+</SCRIPT>
+<%init>
+
+my %opt = @_;
+
+my $value = length($opt{curr_value}) ? $opt{curr_value} : $opt{value};
+$value = $value / 60;
+
+my $onchange = $opt{'onchange'}
+ ? join(' ', map $_.'="'. $opt{'onchange'}. '(this)"',
+ qw( onChange onKeyDown onKeyUp onKeyPress )
+ )
+ : '';
+
+$opt{'size'} ||= 4;
+my $size = 'SIZE="'. $opt{'size'}. '"';
+
+$opt{'maxlength'} ||= 3;
+my $maxlength = 'MAXLENGTH="'. $opt{'maxlength'}. '"';
+
+$opt{'disabled'} = &{ $opt{'disabled'} }( \%opt )
+ if ref($opt{'disabled'}) eq 'CODE';
+$opt{'disabled'} = 'DISABLED'
+ if $opt{'disabled'} && $opt{'disabled'} !~ /disabled/i; # uuh... yeah?
+
+my @style = ref($opt{'style'})
+ ? @{ $opt{'style'} }
+ : $opt{'style'}
+ ? ( $opt{'style'} )
+ : ();
+
+push @style, 'text-align: '. $opt{'text-align'}
+ if $opt{'text-align'};
+
+push @style, 'background-color: #dddddd'
+ if $opt{'disabled'} && ! $opt{'nodarken_disabled'};
+
+my $style = scalar(@style) ? 'STYLE="'. join(';', @style). '"' : '';
+
+</%init>
diff --git a/httemplate/elements/menu.html b/httemplate/elements/menu.html
index 2ae216c..a403bb3 100644
--- a/httemplate/elements/menu.html
+++ b/httemplate/elements/menu.html
@@ -535,6 +535,11 @@ tie my %config_alarm, 'Tie::IxHash',
'Alarm central stations' => [ $fsurl.'browse/alarm_station.html', '' ],
;
+tie my %config_conferencing, 'Tie::IxHash',
+ 'Conferencing types' => [ $fsurl.'browse/conferencing_type.html', '' ],
+ 'Quality levels' => [ $fsurl.'browse/conferencing_quality.html', '' ],
+;
+
tie my %config_export_svc, 'Tie::IxHash', ();
if ( $curuser->access_right('Configuration') ) {
$config_export_svc{'Service definitions'} = [ $fsurl.'browse/part_svc.cgi', 'Services are items you offer to your customers' ];
@@ -551,6 +556,8 @@ $config_export_svc{'RADIUS'} = [ \%config_radius, '' ]
if $curuser->access_right('Configuration');
$config_export_svc{'Cable'} = [ \%config_cable, '' ]
if $curuser->access_right('Configuration');
+$config_export_svc{'Conferencing'} = [ \%config_conferencing, '' ]
+ if $curuser->access_right('Configuration');
$config_export_svc{'Alarm'} = [ \%config_alarm, '' ]
if $curuser->access_right(['Alarm configuration', 'Alarm global configuration']);
$config_export_svc{'Hardware types'} = [ $fsurl.'browse/hardware_class.html', 'Set up hardware type catalog' ]
diff --git a/httemplate/elements/select-conferencing_quality.html b/httemplate/elements/select-conferencing_quality.html
new file mode 100644
index 0000000..b4de267
--- /dev/null
+++ b/httemplate/elements/select-conferencing_quality.html
@@ -0,0 +1,7 @@
+<& /elements/select-table.html,
+ 'table' => 'conferencing_quality',
+ 'name_col' => 'qualityname',
+ 'order_by' => 'ORDER BY qualityid',
+ 'empty_label' => 'Select quality',
+ @_,
+&>
diff --git a/httemplate/elements/select-conferencing_type.html b/httemplate/elements/select-conferencing_type.html
new file mode 100644
index 0000000..d924503
--- /dev/null
+++ b/httemplate/elements/select-conferencing_type.html
@@ -0,0 +1,7 @@
+<& /elements/select-table.html,
+ 'table' => 'conferencing_type',
+ 'name_col' => 'typename',
+ 'order_by' => 'ORDER BY typeid',
+ 'empty_label' => 'Select type',
+ @_,
+&>
diff --git a/httemplate/elements/tr-duration.html b/httemplate/elements/tr-duration.html
new file mode 100644
index 0000000..2517302
--- /dev/null
+++ b/httemplate/elements/tr-duration.html
@@ -0,0 +1,30 @@
+<%doc>
+
+Example:
+
+ <& /elements/tr-duration.html,
+ 'label' => 'Do or do not',
+ 'field' => 'field_name',
+ 'value' => 'Y',
+ &>
+
+</%doc>
+<% include('tr-td-label.html', @_ ) %>
+
+ <TD <% $style %>>
+ <% include('duration.html', @_) %>
+ </TD>
+
+</TR>
+
+<%init>
+
+my %opt = @_;
+
+my $onchange = $opt{'onchange'}
+ ? 'onChange="'. $opt{'onchange'}. '(this)"'
+ : '';
+
+my $style = $opt{'cell_style'} ? 'STYLE="'. $opt{'cell_style'}. '"' : '';
+
+</%init>
diff --git a/httemplate/elements/tr-select-conferencing_quality.html b/httemplate/elements/tr-select-conferencing_quality.html
new file mode 100644
index 0000000..ba7a685
--- /dev/null
+++ b/httemplate/elements/tr-select-conferencing_quality.html
@@ -0,0 +1,6 @@
+<& /elements/tr-select-table.html,
+ label => 'Quality',
+ table => 'conferencing_quality',
+ name_col => 'qualityname',
+ @_,
+&>
diff --git a/httemplate/elements/tr-select-conferencing_type.html b/httemplate/elements/tr-select-conferencing_type.html
new file mode 100644
index 0000000..2177fc6
--- /dev/null
+++ b/httemplate/elements/tr-select-conferencing_type.html
@@ -0,0 +1,6 @@
+<& /elements/tr-select-table.html,
+ label => 'Conference type',
+ table => 'conferencing_type',
+ name_col => 'typename',
+ @_,
+&>
diff --git a/httemplate/view/elements/svc_Common.html b/httemplate/view/elements/svc_Common.html
index d34ed50..65f373c 100644
--- a/httemplate/view/elements/svc_Common.html
+++ b/httemplate/view/elements/svc_Common.html
@@ -78,9 +78,7 @@ function areyousure(href) {
% my $hack_strict_refs = \&{ $f->{'value_callback'} };
% $value = &$hack_strict_refs($svc_x);
% } else {
-% $value = exists($f->{'value'})
-% ? $f->{'value'}
-% : encode_entities($svc_x->$field);
+% $value = encode_entities($svc_x->$field);
% }
% } else {
% $field = $f;