svc_conferencing, RT#24389
authorIvan Kohler <ivan@freeside.biz>
Sun, 5 Jan 2014 00:23:54 +0000 (16:23 -0800)
committerIvan Kohler <ivan@freeside.biz>
Sun, 5 Jan 2014 00:23:54 +0000 (16:23 -0800)
25 files changed:
FS/FS.pm
FS/FS/AccessRight.pm
FS/FS/Schema.pm
FS/FS/access_right.pm
FS/FS/conferencing_quality.pm [new file with mode: 0644]
FS/FS/conferencing_type.pm [new file with mode: 0644]
FS/FS/svc_conferencing.pm [new file with mode: 0644]
FS/MANIFEST
FS/t/conferencing_quality.t [new file with mode: 0644]
FS/t/conferencing_type.t [new file with mode: 0644]
FS/t/svc_conferencing.t [new file with mode: 0644]
httemplate/browse/conferencing_quality.html [new file with mode: 0644]
httemplate/browse/conferencing_type.html [new file with mode: 0644]
httemplate/edit/conferencing_quality.html [new file with mode: 0644]
httemplate/edit/conferencing_type.html [new file with mode: 0644]
httemplate/edit/process/conferencing_quality.html [new file with mode: 0644]
httemplate/edit/process/conferencing_type.html [new file with mode: 0644]
httemplate/elements/duration.html [new file with mode: 0644]
httemplate/elements/menu.html
httemplate/elements/select-conferencing_quality.html [new file with mode: 0644]
httemplate/elements/select-conferencing_type.html [new file with mode: 0644]
httemplate/elements/tr-duration.html [new file with mode: 0644]
httemplate/elements/tr-select-conferencing_quality.html [new file with mode: 0644]
httemplate/elements/tr-select-conferencing_type.html [new file with mode: 0644]
httemplate/view/elements/svc_Common.html

index 485792a..6f770da 100644 (file)
--- 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::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
 L<FS::inventory_class> - Inventory classes
 
 L<FS::inventory_item> - Inventory items
index 41ca954..35994de 100644 (file)
@@ -295,6 +295,7 @@ tie my %rights, 'Tie::IxHash',
     'Services: Wireless broadband services: Advanced search',
     'Services: DSLs',
     'Services: Cable subscribers',
     'Services: Wireless broadband services: Advanced search',
     'Services: DSLs',
     'Services: Cable subscribers',
+    'Services: Conferencing',
     'Services: Dish services',
     'Services: Hardware',
     'Services: Hardware: Advanced search',
     'Services: Dish services',
     'Services: Hardware',
     'Services: Hardware: Advanced search',
index 862e40a..07da81d 100644 (file)
@@ -6055,6 +6055,61 @@ sub tables_hashref {
       'index'  => [],
     },
 
       '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',     '',      '', '', '',
     'vend_main' => {
       'columns' => [
         'vendnum',   'serial',     '',      '', '', '',
index 4931c7f..61e5b7c 100644 (file)
@@ -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',
     '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 ) {
   );
 
 #  foreach my $old_acl ( keys %onetime ) {
diff --git a/FS/FS/conferencing_quality.pm b/FS/FS/conferencing_quality.pm
new file mode 100644 (file)
index 0000000..78b1e0e
--- /dev/null
@@ -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 (file)
index 0000000..3df8913
--- /dev/null
@@ -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 (file)
index 0000000..cae6112
--- /dev/null
@@ -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;
+
index 1f2dfcc..bfc47c6 100644 (file)
@@ -737,3 +737,9 @@ FS/alarm_station.pm
 t/alarm_station.t
 FS/addr_range.pm
 t/addr_range.t
 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 (file)
index 0000000..987ec87
--- /dev/null
@@ -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 (file)
index 0000000..2bcd688
--- /dev/null
@@ -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 (file)
index 0000000..e480c67
--- /dev/null
@@ -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 (file)
index 0000000..8854559
--- /dev/null
@@ -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 (file)
index 0000000..176b6a2
--- /dev/null
@@ -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 (file)
index 0000000..4d93dee
--- /dev/null
@@ -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 (file)
index 0000000..964a560
--- /dev/null
@@ -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 (file)
index 0000000..e68b4ea
--- /dev/null
@@ -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 (file)
index 0000000..a67d779
--- /dev/null
@@ -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 (file)
index 0000000..106e56b
--- /dev/null
@@ -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>
index 2ae216c..a403bb3 100644 (file)
@@ -535,6 +535,11 @@ tie my %config_alarm, 'Tie::IxHash',
   'Alarm central stations' => [ $fsurl.'browse/alarm_station.html', '' ],
 ;
 
   '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' ];
 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');
   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' ]
 $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 (file)
index 0000000..b4de267
--- /dev/null
@@ -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 (file)
index 0000000..d924503
--- /dev/null
@@ -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 (file)
index 0000000..2517302
--- /dev/null
@@ -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 (file)
index 0000000..ba7a685
--- /dev/null
@@ -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 (file)
index 0000000..2177fc6
--- /dev/null
@@ -0,0 +1,6 @@
+<& /elements/tr-select-table.html,
+     label       => 'Conference type',
+     table       => 'conferencing_type',
+     name_col    => 'typename',
+     @_,
+&>
index d34ed50..65f373c 100644 (file)
@@ -78,9 +78,7 @@ function areyousure(href) {
 %       my $hack_strict_refs = \&{ $f->{'value_callback'} };
 %       $value = &$hack_strict_refs($svc_x);
 %     } else {
 %       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;
 %     }
 %   } else {
 %     $field = $f;