Merge branch 'master' of git.freeside.biz:/home/git/freeside
authorIvan Kohler <ivan@freeside.biz>
Wed, 9 Oct 2013 06:00:26 +0000 (23:00 -0700)
committerIvan Kohler <ivan@freeside.biz>
Wed, 9 Oct 2013 06:00:26 +0000 (23:00 -0700)
Conflicts:
FS/FS/cust_main.pm

55 files changed:
1  2 
FS/FS/Mason.pm
FS/FS/Record.pm
FS/FS/Schema.pm
FS/FS/cable_provider.pm
FS/FS/cust_main.pm
FS/FS/cust_pkg.pm
FS/FS/part_event/Condition/pkg_age_Common.pm
FS/FS/part_export/domain_shellcommands.pm
FS/FS/part_export/shellcommands_withdomain.pm
FS/FS/svc_cable.pm
FS/MANIFEST
FS/t/cable_provider.t
bin/test-event
httemplate/browse/cable_provider.html
httemplate/docs/about.html
httemplate/edit/cable_provider.html
httemplate/edit/elements/edit.html
httemplate/edit/process/cable_provider.html
httemplate/elements/menu.html
httemplate/elements/select-cable_provider.html
httemplate/elements/tr-select-cable_provider.html
httemplate/view/cust_main.cgi
ng_selfservice/.freeside.class.php.swp
ng_selfservice/.index.php.swp
ng_selfservice/.logout.php.swp
ng_selfservice/.main.php.swp
ng_selfservice/.password.php.swp
ng_selfservice/.payment.php.swp
ng_selfservice/.payment_ach.php.swp
ng_selfservice/.payment_cc.php.swp
ng_selfservice/.payment_paypal.php.swp
ng_selfservice/.payment_webpay.php.swp
ng_selfservice/.personal.php.swp
ng_selfservice/.process_login.php.swp
ng_selfservice/.process_ticket_create.php.swp
ng_selfservice/.services.php.swp
ng_selfservice/.services_new.php.swp
ng_selfservice/.ticket.php.swp
ng_selfservice/.ticket_create.php.swp
ng_selfservice/.tickets.php.swp
ng_selfservice/.tickets_resolved.php.swp
ng_selfservice/.usage.php.swp
ng_selfservice/.usage_cdr.php.swp
ng_selfservice/.usage_data.php.swp
ng_selfservice/elements/.card.php.swp
ng_selfservice/elements/.check.php.swp
ng_selfservice/elements/.error.php.swp
ng_selfservice/elements/.header.php.swp
ng_selfservice/elements/.menu.php.swp
ng_selfservice/elements/.menu_footer.php.swp
ng_selfservice/elements/.session.php.swp
ng_selfservice/elements/.ticketlist.php.swp
ng_selfservice/js/.menu.js.swp
rt/lib/RT/Interface/Web.pm
rt/share/html/Ticket/Update.html

diff --combined FS/FS/Mason.pm
@@@ -353,6 -353,8 +353,9 @@@ if ( -e $addl_handler_use_file ) 
    use FS::sales_pkg_class;
    use FS::svc_alarm;
    use FS::cable_model;
