[freeside-commits] branch master updated. 5264cbf1175e3ea73cf9bcf5087c5028e6cf3b1c

Ivan ivan at 420.am
Sat Jan 4 16:24:02 PST 2014


The branch, master has been updated
       via  5264cbf1175e3ea73cf9bcf5087c5028e6cf3b1c (commit)
      from  50e89d97c110d58e0755c69775e0d243a82e352d (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 5264cbf1175e3ea73cf9bcf5087c5028e6cf3b1c
Author: Ivan Kohler <ivan at freeside.biz>
Date:   Sat Jan 4 16:23:54 2014 -0800

    svc_conferencing, RT#24389

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;

-----------------------------------------------------------------------

Summary of changes:
 FS/FS.pm                                           |    6 +
 FS/FS/AccessRight.pm                               |    1 +
 FS/FS/Schema.pm                                    |   55 ++++
 FS/FS/access_right.pm                              |    1 +
 FS/FS/conferencing_quality.pm                      |  113 +++++++++
 FS/FS/conferencing_type.pm                         |  113 +++++++++
 FS/FS/svc_conferencing.pm                          |  260 ++++++++++++++++++++
 FS/MANIFEST                                        |    6 +
 FS/t/conferencing_quality.t                        |    5 +
 FS/t/conferencing_type.t                           |    5 +
 FS/t/svc_conferencing.t                            |    5 +
 httemplate/browse/conferencing_quality.html        |   32 +++
 httemplate/browse/conferencing_type.html           |   32 +++
 httemplate/edit/conferencing_quality.html          |   21 ++
 httemplate/edit/conferencing_type.html             |   21 ++
 httemplate/edit/process/conferencing_quality.html  |   10 +
 httemplate/edit/process/conferencing_type.html     |   10 +
 httemplate/elements/duration.html                  |   74 ++++++
 httemplate/elements/menu.html                      |    7 +
 .../elements/select-conferencing_quality.html      |    7 +
 httemplate/elements/select-conferencing_type.html  |    7 +
 httemplate/elements/tr-duration.html               |   30 +++
 .../elements/tr-select-conferencing_quality.html   |    6 +
 .../elements/tr-select-conferencing_type.html      |    6 +
 httemplate/view/elements/svc_Common.html           |    4 +-
 25 files changed, 834 insertions(+), 3 deletions(-)
 create mode 100644 FS/FS/conferencing_quality.pm
 create mode 100644 FS/FS/conferencing_type.pm
 create mode 100644 FS/FS/svc_conferencing.pm
 create mode 100644 FS/t/conferencing_quality.t
 create mode 100644 FS/t/conferencing_type.t
 create mode 100644 FS/t/svc_conferencing.t
 create mode 100644 httemplate/browse/conferencing_quality.html
 create mode 100644 httemplate/browse/conferencing_type.html
 create mode 100644 httemplate/edit/conferencing_quality.html
 create mode 100644 httemplate/edit/conferencing_type.html
 create mode 100644 httemplate/edit/process/conferencing_quality.html
 create mode 100644 httemplate/edit/process/conferencing_type.html
 create mode 100644 httemplate/elements/duration.html
 create mode 100644 httemplate/elements/select-conferencing_quality.html
 create mode 100644 httemplate/elements/select-conferencing_type.html
 create mode 100644 httemplate/elements/tr-duration.html
 create mode 100644 httemplate/elements/tr-select-conferencing_quality.html
 create mode 100644 httemplate/elements/tr-select-conferencing_type.html




More information about the freeside-commits mailing list