+   use FS::invoice_mode;
+   use FS::invoice_conf;
++  use FS::cable_provider;
    # Sammath Naur
  
    if ( $FS::Mason::addl_handler_use ) {
diff --combined FS/FS/Record.pm
@@@ -3038,13 -3038,13 +3038,8 @@@ Checks to see if the string is encrypte
  
  sub is_encrypted {
    my ($self, $value) = @_;
--  # Possible Bug - Some work may be required here....
--
--  if ($value =~ /^M/ && length($value) > 80) {
--    return 1;
--  } else {
--    return 0;
--  }
++  # could be more precise about it, but this will do for now
++  $value =~ /^M/ && length($value) > 80;
  }
  
  =item decrypt($value)
diff --combined FS/FS/Schema.pm
@@@ -4272,6 -4272,6 +4272,8 @@@ sub tables_hashref 
      'svc_cable' => {
        'columns' => [
          'svcnum',        'int',     '',      '', '', '', 
++        'providernum',   'int', 'NULL',      '', '', '',
++        # XXX "Circuit ID/Order number"
          'modelnum',      'int', 'NULL',      '', '', '',
          'serialnum', 'varchar', 'NULL', $char_d, '', '',
          'mac_addr',  'varchar', 'NULL',      12, '', '', 
        'index'  => [],
      },
  
++    'cable_provider' => {
++      'columns' => [
++        'providernum', 'serial',     '',      '', '', '',
++        'provider',   'varchar',     '', $char_d, '', '',
++        'disabled',      'char', 'NULL',       1, '', '', 
++      ],
++      'primary_key' => 'providernum',
++      'unique' => [ [ 'provider' ], ],
++      'index'  => [],
++    },
++
      'vend_main' => {
        'columns' => [
          'vendnum',   'serial',     '',      '', '', '',
        'index'       => [ [ 'derivenum', ], ],
      },
  
+     'invoice_mode' => {
+       'columns' => [
+         'modenum',      'serial', '', '', '', '',
+         'agentnum',        'int', 'NULL', '', '', '',
+         'modename',    'varchar', '', 32, '', '',
+       ],
+       'primary_key' => 'modenum',
+       'unique'      => [ ],
+       'index'       => [ ],
+     },
+     'invoice_conf' => {
+       'columns' => [
+         'confnum',              'serial',   '', '', '', '',
+         'modenum',              'int',      '', '', '', '',
+         'locale',               'varchar',  'NULL', 16, '', '',
+         'notice_name',          'varchar',  'NULL', 64, '', '',
+         'subject',              'varchar',  'NULL', 64, '', '',
+         'htmlnotes',            'text',     'NULL', '', '', '',
+         'htmlfooter',           'text',     'NULL', '', '', '',
+         'htmlsummary',          'text',     'NULL', '', '', '',
+         'htmlreturnaddress',    'text',     'NULL', '', '', '',
+         'latexnotes',           'text',     'NULL', '', '', '',
+         'latexfooter',          'text',     'NULL', '', '', '',
+         'latexsummary',         'text',     'NULL', '', '', '',
+         'latexcoupon',          'text',     'NULL', '', '', '',
+         'latexsmallfooter',     'text',     'NULL', '', '', '',
+         'latexreturnaddress',   'text',     'NULL', '', '', '',
+         'latextopmargin',       'varchar',  'NULL', 16, '', '',
+         'latexheadsep',         'varchar',  'NULL', 16, '', '',
+         'latexaddresssep',      'varchar',  'NULL', 16, '', '',
+         'latextextheight',      'varchar',  'NULL', 16, '', '',
+         'latexextracouponspace','varchar',  'NULL', 16, '', '',
+         'latexcouponfootsep',   'varchar',  'NULL', 16, '', '',
+         'latexcouponamountenclosedsep', 'varchar',  'NULL', 16, '', '',
+         'latexcoupontoaddresssep',      'varchar',  'NULL', 16, '', '',
+         'latexverticalreturnaddress',      'char',  'NULL',  1, '', '',
+         'latexcouponaddcompanytoaddress',  'char',  'NULL',  1, '', '',
+         'logo_png',             'blob',     'NULL', '', '', '',
+         'logo_eps',             'blob',     'NULL', '', '', '',
+         'lpr',                  'varchar',  'NULL', $char_d, '', '',
+       ],
+       'primary_key' => 'confnum',
+       'unique' => [ [ 'modenum', 'locale' ] ],
+       'index'  => [ ],
+     },
  
      # name type nullability length default local
  
diff --combined FS/FS/cable_provider.pm
index 0000000,0000000..e988192
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,112 @@@
++package FS::cable_provider;
++
++use strict;
++use base qw( FS::Record );
++use FS::Record qw( qsearch qsearchs );
++
++=head1 NAME
++
++FS::cable_provider - Object methods for cable_provider records
++
++=head1 SYNOPSIS
++
++  use FS::cable_provider;
++
++  $record = new FS::cable_provider \%hash;
++  $record = new FS::cable_provider { 'column' => 'value' };
++
++  $error = $record->insert;
++
++  $error = $new_record->replace($old_record);
++
++  $error = $record->delete;
++
++  $error = $record->check;
++
++=head1 DESCRIPTION
++
++An FS::cable_provider object represents a cable service provider.
++FS::cable_provider inherits from FS::Record.  The following fields are
++currently supported:
++
++=over 4
++
++=item providernum
++
++primary key
++
++=item provider
++
++provider
++
++=item disabled
++
++disabled
++
++
++=back
++
++=head1 METHODS
++
++=over 4
++
++=item new HASHREF
++
++Creates a new provider.  To add the provider 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
++
++# the new method can be inherited from FS::Record, if a table method is defined
++
++sub table { 'cable_provider'; }
++
++=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 provider.  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('providernum')
++    || $self->ut_text('provider')
++    || $self->ut_enum('disabled', [ '', 'Y' ] )
++  ;
++  return $error if $error;
++
++  $self->SUPER::check;
++}
++
++=back
++
++=head1 BUGS
++
++=head1 SEE ALSO
++
++L<FS::Record>, schema.html from the base documentation.
++
++=cut
++
++1;
++
diff --combined FS/FS/cust_main.pm
@@@ -17,6 -17,7 +17,7 @@@ use vars qw( $DEBUG $me $con
               @encrypted_fields
               $import
               $ignore_expired_card $ignore_banned_card $ignore_illegal_zip
+              $ignore_invalid_card
               $skip_fuzzyfiles
               @paytypes
             );
@@@ -89,6 -90,7 +90,7 @@@ $me = '[FS::cust_main]'
  $import = 0;
  $ignore_expired_card = 0;
  $ignore_banned_card = 0;
+ $ignore_invalid_card = 0;
  
  $skip_fuzzyfiles = 0;
  
@@@ -102,6 -104,7 +104,7 @@@ sub nohistory_fields { ('payinfo', 'pay
  install_callback FS::UID sub { 
    $conf = new FS::Conf;
    #yes, need it for stuff below (prolly should be cached)
+   $ignore_invalid_card = $conf->exists('allow_invalid_cards');
  };
  
  sub _cache {
@@@ -1826,7 -1829,8 +1829,8 @@@ sub check 
  
    # Need some kind of global flag to accept invalid cards, for testing
    # on scrubbed data.
-   if ( !$import && $check_payinfo && $self->payby =~ /^(CARD|DCRD)$/ ) {
+   if ( !$import && !$ignore_invalid_card && $check_payinfo && 
+     $self->payby =~ /^(CARD|DCRD)$/ ) {
  
      my $payinfo = $self->payinfo;
      $payinfo =~ s/\D//g;
        $self->payissue('');
      }
  
-   } elsif ( $check_payinfo && $self->payby =~ /^(CHEK|DCHK)$/ ) {
+   } elsif ( !$ignore_invalid_card && $check_payinfo && 
+     $self->payby =~ /^(CHEK|DCHK)$/ ) {
  
      my $payinfo = $self->payinfo;
      $payinfo =~ s/[^\d\@\.]//g;
@@@ -2092,21 -2097,6 +2097,21 @@@ sub cust_contact 
    qsearch('contact', { 'custnum' => $self->custnum } );
  }
  
 +=item cust_payby
 +
 +Returns all payment methods (see L<FS::cust_payby>) for this customer.
 +
 +=cut
 +
 +sub cust_payby {
 +  my $self = shift;
 +  qsearch({
 +    'table'    => 'cust_payby',
 +    'hashref'  => { 'custnum' => $self->custnum },
 +    'order_by' => 'ORDER BY weight ASC',
 +  });
 +}
 +
  =item unsuspend
  
  Unsuspends all unflagged suspended packages (see L</unflagged_suspended_pkgs>
@@@ -4071,6 -4061,16 +4076,16 @@@ sub ship_contact_firstlast 
  #  code2country($self->country);
  #}
  
+ sub bill_country_full {
+   my $self = shift;
+   code2country($self->bill_location->country);
+ }
+ sub ship_country_full {
+   my $self = shift;
+   code2country($self->ship_location->country);
+ }
  =item county_state_county [ PREFIX ]
  
  Returns a string consisting of just the county, state and country.
@@@ -4910,9 -4910,9 +4925,9 @@@ sub queueable_print 
    my %opt = @_;
  
    my $self = qsearchs('cust_main', { 'custnum' => $opt{custnum} } )
-     or die "invalid customer number: " . $opt{custvnum};
+     or die "invalid customer number: " . $opt{custnum};
  
-   my $error = $self->print( $opt{template} );
+   my $error = $self->print( { 'template' => $opt{template} } );
    die $error if $error;
  }
  
@@@ -5140,12 -5140,13 +5155,12 @@@ sub _upgrade_data { #class metho
        die $error if $error;
  
        $cust_main->setfield($_, '') foreach @payfields;
 -      #$DEBUG = 2;
        $error = $cust_main->replace;
        die $error if $error;
  
      };
  
-     FS::upgrade_journal->set_done('cust_main__trimspaces');
+     FS::upgrade_journal->set_done('cust_main__cust_payby');
    }
  
    $class->_upgrade_otaker(%opts);
diff --combined FS/FS/cust_pkg.pm
@@@ -2613,14 -2613,14 +2613,30 @@@ sub part_pkg_currency_option 
  
  =item cust_svc [ OPTION => VALUE ... ] (current usage)
  
++=item cust_svc_unsorted [ OPTION => VALUE ... ] 
++
  Returns the services for this package, as FS::cust_svc objects (see
  L<FS::cust_svc>).  Available options are svcpart and svcdb.  If either is
  spcififed, returns only the matching services.
  
++As an optimization, use the cust_svc_unsorted version if you are not displaying
++the results.
++
  =cut
  
  sub cust_svc {
    my $self = shift;
++  cluck "cust_pkg->cust_svc called" if $DEBUG > 2;
++  $self->_sort_cust_svc( $self->cust_svc_unsorted_arrayref );
++}
++
++sub cust_svc_unsorted {
++  my $self = shift;
++  @{ $self->cust_svc_unsorted_arrayref };
++}
++
++sub cust_svc_unsorted_arrayref {
++  my $self = shift;
  
    return () unless $self->num_cust_svc(@_);
  
      $search{extra_sql} = ' AND svcdb = '. dbh->quote( $opt{'svcdb'} );
    }
  
--  cluck "cust_pkg->cust_svc called" if $DEBUG > 2;
--
--  #if ( $self->{'_svcnum'} ) {
--  #  values %{ $self->{'_svcnum'}->cache };
--  #} else {
--    $self->_sort_cust_svc( [ qsearch(\%search) ] );
--  #}
++  [ qsearch(\%search) ];
  
  }
  
@@@ -49,7 -49,7 +49,7 @@@ sub condition 
  }
  
  sub pkg_age_age {
--  my( $self, $cust_pkg, %opt );
++  my( $self, $cust_pkg, %opt ) = @_;
    $self->option_age_from('age', $opt{'time'} );
  }
  
@@@ -49,8 -49,8 +49,7 @@@ The following variables are available f
    <LI><code>$uid</code> - of catchall account
    <LI><code>$gid</code> - of catchall account
    <LI><code>$dir</code> - home directory of catchall account
--  <LI>All other fields in
--    <a href="../docs/schema.html#svc_domain">svc_domain</a> are also available.
++  <LI>All other fields in <b>svc_domain</b> are also available.
  </UL>
  END
  );
@@@ -141,7 -141,7 +141,32 @@@ The following variables are available f
    <LI><code>$shell</code>
    <LI><code>$quota</code>
    <LI><code>@radius_groups</code>
--  <LI>All other fields in <a href="../docs/schema.html#svc_acct">svc_acct</a> are also available.
++  <LI><code>$reasonnum (when suspending)</code>
++  <LI><code>$reasontext (when suspending)</code>
++  <LI><code>$reasontypenum (when suspending)</code>
++  <LI><code>$reasontypetext (when suspending)</code>
++  <LI><code>$pkgnum</code>
++  <LI><code>$custnum</code>
++  <LI>All other fields in <b>svc_acct</b> are also available.
++  <LI>The following fields from <b>cust_main</b> are also available (except during replace): company, address1, address2, city, state, zip, county, daytime, night, fax, otaker, agent_custid, locale.  When used on the command line (rather than STDIN), they will be quoted for the shell already (do not add additional quotes).
++</UL>
++For the package changed command only, the following fields are also available:
++<UL>
++  <LI>$old_pkgnum and $new_pkgnum
++  <LI>$old_pkgpart and $new_pkgpart
++  <LI>$old_agent_pkgid and $new_agent_pkgid
++  <LI>$old_order_date and $new_order_date
++  <LI>$old_start_date and $new_start_date
++  <LI>$old_setup and $new_setup
++  <LI>$old_bill and $new_bill
++  <LI>$old_last_bill and $new_last_bill
++  <LI>$old_susp and $new_susp
++  <LI>$old_adjourn and $new_adjourn
++  <LI>$old_resume and $new_resume
++  <LI>$old_cancel and $new_cancel
++  <LI>$old_unancel and $new_unancel
++  <LI>$old_expire and $new_expire
++  <LI>$old_contract_end and $new_contract_end
  </UL>
  END
  );
diff --combined FS/FS/svc_cable.pm
@@@ -4,6 -4,6 +4,7 @@@ use base qw( FS::svc_Common ); #qw( FS:
  use strict;
  use Tie::IxHash;
  use FS::Record qw( qsearchs ); # qw( qsearch qsearchs );
++use FS::cable_provider;
  use FS::cable_model;
  
  =head1 NAME
@@@ -72,24 -72,24 +73,35 @@@ sub search_sql 
  sub table_info {
  
    tie my %fields, 'Tie::IxHash',
--    'svcnum'     => 'Service',
--    'modelnum'   => { label             => 'Model',
--                      type              => 'select-cable_model',
--                      disable_inventory => 1,
--                      disable_select    => 1,
--                      value_callback    => sub {
--                                             my $svc = shift;
--                                             $svc->cable_model->model_name;
--                                           },
--                    },
--    'serialnum'  => 'Serial number',
--    'mac_addr'   => { label          => 'MAC address',
--                      type           => 'input-mac_addr',
--                      value_callback => sub {
--                                          my $svc = shift;
--                                          join(':', $svc->mac_addr =~ /../g);
--                                        },
--                    },
++    'svcnum'      => 'Service',
++    'providernum' => { label             => 'Provider',
++                       type              => 'select-cable_provider',
++                       disable_inventory => 1,
++                       disable_select    => 1,
++                       value_callback    => sub {
++                                              my $svc = shift;
++                                              my $p = $svc->cable_provider;
++                                              $p ? $p->provider : '';
++                                            },
++                     },
++    #XXX "Circuit ID/Order number"
++    'modelnum'    => { label             => 'Model',
++                       type              => 'select-cable_model',
++                       disable_inventory => 1,
++                       disable_select    => 1,
++                       value_callback    => sub {
++                                              my $svc = shift;
++                                              $svc->cable_model->model_name;
++                                            },
++                     },
++    'serialnum'   => 'Serial number',
++    'mac_addr'    => { label          => 'MAC address',
++                       type           => 'input-mac_addr',
++                       value_callback => sub {
++                                           my $svc = shift;
++                                           join(':', $svc->mac_addr =~ /../g);
++                                         },
++                     },
    ;
  
    {
@@@ -130,6 -130,6 +142,7 @@@ sub check 
  
    my $error = 
         $self->ut_numbern('svcnum')
++    || $self->ut_foreign_key('providernum', 'cable_provider', 'providernum')
      || $self->ut_foreign_key('modelnum', 'cable_model', 'modelnum')
      || $self->ut_alpha('serialnum')
      || $self->ut_mac_addr('mac_addr')
    $self->SUPER::check;
  }
  
++=item cable_provider
++
++Returns the cable_provider object for this record.
++
++=cut
++
++sub cable_provider {
++  my $self = shift;
++  qsearchs('cable_provider', { 'providernum'=>$self->providernum } );
++}
++
  =item cable_model
  
  Returns the cable_model object for this record.
diff --combined FS/MANIFEST
@@@ -720,3 -720,7 +720,9 @@@ FS/svc_alarm.p
  t/svc_alarm.t
  FS/cable_model.pm
  t/cable_model.t
+ FS/invoice_mode.pm
+ t/invoice_mode.t
+ FS/invoice_conf.pm
+ t/invoice_conf.t
++FS/cable_provider.pm
++t/cable_provider.t
diff --combined FS/t/cable_provider.t
index 0000000,0000000..c794379
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,5 @@@
++BEGIN { $| = 1; print "1..1\n" }
++END {print "not ok 1\n" unless $loaded;}
++use FS::cable_provider;
++$loaded=1;
++print "ok 1\n";
diff --combined bin/test-event
index d3a9f11,d3a9f11..73c9d31
mode 100644,100644..100755
@@@ -34,7 -34,7 +34,10 @@@ print "\n"
  
  my @conditions = $part_event->part_event_condition;
  foreach my $condition ( @conditions ) {
--  my $sat = $condition->condition( $object, 'cust_event' => $cust_event );
++  my $sat = $condition->condition( $object,
++                                   'cust_event' => $cust_event,
++                                   'time' => time,
++                                 );
  
    my $sql = $condition->condition_sql();
    
index 0000000,0000000..0d34498
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,32 @@@
++<& elements/browse.html,
++     'title'              => 'Cable providers',
++     'html_init'          => $html_init,
++     'name'               => 'providers',
++     'disableable'        => 1,
++     'disabled_statuspos' => 1,
++     'query'              => { 'table'     => 'cable_provider',
++                               'hashref'   => {},
++                               'order_by' => 'ORDER BY provider',
++                             },
++     '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/cable_provider.html"><I>Add a provider</I></A><BR><BR>!;
++
++my $count_query = 'SELECT COUNT(*) FROM cable_provider';
++
++my $link = [ $p.'edit/cable_provider.html?', 'providernum' ];
++
++my $header = [ 'Provider' ];
++my $fields = [ 'provider' ];
++my $links  = [ $link ];
++
++</%init>
@@@ -56,7 -56,7 +56,7 @@@ GNU <b>Affero</b> General Public Licens
  
  % unless ( $agentnum ) {
    <CENTER>
--  <FONT SIZE="-3">"I can't figure out ... if it's an end or the beginning" - R. Hunter</FONT>
++  <FONT SIZE="-3">"" - R. Hunter</FONT>
    </CENTER>
  % }
  
index 0000000,0000000..9a911cc
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,20 @@@
++<& elements/edit.html,
++     'name_singular' => 'Provider',
++     'table'         => 'cable_provider',
++     'fields'        => [
++                          'provider',
++                          { field=>'disabled', type=>'checkbox', value=>'Y', },
++                        ],
++     'labels'        => {
++                          'providernum' => 'Provider',
++                          'provider'    => 'Provider',
++                          'disabled'    => 'Disabled',
++                        },
++     'viewall_dir'   => 'browse',
++&>
++<%init>
++
++die "access denied"
++  unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
++
++</%init>
@@@ -116,9 -116,6 +116,9 @@@ Example
      # display of primary key, no submit button, no html_foot, no footer)
      'embed' => $object, #need to pass the object
  
 +    #don't show the primary key label and value
 +    'no_pkey_display' => 1,
 +
      ###
      # HTML callbacks
      ###
    <INPUT TYPE="hidden" NAME="svcdb" VALUE="<% $table %>">
    <INPUT TYPE="hidden" NAME="<% $pkey %>" VALUE="<% $clone ? '' : $object->$pkey() %>">
  
 -  <FONT SIZE="+1"><B>
 -  <% ( $opt{labels} && exists $opt{labels}->{$pkey} )
 -        ? $opt{labels}->{$pkey}
 -        : $pkey
 -  %>
 -  </B></FONT>
 -  #<% ( !$clone && $object->$pkey() ) || "(NEW)" %>
 +%   unless ( $opt{'no_pkey_display'} ) {
 +
 +      <FONT SIZE="+1"><B>
 +      <% ( $opt{labels} && exists $opt{labels}->{$pkey} )
 +            ? $opt{labels}->{$pkey}
 +            : $pkey
 +      %>
 +      </B></FONT>
 +      #<% ( !$clone && $object->$pkey() ) || "(NEW)" %>
 +
 +%   }
  
  % }
  
  %     qw( width height config ),                           #htmlarea
  %     qw( alt_format ),                                    #select-cust_location
  %     qw( classnum ),                                   # select-inventory_item
+ %     qw( aligned ),                                    # columnstart
  %   ;
  %
  %   #select-table
index 0000000,0000000..ecffaf6
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,10 @@@
++<& elements/process.html,
++     'table'       => 'cable_provider',
++     'viewall_dir' => 'browse',
++&>
++<%init>
++
++die "access denied"
++  unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
++
++</%init>
@@@ -197,6 -197,10 +197,10 @@@ foreach my $svcdb ( FS::part_svc->svc_t
        [ $fsurl. 'search/report_svc_phone_usage.html',
          'Total usage (minutes, and amount billed) for the specified time period, per phone number.',
        ];
+     $report_svc{"${name} by state"} =
+       [ $fsurl. 'search/phone_state.html',
+         'Current or historical phone services broken down by state.',
+       ];
  
    }
  
@@@ -517,6 -521,6 +521,7 @@@ tie my %config_radius, 'Tie::IxHash'
  ;
  
  tie my %config_cable, 'Tie::IxHash',
++  'Cable providers' => [ $fsurl.'browse/cable_provider.html', '' ],
    'Cable modem models' => [ $fsurl.'browse/cable_model.html', '' ],
  ;
  
@@@ -600,6 -604,7 +605,7 @@@ $config_billing{'Billing events'} = [ $
      || $curuser->access_right('Edit global billing events');
  if ( $curuser->access_right('Configuration') ) {
    #$config_billing{'Invoice events'}         = [ $fsurl.'browse/part_bill_event.cgi', 'Deprecated, old-style actions for overdue invoices' ];
+   $config_billing{'Invoice configurations'}      = [ $fsurl.'browse/invoice_conf.html', 'Adjust invoice settings for special-purpose notices' ];
    $config_billing{'Invoice templates'}      = [ $fsurl.'browse/invoice_template.html', 'Edit templates for HTML, plaintext and typeset invoices' ];
    $config_billing{'separator'} = ''; #its a separator!
    $config_billing{'Prepaid cards'}          = [ $fsurl.'search/prepay_credit.html', 'View outstanding cards, generate new cards' ];
index 0000000,0000000..9530b78
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,7 @@@
++<% include( '/elements/select-table.html',
++    'table'            => 'cable_provider',
++    'name_col'         => 'provider',
++    'empty_label'      => 'Select provider',
++    @_,
++   )
++%>
index 0000000,0000000..abb8564
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,12 @@@
++% #if ( scalar(@domains) < 2 ) {
++% #} else {
++  <TR>
++    <TD ALIGN="right"><% $opt{'label'} || 'Provider' %></TD>
++    <TD>
++      <% include( '/elements/select-cable_provider.html', %opt) %>
++    </TD>
++   </TR>
++% #}
++<%init>
++  my %opt = @_;
++</%init>
@@@ -147,7 -147,7 +147,6 @@@ function areyousure(href, message) 
  % if ( $br ) {
    <BR><BR>
  % }
--</%doc>
  
  %my $signupurl = $conf->config('signupurl');
  %if ( $signupurl ) {
diff --combined ng_selfservice/.freeside.class.php.swp
index 5c39524,5c39524..0000000
deleted file mode 100644,100644
Binary files differ
diff --combined ng_selfservice/.index.php.swp
index 50c9cfb,50c9cfb..0000000
deleted file mode 100644,100644
Binary files differ
diff --combined ng_selfservice/.logout.php.swp
index ec27faa,ec27faa..0000000
deleted file mode 100644,100644
Binary files differ
diff --combined ng_selfservice/.main.php.swp
index cc55626,cc55626..0000000
deleted file mode 100644,100644
Binary files differ
diff --combined ng_selfservice/.password.php.swp
index e1e968f,e1e968f..0000000
deleted file mode 100644,100644
Binary files differ
diff --combined ng_selfservice/.payment.php.swp
index 2b705a3,2b705a3..0000000
deleted file mode 100644,100644
Binary files differ
diff --combined ng_selfservice/.payment_ach.php.swp
index 1a87a2d,1a87a2d..0000000
deleted file mode 100644,100644
Binary files differ
diff --combined ng_selfservice/.payment_cc.php.swp
index 369d104,369d104..0000000
deleted file mode 100644,100644
Binary files differ
diff --combined ng_selfservice/.payment_paypal.php.swp
index 3abff2f,3abff2f..0000000
deleted file mode 100644,100644
Binary files differ
diff --combined ng_selfservice/.payment_webpay.php.swp
index 6ef3df9,6ef3df9..0000000
deleted file mode 100644,100644
Binary files differ
diff --combined ng_selfservice/.personal.php.swp
index f5e8c23,f5e8c23..0000000
deleted file mode 100644,100644
Binary files differ
diff --combined ng_selfservice/.process_login.php.swp
index c530f11,c530f11..0000000
deleted file mode 100644,100644
Binary files differ
diff --combined ng_selfservice/.process_ticket_create.php.swp
index c286792,c286792..0000000
deleted file mode 100644,100644
Binary files differ
diff --combined ng_selfservice/.services.php.swp
index e063e40,e063e40..0000000
deleted file mode 100644,100644
Binary files differ
diff --combined ng_selfservice/.services_new.php.swp
index 8d0c657,8d0c657..0000000
deleted file mode 100644,100644
Binary files differ
diff --combined ng_selfservice/.ticket.php.swp
index e9b2503,e9b2503..0000000
deleted file mode 100644,100644
Binary files differ
diff --combined ng_selfservice/.ticket_create.php.swp
index 65b00fe,65b00fe..0000000
deleted file mode 100644,100644
Binary files differ
diff --combined ng_selfservice/.tickets.php.swp
index 7b4d67b,7b4d67b..0000000
deleted file mode 100644,100644
Binary files differ
diff --combined ng_selfservice/.tickets_resolved.php.swp
index 1b3c634,1b3c634..0000000
deleted file mode 100644,100644
Binary files differ
diff --combined ng_selfservice/.usage.php.swp
index 61fd4fa,61fd4fa..0000000
deleted file mode 100644,100644
Binary files differ
diff --combined ng_selfservice/.usage_cdr.php.swp
index 83c270a,83c270a..0000000
deleted file mode 100644,100644
Binary files differ
diff --combined ng_selfservice/.usage_data.php.swp
index e5a9272,e5a9272..0000000
deleted file mode 100644,100644
Binary files differ
diff --combined ng_selfservice/elements/.card.php.swp
index 15d30ce,15d30ce..0000000
deleted file mode 100644,100644
Binary files differ
diff --combined ng_selfservice/elements/.check.php.swp
index fe08303,fe08303..0000000
deleted file mode 100644,100644
Binary files differ
diff --combined ng_selfservice/elements/.error.php.swp
index 1a6eb28,1a6eb28..0000000
deleted file mode 100644,100644
Binary files differ
diff --combined ng_selfservice/elements/.header.php.swp
index 2371770,2371770..0000000
deleted file mode 100644,100644
Binary files differ
diff --combined ng_selfservice/elements/.menu.php.swp
index 0c29ff9,0c29ff9..0000000
deleted file mode 100644,100644
Binary files differ
diff --combined ng_selfservice/elements/.menu_footer.php.swp
index 4bd2b30,4bd2b30..0000000
deleted file mode 100644,100644
Binary files differ
diff --combined ng_selfservice/elements/.session.php.swp
index ddd0137,ddd0137..0000000
deleted file mode 100644,100644
Binary files differ
diff --combined ng_selfservice/elements/.ticketlist.php.swp
index db3d0fe,db3d0fe..0000000
deleted file mode 100644,100644
Binary files differ
diff --combined ng_selfservice/js/.menu.js.swp
index 8df94a9,8df94a9..0000000
deleted file mode 100644,100644
Binary files differ
@@@ -2070,7 -2070,7 +2070,6 @@@ sub _ProcessUpdateMessageRecipients 
      if (grep $_ eq 'Requestor' || $_ eq 'Requestors', @{ $args{ARGSRef}->{'SkipNotification'} || [] }) {
          push @txn_squelch, map $_->address, Email::Address->parse( $message_args->{Requestor} );
          push @txn_squelch, $args{TicketObj}->Requestors->MemberEmailAddresses;
--
      }
  
      push @txn_squelch, @{$args{ARGSRef}{SquelchMailTo}} if $args{ARGSRef}{SquelchMailTo};
      }
  }
  
++sub ProcessAttachments {
++    my %args = (
++        ARGSRef => {},
++        @_
++    );
++
++    my $ARGSRef = $args{ARGSRef} || {};
++    # deal with deleting uploaded attachments
++    foreach my $key ( keys %$ARGSRef ) {
++        if ( $key =~ m/^DeleteAttach-(.+)$/ ) {
++            delete $session{'Attachments'}{$1};
++        }
++        $session{'Attachments'} = { %{ $session{'Attachments'} || {} } };
++    }
++
++    # store the uploaded attachment in session
++    if ( defined $ARGSRef->{'Attach'} && length $ARGSRef->{'Attach'} )
++    {    # attachment?
++        my $attachment = MakeMIMEEntity( AttachmentFieldName => 'Attach' );
++
++        my $file_path = Encode::decode_utf8("$ARGSRef->{'Attach'}");
++        $session{'Attachments'} =
++          { %{ $session{'Attachments'} || {} }, $file_path => $attachment, };
++    }
++
++    # delete temporary storage entry to make WebUI clean
++    unless ( keys %{ $session{'Attachments'} } and $ARGSRef->{'UpdateAttach'} )
++    {
++        delete $session{'Attachments'};
++    }
++}
++
++
  =head2 MakeMIMEEntity PARAMHASH
  
  Takes a paramhash Subject, Body and AttachmentFieldName.
@@@ -2174,37 -2174,37 +2206,6 @@@ sub MakeMIMEEntity 
  
  }
  
--sub ProcessAttachments {
--    my %args = (
--        ARGSRef => {},
--        @_
--    );
--
--    my $ARGSRef = $args{ARGSRef} || {};
--    # deal with deleting uploaded attachments
--    foreach my $key ( keys %$ARGSRef ) {
--        if ( $key =~ m/^DeleteAttach-(.+)$/ ) {
--            delete $session{'Attachments'}{$1};
--        }
--        $session{'Attachments'} = { %{ $session{'Attachments'} || {} } };
--    }
--
--    # store the uploaded attachment in session
--    if ( defined $ARGSRef->{'Attach'} && length $ARGSRef->{'Attach'} )
--    {    # attachment?
--        my $attachment = MakeMIMEEntity( AttachmentFieldName => 'Attach' );
--
--        my $file_path = Encode::decode_utf8("$ARGSRef->{'Attach'}");
--        $session{'Attachments'} =
--          { %{ $session{'Attachments'} || {} }, $file_path => $attachment, };
--    }
--
--    # delete temporary storage entry to make WebUI clean
--    unless ( keys %{ $session{'Attachments'} } and $ARGSRef->{'UpdateAttach'} )
--    {
--        delete $session{'Attachments'};
--    }
--}
  
  
  =head2 ParseDateToISO
@@@ -290,6 -290,6 +290,7 @@@ if ( $ARGS{'SubmitTicket'} ) 
  
      my %squelched = ProcessTransactionSquelching( \%ARGS );
      $ARGS{'SquelchMailTo'} = [keys %squelched] if keys %squelched;
++warn @{ $ARGS{'SquelchMailTo'} } if $ARGS{'SquelchMailTo'};
  
      my $CFs = $TicketObj->TransactionCustomFields;
      my $ValidCFs = $m->comp(
      );
      $checks_failure = 1 unless $status;
  }
++warn @{ $ARGS{'SquelchMailTo'} } if $ARGS{'SquelchMailTo'};
  
  # check email addresses for RT's
  {