diff options
Diffstat (limited to 'fs_selfservice/FS-SelfService')
105 files changed, 9465 insertions, 0 deletions
| diff --git a/fs_selfservice/FS-SelfService/Changes b/fs_selfservice/FS-SelfService/Changes new file mode 100644 index 000000000..b9e26b7dc --- /dev/null +++ b/fs_selfservice/FS-SelfService/Changes @@ -0,0 +1,6 @@ +Revision history for Perl extension FS::SelfService. + +0.01  Tue May 28 16:49:41 2002 +	- original version; created by h2xs 1.21 with options +		-A -X -n FS::SelfService + diff --git a/fs_selfservice/FS-SelfService/MANIFEST b/fs_selfservice/FS-SelfService/MANIFEST new file mode 100644 index 000000000..2e4d3fec4 --- /dev/null +++ b/fs_selfservice/FS-SelfService/MANIFEST @@ -0,0 +1,9 @@ +Changes +Makefile.PL +MANIFEST +SelfService.pm +SelfService/XMLRPC.pm +test.pl +freeside-selfservice-clientd +freeside-selfservice-soap-server +freeside-selfservice-xmlrpc-server diff --git a/fs_selfservice/FS-SelfService/Makefile.PL b/fs_selfservice/FS-SelfService/Makefile.PL new file mode 100644 index 000000000..600c9d5f5 --- /dev/null +++ b/fs_selfservice/FS-SelfService/Makefile.PL @@ -0,0 +1,21 @@ +use ExtUtils::MakeMaker; +# See lib/ExtUtils/MakeMaker.pm for details of how to influence +# the contents of the Makefile that is written. +WriteMakefile( +    'NAME'		=> 'FS::SelfService', +    'VERSION_FROM'	=> 'SelfService.pm', # finds $VERSION +    'EXE_FILES'         => [ 'freeside-selfservice-clientd', +                             'freeside-selfservice-soap-server', +                             'freeside-selfservice-xmlrpc-server', +                           ], +    'INSTALLSCRIPT'     => '/usr/local/sbin', +    'INSTALLSITEBIN'    => '/usr/local/sbin', +    'INSTALLSITESCRIPT' => '/usr/local/sbin', #recent deb users this... +    'PERM_RWX'          => '750', +    'PREREQ_PM'		=> { +                             'Storable' => 2.09, +                           }, # e.g., Module::Name => 1.1 +    ($] >= 5.005 ?    ## Add these new keywords supported since 5.005 +      (ABSTRACT_FROM => 'SelfService.pm', # retrieve abstract from module +       AUTHOR     => 'Ivan Kohler <ivan-freeside-selfservice@420.am>') : ()), +); diff --git a/fs_selfservice/FS-SelfService/SelfService.pm b/fs_selfservice/FS-SelfService/SelfService.pm new file mode 100644 index 000000000..49629d423 --- /dev/null +++ b/fs_selfservice/FS-SelfService/SelfService.pm @@ -0,0 +1,1831 @@ +package FS::SelfService; + +use strict; +use vars qw( $VERSION @ISA @EXPORT_OK $DEBUG +             $skip_uid_check $dir $socket %autoload $tag ); +use Exporter; +use Socket; +use FileHandle; +#use IO::Handle; +use IO::Select; +use Storable 2.09 qw(nstore_fd fd_retrieve); + +$VERSION = '0.03'; + +@ISA = qw( Exporter ); + +$DEBUG = 0; + +$dir = "/usr/local/freeside"; +$socket =  "$dir/selfservice_socket"; +$socket .= '.'.$tag if defined $tag && length($tag); + +#maybe should ask ClientAPI for this list +%autoload = ( +  'passwd'                    => 'passwd/passwd', +  'chfn'                      => 'passwd/passwd', +  'chsh'                      => 'passwd/passwd', +  'login_info'                => 'MyAccount/login_info', +  'login'                     => 'MyAccount/login', +  'logout'                    => 'MyAccount/logout', +  'customer_info'             => 'MyAccount/customer_info', +  'edit_info'                 => 'MyAccount/edit_info',     #add to ss cgi! +  'invoice'                   => 'MyAccount/invoice', +  'invoice_logo'              => 'MyAccount/invoice_logo', +  'list_invoices'             => 'MyAccount/list_invoices', #? +  'cancel'                    => 'MyAccount/cancel',        #add to ss cgi! +  'payment_info'              => 'MyAccount/payment_info', +  'payment_info_renew_info'   => 'MyAccount/payment_info_renew_info', +  'process_payment'           => 'MyAccount/process_payment', +  'process_payment_order_pkg' => 'MyAccount/process_payment_order_pkg', +  'process_payment_change_pkg' => 'MyAccount/process_payment_change_pkg', +  'process_payment_order_renew' => 'MyAccount/process_payment_order_renew', +  'process_prepay'            => 'MyAccount/process_prepay', +  'realtime_collect'          => 'MyAccount/realtime_collect', +  'list_pkgs'                 => 'MyAccount/list_pkgs',     #add to ss (added?) +  'list_svcs'                 => 'MyAccount/list_svcs',     #add to ss (added?) +  'list_svc_usage'            => 'MyAccount/list_svc_usage',    +  'list_cdr_usage'            => 'MyAccount/list_cdr_usage',    +  'list_support_usage'        => 'MyAccount/list_support_usage',    +  'order_pkg'                 => 'MyAccount/order_pkg',     #add to ss cgi! +  'change_pkg'                => 'MyAccount/change_pkg',  +  'order_recharge'            => 'MyAccount/order_recharge', +  'renew_info'                => 'MyAccount/renew_info', +  'order_renew'               => 'MyAccount/order_renew', +  'cancel_pkg'                => 'MyAccount/cancel_pkg',    #add to ss cgi! +  'charge'                    => 'MyAccount/charge',        #? +  'part_svc_info'             => 'MyAccount/part_svc_info', +  'provision_acct'            => 'MyAccount/provision_acct', +  'provision_external'        => 'MyAccount/provision_external', +  'unprovision_svc'           => 'MyAccount/unprovision_svc', +  'myaccount_passwd'          => 'MyAccount/myaccount_passwd', +  'signup_info'               => 'Signup/signup_info', +  'skin_info'                 => 'MyAccount/skin_info', +  'access_info'               => 'MyAccount/access_info', +  'domain_select_hash'        => 'Signup/domain_select_hash',  # expose? +  'new_customer'              => 'Signup/new_customer', +  'capture_payment'           => 'Signup/capture_payment', +  'agent_login'               => 'Agent/agent_login', +  'agent_logout'              => 'Agent/agent_logout', +  'agent_info'                => 'Agent/agent_info', +  'agent_list_customers'      => 'Agent/agent_list_customers', +  'mason_comp'                => 'MasonComponent/mason_comp', +  'call_time'                 => 'PrepaidPhone/call_time', +  'call_time_nanpa'           => 'PrepaidPhone/call_time_nanpa', +  'phonenum_balance'          => 'PrepaidPhone/phonenum_balance', +  'bulk_processrow'           => 'Bulk/processrow', +  'check_username'            => 'Bulk/check_username', +  #sg +  'ping'                      => 'SGNG/ping', +  'decompify_pkgs'            => 'SGNG/decompify_pkgs', +  'previous_payment_info'     => 'SGNG/previous_payment_info', +  'previous_payment_info_renew_info' +                              => 'SGNG/previous_payment_info_renew_info', +  'previous_process_payment'  => 'SGNG/previous_process_payment', +  'previous_process_payment_order_pkg' +                              => 'SGNG/previous_process_payment_order_pkg', +  'previous_process_payment_change_pkg' +                              => 'SGNG/previous_process_payment_change_pkg', +  'previous_process_payment_order_renew' +                              => 'SGNG/previous_process_payment_order_renew', +); +@EXPORT_OK = ( +  keys(%autoload), +  qw( regionselector regionselector_hashref location_form +      expselect popselector domainselector didselector +    ) +); + +$ENV{'PATH'} ='/usr/bin:/usr/ucb:/bin'; +$ENV{'SHELL'} = '/bin/sh'; +$ENV{'IFS'} = " \t\n"; +$ENV{'CDPATH'} = ''; +$ENV{'ENV'} = ''; +$ENV{'BASH_ENV'} = ''; + +#you can add BEGIN { $FS::SelfService::skip_uid_check = 1; }  +#if you grant appropriate permissions to whatever user +my $freeside_uid = scalar(getpwnam('freeside')); +die "not running as the freeside user\n" +  if $> != $freeside_uid && ! $skip_uid_check; + +-e $dir or die "FATAL: $dir doesn't exist!"; +-d $dir or die "FATAL: $dir isn't a directory!"; +-r $dir or die "FATAL: Can't read $dir as freeside user!"; +-x $dir or die "FATAL: $dir not searchable (executable) as freeside user!"; + +foreach my $autoload ( keys %autoload ) { + +  my $eval = +  "sub $autoload { ". ' +                   my $param; +                   if ( ref($_[0]) ) { +                     $param = shift; +                   } else { +                     #warn scalar(@_). ": ". join(" / ", @_); +                     $param = { @_ }; +                   } + +                   $param->{_packet} = \''. $autoload{$autoload}. '\'; + +                   simple_packet($param); +                 }'; + +  eval $eval; +  die $@ if $@; + +} + +sub simple_packet { +  my $packet = shift; +  warn "sending ". $packet->{_packet}. " to server" +    if $DEBUG; +  socket(SOCK, PF_UNIX, SOCK_STREAM, 0) or die "socket: $!"; +  connect(SOCK, sockaddr_un($socket)) or die "connect to $socket: $!"; +  nstore_fd($packet, \*SOCK) or die "can't send packet: $!"; +  SOCK->flush; + +  #shoudl trap: Magic number checking on storable file failed at blib/lib/Storable.pm (autosplit into blib/lib/auto/Storable/fd_retrieve.al) line 337, at /usr/local/share/perl/5.6.1/FS/SelfService.pm line 71 + +  #block until there is a message on socket +#  my $w = new IO::Select; +#  $w->add(\*SOCK); +#  my @wait = $w->can_read; + +  warn "reading message from server" +    if $DEBUG; + +  my $return = fd_retrieve(\*SOCK) or die "error reading result: $!"; +  die $return->{'_error'} if defined $return->{_error} && $return->{_error}; + +  warn "returning message to client" +    if $DEBUG; + +  $return; +} + +=head1 NAME + +FS::SelfService - Freeside self-service API + +=head1 SYNOPSIS + +  # password and shell account changes +  use FS::SelfService qw(passwd chfn chsh); + +  # "my account" functionality +  use FS::SelfService qw( login customer_info invoice cancel payment_info process_payment ); + +  my $rv = login( { 'username' => $username, +                    'domain'   => $domain, +                    'password' => $password, +                  } +                ); + +  if ( $rv->{'error'} ) { +    #handle login error... +  } else { +    #successful login +    my $session_id = $rv->{'session_id'}; +  } + +  my $customer_info = customer_info( { 'session_id' => $session_id } ); + +  #payment_info and process_payment are available in 1.5+ only +  my $payment_info = payment_info( { 'session_id' => $session_id } ); + +  #!!! process_payment example + +  #!!! list_pkgs example + +  #!!! order_pkg example + +  #!!! cancel_pkg example + +  # signup functionality +  use FS::SelfService qw( signup_info new_customer ); + +  my $signup_info = signup_info; + +  $rv = new_customer( { +                        'first'            => $first, +                        'last'             => $last, +                        'company'          => $company, +                        'address1'         => $address1, +                        'address2'         => $address2, +                        'city'             => $city, +                        'state'            => $state, +                        'zip'              => $zip, +                        'country'          => $country, +                        'daytime'          => $daytime, +                        'night'            => $night, +                        'fax'              => $fax, +                        'payby'            => $payby, +                        'payinfo'          => $payinfo, +                        'paycvv'           => $paycvv, +                        'paystart_month'   => $paystart_month +                        'paystart_year'    => $paystart_year, +                        'payissue'         => $payissue, +                        'payip'            => $payip +                        'paydate'          => $paydate, +                        'payname'          => $payname, +                        'invoicing_list'   => $invoicing_list, +                        'referral_custnum' => $referral_custnum, +                        'agentnum'         => $agentnum, +                        'pkgpart'          => $pkgpart, + +                        'username'         => $username, +                        '_password'        => $password, +                        'popnum'           => $popnum, +                        #OR +                        'countrycode'      => 1, +                        'phonenum'         => $phonenum, +                        'pin'              => $pin, +                      } +                    ); +   +  my $error = $rv->{'error'}; +  if ( $error eq '_decline' ) { +    print_decline(); +  } elsif ( $error ) { +    reprint_signup(); +  } else { +    print_success(); +  } + +=head1 DESCRIPTION + +Use this API to implement your own client "self-service" module. + +If you just want to customize the look of the existing "self-service" module, +see XXXX instead. + +=head1 PASSWORD, GECOS, SHELL CHANGING FUNCTIONS + +=over 4 + +=item passwd + +=item chfn + +=item chsh + +=back + +=head1 "MY ACCOUNT" FUNCTIONS + +=over 4 + +=item login HASHREF + +Creates a user session.  Takes a hash reference as parameter with the +following keys: + +=over 4 + +=item username + +Username + +=item domain + +Domain + +=item password + +Password + +=back + +Returns a hash reference with the following keys: + +=over 4 + +=item error + +Empty on success, or an error message on errors. + +=item session_id + +Session identifier for successful logins + +=back + +=item customer_info HASHREF + +Returns general customer information. + +Takes a hash reference as parameter with a single key: B<session_id> + +Returns a hash reference with the following keys: + +=over 4 + +=item name + +Customer name + +=item balance + +Balance owed + +=item open + +Array reference of hash references of open inoices.  Each hash reference has +the following keys: invnum, date, owed + +=item small_custview + +An HTML fragment containing shipping and billing addresses. + +=item The following fields are also returned + +first last company address1 address2 city county state zip country daytime night fax ship_first ship_last ship_company ship_address1 ship_address2 ship_city ship_state ship_zip ship_country ship_daytime ship_night ship_fax payby payinfo payname month year invoicing_list postal_invoicing + +=back + +=item edit_info HASHREF + +Takes a hash reference as parameter with any of the following keys: + +first last company address1 address2 city county state zip country daytime night fax ship_first ship_last ship_company ship_address1 ship_address2 ship_city ship_state ship_zip ship_country ship_daytime ship_night ship_fax payby payinfo paycvv payname month year invoicing_list postal_invoicing + +If a field exists, the customer record is updated with the new value of that +field.  If a field does not exist, that field is not changed on the customer +record. + +Returns a hash reference with a single key, B<error>, empty on success, or an +error message on errors + +=item invoice HASHREF + +Returns an invoice.  Takes a hash reference as parameter with two keys: +session_id and invnum + +Returns a hash reference with the following keys: + +=over 4 + +=item error + +Empty on success, or an error message on errors + +=item invnum + +Invoice number + +=item invoice_text + +Invoice text + +=back + +=item list_invoices HASHREF + +Returns a list of all customer invoices.  Takes a hash references with a single +key, session_id. + +Returns a hash reference with the following keys: + +=over 4 + +=item error + +Empty on success, or an error message on errors + +=item invoices + +Reference to array of hash references with the following keys: + +=over 4 + +=item invnum + +Invoice ID + +=item _date + +Invoice date, in UNIX epoch time + +=back + +=back + +=item cancel HASHREF + +Cancels this customer. + +Takes a hash reference as parameter with a single key: B<session_id> + +Returns a hash reference with a single key, B<error>, which is empty on +success or an error message on errors. + +=item payment_info HASHREF + +Returns information that may be useful in displaying a payment page. + +Takes a hash reference as parameter with a single key: B<session_id>. + +Returns a hash reference with the following keys: + +=over 4 + +=item error + +Empty on success, or an error message on errors + +=item balance + +Balance owed + +=item payname + +Exact name on credit card (CARD/DCRD) + +=item address1 + +Address line one + +=item address2 + +Address line two + +=item city + +City + +=item state + +State + +=item zip + +Zip or postal code + +=item payby + +Customer's current default payment type. + +=item card_type + +For CARD/DCRD payment types, the card type (Visa card, MasterCard, Discover card, American Express card, etc.) + +=item payinfo + +For CARD/DCRD payment types, the card number + +=item month + +For CARD/DCRD payment types, expiration month + +=item year + +For CARD/DCRD payment types, expiration year + +=item cust_main_county + +County/state/country data - array reference of hash references, each of which has the fields of a cust_main_county record (see L<FS::cust_main_county>).  Note these are not FS::cust_main_county objects, but hash references of columns and values. + +=item states + +Array reference of all states in the current default country. + +=item card_types + +Hash reference of card types; keys are card types, values are the exact strings +passed to the process_payment function + +=cut + +#this doesn't actually work yet +# +#=item paybatch +# +#Unique transaction identifier (prevents multiple charges), passed to the +#process_payment function + +=back + +=item process_payment HASHREF + +Processes a payment and possible change of address or payment type.  Takes a +hash reference as parameter with the following keys: + +=over 4 + +=item session_id + +Session identifier + +=item amount + +Amount + +=item save + +If true, address and card information entered will be saved for subsequent +transactions. + +=item auto + +If true, future credit card payments will be done automatically (sets payby to +CARD).  If false, future credit card payments will be done on-demand (sets +payby to DCRD).  This option only has meaning if B<save> is set true.   + +=item payname + +Name on card + +=item address1 + +Address line one + +=item address2 + +Address line two + +=item city + +City + +=item state + +State + +=item zip + +Zip or postal code + +=item country + +Two-letter country code + +=item payinfo + +Card number + +=item month + +Card expiration month + +=item year + +Card expiration year + +=cut + +#this doesn't actually work yet +# +#=item paybatch +# +#Unique transaction identifier, returned from the payment_info function. +#Prevents multiple charges. + +=back + +Returns a hash reference with a single key, B<error>, empty on success, or an +error message on errors. + +=item process_payment_order_pkg + +Combines the B<process_payment> and B<order_pkg> functions in one step.  If the +payment processes sucessfully, the package is ordered.  Takes a hash reference +as parameter with the keys of both methods. + +Returns a hash reference with a single key, B<error>, empty on success, or an +error message on errors. + +=item process_payment_change_pkg + +Combines the B<process_payment> and B<change_pkg> functions in one step.  If the +payment processes sucessfully, the package is ordered.  Takes a hash reference +as parameter with the keys of both methods. + +Returns a hash reference with a single key, B<error>, empty on success, or an +error message on errors. + + +=item process_payment_order_renew + +Combines the B<process_payment> and B<order_renew> functions in one step.  If +the payment processes sucessfully, the renewal is processed.  Takes a hash +reference as parameter with the keys of both methods. + +Returns a hash reference with a single key, B<error>, empty on success, or an +error message on errors. + +=item list_pkgs + +Returns package information for this customer.  For more detail on services, +see L</list_svcs>. + +Takes a hash reference as parameter with a single key: B<session_id> + +Returns a hash reference containing customer package information.  The hash reference contains the following keys: + +=over 4 + +=item custnum + +Customer number + +=item error + +Empty on success, or an error message on errors. + +=item cust_pkg HASHREF + +Array reference of hash references, each of which has the fields of a cust_pkg +record (see L<FS::cust_pkg>) as well as the fields below.  Note these are not +the internal FS:: objects, but hash references of columns and values. + +=over 4 + +=item part_pkg fields + +All fields of part_pkg for this specific cust_pkg (be careful with this +information - it may reveal more about your available packages than you would +like users to know in aggregate)  + +=cut + +#XXX pare part_pkg fields down to a more secure subset + +=item part_svc + +An array of hash references indicating information on unprovisioned services +available for provisioning for this specific cust_pkg.  Each has the following +keys: + +=over 4 + +=item part_svc fields + +All fields of part_svc (be careful with this information - it may reveal more +about your available packages than you would like users to know in aggregate)  + +=cut + +#XXX pare part_svc fields down to a more secure subset + +=back + +=item cust_svc + +An array of hash references indicating information on the customer services +already provisioned for this specific cust_pkg.  Each has the following keys: + +=over 4 + +=item label + +Array reference with three elements: The first element is the name of this service.  The second element is a meaningful user-specific identifier for the service (i.e. username, domain or mail alias).  The last element is the table name of this service. + +=back + +=item svcnum + +Primary key for this service + +=item svcpart + +Service definition (see L<FS::part_svc>) + +=item pkgnum + +Customer package (see L<FS::cust_pkg>) + +=item overlimit + +Blank if the service is not over limit, or the date the service exceeded its usage limit (as a UNIX timestamp). + +=back + +=back + +=item list_svcs + +Returns service information for this customer. + +Takes a hash reference as parameter with a single key: B<session_id> + +Returns a hash reference containing customer package information.  The hash reference contains the following keys: + +=over 4 + +=item custnum + +Customer number + +=item svcs + +An array of hash references indicating information on all of this customer's +services.  Each has the following keys: + +=over 4 + +=item svcnum + +Primary key for this service + +=item label + +Name of this service + +=item value + +Meaningful user-specific identifier for the service (i.e. username, domain, or +mail alias). + +=back + +Account (svc_acct) services also have the following keys: + +=over 4 + +=item username + +Username + +=item email + +username@domain + +=item seconds + +Seconds remaining + +=item upbytes + +Upload bytes remaining + +=item downbytes + +Download bytes remaining + +=item totalbytes + +Total bytes remaining + +=item recharge_amount + +Cost of a recharge + +=item recharge_seconds + +Number of seconds gained by recharge + +=item recharge_upbytes + +Number of upload bytes gained by recharge + +=item recharge_downbytes + +Number of download bytes gained by recharge + +=item recharge_totalbytes + +Number of total bytes gained by recharge + +=back + +=back + +=item order_pkg + +Orders a package for this customer. + +Takes a hash reference as parameter with the following keys: + +=over 4 + +=item session_id + +Session identifier + +=item pkgpart + +Package to order (see L<FS::part_pkg>). + +=item svcpart + +Service to order (see L<FS::part_svc>). + +Normally optional; required only to provision a non-svc_acct service, or if the +package definition does not contain one svc_acct service definition with +quantity 1 (it may contain others with quantity >1).  A svcpart of "none" can +also be specified to indicate that no initial service should be provisioned. + +=back + +Fields used when provisioning an svc_acct service: + +=over 4 + +=item username + +Username + +=item _password + +Password + +=item sec_phrase + +Optional security phrase + +=item popnum + +Optional Access number number + +=back + +Fields used when provisioning an svc_domain service: + +=over 4 + +=item domain + +Domain + +=back + +Fields used when provisioning an svc_phone service: + +=over 4 + +=item phonenum + +Phone number + +=item pin + +Voicemail PIN + +=item sip_password + +SIP password + +=back + +Fields used when provisioning an svc_external service: + +=over 4 + +=item id + +External numeric ID. + +=item title + +External text title. + +=back + +Returns a hash reference with a single key, B<error>, empty on success, or an +error message on errors.  The special error '_decline' is returned for +declined transactions. + +=item change_pkg + +Changes a package for this customer. + +Takes a hash reference as parameter with the following keys: + +=over 4 + +=item session_id + +Session identifier + +=item pkgnum + +Existing customer package. + +=item pkgpart + +New package to order (see L<FS::part_pkg>). + +=back + +Returns a hash reference with a single key, B<error>, empty on success, or an +error message on errors.   + +=item renew_info + +Provides useful info for early renewals. + +Takes a hash reference as parameter with the following keys: + +=over 4 + +=item session_id + +Session identifier + +=back + +Returns a hash reference.  On errors, it contains a single key, B<error>, with +the error message.  Otherwise, contains a single key, B<dates>, pointing to +an array refernce of hash references.  Each hash reference contains the +following keys: + +=over 4 + +=item bill_date + +(Future) Bill date.  Indicates a future date for which billing could be run. +Specified as a integer UNIX timestamp.  Pass this value to the B<order_renew> +function. + +=item bill_date_pretty + +(Future) Bill date as a human-readable string.  (Convenience for display; +subject to change, so best not to parse for the date.) + +=item amount + +Base amount which will be charged if renewed early as of this date. + +=item renew_date + +Renewal date; i.e. even-futher future date at which the customer will be paid +through if the early renewal is completed with the given B<bill-date>. +Specified as a integer UNIX timestamp. + +=item renew_date_pretty + +Renewal date as a human-readable string.  (Convenience for display; +subject to change, so best not to parse for the date.) + +=item pkgnum + +Package that will be renewed. + +=item expire_date + +Expiration date of the package that will be renewed. + +=item expire_date_pretty + +Expiration date of the package that will be renewed, as a human-readable +string.  (Convenience for display; subject to change, so best not to parse for +the date.) + +=back + +=item order_renew + +Renews this customer early; i.e. runs billing for this customer in advance. + +Takes a hash reference as parameter with the following keys: + +=over 4 + +=item session_id + +Session identifier + +=item date + +Integer date as returned by the B<renew_info> function, indicating the advance +date for which to run billing. + +=back + +Returns a hash reference with a single key, B<error>, empty on success, or an +error message on errors. + +=item cancel_pkg + +Cancels a package for this customer. + +Takes a hash reference as parameter with the following keys: + +=over 4 + +=item session_id + +Session identifier + +=item pkgpart + +pkgpart of package to cancel + +=back + +Returns a hash reference with a single key, B<error>, empty on success, or an +error message on errors. + +=back + +=head1 SIGNUP FUNCTIONS + +=over 4 + +=item signup_info HASHREF + +Takes a hash reference as parameter with the following keys: + +=over 4 + +=item session_id - Optional agent/reseller interface session + +=back + +Returns a hash reference containing information that may be useful in +displaying a signup page.  The hash reference contains the following keys: + +=over 4 + +=item cust_main_county + +County/state/country data - array reference of hash references, each of which has the fields of a cust_main_county record (see L<FS::cust_main_county>).  Note these are not FS::cust_main_county objects, but hash references of columns and values. + +=item part_pkg + +Available packages - array reference of hash references, each of which has the fields of a part_pkg record (see L<FS::part_pkg>).  Each hash reference also has an additional 'payby' field containing an array reference of acceptable payment types specific to this package (see below and L<FS::part_pkg/payby>).  Note these are not FS::part_pkg objects, but hash references of columns and values.  Requires the 'signup_server-default_agentnum' configuration value to be set, or +an agentnum specified explicitly via reseller interface session_id in the +options. + +=item agent + +Array reference of hash references, each of which has the fields of an agent record (see L<FS::agent>).  Note these are not FS::agent objects, but hash references of columns and values. + +=item agentnum2part_pkg + +Hash reference; keys are agentnums, values are array references of available packages for that agent, in the same format as the part_pkg arrayref above. + +=item svc_acct_pop + +Access numbers - array reference of hash references, each of which has the fields of an svc_acct_pop record (see L<FS::svc_acct_pop>).  Note these are not FS::svc_acct_pop objects, but hash references of columns and values. + +=item security_phrase + +True if the "security_phrase" feature is enabled + +=item payby + +Array reference of acceptable payment types for signup + +=over 4 + +=item CARD + +credit card - automatic + +=item DCRD + +credit card - on-demand - version 1.5+ only + +=item CHEK + +electronic check - automatic + +=item DCHK + +electronic check - on-demand - version 1.5+ only + +=item LECB + +Phone bill billing + +=item BILL + +billing, not recommended for signups + +=item COMP + +free, definitely not recommended for signups + +=item PREPAY + +special billing type: applies a credit (see FS::prepay_credit) and sets billing type to BILL + +=back + +=item cvv_enabled + +True if CVV features are available (1.5+ or 1.4.2 with CVV schema patch) + +=item msgcat + +Hash reference of message catalog values, to support error message customization.  Currently available keys are: passwords_dont_match, invalid_card, unknown_card_type, and not_a (as in "Not a Discover card").  Values are configured in the web interface under "View/Edit message catalog". + +=item statedefault + +Default state + +=item countrydefault + +Default country + +=back + +=item new_customer HASHREF + +Creates a new customer.  Takes a hash reference as parameter with the +following keys: + +=over 4 + +=item first + +first name (required) + +=item last + +last name (required) + +=item ss + +(not typically collected; mostly used for ACH transactions) + +=item company + +Company name + +=item address1 (required) + +Address line one + +=item address2 + +Address line two + +=item city (required) + +City + +=item county + +County + +=item state (required) + +State + +=item zip (required) + +Zip or postal code + +=item daytime + +Daytime phone number + +=item night + +Evening phone number + +=item fax + +Fax number + +=item payby + +CARD, DCRD, CHEK, DCHK, LECB, BILL, COMP or PREPAY (see L</signup_info> (required) + +=item payinfo + +Card number for CARD/DCRD, account_number@aba_number for CHEK/DCHK, prepaid "pin" for PREPAY, purchase order number for BILL + +=item paycvv + +Credit card CVV2 number (1.5+ or 1.4.2 with CVV schema patch) + +=item paydate + +Expiration date for CARD/DCRD + +=item payname + +Exact name on credit card for CARD/DCRD, bank name for CHEK/DCHK + +=item invoicing_list + +comma-separated list of email addresses for email invoices.  The special value 'POST' is used to designate postal invoicing (it may be specified alone or in addition to email addresses), + +=item referral_custnum + +referring customer number + +=item agentnum + +Agent number + +=item pkgpart + +pkgpart of initial package + +=item username + +Username + +=item _password + +Password + +=item sec_phrase + +Security phrase + +=item popnum + +Access number (index, not the literal number) + +=item countrycode + +Country code (to be provisioned as a service) + +=item phonenum + +Phone number (to be provisioned as a service) + +=item pin + +Voicemail PIN + +=back + +Returns a hash reference with the following keys: + +=over 4 + +=item error + +Empty on success, or an error message on errors.  The special error '_decline' is returned for declined transactions; other error messages should be suitable for display to the user (and are customizable in under Configuration | View/Edit message catalog) + +=back + +=item regionselector HASHREF | LIST + +Takes as input a hashref or list of key/value pairs with the following keys: + +=over 4 + +=item selected_county + +Currently selected county + +=item selected_state + +Currently selected state + +=item selected_country + +Currently selected country + +=item prefix + +Specify a unique prefix string  if you intend to use the HTML output multiple time son one page. + +=item onchange + +Specify a javascript subroutine to call on changes + +=item default_state + +Default state + +=item default_country + +Default country + +=item locales + +An arrayref of hash references specifying regions.  Normally you can just pass the value of the I<cust_main_county> field returned by B<signup_info>. + +=back + +Returns a list consisting of three HTML fragments for county selection, +state selection and country selection, respectively. + +=cut + +#false laziness w/FS::cust_main_county (this is currently the "newest" version) +sub regionselector { +  my $param; +  if ( ref($_[0]) ) { +    $param = shift; +  } else { +    $param = { @_ }; +  } +  $param->{'selected_country'} ||= $param->{'default_country'}; +  $param->{'selected_state'} ||= $param->{'default_state'}; + +  my $prefix = exists($param->{'prefix'}) ? $param->{'prefix'} : ''; + +  my $countyflag = 0; + +  my %cust_main_county; + +#  unless ( @cust_main_county ) { #cache  +    #@cust_main_county = qsearch('cust_main_county', {} ); +    #foreach my $c ( @cust_main_county ) { +    foreach my $c ( @{ $param->{'locales'} } ) { +      #$countyflag=1 if $c->county; +      $countyflag=1 if $c->{county}; +      #push @{$cust_main_county{$c->country}{$c->state}}, $c->county; +      #$cust_main_county{$c->country}{$c->state}{$c->county} = 1; +      $cust_main_county{$c->{country}}{$c->{state}}{$c->{county}} = 1; +    } +#  } +  $countyflag=1 if $param->{selected_county}; + +  my $script_html = <<END; +    <SCRIPT> +    function opt(what,value,text) { +      var optionName = new Option(text, value, false, false); +      var length = what.length; +      what.options[length] = optionName; +    } +    function ${prefix}country_changed(what) { +      country = what.options[what.selectedIndex].text; +      for ( var i = what.form.${prefix}state.length; i >= 0; i-- ) +          what.form.${prefix}state.options[i] = null; +END +      #what.form.${prefix}state.options[0] = new Option('', '', false, true); + +  foreach my $country ( sort keys %cust_main_county ) { +    $script_html .= "\nif ( country == \"$country\" ) {\n"; +    foreach my $state ( sort keys %{$cust_main_county{$country}} ) { +      my $text = $state || '(n/a)'; +      $script_html .= qq!opt(what.form.${prefix}state, "$state", "$text");\n!; +    } +    $script_html .= "}\n"; +  } + +  $script_html .= <<END; +    } +    function ${prefix}state_changed(what) { +END + +  if ( $countyflag ) { +    $script_html .= <<END; +      state = what.options[what.selectedIndex].text; +      country = what.form.${prefix}country.options[what.form.${prefix}country.selectedIndex].text; +      for ( var i = what.form.${prefix}county.length; i >= 0; i-- ) +          what.form.${prefix}county.options[i] = null; +END + +    foreach my $country ( sort keys %cust_main_county ) { +      $script_html .= "\nif ( country == \"$country\" ) {\n"; +      foreach my $state ( sort keys %{$cust_main_county{$country}} ) { +        $script_html .= "\nif ( state == \"$state\" ) {\n"; +          #foreach my $county ( sort @{$cust_main_county{$country}{$state}} ) { +          foreach my $county ( sort keys %{$cust_main_county{$country}{$state}} ) { +            my $text = $county || '(n/a)'; +            $script_html .= +              qq!opt(what.form.${prefix}county, "$county", "$text");\n!; +          } +        $script_html .= "}\n"; +      } +      $script_html .= "}\n"; +    } +  } + +  $script_html .= <<END; +    } +    </SCRIPT> +END + +  my $county_html = $script_html; +  if ( $countyflag ) { +    $county_html .= qq!<SELECT NAME="${prefix}county" onChange="$param->{'onchange'}">!; +    $county_html .= '</SELECT>'; +  } else { +    $county_html .= +      qq!<INPUT TYPE="hidden" NAME="${prefix}county" VALUE="$param->{'selected_county'}">!; +  } + +  my $state_html = qq!<SELECT NAME="${prefix}state" !. +                   qq!onChange="${prefix}state_changed(this); $param->{'onchange'}">!; +  foreach my $state ( sort keys %{ $cust_main_county{$param->{'selected_country'}} } ) { +    my $text = $state || '(n/a)'; +    my $selected = $state eq $param->{'selected_state'} ? 'SELECTED' : ''; +    $state_html .= "\n<OPTION $selected VALUE=$state>$text</OPTION>" +  } +  $state_html .= '</SELECT>'; + +  my $country_html = ''; +  if ( scalar( keys %cust_main_county ) > 1 )  { + +    $country_html = qq(<SELECT NAME="${prefix}country" ). +                    qq(onChange="${prefix}country_changed(this); ). +                                 $param->{'onchange'}. +                               '"'. +                      '>'; +    my $countrydefault = $param->{default_country} || 'US'; +    foreach my $country ( +      sort { ($b eq $countrydefault) <=> ($a eq $countrydefault) or $a cmp $b } +        keys %cust_main_county +    ) { +      my $selected = $country eq $param->{'selected_country'} +                       ? ' SELECTED' +                       : ''; +      $country_html .= "\n<OPTION$selected>$country</OPTION>" +    } +    $country_html .= '</SELECT>'; +  } else { + +    $country_html = qq(<INPUT TYPE="hidden" NAME="${prefix}country" ). +                            ' VALUE="'. (keys %cust_main_county )[0]. '">'; + +  } + +  ($county_html, $state_html, $country_html); + +} + +sub regionselector_hashref { +  my ($county_html, $state_html, $country_html) = regionselector(@_); +  { +    'county_html'  => $county_html, +    'state_html'   => $state_html, +    'country_html' => $country_html, +  }; +} + +=item location_form HASHREF | LIST + +Takes as input a hashref or list of key/value pairs with the following keys: + +=over 4 + +=item session_id + +Current customer session_id + +=item no_asterisks + +Omit red asterisks from required fields. + +=item address1_label + +Label for first address line. + +=back + +Returns an HTML fragment for a location form (address, city, state, zip, +country) + +=cut + +sub location_form { +  my $param; +  if ( ref($_[0]) ) { +    $param = shift; +  } else { +    $param = { @_ }; +  } + +  my $session_id = delete $param->{'session_id'}; + +  my $rv = mason_comp( 'session_id' => $session_id, +                       'comp'       => '/elements/location.html', +                       'args'       => [ %$param ], +                     ); + +  #hmm. +  $rv->{'error'} || $rv->{'output'}; + +} + + +#=item expselect HASHREF | LIST +# +#Takes as input a hashref or list of key/value pairs with the following keys: +# +#=over 4 +# +#=item prefix - Specify a unique prefix string  if you intend to use the HTML output multiple time son one page. +# +#=item date - current date, in yyyy-mm-dd or m-d-yyyy format +# +#=back + +=item expselect PREFIX [ DATE ] + +Takes as input a unique prefix string and the current expiration date, in +yyyy-mm-dd or m-d-yyyy format + +Returns an HTML fragments for expiration date selection. + +=cut + +sub expselect { +  #my $param; +  #if ( ref($_[0]) ) { +  #  $param = shift; +  #} else { +  #  $param = { @_ }; +  #my $prefix = $param->{'prefix'}; +  #my $prefix = exists($param->{'prefix'}) ? $param->{'prefix'} : ''; +  #my $date =   exists($param->{'date'})   ? $param->{'date'}   : ''; +  my $prefix = shift; +  my $date = scalar(@_) ? shift : ''; + +  my( $m, $y ) = ( 0, 0 ); +  if ( $date  =~ /^(\d{4})-(\d{2})-\d{2}$/ ) { #PostgreSQL date format +    ( $m, $y ) = ( $2, $1 ); +  } elsif ( $date =~ /^(\d{1,2})-(\d{1,2}-)?(\d{4}$)/ ) { +    ( $m, $y ) = ( $1, $3 ); +  } +  my $return = qq!<SELECT NAME="$prefix!. qq!_month" SIZE="1">!; +  for ( 1 .. 12 ) { +    $return .= qq!<OPTION VALUE="$_"!; +    $return .= " SELECTED" if $_ == $m; +    $return .= ">$_"; +  } +  $return .= qq!</SELECT>/<SELECT NAME="$prefix!. qq!_year" SIZE="1">!; +  my @t = localtime; +  my $thisYear = $t[5] + 1900; +  for ( ($thisYear > $y && $y > 0 ? $y : $thisYear) .. ($thisYear+10) ) { +    $return .= qq!<OPTION VALUE="$_"!; +    $return .= " SELECTED" if $_ == $y; +    $return .= ">$_"; +  } +  $return .= "</SELECT>"; + +  $return; +} + +=item popselector HASHREF | LIST + +Takes as input a hashref or list of key/value pairs with the following keys: + +=over 4 + +=item popnum + +Access number number + +=item pops + +An arrayref of hash references specifying access numbers.  Normally you can just pass the value of the I<svc_acct_pop> field returned by B<signup_info>. + +=back + +Returns an HTML fragment for access number selection. + +=cut + +#horrible false laziness with FS/FS/svc_acct_pop.pm::popselector +sub popselector { +  my $param; +  if ( ref($_[0]) ) { +    $param = shift; +  } else { +    $param = { @_ }; +  } +  my $popnum = $param->{'popnum'}; +  my $pops = $param->{'pops'}; + +  return '<INPUT TYPE="hidden" NAME="popnum" VALUE="">' unless @$pops; +  return $pops->[0]{city}. ', '. $pops->[0]{state}. +         ' ('. $pops->[0]{ac}. ')/'. $pops->[0]{exch}. '-'. $pops->[0]{loc}. +         '<INPUT TYPE="hidden" NAME="popnum" VALUE="'. $pops->[0]{popnum}. '">' +    if scalar(@$pops) == 1; + +  my %pop = (); +  my %popnum2pop = (); +  foreach (@$pops) { +    push @{ $pop{ $_->{state} }->{ $_->{ac} } }, $_; +    $popnum2pop{$_->{popnum}} = $_; +  } + +  my $text = <<END; +    <SCRIPT> +    function opt(what,href,text) { +      var optionName = new Option(text, href, false, false) +      var length = what.length; +      what.options[length] = optionName; +    } +END + +  my $init_popstate = $param->{'init_popstate'}; +  if ( $init_popstate ) { +    $text .= '<INPUT TYPE="hidden" NAME="init_popstate" VALUE="'. +             $init_popstate. '">'; +  } else { +    $text .= <<END; +      function acstate_changed(what) { +        state = what.options[what.selectedIndex].text; +        what.form.popac.options.length = 0 +        what.form.popac.options[0] = new Option("Area code", "-1", false, true); +END +  }  + +  my @states = $init_popstate ? ( $init_popstate ) : keys %pop; +  foreach my $state ( sort { $a cmp $b } @states ) { +    $text .= "\nif ( state == \"$state\" ) {\n" unless $init_popstate; + +    foreach my $ac ( sort { $a cmp $b } keys %{ $pop{$state} }) { +      $text .= "opt(what.form.popac, \"$ac\", \"$ac\");\n"; +      if ($ac eq $param->{'popac'}) { +        $text .= "what.form.popac.options[what.form.popac.length-1].selected = true;\n"; +      } +    } +    $text .= "}\n" unless $init_popstate; +  } +  $text .= "popac_changed(what.form.popac)}\n"; + +  $text .= <<END; +  function popac_changed(what) { +    ac = what.options[what.selectedIndex].text; +    what.form.popnum.options.length = 0; +    what.form.popnum.options[0] = new Option("City", "-1", false, true); + +END + +  foreach my $state ( @states ) { +    foreach my $popac ( keys %{ $pop{$state} } ) { +      $text .= "\nif ( ac == \"$popac\" ) {\n"; + +      foreach my $pop ( @{$pop{$state}->{$popac}}) { +        my $o_popnum = $pop->{popnum}; +        my $poptext =  $pop->{city}. ', '. $pop->{state}. +                       ' ('. $pop->{ac}. ')/'. $pop->{exch}. '-'. $pop->{loc}; + +        $text .= "opt(what.form.popnum, \"$o_popnum\", \"$poptext\");\n"; +        if ($popnum == $o_popnum) { +          $text .= "what.form.popnum.options[what.form.popnum.length-1].selected = true;\n"; +        } +      } +      $text .= "}\n"; +    } +  } + + +  $text .= "}\n</SCRIPT>\n"; + +  $param->{'acstate'} = '' unless defined($param->{'acstate'}); + +  $text .= +    qq!<TABLE CELLPADDING="0"><TR><TD><SELECT NAME="acstate"! . +    qq!SIZE=1 onChange="acstate_changed(this)"><OPTION VALUE=-1>State!; +  $text .= "<OPTION" . ($_ eq $param->{'acstate'} ? " SELECTED" : "") . +           ">$_" foreach sort { $a cmp $b } @states; +  $text .= '</SELECT>'; #callback? return 3 html pieces?  #'</TD>'; + +  $text .= +    qq!<SELECT NAME="popac" SIZE=1 onChange="popac_changed(this)">!. +    qq!<OPTION>Area code</SELECT></TR><TR VALIGN="top">!; + +  $text .= qq!<TR><TD><SELECT NAME="popnum" SIZE=1 STYLE="width: 20em"><OPTION>City!; + + +  #comment this block to disable initial list polulation +  my @initial_select = (); +  if ( scalar( @$pops ) > 100 ) { +    push @initial_select, $popnum2pop{$popnum} if $popnum2pop{$popnum}; +  } else { +    @initial_select = @$pops; +  } +  foreach my $pop ( sort { $a->{state} cmp $b->{state} } @initial_select ) { +    $text .= qq!<OPTION VALUE="!. $pop->{popnum}. '"'. +             ( ( $popnum && $pop->{popnum} == $popnum ) ? ' SELECTED' : '' ). ">". +             $pop->{city}. ', '. $pop->{state}. +               ' ('. $pop->{ac}. ')/'. $pop->{exch}. '-'. $pop->{loc}; +  } + +  $text .= qq!</SELECT></TD></TR></TABLE>!; + +  $text; + +} + +=item domainselector HASHREF | LIST + +Takes as input a hashref or list of key/value pairs with the following keys: + +=over 4 + +=item pkgnum + +Package number + +=item domsvc + +Service number of the selected item. + +=back + +Returns an HTML fragment for domain selection. + +=cut + +sub domainselector { +  my $param; +  if ( ref($_[0]) ) { +    $param = shift; +  } else { +    $param = { @_ }; +  } +  my $domsvc= $param->{'domsvc'}; +  my $rv =  +      domain_select_hash(map {$_ => $param->{$_}} qw(pkgnum svcpart pkgpart) ); +  my $domains = $rv->{'domains'}; +  $domsvc = $rv->{'domsvc'} unless $domsvc; + +  return '<INPUT TYPE="hidden" NAME="domsvc" VALUE="">' +    unless scalar(keys %$domains); + +  if (scalar(keys %$domains) == 1) { +    my $key; +    foreach(keys %$domains) { +      $key = $_; +    } +    return '<TR><TD ALIGN="right">Domain</TD><TD>'. $domains->{$key}. +           '<INPUT TYPE="hidden" NAME="domsvc" VALUE="'. $key. '"></TD></TR>' +  } + +  my $text .= qq!<TR><TD ALIGN="right">Domain</TD><TD><SELECT NAME="domsvc" SIZE=1 STYLE="width: 20em"><OPTION>(Choose Domain)!; + + +  foreach my $domain ( sort { $domains->{$a} cmp $domains->{$b} } keys %$domains ) { +    $text .= qq!<OPTION VALUE="!. $domain. '"'. +             ( ( $domsvc && $domain == $domsvc ) ? ' SELECTED' : '' ). ">". +             $domains->{$domain}; +  } + +  $text .= qq!</SELECT></TD></TR>!; + +  $text; + +} + +=item didselector HASHREF | LIST + +Takes as input a hashref or list of key/value pairs with the following keys: + +=over 4 + +=item field + +Field name for the returned HTML fragment. + +=item svcpart + +Service definition (see L<FS::part_svc>) + +=back + +Returns an HTML fragment for DID selection. + +=cut + +sub didselector { +  my $param; +  if ( ref($_[0]) ) { +    $param = shift; +  } else { +    $param = { @_ }; +  } + +  my $rv = mason_comp( 'comp'=>'/elements/select-did.html', +                       'args'=>[ %$param ], +                     ); + +  #hmm. +  $rv->{'error'} || $rv->{'output'}; + +} + +=back + +=head1 RESELLER FUNCTIONS + +Note: Resellers can also use the B<signup_info> and B<new_customer> functions +with their active session, and the B<customer_info> and B<order_pkg> functions +with their active session and an additional I<custnum> parameter. + +For the most part, development of the reseller web interface has been +superceded by agent-virtualized access to the backend. + +=over 4 + +=item agent_login + +Agent login + +=item agent_info + +Agent info + +=item agent_list_customers + +List agent's customers. + +=back + +=head1 BUGS + +=head1 SEE ALSO + +L<freeside-selfservice-clientd>, L<freeside-selfservice-server> + +=cut + +1; + diff --git a/fs_selfservice/FS-SelfService/SelfService/FreeRadiusVoip.pm b/fs_selfservice/FS-SelfService/SelfService/FreeRadiusVoip.pm new file mode 100644 index 000000000..0df24f7d7 --- /dev/null +++ b/fs_selfservice/FS-SelfService/SelfService/FreeRadiusVoip.pm @@ -0,0 +1,61 @@ +#Add this to the modules section of radiusd.conf +# perl { +#   #path to this module +#   module=/usr/local/share/perl/5.8.8/FS/SelfService/FreeRadiusVoip.pm +#   func_authorize = authorize; +# } +# +#In the Authorize section  +#Make sure that you have 'files' uncommented. Then add a line containing 'perl' +# after it.  +# +# #N/A# Add a line containing 'perl' to the Accounting section.  +#  +# and on debian systems, add this to /etc/init.d/freeradius, with the +# correct path (http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=416266) +#               LD_PRELOAD=/usr/lib/libperl.so.5.8.8 +#               export LD_PRELOAD + +BEGIN { $FS::SelfService::skip_uid_check = 1; }  + +use strict; +use vars qw(%RAD_REQUEST %RAD_REPLY %RAD_CHECK); +#use Data::Dumper; +use FS::SelfService qw(call_time); + +use constant RLM_MODULE_REJECT=>   0; #immediately reject the request +use constant RLM_MODULE_FAIL=>     1; #module failed, don't reply +use constant RLM_MODULE_OK=>       2; #the module is OK, continue +use constant RLM_MODULE_HANDLED=>  3; #the module handled the request, so stop +use constant RLM_MODULE_INVALID=>  4; #the module considers the request invalid +use constant RLM_MODULE_USERLOCK=> 5; #reject the request (user is locked out) +use constant RLM_MODULE_NOTFOUND=> 6; #user not found +use constant RLM_MODULE_NOOP=>     7; #module succeeded without doing anything +use constant RLM_MODULE_UPDATED=>  8; #OK (pairs modified) +use constant RLM_MODULE_NUMCODES=> 9; #How many return codes there are + +sub authorize { + +  #&log_request_attributes(); + +  my $response = call_time( 'src' => $RAD_REQUEST{'Calling-Station-Id'}, +                            'dst' => $RAD_REQUEST{'Called-Station-Id'},  ); + +  if ( $response->{'error'} ) { +    $RAD_REPLY{'Reply-Message'} = $response->{'error'}; +    return RLM_MODULE_REJECT; +  } else { +    $RAD_REPLY{'Session-Timeout'} = $response->{'seconds'}; +    return RLM_MODULE_OK; +  } + +} + +sub log_request_attributes { +       # This shouldn't be done in production environments! +       # This is only meant for debugging! +       for (keys %RAD_REQUEST) { +               &radiusd::radlog(1, "RAD_REQUEST: $_ = $RAD_REQUEST{$_}"); +       } +} + diff --git a/fs_selfservice/FS-SelfService/SelfService/XMLRPC.pm b/fs_selfservice/FS-SelfService/SelfService/XMLRPC.pm new file mode 100644 index 000000000..4e0d3e909 --- /dev/null +++ b/fs_selfservice/FS-SelfService/SelfService/XMLRPC.pm @@ -0,0 +1,88 @@ +package FS::SelfService::XMLRPC; + +=head1 NAME + +FS::SelfService::XMLRPC - Freeside XMLRPC accessible self-service API + +=head1 SYNOPSIS + +=head1 DESCRIPTION + +Use this API to implement your own client "self-service" module vi XMLRPC. + +Each routine described in L<FS::SelfService> is available vi XMLRPC as the +method FS.SelfService.XMLRPC.B<method>.  All values are passed to the +selfservice-server in a struct of strings.  The return values are in a +struct as strings, arrays, or structs as appropriate for the values +described in L<FS::SelfService>. + +=head1 BUGS + +=head1 SEE ALSO + +L<freeside-selfservice-clientd>, L<freeside-selfservice-server>,L<FS::SelfService> + +=cut + +use strict; +use vars qw($DEBUG $AUTOLOAD); +use FS::SelfService; + +$DEBUG = 0; +$FS::SelfService::DEBUG = $DEBUG; + +sub AUTOLOAD { +  my $call = $AUTOLOAD; +  $call =~ s/^FS::SelfService::XMLRPC:://; +  if (exists($FS::SelfService::autoload{$call})) { +    shift; #discard package name; +    $call = "FS::SelfService::$call"; +    no strict 'refs'; +    &{$call}(@_); +  }else{ +    die "No such procedure: $call"; +  } +} + +package SOAP::Transport::HTTP::Daemon;  # yuck + +use POSIX qw(:sys_wait_h); + +no warnings 'redefine'; + +sub handle { +  my $self = shift->new; + +  local $SIG{CHLD} = 'IGNORE'; + +ACCEPT: +  while (my $c = $self->accept) { +     +    my $kid = 0; +    do { +      $kid = waitpid(-1, WNOHANG); +      warn "found kid $kid"; +    } while $kid > 0; + +    my $pid = fork; +    next ACCEPT if $pid; + +    if ( not defined $pid ) { +      warn "fork() failed: $!"; +      $c = undef; +    } else { +      while (my $r = $c->get_request) { +        $self->request($r); +        $self->SUPER::handle; +        $c->send_response($self->response); +      } +      # replaced ->close, thanks to Sean Meisner <Sean.Meisner@VerizonWireless.com> +      # shutdown() doesn't work on AIX. close() is used in this case. Thanks to Jos Clijmans <jos.clijmans@recyfin.be> +      UNIVERSAL::isa($c, 'shutdown') ? $c->shutdown(2) : $c->close();  +      $c->close; +    } +    exit; +  } +} + +1; diff --git a/fs_selfservice/FS-SelfService/cgi/ach_payment_results.html b/fs_selfservice/FS-SelfService/cgi/ach_payment_results.html new file mode 100644 index 000000000..987b97efb --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/ach_payment_results.html @@ -0,0 +1,11 @@ +<%= $url = "$selfurl?session=$session_id;action="; ''; %> +<%= include('header') %> + +<FONT SIZE=4>Payment results</FONT><BR><BR> +<%= if ( $error ) { +  $OUT .= qq!<FONT SIZE="+1" COLOR="#ff0000">Error processing your payment: $error</FONT>!; +} else { +  $OUT .= 'Your payment was processed successfully.  Thank you.'; +} %> + +<%= include('footer') %> diff --git a/fs_selfservice/FS-SelfService/cgi/agent.cgi b/fs_selfservice/FS-SelfService/cgi/agent.cgi new file mode 100644 index 000000000..6e8de619a --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/agent.cgi @@ -0,0 +1,458 @@ +#!/usr/bin/perl -T +#!/usr/bin/perl -Tw + +#some false laziness w/selfservice.cgi + +use strict; +use vars qw($DEBUG $me $cgi $session_id $form_max $template_dir); +use subs qw(do_template); +use CGI; +use CGI::Carp qw(fatalsToBrowser); +use Business::CreditCard; +use Text::Template; +#use HTML::Entities; +use FS::SelfService qw( agent_login agent_logout agent_info +                        agent_list_customers +                        signup_info new_customer +                        customer_info list_pkgs order_pkg +                        part_svc_info provision_acct provision_external +                        unprovision_svc +                      ); + +$DEBUG = 0; +$me = 'agent.cgi:'; + +$template_dir = '.'; + +$form_max = 255; + +warn "$me starting\n" if $DEBUG; + +warn "$me initializing CGI\n" if $DEBUG; +$cgi = new CGI; + +unless ( defined $cgi->param('session') ) { +  warn "$me no session defined, sending login page\n" if $DEBUG; +  do_template('agent_login',{}); +  exit; +} + +if ( $cgi->param('session') eq 'login' ) { + +  warn "$me processing login\n" if $DEBUG; + +  $cgi->param('username') =~ /^\s*([a-z0-9_\-\.\&]{0,$form_max})\s*$/i +    or die "illegal username"; +  my $username = $1; + +  $cgi->param('password') =~ /^(.{0,$form_max})$/ +    or die "illegal password"; +  my $password = $1; + +  my $rv = agent_login( +    'username' => $username, +    'password' => $password, +  ); +  if ( $rv->{error} ) { +    do_template('agent_login', { +      'error'    => $rv->{error}, +      'username' => $username, +    } ); +    exit; +  } else { +    $cgi->param('session' => $rv->{session_id} ); +    $cgi->param('action'  => 'agent_main' ); +  } +} + +$session_id = $cgi->param('session'); + +warn "$me checking action\n" if $DEBUG; +$cgi->param('action') =~ +   /^(agent_main|signup|process_signup|list_customers|view_customer|agent_provision|provision_svc|process_svc_acct|process_svc_external|delete_svc|agent_order_pkg|process_order_pkg|logout)$/ +  or die "unknown action ". $cgi->param('action'); +my $action = $1; + +warn "$me running $action\n" if $DEBUG; +my $result = eval "&$action();"; +die $@ if $@; + +if ( $result->{error} eq "Can't resume session" ) { #ick +  do_template('agent_login',{}); +  exit; +} + +warn "$me processing template $action\n" if $DEBUG; +do_template($action, { +  'session_id' => $session_id, +  %{$result} +}); +warn "$me done processing template $action\n" if $DEBUG; + +#--  + +sub logout { +  $action = 'agent_logout'; +  agent_logout( 'session_id' => $session_id ); +} + +sub agent_main { agent_info( 'session_id' => $session_id ); } + +sub signup { signup_info( 'session_id' => $session_id ); } + +sub process_signup { + +  my $init_data = signup_info( 'session_id' => $session_id ); +  if ( $init_data->{'error'} ) { +    if ( $init_data->{'error'} eq "Can't resume session" ) { #ick +      do_template('agent_login',{}); +      exit; +    } else { #? +      die $init_data->{'error'}; +    } +  } + +  my $error = ''; + +  #false laziness w/signup.cgi, identical except for agentnum vs session_id +  my $payby = $cgi->param('payby'); +  if ( $payby eq 'CHEK' || $payby eq 'DCHK' ) { +    #$payinfo = join('@', map { $cgi->param( $payby. "_payinfo$_" ) } (1,2) ); +    $cgi->param('payinfo' => $cgi->param($payby. '_payinfo1'). '@'.  +                             $cgi->param($payby. '_payinfo2') +               ); +  } else { +    $cgi->param('payinfo' => $cgi->param( $payby. '_payinfo' ) ); +  } +  $cgi->param('paydate' => $cgi->param( $payby. '_month' ). '-'. +                           $cgi->param( $payby. '_year' ) +             ); +  $cgi->param('payname' => $cgi->param( $payby. '_payname' ) ); +  $cgi->param('paycvv' => defined $cgi->param( $payby. '_paycvv' ) +                            ? $cgi->param( $payby. '_paycvv' ) +                            : '' +             ); + +  if ( $cgi->param('invoicing_list') ) { +    $cgi->param('invoicing_list' => $cgi->param('invoicing_list'). ', POST') +      if $cgi->param('invoicing_list_POST'); +  } else { +    $cgi->param('invoicing_list' => 'POST' ); +  } + +  if ( $cgi->param('_password') ne $cgi->param('_password2') ) { +    $error = $init_data->{msgcat}{passwords_dont_match}; #msgcat +    $cgi->param('_password', ''); +    $cgi->param('_password2', ''); +  } + +  if ( $payby =~ /^(CARD|DCRD)$/ && $cgi->param('CARD_type') ) { +    my $payinfo = $cgi->param('payinfo'); +    $payinfo =~ s/\D//g; + +    $payinfo =~ /^(\d{13,16})$/ +      or $error ||= $init_data->{msgcat}{invalid_card}; #. $self->payinfo; +    $payinfo = $1; +    validate($payinfo) +      or $error ||= $init_data->{msgcat}{invalid_card}; #. $self->payinfo; +    cardtype($payinfo) eq $cgi->param('CARD_type') +      or $error ||= $init_data->{msgcat}{not_a}. $cgi->param('CARD_type'); +  } + +  unless ( $error ) { +    my $rv = new_customer ( { +      'session_id'       => $session_id, +      map { $_ => scalar($cgi->param($_)) } +        qw( last first ss company +            address1 address2 city county state zip country +            daytime night fax + +            ship_last ship_first ship_company +            ship_address1 ship_address2 ship_city ship_county ship_state +              ship_zip ship_country +            ship_daytime ship_night ship_fax + +            payby payinfo paycvv paydate payname invoicing_list +            referral_custnum promo_code reg_code +            pkgpart username sec_phrase _password popnum refnum +          ), +        grep { /^snarf_/ } $cgi->param +    } ); +    $error = $rv->{'error'}; +  } +  #eslaf + +  if ( $error ) {  +    $action = 'signup'; +    my $r = {  +      $cgi->Vars, +      %{$init_data}, +      'error' => $error, +    }; +    #warn join('\n', map "$_ => $r->{$_}", keys %$r )."\n"; +    $r; +  } else { +    $action = 'agent_main'; +    my $agent_info = agent_info( 'session_id' => $session_id ); +    $agent_info->{'message'} = 'Signup successful'; +    $agent_info; +  } + +} + +sub list_customers { + +  my $results =  +    agent_list_customers( 'session_id' => $session_id, +                          map { $_ => $cgi->param($_) } +                            grep defined($cgi->param($_)), +                                 qw(prospect active susp cancel), +                                 'search', +                        ); + +  if ( scalar( @{$results->{'customers'}} ) == 1 ) { +    $action = 'view_customer'; +    customer_info ( +      'agent_session_id' => $session_id, +      'custnum'          => $results->{'customers'}[0]{'custnum'}, +    ); +  } else { +    $results; +  } + +} + +sub view_customer { + +  #my $init_data = signup_info( 'session_id' => $session_id ); +  #if ( $init_data->{'error'} ) { +  #  if ( $init_data->{'error'} eq "Can't resume session" ) { #ick +  #    do_template('agent_login',{}); +  #    exit; +  #  } else { #? +  #    die $init_data->{'error'}; +  #  } +  #} +  # +  #my $customer_info = +  customer_info ( +    'agent_session_id' => $session_id, +    'custnum'          => $cgi->param('custnum'), +  ); +  # +  #return { +  #  ( map { $_ => $init_data->{$_} } +  #        qw( part_pkg security_phrase svc_acct_pop ), +  #  ), +  #  %$customer_info, +  #}; +} + +sub agent_order_pkg { + +  my $init_data = signup_info( 'session_id' => $session_id ); +  if ( $init_data->{'error'} ) { +    if ( $init_data->{'error'} eq "Can't resume session" ) { #ick +      do_template('agent_login',{}); +      exit; +    } else { #? +      die $init_data->{'error'}; +    } +  } + +  my $customer_info = customer_info ( +    'agent_session_id' => $session_id, +    'custnum'          => $cgi->param('custnum'), +  ); + +  return { +    ( map { $_ => $init_data->{$_} } +          qw( part_pkg security_phrase svc_acct_pop ), +    ), +    %$customer_info, +  }; + +} + +sub agent_provision { +  my $result = list_pkgs( +    'agent_session_id' => $session_id, +    'custnum'          => $cgi->param('custnum'), +  ); +  die $result->{'error'} if exists $result->{'error'} && $result->{'error'}; +  $result; +} + +sub provision_svc { + +  my $result = part_svc_info( +    'agent_session_id' => $session_id, +    map { $_ => $cgi->param($_) } qw( pkgnum svcpart custnum ), +  ); +  die $result->{'error'} if exists $result->{'error'} && $result->{'error'}; + +  $result->{'svcdb'} =~ /^svc_(.*)$/ +    #or return { 'error' => 'Unknown svcdb '. $result->{'svcdb'} }; +    or die 'Unknown svcdb '. $result->{'svcdb'}; +  $action .= "_$1"; +  $action = "agent_$action"; + +  $result; +} + +sub process_svc_acct { + +  my $result = provision_acct ( +    'agent_session_id' => $session_id, +    map { $_ => $cgi->param($_) } qw( +      custnum pkgnum svcpart username _password _password2 sec_phrase popnum ) +  ); + +  if ( exists $result->{'error'} && $result->{'error'} ) {  +    #warn "$result $result->{'error'}";  +    $action = 'provision_svc_acct'; +    $action = "agent_$action"; +    return { +      $cgi->Vars, +      %{ part_svc_info( 'agent_session_id' => $session_id, +                        map { $_ => $cgi->param($_) } qw(pkgnum svcpart custnum) +                      ) +      }, +      'error' => $result->{'error'}, +    }; +  } else { +    #warn "$result $result->{'error'}";  +    $action = 'agent_provision'; +    return { +      %{agent_provision()}, +      'message' => $result->{'svc'}. ' setup successfully.', +    }; +  } + +} + +sub process_svc_external { + +  my $result = provision_external ( +    'agent_session_id' => $session_id, +    map { $_ => $cgi->param($_) } qw( custnum pkgnum svcpart ) +  ); + +  #warn "$result $result->{'error'}";  +  $action = 'agent_provision'; +  return { +    %{agent_provision()}, +    'message' => $result->{'error'} +                   ? '<FONT COLOR="#FF0000">'. $result->{'error'}. '</FONT>' +                   : $result->{'svc'}. ' setup successfully'. +                     ': serial number '. +                     sprintf('%010d', $result->{'id'}). '-'. $result->{'title'} +  }; + +} + +sub delete_svc { +  my $result = unprovision_svc( +    'agent_session_id' => $session_id, +    'custnum'          => $cgi->param('custnum'), +    'svcnum'           => $cgi->param('svcnum'), +  ); + +  $action = 'agent_provision'; + +  return { +    %{agent_provision()}, +    'message' => $result->{'error'} +                   ? '<FONT COLOR="#FF0000">'. $result->{'error'}. '</FONT>' +                   : $result->{'svc'}. ' removed.' +  }; + +} + +sub process_order_pkg { + +  my $results = ''; + +  unless ( length($cgi->param('_password')) ) { +    my $init_data = signup_info( 'session_id' => $session_id ); +    #die $init_data->{'error'} if $init_data->{'error'}; +    $results = { 'error' => $init_data->{msgcat}{empty_password} }; +  } +  if ( $cgi->param('_password') ne $cgi->param('_password2') ) { +    my $init_data = signup_info( 'session_id' => $session_id ); +    $results = { 'error' => $init_data->{msgcat}{passwords_dont_match} }; +    $cgi->param('_password', ''); +    $cgi->param('_password2', ''); +  } + +  $results ||= order_pkg ( +    'agent_session_id' => $session_id, +    map { $_ => $cgi->param($_) } +        qw( custnum pkgpart username _password _password2 sec_phrase popnum ) +  ); + +  if ( $results->{'error'} ) { +    $action = 'agent_order_pkg'; +    return { +      $cgi->Vars, +      %{agent_order_pkg()}, +      #'message' => '<FONT COLOR="#FF0000">'. $results->{'error'}. '</FONT>', +      'error' => '<FONT COLOR="#FF0000">'. $results->{'error'}. '</FONT>', +    }; +  } else { +    $action = 'view_customer'; +    #$cgi->delete( grep { $_ ne 'custnum' } $cgi->param ); +    return { +      %{view_customer()}, +      'message' => 'Package order successful.', +    }; +  } + +} + +#-- + +sub do_template { +  my $name = shift; +  my $fill_in = shift; +  #warn join(' / ', map { "$_=>".$fill_in->{$_} } keys %$fill_in). "\n"; + +  $cgi->delete_all(); +  $fill_in->{'selfurl'} = $cgi->self_url; #OLD +  $fill_in->{'self_url'} = $cgi->self_url; +  $fill_in->{'cgi'} = \$cgi; + +  my $template = new Text::Template( TYPE    => 'FILE', +                                     SOURCE  => "$template_dir/$name.html", +                                     DELIMITERS => [ '<%=', '%>' ], +                                     UNTAINT => 1,                    ) +    or die $Text::Template::ERROR; + +  local $^W = 0; +  print $cgi->header( '-expires' => 'now' ), +        $template->fill_in( PACKAGE => 'FS::SelfService::_agentcgi', +                            HASH    => $fill_in +                          ); +} + +package FS::SelfService::_agentcgi; + +use HTML::Entities; +use FS::SelfService qw(regionselector expselect popselector); + +#false laziness w/selfservice.cgi +sub include { +  my $name = shift; +  my $template = new Text::Template( TYPE   => 'FILE', +                                     SOURCE => "$main::template_dir/$name.html", +                                     DELIMITERS => [ '<%=', '%>' ], +                                     UNTAINT => 1,                    +                                   ) +    or die $Text::Template::ERROR; + +  $template->fill_in( PACKAGE => 'FS::SelfService::_agentcgi', +                      #HASH    => $fill_in +                    ); + +} + diff --git a/fs_selfservice/FS-SelfService/cgi/agent_customer_menu.html b/fs_selfservice/FS-SelfService/cgi/agent_customer_menu.html new file mode 100644 index 000000000..603fc0bd2 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/agent_customer_menu.html @@ -0,0 +1,7 @@ +<%= $url = "$selfurl?session=$session_id;custnum=$custnum;action="; ''; %> +<TD VALIGN="top" HEIGHT=384 BGCOLOR="#dddddd"> +<A HREF="<%= $url %>agent_provision">Setup services</A><BR><BR> +<A HREF="<%= $url %>agent_order_pkg">Purchase additional package</A><BR><BR> + +</TD> + diff --git a/fs_selfservice/FS-SelfService/cgi/agent_delete_svc.html b/fs_selfservice/FS-SelfService/cgi/agent_delete_svc.html new file mode 100644 index 000000000..63fa127b2 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/agent_delete_svc.html @@ -0,0 +1,17 @@ +<HTML><HEAD><TITLE>MyAccount</TITLE></HEAD> +<BODY BGCOLOR="#eeeeee"><FONT SIZE=5>MyAccount</FONT><BR><BR> +<%= $url = "$selfurl?session=$session_id;action="; ''; %> +<%= include('myaccount_menu') %> +<TD VALIGN="top"> +<%= $small_custview %> +<BR> +<%= if ( $error ) { + +  $OUT .= qq!<FONT SIZE="+1" COLOR="#ff0000">Error: $error</FONT>!; +} else { +  $OUT .= "<FONT SIZE=4>$svc removed.</FONT>"; +} %> + +</TD></TR></TABLE> + +<%= include('footer') %> diff --git a/fs_selfservice/FS-SelfService/cgi/agent_login.html b/fs_selfservice/FS-SelfService/cgi/agent_login.html new file mode 100644 index 000000000..4b0778ec5 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/agent_login.html @@ -0,0 +1,22 @@ +<HTML><HEAD><TITLE>Reseller Login</TITLE></HEAD> +<BODY BGCOLOR="#e8e8e8"><FONT SIZE=5>Reseller Login</FONT><BR><BR> +<FONT SIZE="+1" COLOR="#ff0000"><%= $error %></FONT> +<FORM ACTION="<%= $self_url %>" METHOD=POST> +<INPUT TYPE="hidden" NAME="session" VALUE="login"> +<TABLE BGCOLOR="#c0c0c0" BORDER=0 CELLSPACING=2 CELLPADDING=0> +<TR> +  <TH ALIGN="right">Username </TH> +  <TD> +    <INPUT TYPE="text" NAME="username" VALUE="<%= $username %>"> +  </TD> +</TR> +<TR> +  <TH ALIGN="right">Password </TH> +  <TD> +    <INPUT TYPE="password" NAME="password"> +  </TD> +</TR> +</TABLE> +<BR><BR><INPUT TYPE="submit" VALUE="Login"> +</FORM></BODY></HTML> + diff --git a/fs_selfservice/FS-SelfService/cgi/agent_logout.html b/fs_selfservice/FS-SelfService/cgi/agent_logout.html new file mode 100644 index 000000000..98094679a --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/agent_logout.html @@ -0,0 +1,5 @@ +<HTML><HEAD><TITLE>Reseller</TITLE></HEAD> +<BODY BGCOLOR="#eeeeee"><FONT SIZE=5>Reseller</FONT><BR><BR> +You have been logged out. +</BODY></HTML> + diff --git a/fs_selfservice/FS-SelfService/cgi/agent_main.html b/fs_selfservice/FS-SelfService/cgi/agent_main.html new file mode 100644 index 000000000..3aefd61b1 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/agent_main.html @@ -0,0 +1,33 @@ +<HTML><HEAD><TITLE>Reseller</TITLE></HEAD> +<BODY BGCOLOR="#eeeeee"><FONT SIZE=5>Reseller</FONT><BR><BR> +<%= $url = "$selfurl?session=$session_id;action="; ''; %> +<TABLE BORDER=0 CELLPADDING=4><TR> +<%= include('agent_menu') %> +<TD VALIGN="top"> + +<%= $message +      ? "<FONT SIZE=\"+2\"><B>$message</B></FONT>" +      : "Hello $agent!" +%><BR><BR> + +<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=2 BGCOLOR="#eeeeee"> +<TR><TH BGCOLOR="#cccccc">Customer summary</TH></TR> +<TR><TD BGCOLOR="#dddddd"> + +  <B><%= $num_prospect %></B> +  <%= $num_prospect ? qq!<A HREF="${url}list_customers;prospect=1">! : '' %>prospects</A> + +  <BR><FONT COLOR="#00CC00"><B><%= $num_active %></B></FONT> +  <%= $num_active ? qq!<A HREF="${url}list_customers;active=1">! : '' %>active</A> + +  <BR><FONT COLOR="#FF9900"><B><%= $num_susp %></B></FONT> +  <%= $num_susp ? qq!<A HREF="${url}list_customers;susp=1">! : '' %>suspended</A> + +  <BR><FONT COLOR="#FF0000"><B><%= $num_cancel %></B></FONT> +  <%= $num_cancel ? qq!<A HREF="${url}list_customers;cancel=1">! : '' %>cancelled</A> + +</TD></TR></TABLE> + +</TD></TR></TABLE> + +<%= include('footer') %> diff --git a/fs_selfservice/FS-SelfService/cgi/agent_menu.html b/fs_selfservice/FS-SelfService/cgi/agent_menu.html new file mode 100644 index 000000000..84a295304 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/agent_menu.html @@ -0,0 +1,15 @@ +<%= $url = "$selfurl?session=$session_id;action="; ''; %> +<TD VALIGN="top" HEIGHT=384 BGCOLOR="#dddddd"> + +<A HREF="<%= $url %>agent_main">Overview</A><BR><BR> +<A HREF="<%= $url %>signup">New customer<!--/prospect--></A><BR><BR> +<FORM ACTION="<%= $selfurl %>"> +<INPUT TYPE="hidden" NAME="session" VALUE="<%= $session_id %>"> +<INPUT TYPE="hidden" NAME="action" VALUE="list_customers"> +<INPUT TYPE="text" NAME="search" SIZE=20><BR> +<SMALL><I>cust #, last name, or company</I></SMALL><BR> +<INPUT TYPE="submit" VALUE="Search customers"><BR> +</FORM> +<A HREF="<%= $url %>logout">Logout</A><BR><BR> + +</TD> diff --git a/fs_selfservice/FS-SelfService/cgi/agent_order_pkg.html b/fs_selfservice/FS-SelfService/cgi/agent_order_pkg.html new file mode 100644 index 000000000..18a37e891 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/agent_order_pkg.html @@ -0,0 +1,18 @@ +<HTML><HEAD><TITLE>Reseller</TITLE></HEAD> +<BODY BGCOLOR="#eeeeee"><FONT SIZE=5>Reseller</FONT><BR><BR> +<%= $url = "$selfurl?session=$session_id;custnum=$custnum;action="; ''; %> +<TABLE BORDER=0 CELLPADDING=4><TR> +<%= include('agent_menu') %> +<TD VALIGN="top"> +<%= $small_custview %> +<BR> + +<TABLE BORDER=0 CELLPADDING=4><TR> +<%= include('agent_customer_menu') %> +<TD VALIGN="top"> +<%= include('order_pkg') %> +</TD></TR></TABLE> + +</TD></TR></TABLE> + +<%= include('footer') %> diff --git a/fs_selfservice/FS-SelfService/cgi/agent_provision.html b/fs_selfservice/FS-SelfService/cgi/agent_provision.html new file mode 100644 index 000000000..f7f39b513 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/agent_provision.html @@ -0,0 +1,23 @@ +<HTML><HEAD><TITLE>Reseller</TITLE></HEAD> +<BODY BGCOLOR="#eeeeee"><FONT SIZE=5>Reseller</FONT><BR><BR> +<%= $url = "$selfurl?session=$session_id;custnum=$custnum;action="; ''; %> +<TABLE BORDER=0 CELLPADDING=4><TR> +<%= include('agent_menu') %> +<TD VALIGN="top"> + +<%= $message +      ? "<FONT SIZE=\"+2\"><B>$message</B></FONT><BR><BR>" +      : '' +%> + +<%= $small_custview %> +<BR> + +<TABLE BORDER=0 CELLPADDING=4><TR> +<%= include('agent_customer_menu') %> +<TD VALIGN="top"> +<%= include('provision_list') %> +</TD></TR></TABLE> + +</TD></TR></TABLE> +<%= include('footer') %> diff --git a/fs_selfservice/FS-SelfService/cgi/agent_provision_svc_acct.html b/fs_selfservice/FS-SelfService/cgi/agent_provision_svc_acct.html new file mode 100644 index 000000000..a867edb08 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/agent_provision_svc_acct.html @@ -0,0 +1,16 @@ +<HTML><HEAD><TITLE>Reseller</TITLE></HEAD> +<BODY BGCOLOR="#eeeeee"><FONT SIZE=5>Reseller</FONT><BR><BR> +<%= $url = "$selfurl?session=$session_id;custnum=$custnum;action="; ''; %> +<TABLE BORDER=0 CELLPADDING=4><TR> +<%= include('agent_menu') %> +<TD VALIGN="top"> +<%= $small_custview %> +<BR> +<TABLE BORDER=0 CELLPADDING=4><TR> +<%= include('agent_customer_menu') %> +<TD VALIGN="top"> +<%= include('svc_acct') %> +</TD></TR></TABLE> + +</TD></TR></TABLE> +<%= include('footer') %> diff --git a/fs_selfservice/FS-SelfService/cgi/bill.html b/fs_selfservice/FS-SelfService/cgi/bill.html new file mode 100644 index 000000000..a3884e0f2 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/bill.html @@ -0,0 +1,15 @@ +<TR> +  <TD ALIGN="right">P.O. number</TD> +  <TD><INPUT TYPE="text" NAME="payinfo" SIZE=10 MAXLENGTH=20 VALUE="<%=$payinfo%>"></TD> +</TR><TR> +  <TD ALIGN="right">Attention</TD> +  <TD><INPUT TYPE="text" SIZE=32 MAXLENGTH=80 NAME="payname" VALUE="<%=$payname%>"></TD> +</TR><TR> +  <TD ALIGN="right">Postal mail invoice</TD> +  <TD><INPUT TYPE="checkbox" NAME="postal_invoicing" VALUE="POST" <%= +    $postal_invoicing ? 'CHECKED' : '' +    %>></TD> +</TR><TR> +  <TD>Email address(es)</TD> +  <TD><INPUT TYPE="text" NAME="invoicing_list" VALUE="<%= join(',', $invoicing_list ) %>"></TD> +</TR> diff --git a/fs_selfservice/FS-SelfService/cgi/card.html b/fs_selfservice/FS-SelfService/cgi/card.html new file mode 100644 index 000000000..c7db2b398 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/card.html @@ -0,0 +1,47 @@ +<TR> +  <TH ALIGN="right">Card number</TH> +  <TD COLSPAN=6> +    <TABLE> +      <TR> +        <TD> +          <INPUT TYPE="text" NAME="payinfo" SIZE=20 MAXLENGTH=19 VALUE="<%=$payinfo%>"> </TD> +        <TH>Exp.</TH> +        <TD> +          <SELECT NAME="month"> +            <%= for ( ( map "0$_", 1 .. 9 ), 10 .. 12 ) { +                  $OUT .= '<OPTION'. ($_ == $month ? ' SELECTED' : ''). ">$_\n"; +            } %> +          </SELECT> +        </TD> +        <TD> / </TD> +        <TD> +          <SELECT NAME="year"> +            <%= my @a = localtime; for ( $a[5]+1900 .. $a[5]+1915 ) { +                  $OUT .= '<OPTION'. ($_ == $year ? ' SELECTED' : ''). ">$_\n"; +            } %> +          </SELECT> +        </TD> +      </TR> +    </TABLE> +  </TD> +</TR> +<%=  +  if ( $withcvv ) { +    $OUT .= qq!<TR>!; +    $OUT .= qq!<TD ALIGN="right">CVV2 (<A HREF="javascript:myopen('cvv2.html','cvv2','toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=yes,copyhistory=no,width=480,height=288')">help</A>)</TD>!; +    $OUT .= qq!<TD><INPUT TYPE="text" NAME="paycvv" VALUE="" SIZE=4 MAXLENGTH=4></TD>!; +    $OUT .= qq!</TR>!; +  } +  ''; +%> +<TR> +  <TH ALIGN="right">Exact name on card</TH> +  <TD COLSPAN=6><INPUT TYPE="text" SIZE=32 MAXLENGTH=80 NAME="payname" VALUE="<%=$payname%>"></TD> +</TR> + +<%= location_form( 'session_id'     => $session_id, +                   'no_asterisks'   => 1, +                   #'address1_label' => 'Card billing address', +                   'address1_label' => 'Card billing address', +                 ) +%> diff --git a/fs_selfservice/FS-SelfService/cgi/change_bill.html b/fs_selfservice/FS-SelfService/cgi/change_bill.html new file mode 100755 index 000000000..c0977d946 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/change_bill.html @@ -0,0 +1,20 @@ +<%= $url = "$selfurl?session=$session_id;action="; ''; %> +<%= include('header') %> + +<FONT SIZE=4>Edit billing address</FONT><BR><BR> +<%= if ( $error ) {  +  $OUT .= qq!<FONT SIZE="+1" COLOR="#ff0000">Error: $error</FONT><BR><BR>!; +}  ''; %> + +<FORM NAME="ChangeBillForm" ACTION="<%= $selfurl %>" METHOD=POST onSubmit="document.bottomform.submit.disabled=true;"> +<INPUT TYPE="hidden" NAME="session" VALUE="<%= $session_id %>"> +<INPUT TYPE="hidden" NAME="action" VALUE="process_change_bill"> +<TABLE BGCOLOR="#cccccc" BORDER=0 CELLSPACING=0> + +<%= $r=qq!<font color="#ff0000">*</font> !; include('contact') %> + +<INPUT TYPE="submit" NAME="submit" VALUE="<%= $custnum ?  "Apply Changes" : "Add Customer" %>"> +<BR> +</FORM> + +<%= include('footer') %> diff --git a/fs_selfservice/FS-SelfService/cgi/change_password.html b/fs_selfservice/FS-SelfService/cgi/change_password.html new file mode 100644 index 000000000..9b91d2cad --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/change_password.html @@ -0,0 +1,48 @@ +<%= $url = "$selfurl?session=$session_id;action="; ''; %> +<%= include('header') %> + +<FONT SIZE=4>Change password</FONT><BR><BR> + +<%= if ( $error ) { +  $OUT .= qq!<FONT SIZE="+1" COLOR="#ff0000">$error</FONT><BR><BR>!; +} ''; %> + +<FORM ACTION="<%= $selfurl %>" METHOD="POST"> +<INPUT TYPE="hidden" NAME="session" VALUE="<%= $session_id %>"> +<INPUT TYPE="hidden" NAME="action" VALUE="process_change_password"> + +<TABLE BGCOLOR="#cccccc"> + +  <TR> +    <TH ALIGN="right">Change password for account: </TH> +    <TD> +      <SELECT NAME="svcnum"> +        <%= foreach my $svc ( @svcs ) { +              $OUT .= '<OPTION VALUE="'. $svc->{'svcnum'}. '"'. +                        ( $svc->{'svcnum'} eq $svcnum ? ' SELECTED' : '' ). '>'. +                      $svc->{'label'}. ': '. $svc->{'value'}. "\n"; +            } +        %> +      </SELECT> +    </TD> +  </TR> + +  <TR> +    <TH ALIGN="right">New password: </TH> +    <TD><INPUT TYPE="password" NAME="new_password" SIZE="18"></TD> +  </TR> + +  <TR> +    <TH ALIGN="right">Re-enter new password: </TH> +    <TD><INPUT TYPE="password" NAME="new_password2" SIZE="18"></TD> +  </TR> + +</TABLE> +<BR> + +<INPUT TYPE="submit" VALUE="Change password"> + +</FORM> + + +<%= include('footer') %> diff --git a/fs_selfservice/FS-SelfService/cgi/change_pay.html b/fs_selfservice/FS-SelfService/cgi/change_pay.html new file mode 100644 index 000000000..bbe452786 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/change_pay.html @@ -0,0 +1,70 @@ +<%= $url = "$selfurl?session=$session_id;action="; ''; %> +<%= include('header') %> + +<FONT SIZE=4>Change payment information</FONT><BR><BR> +<%= if ( $error ) {  +  $OUT .= qq!<FONT SIZE="+1" COLOR="#ff0000">Error: $error</FONT><BR><BR>!; +  }  ''; %> + +<FORM NAME="OneTrueForm" METHOD="POST" ACTION="<%=$selfurl%>" onSubmit="document.OneTrueForm.process.disabled=true"> +<%= +  use Tie::IxHash; +  use HTML::Widgets::SelectLayers; + +  my $preauto = '<TR><TD COLSPAN=3><INPUT TYPE="checkbox" NAME="auto" VALUE="1"'; +  my $postauto = '>Charge future payments to this card automatically</TD></TR>'; + +  my $tail = qq(</TABLE><INPUT TYPE="hidden" NAME="session" VALUE="$session_id">).  +             qq(<INPUT TYPE="hidden" NAME="action" VALUE="process_change_pay">). +             qq(<BR>). +             qq(<INPUT TYPE="submit" NAME="process" ). +             qq(VALUE="Save payment information"> ). +             qq(<!-- onClick="this.disabled=true"> -->); + + +  my %paybychecked = ( +    'BILL' => include('bill'), +    'CARD' => include('card')."$preauto CHECKED $postauto", +    'DCRD' => include('card')."$preauto $postauto", +    'CHEK' => include('check')."$preauto CHECKED $postauto", +    'DCHK' => include('check')."$preauto $postauto", +  ); +  my %payby_index = ( 'CARD'   => qq/Credit Card/, +                      'DCRD'   => qq/Credit Card/, +                      'CHEK'   => qq/Check/, +                      'DCHK'   => qq/Check/, +                      'LECB'   => qq/Phone Bill Billing/, +                      'BILL'   => qq/Billing/, +                      'COMP'   => qq/Complimentary/, +                      'PREP'   => qq/Prepaid Card/, +                      'PREPAY' => qq/Prepaid Card/, +                    ); +  tie my %options, 'Tie::IxHash', (); +  foreach my $payby_option ( grep { exists( $payby_index{$_} ) } @paybys ) { +    $options{$payby_option} = $payby_index{$payby_option}; +  } +  $options{$payby} = $payby_index{$payby} +    unless exists($options{$payby}); + +  #don't want to show multiple "Credit card" or "Check" options +  my %paybyremove = ( +    'CARD' => 'DCRD', +    'DCRD' => 'CARD', +    'CHEK' => 'DCHK', +    'DCHK' => 'CHEK', +  ); +  delete( $options{ $paybyremove{$payby} } ); +  delete $options{'DCRD'} unless $payby eq 'DCRD' || ! exists $options{'CARD'}; +  delete $options{'DCHK'} unless $payby eq 'DCHK' || ! exists $options{'CHEK'}; + +  HTML::Widgets::SelectLayers->new( +    options => \%options, +    selected_layer => $payby, +#    form_name => 'dummy', +#    form_action => 'dummy.cgi', +    layer_callback => sub { my $layer = shift; return '<TABLE BGCOLOR="#cccccc">'.$paybychecked{$layer}.qq!<INPUT TYPE="hidden" NAME="payby" VALUE="$layer">$tail!; }, +  )->html; + +%> + +<%= include('footer') %> diff --git a/fs_selfservice/FS-SelfService/cgi/change_pkg.html b/fs_selfservice/FS-SelfService/cgi/change_pkg.html new file mode 100644 index 000000000..a841308a5 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/change_pkg.html @@ -0,0 +1,37 @@ +<SCRIPT TYPE="text/javascript"> +function enable_change_pkg () { +  if ( document.ChangePkgForm.pkgpart.selectedIndex > 0 ) { +    document.ChangePkgForm.submit.disabled = false; +  } else { +    document.ChangePkgForm.submit.disabled = true; +  } +} +</SCRIPT> +<FONT SIZE=4>Purchase replacement package for "<%= $pkg; %>"</FONT><BR><BR> +<%= if ( $error ) { +  $OUT .= qq!<FONT SIZE="+1" COLOR="#ff0000">$error</FONT><BR><BR>!; +} ''; %> +<FORM NAME="ChangePkgForm" ACTION="<%= $selfurl %>" METHOD=POST> +<INPUT TYPE="hidden" NAME="session" VALUE="<%= $session_id %>"> +<INPUT TYPE="hidden" NAME="action" VALUE="process_change_pkg"> +<INPUT TYPE="hidden" NAME="pkgnum" VALUE="<%= $pkgnum %>"> +<INPUT TYPE="hidden" NAME="pkg" VALUE="<%= $pkg %>"> +<TABLE BGCOLOR="#cccccc" BORDER=0 CELLSPACING=0> +<TR> +  <TD COLSPAN=2><SELECT NAME="pkgpart" onChange="enable_change_pkg()"> +  <OPTION VALUE=""> + +  <%= +    foreach my $part_pkg ( @part_pkg ) { +      $OUT .= '<OPTION VALUE="'. $part_pkg->{'pkgpart'}. '"'; +      $OUT .= ' SELECTED' if $pkgpart && $part_pkg->{'pkgpart'} == $pkgpart; +      $OUT .= '>'. $part_pkg->{'pkg'}; +    } +  %> + +  </SELECT></TD> +</TR> +</TABLE> +<INPUT NAME="submit" TYPE="submit" VALUE="Purchase" disabled> +</FORM> + diff --git a/fs_selfservice/FS-SelfService/cgi/change_ship.html b/fs_selfservice/FS-SelfService/cgi/change_ship.html new file mode 100755 index 000000000..f03aeb5be --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/change_ship.html @@ -0,0 +1,99 @@ +<%= $url = "$selfurl?session=$session_id;action="; ''; %> +<%= include('header') %> + +<FONT SIZE=4>Edit service address</FONT><BR><BR> +<%= if ( $error ) {  +  $OUT .= qq!<FONT SIZE="+1" COLOR="#ff0000">Error: $error</FONT><BR><BR>!; +}  ''; %> + +<FORM NAME="OneTrueForm" ACTION="<%= $selfurl %>" METHOD=POST onSubmit="document.bottomform.submit.disabled=true;"> +<INPUT TYPE="hidden" NAME="session" VALUE="<%= $session_id %>"> +<INPUT TYPE="hidden" NAME="action" VALUE="process_change_ship"> +<TABLE BGCOLOR="#cccccc" BORDER=0 CELLSPACING=0> + +<%= +  foreach ( +    qw( last first company address1 address2 city county state zip country +        daytime night fax ) +  ) { +    $OUT .= qq!<INPUT TYPE="hidden" NAME="$_" VALUE="${$_}">!; +  }; +  ''; +%> +<SCRIPT> +function bill_changed(what) { +  if ( what.form.same.checked ) { +<%= +  for (qw( last first company address1 address2 city zip daytime night fax )) {  +    $OUT .= "what.form.ship_$_.value = what.form.$_.value;"; +  }  +  ''; +%> +    what.form.ship_country.selectedIndex = what.form.country.selectedIndex; + +    function fix_ship_county() { +      what.form.ship_county.selectedIndex = what.form.county.selectedIndex; +    } + +    function fix_ship_state() { +      what.form.ship_state.selectedIndex = what.form.state.selectedIndex; +      ship_state_changed(what.form.ship_state, fix_ship_county ); +    } + +    ship_country_changed(what.form.ship_country, fix_ship_state ); + +  } +} +function samechanged(what) { +  if ( what.checked ) { +    bill_changed(what); + +<%= +  for (qw( last first company address1 address2 city county state zip country daytime night fax )) {  +    $OUT .= "what.form.ship_$_.disabled = true;"; +    $OUT .= "what.form.ship_$_.style.backgroundColor = '#dddddd';"; +  }  +  if ( $require_address2 ) { +    $OUT .= "document.getElementById('ship_address2_required').style.visibility = 'hidden';"; +    $OUT .= "document.getElementById('ship_address2_label').style.visibility = 'hidden';"; +  } +%>  + +  } else { + +<%= +  for (qw( last first company address1 address2 city county state zip country daytime night fax )) {  +    $OUT .= "what.form.ship_$_.disabled = false;"; +    $OUT .= "what.form.ship_$_.style.backgroundColor = '#ffffff';"; +  }  +  if ( $require_address2 ) { +    $OUT .= "document.getElementById('ship_address2_required').style.visibility = '';"; +    $OUT .= "document.getElementById('ship_address2_label').style.visibility = '';"; +  } +%> +  } +} +</SCRIPT> +(<INPUT TYPE="checkbox" NAME="same" VALUE="Y" onClick="samechanged(this)" +  <%= (!$ship_last || $cgi->param('same') eq 'Y') ? 'CHECKED' : '' %> + >same as billing address) +<%= $r=qq!<font color="#ff0000">*</font> !; +    if (!$ship_last || $cgi->param('same') eq 'Y') { +      $disabled = 'DISABLED STYLE="background-color: #dddddd"'; +      foreach ( qw( last first company address1 address2 city county state +                    zip country daytime night fax ) +      ) { +        ${"ship_$_"} = ${$_}; +      } +    }else{ +      $disabled = ''; +    } +    $pre = 'ship_'; +    include('contact'); +%> + +<INPUT TYPE="submit" NAME="submit" VALUE="<%= $custnum ?  "Apply Changes" : "Add Customer" %>"> +<BR> +</FORM> + +<%= include('footer') %> diff --git a/fs_selfservice/FS-SelfService/cgi/check.html b/fs_selfservice/FS-SelfService/cgi/check.html new file mode 100644 index 000000000..68753fe08 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/check.html @@ -0,0 +1,54 @@ +<TR> +  <TD ALIGN="right">Account type</TD> +  <TD> +    <SELECT NAME="paytype"> +      <%= foreach ( @paytypes ) { +            $selected = $paytype eq $_ ? ' SELECTED' : ''; +            $OUT .= qq(<OPTION$selected VALUE="$_">$_\n); +      } %> +    </SELECT> +  </TD> +</TD><TR> +  <TD ALIGN="right">Account number</TD> +  <TD><INPUT TYPE="text" NAME="payinfo1" SIZE=10 MAXLENGTH=20 VALUE="<%=$payinfo1%>"></TD> +</TD><TR> +  <TD ALIGN="right">ABA/Routing number</TD> +  <TD><INPUT TYPE="text" NAME="payinfo2" SIZE=10 MAXLENGTH=9 VALUE="<%=$payinfo2%>"></TD> +</TR><TR> +  <TD ALIGN="right">Bank name</TD> +  <TD><INPUT TYPE="text" SIZE=32 MAXLENGTH=80 NAME="payname" VALUE="<%=$payname%>"></TD> +</TR><TR> +  <%= +    $OUT = ''; +    if ($show_paystate) { +      $OUT .= qq!<TD ALIGN="right">Bank state</TD><TD><SELECT NAME="paystate">!; +      for ( @states ) { +        $OUT .= '<OPTION'. ($_ eq $paystate ? ' SELECTED' : '' ). ">$_\n"; +      } +      $OUT .= '</SELECT></TD></TR><TR>'; +    } +  %> +  <%= +    $OUT = ''; +    if ($show_ss) { +      $OUT .= '<TD ALIGN="right">Account holder<BR>Social '; +      $OUT .= 'security or tax ID #</TD><TD>'; +      $OUT .= qq!<INPUT TYPE="text" SIZE=32 MAXLENGTH=80 NAME="ss" VALUE="$ss">!; +      $OUT .= '</TD></TR><TR>'; +    } +  %> +  <%= +    $OUT = ''; +    if ($show_stateid) { +      $OUT .= '<TD ALIGN="right">'; +      $OUT .= qq!Account holder<BR>$stateid_label</TD><TD>!; +      $OUT .= qq!<INPUT TYPE="text" SIZE=32 MAXLENGTH=80 NAME="stateid" VALUE="$stateid"></TD>!; +      $OUT .= qq!<TD ALIGN="right">$stateid_state_label</TD>!; +      $OUT .= '<TD><SELECT NAME="stateid_state">'; +      for ( @states ) { +        $OUT .= '<OPTION'. ($_ eq $stateid_state ? ' SELECTED' : '' ). ">$_\n"; +      } +      $OUT .='</SELECT></TD></TR><TR>'; +    } +  %> +</TR> diff --git a/fs_selfservice/FS-SelfService/cgi/contact.html b/fs_selfservice/FS-SelfService/cgi/contact.html new file mode 100644 index 000000000..20c15df78 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/contact.html @@ -0,0 +1,135 @@ +<TABLE BGCOLOR="#cccccc" BORDER=0 CELLSPACING=0> + +<TR> +  <TH ALIGN="right"><%=$r%>Contact name<BR>(last, first)</TH> +  <TD COLSPAN=5> +    <INPUT TYPE="text" NAME="<%=$pre%>last" VALUE="<%= ${$pre.'last'} %>" onChange="<%= $onchange %>" <%=$disabled%>> ,  +    <INPUT TYPE="text" NAME="<%=$pre%>first" VALUE="<%= ${$pre.'first'} %>" onChange="<%= $onchange %>" <%=$disabled%>> +  </TD> +</TR> + +<TR> +  <TD ALIGN="right">Company</TD> +  <TD COLSPAN=7> +    <INPUT TYPE="text" NAME="<%=$pre%>company" VALUE="<%= ${$pre.'company'} %>" SIZE=70 onChange="<%= $onchange %>" <%=$disabled%>> +  </TD> +</TR> + +<TR> +  <TH ALIGN="right"><%=$r%>Address</TH> +  <TD COLSPAN=7> +    <INPUT TYPE="text" NAME="<%=$pre%>address1" VALUE="<%= ${$pre.'address1'} %>" SIZE=70 onChange="<%= $onchange %>" <%=$disabled%>> +  </TD> +</TR> + +<TR> +  <TD ALIGN="right"> +    <%=  +      my $style = +        ( $disabled +          || !$require_address2  +          || ( !$pre && $ship_last ) +        ) +          ? 'visibility:hidden' +          : ''; + +      $OUT .= qq!<FONT ID="${pre}address2_required" color="#ff0000" STYLE="$style">*</FONT> <FONT ID="${pre}address2_label" STYLE="$style"><B>Unit #</B></FONT>!; +    %> +  </TD> +  <TD COLSPAN=7> +    <INPUT TYPE="text" NAME="<%=$pre%>address2" VALUE="<%= ${$pre.'address2'} %>" SIZE=70 onChange="<%= $onchange %>" <%=$disabled%>> +  </TD> +</TR> + +<TR> +  <TH ALIGN="right"><%=$r%>City</TH> +  <TD> +    <INPUT TYPE="text" ID="<%=$pre%>city" NAME="<%=$pre%>city" VALUE="<%= ${$pre.'city'} %>" onChange="<%= $onchange %>" <%=$disabled%>> +  </TD> +  <%=  +    ($county_html, $state_html, $country_html) =  +      FS::SelfService::regionselector( { +        prefix           => $pre, +        selected_county  => ${$pre.'county'}, +        selected_state   => ${$pre.'state'}, +        selected_country => ${$pre.'country'}, +        default_state    => $statedefault, +        default_country  => $countrydefault, +        locales          => \@cust_main_county, +      } ); + +  $OUT .= qq!<TH ALIGN="right">${r}State/County</TH>!; +  $OUT .= qq!<TD>$county_html $state_html</TD>!; +  $OUT .= qq!<TH>${r}Zip</TH>!; +  $OUT .= qq!<TD><INPUT TYPE="text" NAME="${pre}zip" VALUE="${$pre.'zip'}" SIZE=10 onChange="$onchange" $disabled></TD>!; +  $OUT .= qq!</TR>!; +  $OUT .= qq!<TR>!; +  $OUT .= qq!<TH ALIGN="right">${r}Country</TH>!; +  $OUT .= qq!<TD COLSPAN=5>$country_html</TD>!; +  %> +</TR> + +<SCRIPT> +  <%= +    if ( $disabled ) { +      $OUT .= qq!var what = document.getElementById("${pre}city");!; +      for (qw( county state country ) ) { +        $OUT .= "what.form.$pre$_.disabled = true;"; +        $OUT .= "what.form.$pre$_.style.backgroundColor = '#dddddd';"; +      } +    }else{ +      ''; +    } +  %> +</SCRIPT> + +<TR> +  <TD ALIGN="right">Day Phone</TD> +  <TD COLSPAN=5> +    <INPUT TYPE="text" NAME="<%=$pre%>daytime" VALUE="<%= ${$pre.'daytime'} %>" SIZE=18 onChange="<%= $onchange %>" <%=$disabled%>> +  </TD> +</TR> + +<TR> +  <TD ALIGN="right">Night Phone</TD> +  <TD COLSPAN=5> +    <INPUT TYPE="text" NAME="<%=$pre%>night" VALUE="<%= ${$pre.'night'} %>" SIZE=18 onChange="<%= $onchange %>" <%=$disabled%>> +  </TD> +</TR> + +<TR> +  <TD ALIGN="right">Fax</TD> +  <TD COLSPAN=5> +    <INPUT TYPE="text" NAME="<%=$pre%>fax" VALUE="<%= ${$pre.'fax'} %>" SIZE=12 onChange="<%= $onchange %>" <%=$disabled%>> +  </TD> +</TR> + +</TABLE> +<%=$r%>required fields<BR> + +<!-- +#my($county_html, $state_html, $country_html) = +#  FS::cust_main_county::regionselector( $cust_main->get($pre.'county'), +#                                        $cust_main->get($pre.'state'), +#                                        $cust_main->get($pre.'country'), +#                                        $pre, +#                                        $onchange, +#                                        $disabled, +#                                      ); + +my %select_hash = ( +  'county'   => ${$pre.'county'}, +  'state'    => ${$pre.'state'}, +  'country'  => ${$pre.'country'}, +  'prefix'   => $pre, +  'onchange' => $onchange, +  'disabled' => $disabled, +); + +my @counties = counties( ${$pre.'state'}, +                         ${$pre.'country'}, +                       ); +my $county_style = scalar(@counties) > 1 ? '' : 'STYLE="visibility:hidden"'; + +my $r = qq!<font color="#ff0000">*</font> !; +--> diff --git a/fs_selfservice/FS-SelfService/cgi/cust_bill-logo.cgi b/fs_selfservice/FS-SelfService/cgi/cust_bill-logo.cgi new file mode 100644 index 000000000..253f853f8 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/cust_bill-logo.cgi @@ -0,0 +1,25 @@ +#!/usr/bin/perl -T +#!/usr/bin/perl -Tw + +use strict; +use CGI; +use FS::SelfService qw( invoice_logo ); + +my $cgi = new CGI; + +my %hash = (); +if ( $cgi->param('invnum') ) { +  $hash{$_} = scalar($cgi->param($_)) foreach qw( invnum template ); +} else { +  my($query) = $cgi->keywords; +  $query =~ /^([^\.\/]*)$/ or '' =~ /^()$/; +  $hash{'template'} = $1; +} + +my $hashref = invoice_logo(%hash); + +print $cgi->header( '-type'    => $hashref->{'content_type'}, +                    '-expires' => 'now', +                  ). +      $hashref->{'logo'}; + diff --git a/fs_selfservice/FS-SelfService/cgi/customer_change_pkg.html b/fs_selfservice/FS-SelfService/cgi/customer_change_pkg.html new file mode 100644 index 000000000..95bdab76c --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/customer_change_pkg.html @@ -0,0 +1,6 @@ +<%= $url = "$selfurl?session=$session_id;action="; ''; %> +<%= include('header') %> + +<%= include('change_pkg') %> + +<%= include('footer') %> diff --git a/fs_selfservice/FS-SelfService/cgi/customer_order_pkg.html b/fs_selfservice/FS-SelfService/cgi/customer_order_pkg.html new file mode 100755 index 000000000..a20e8acbc --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/customer_order_pkg.html @@ -0,0 +1,6 @@ +<%= $url = "$selfurl?session=$session_id;action="; ''; %> +<%= include('header') %> + +<%= include('order_pkg') %> + +<%= include('footer') %> diff --git a/fs_selfservice/FS-SelfService/cgi/cvv2.html b/fs_selfservice/FS-SelfService/cgi/cvv2.html new file mode 100644 index 000000000..b178c8513 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/cvv2.html @@ -0,0 +1,25 @@ +<HTML> +  <HEAD> +    <TITLE> +      CVV2 information +    </TITLE> +  </HEAD> +  <BODY BGCOLOR="#e8e8e8"> +  The CVV2 number (also called CVC2 or CID) is a three- or four-digit +  security code used to reduce credit card fraud.<BR><BR> +  <TABLE BORDER=0 CELLSPACING=4> +    <TR> +      <TH>Visa / MasterCard / Discover</TH> +      <TH>American Express</TH> +    </TR> +    <TR> +      <TD> +        <IMG BORDER=0 ALT="Visa/MasterCard/Discover" SRC="cvv2.png"> +      </TD> +      <TD> +        <IMG BORDER=0 ALT="American Express" SRC="cvv2_amex.png"> +      </TD> +  </TABLE> +    <CENTER><A HREF="javascript:close()">(close window)</A></CENTER> +  </BODY> +</HTML> diff --git a/fs_selfservice/FS-SelfService/cgi/cvv2.png b/fs_selfservice/FS-SelfService/cgi/cvv2.pngBinary files differ new file mode 100644 index 000000000..4610dcbe6 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/cvv2.png diff --git a/fs_selfservice/FS-SelfService/cgi/cvv2_amex.png b/fs_selfservice/FS-SelfService/cgi/cvv2_amex.pngBinary files differ new file mode 100644 index 000000000..21c36a0ab --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/cvv2_amex.png diff --git a/fs_selfservice/FS-SelfService/cgi/decline.html b/fs_selfservice/FS-SelfService/cgi/decline.html new file mode 100644 index 000000000..c50081e38 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/decline.html @@ -0,0 +1,14 @@ +<HTML> +  <HEAD> +    <TITLE>Processing error</TITLE> +    <%= $head %> +  </HEAD> +  <BODY BGCOLOR="<%= $body_bgcolor || '#eeeeee' %>"> +  <%= $body_header %> + + +<FONT SIZE=7>Processing error</FONT><BR><BR> +There has been an error processing your account.  Please contact customer +support. + +<%= $body_footer %> diff --git a/fs_selfservice/FS-SelfService/cgi/delete_svc.html b/fs_selfservice/FS-SelfService/cgi/delete_svc.html new file mode 100644 index 000000000..e16b01eea --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/delete_svc.html @@ -0,0 +1,11 @@ +<%= $url = "$selfurl?session=$session_id;action="; ''; %> +<%= include('header') %> + +<%= if ( $error ) { +  $OUT .= qq!<FONT SIZE="+1" COLOR="#ff0000">Error: $error</FONT>!; +} else { +  $OUT .= "<FONT SIZE=4>$svc removed.</FONT>"; +} %> + + +<%= include('footer') %> diff --git a/fs_selfservice/FS-SelfService/cgi/footer.html b/fs_selfservice/FS-SelfService/cgi/footer.html new file mode 100644 index 000000000..4889b741a --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/footer.html @@ -0,0 +1,3 @@ +</TD></TR></TABLE> +<%= $body_footer %> +</BODY></HTML> diff --git a/fs_selfservice/FS-SelfService/cgi/header.html b/fs_selfservice/FS-SelfService/cgi/header.html new file mode 100644 index 000000000..630959e33 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/header.html @@ -0,0 +1,23 @@ +<HTML> +  <HEAD> +    <TITLE><%= $title || 'MyAccount' %></TITLE> +    <%= $head %> +  </HEAD> +  <BODY BGCOLOR="<%= $body_bgcolor || '#eeeeee' %>"> +    <script language="JavaScript"><!-- +      var mywindow = -1; +      function myopen(filename,windowname,properties) { +        myclose(); +        mywindow = window.open(filename,windowname,properties); +      } +      function myclose() { +        if ( mywindow != -1 ) +          mywindow.close(); +        mywindow = -1 +      } +    //--></script> +    <%= $body_header %> +    <FONT SIZE=5><%= $title || 'MyAccount' %></FONT> +    <BR><BR> +    <%= include('myaccount_menu') %> +    <TD VALIGN="top"> diff --git a/fs_selfservice/FS-SelfService/cgi/iframecontentmws.js b/fs_selfservice/FS-SelfService/cgi/iframecontentmws.js new file mode 100644 index 000000000..f2a91d21b --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/iframecontentmws.js @@ -0,0 +1,59 @@ +/*
 + iframecontentmws.js - Foteos Macrides (author and copyright holder)
 +   Initial: October 10, 2004 - Last Revised: January 26, 2008
 + Scripts for using HTML documents as iframe content in overlibmws popups.
 +
 + See http://www.macridesweb.com/oltest/IFRAME.html
 + and http://www.macridesweb.com/oltest/AJAX.html#ajaxex3
 + for more information.
 +*/
 +
 +/*
 + Use as lead argument in overlib or overlb2 calls.  Include WRAP and
 + TEXTPADDING,0 in the call to ensure that the width arg is respected (unless
 + the CAPTION plus CLOSETEXT widths add up to more than the width arg, in which
 + case you should increase the width arg).  The name arg should be a unique
 + string for each popup with iframe content in the document.  The frameborder
 + arg should be 1 (browser default if omitted) or 0.  The scrolling arg should
 + be 'auto' (default if omitted), 'yes' or 'no'.
 +*/
 +function OLiframeContent(src, width, height, name, frameborder, scrolling) {
 + 
 + /* stupid safari iframe location caching... */
 + var d = new Date();
 + var unique = d.getTime() + '' + Math.floor(1000 * Math.random());
 + name = name + '' + unique;
 +
 + return ('<iframe src="'+src+'" width="'+width+'" height="'+height+'"'
 + +(name!=null?' name="'+name+'" id="'+name+'"':'')
 + +(frameborder!=null?' frameborder="'+frameborder+'"':'')
 + +' scrolling="'+(scrolling!=null?scrolling:'auto')
 + +'"><div>[iframe not supported]</div></iframe>');
 +}
 +
 +/*
 + Swap the src if we are iframe content.  The name arg should be the same
 + string as in the OLiframeContent function for the popup.  The src arg is
 + a partial, relative, or complete URL for the document to be swapped in.
 +*/
 +function OLswapIframeSrc(name, src){
 + if(parent==self){
 +  alert(src+'\n\n is only for iframe content');
 +  return;
 + }
 + var o=parent.OLgetRef(name);
 + if(o)o.src=src;
 + else alert(src+'\n\n is not available');
 +}
 +
 +/*
 + Emulate the Back button if we are iframe content.  Use only in documents
 + which are swapped in by using the OLswapIframeSrc function.
 +*/
 +function OLiframeBack(){
 + if(parent==self){
 +  alert('This feature is only for iframe content');
 +  return;
 + }
 + history.back();
 +}
 diff --git a/fs_selfservice/FS-SelfService/cgi/images/cross.png b/fs_selfservice/FS-SelfService/cgi/images/cross.pngBinary files differ new file mode 100644 index 000000000..1514d51a3 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/images/cross.png diff --git a/fs_selfservice/FS-SelfService/cgi/images/wait-orange.gif b/fs_selfservice/FS-SelfService/cgi/images/wait-orange.gifBinary files differ new file mode 100644 index 000000000..92c7f3476 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/images/wait-orange.gif diff --git a/fs_selfservice/FS-SelfService/cgi/list_customers.html b/fs_selfservice/FS-SelfService/cgi/list_customers.html new file mode 100644 index 000000000..7fe7fa493 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/list_customers.html @@ -0,0 +1,36 @@ +<HTML><HEAD><TITLE>Reseller</TITLE></HEAD> +<BODY BGCOLOR="#eeeeee"><FONT SIZE=5>Reseller</FONT><BR><BR> +<%= $url = "$selfurl?session=$session_id;action="; ''; %> +<TABLE BORDER=0 CELLPADDING=4><TR> +<%= include('agent_menu') %> +<TD VALIGN="top"> + +<%= +  if ( @customers ) { +    $OUT .= '<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=2 BGCOLOR="#eeeeee">'. +            '<TR><TH BGCOLOR="#cccccc" COLSPAN=3>Customers</TH><TD>'; +    my $col1 = "ffffff"; +    my $col2 = "dddddd"; +    my $col = $col1; + +    foreach my $customer ( @customers ) { +      my $td = qq!<TD BGCOLOR="#$col">!; +      my $a = qq!<A HREF="${url}view_customer;custnum=!.  +              $customer->{'custnum'}. '">'; +      $OUT .= +        '<TR>'. +        "$td<FONT COLOR=\"". $customer->{'statuscolor'}. '">'. +          ucfirst($customer->{'status'}). "</TD>". "$td</TD>". +        "$td$a". $customer->{'name'}. "</A></TD>". +        '</TR>'; +        #"$td</TD>". +      $col = $col eq $col1 ? $col2 : $col1; +    } +    $OUT .= '</TABLE>'; +  } else { +    $OUT .= 'No customers.<BR><BR>'; +  } +%> + +</TD></TR></TABLE> +<%= include('footer') %> diff --git a/fs_selfservice/FS-SelfService/cgi/login.html b/fs_selfservice/FS-SelfService/cgi/login.html new file mode 100644 index 000000000..f7473b1d5 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/login.html @@ -0,0 +1,95 @@ +<HTML> +  <HEAD> +    <TITLE>Login</TITLE> +    <%= $head %> +  </HEAD> +  <BODY BGCOLOR="<%= $body_bgcolor || '#eeeeee' %>"> +  <%= $body_header %> + +<FONT SIZE=5>Login</FONT><BR><BR> +<FONT SIZE="+1" COLOR="#ff0000"><%= $error %></FONT> + +<FORM ACTION="<%= $self_url %>" METHOD=POST> +<INPUT TYPE="hidden" NAME="session" VALUE="login"> +<INPUT TYPE="hidden" NAME="agentnum" VALUE="<%= $agentnum %>"> + +<TABLE BGCOLOR="<%= $box_bgcolor || '#c0c0c0' %>" BORDER=0 CELLSPACING=2 CELLPADDING=0> + +<TR> +  <TH ALIGN="right">Username </TH> +  <TD> +    <INPUT TYPE="text" NAME="username" VALUE="<%= $username %>"><%= $single_domain ? '@'.$single_domain : '' %> +  </TD> +</TR> + +<%= +if ( $single_domain ) { + +  $OUT .= qq(<INPUT TYPE="hidden" NAME="domain" VALUE="$single_domain">); + +} else { + +  $OUT .= qq( +    <TR> +      <TH ALIGN="right">Domain </TH> +      <TD> +        <INPUT TYPE="text" NAME="domain" VALUE="$domain"> +      </TD> +    </TR> +  ); + +} + +%> + +<TR> +  <TH ALIGN="right">Password </TH> +  <TD> +    <INPUT TYPE="password" NAME="password"> +  </TD> +</TR> +<TR> +  <TD COLSPAN=2 ALIGN="center"><INPUT TYPE="submit" VALUE="Login"></TD> +</TR> +</TABLE> +</FORM> + +<%=  + +if ( $phone_login ) { + +  $box_bgcolor ||= '#c0c0c0'; + +  $OUT .= qq( + +    <B>OR</B><BR><BR> +     +    <FORM ACTION="$self_url" METHOD=POST> +    <INPUT TYPE="hidden" NAME="session" VALUE="login"> +    <TABLE BGCOLOR="$box_bgcolor" BORDER=0 CELLSPACING=2 CELLPADDING=0> +    <TR> +      <TH ALIGN="right">Phone number </TH> +      <TD> +        <INPUT TYPE="text" NAME="username" VALUE="$username"> +      </TD> +    </TR> +    <INPUT TYPE="hidden" NAME="domain" VALUE="svc_phone"> +    <TR> +      <TH ALIGN="right">PIN </TH> +      <TD> +        <INPUT TYPE="password" NAME="password"> +      </TD> +    </TR> +    <TR> +      <TD COLSPAN=2 ALIGN="center"><INPUT TYPE="submit" VALUE="Login"></TD> +    </TR> +    </TABLE> +    </FORM> + +  ); + +} + +%> + +<%= $body_footer %> diff --git a/fs_selfservice/FS-SelfService/cgi/logout.html b/fs_selfservice/FS-SelfService/cgi/logout.html new file mode 100644 index 000000000..5e22ad80c --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/logout.html @@ -0,0 +1,13 @@ +<HTML> +  <HEAD> +    <TITLE>MyAccount</TITLE> +    <%= $head %> +  </HEAD> +  <BODY BGCOLOR="<%= $body_bgcolor || '#eeeeee' %>"> +  <%= $body_header %> + +  <FONT SIZE=5>MyAccount</FONT><BR><BR> +You have been logged out. + +<%= $body_footer %> + diff --git a/fs_selfservice/FS-SelfService/cgi/make_ach_payment.html b/fs_selfservice/FS-SelfService/cgi/make_ach_payment.html new file mode 100644 index 000000000..8802a5d97 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/make_ach_payment.html @@ -0,0 +1,43 @@ +<%= $url = "$selfurl?session=$session_id;action="; ''; %> +<%= include('header') %> + +<FONT SIZE=4>Make a payment</FONT><BR><BR> +<FORM NAME="OneTrueForm" METHOD="POST" ACTION="<%=$selfurl%>" onSubmit="document.OneTrueForm.process.disabled=true"> +<INPUT TYPE="hidden" NAME="session" VALUE="<%=$session_id%>"> +<INPUT TYPE="hidden" NAME="action" VALUE="ach_payment_results"> +<TABLE BGCOLOR="#cccccc"> +<TR> +  <TD ALIGN="right">Amount Due</TD> +  <TD> +    <TABLE><TR><TD BGCOLOR="#ffffff"> +      $<%=sprintf("%.2f",$balance)%> +    </TD></TR></TABLE> +  </TD> +</TR> +<TR> +  <TD ALIGN="right">Payment amount</TD> +  <TD> +    <TABLE><TR><TD BGCOLOR="#ffffff"> +      $<INPUT TYPE="text" NAME="amount" SIZE=8 VALUE="<%=sprintf("%.2f",$balance)%>"> +    </TD></TR></TABLE> +  </TD> +</TR> +<%= include('check') %> +<TR> +  <TD COLSPAN=2> +    <INPUT TYPE="checkbox" CHECKED NAME="save" VALUE="1"> +    Remember this information +  </TD> +</TR><TR> +  <TD COLSPAN=2> +    <INPUT TYPE="checkbox"<%= $payby eq 'CHEK' ? ' CHECKED' : '' %> NAME="auto" VALUE="1" onClick="if (this.checked) { document.OneTrueForm.save.checked=true; }"> +    Charge future payments to this account automatically +  </TD> +</TR> +</TABLE> +<BR> +<INPUT TYPE="hidden" NAME="paybatch" VALUE="<%=$paybatch%>"> +<INPUT TYPE="submit" NAME="process" VALUE="Process payment"> <!-- onClick="this.disabled=true"> --> +</FORM> + +<%= include('footer') %> diff --git a/fs_selfservice/FS-SelfService/cgi/make_payment.html b/fs_selfservice/FS-SelfService/cgi/make_payment.html new file mode 100644 index 000000000..96a17ba4c --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/make_payment.html @@ -0,0 +1,53 @@ +<%= $url = "$selfurl?session=$session_id;action="; ''; %> +<%= include('header') %> + +<FONT SIZE=4>Make a payment</FONT><BR><BR> +<FORM NAME="OneTrueForm" METHOD="POST" ACTION="<%=$selfurl%>" onSubmit="document.OneTrueForm.process.disabled=true"> +<INPUT TYPE="hidden" NAME="session" VALUE="<%=$session_id%>"> +<INPUT TYPE="hidden" NAME="action" VALUE="payment_results"> +<TABLE BGCOLOR="#cccccc"> +<TR> +  <TH ALIGN="right">Amount Due</TH> +  <TD COLSPAN=7> +    <TABLE><TR><TD BGCOLOR="#ffffff"> +      $<%=sprintf("%.2f",$balance)%> +    </TD></TR></TABLE> +  </TD> +</TR> +<TR> +  <TH ALIGN="right">Payment amount</TH> +  <TD COLSPAN=7> +    <TABLE><TR><TD BGCOLOR="#ffffff"> +      $<INPUT TYPE="text" NAME="amount" SIZE=8 VALUE="<%=sprintf("%.2f",$balance)%>"> +    </TD></TR></TABLE> +  </TD> +</TR><TR> +  <TH ALIGN="right">Card type</TH> +  <TD COLSPAN=7> +    <SELECT NAME="card_type"><OPTION></OPTION> +      <%= foreach ( keys %card_types ) { +            $selected = $card_type eq $card_types{$_} ? ' SELECTED' : ''; +            $OUT .= qq(<OPTION$selected VALUE="). $card_types{$_}. qq(">$_\n); +      } %> +    </SELECT> +  </TD> +</TR> +<%= include('card') %> +<TR> +  <TD COLSPAN=8> +    <INPUT TYPE="checkbox" CHECKED NAME="save" VALUE="1"> +    Remember this information +  </TD> +</TR><TR> +  <TD COLSPAN=8> +    <INPUT TYPE="checkbox"<%= $payby eq 'CARD' ? ' CHECKED' : '' %> NAME="auto" VALUE="1" onClick="if (this.checked) { document.OneTrueForm.save.checked=true; }"> +    Charge future payments to this card automatically +  </TD> +</TR> +</TABLE> +<BR> +<INPUT TYPE="hidden" NAME="paybatch" VALUE="<%=$paybatch%>"> +<INPUT TYPE="submit" NAME="process" VALUE="Process payment"> <!-- onClick="this.disabled=true"> --> +</FORM> + +<%= include('footer') %> diff --git a/fs_selfservice/FS-SelfService/cgi/make_thirdparty_payment.html b/fs_selfservice/FS-SelfService/cgi/make_thirdparty_payment.html new file mode 100755 index 000000000..b2900b1e9 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/make_thirdparty_payment.html @@ -0,0 +1,37 @@ +<%= $url = "$selfurl?session=$session_id;action="; ''; %> +<%= include('header') %> + +<SCRIPT TYPE="text/javascript"> +  function popcollect() { +    overlib( OLiframeContent('<%= $popup_url %>', 336, 550, 'Secure Payment Area', 0, 'auto' ), CAPTION, 'Pay now', STICKY, AUTOSTATUSCAP, MIDX, 0, MIDY, 0, DRAGGABLE, CLOSECLICK, BGCOLOR, '#333399', CGCOLOR, '#333399', CLOSETEXT, 'Close' ); +    return false; +  } +</SCRIPT> +<SCRIPT TYPE="text/javascript" SRC="overlibmws.js"></SCRIPT> +<SCRIPT TYPE="text/javascript" SRC="overlibmws_iframe.js"></SCRIPT> +<SCRIPT TYPE="text/javascript" SRC="overlibmws_draggable.js"></SCRIPT> +<SCRIPT TYPE="text/javascript" SRC="overlibmws_crossframe.js"></SCRIPT> +<SCRIPT TYPE="text/javascript" SRC="iframecontentmws.js"></SCRIPT> + +<FONT SIZE=4>Pay now</FONT><BR><BR> + +<%= if ( $error ) { +  $OUT .= qq!<FONT SIZE="+1" COLOR="#ff0000">$error</FONT><BR><BR>!; +}else{ +  $OUT .= <<EOF; +    You are about to contact our payment processor to pay $amount.<BR><BR> +    Your transaction reference number is $reference <BR><BR> +    <FORM NAME="collect_popper" method="post" action="javascript:void(0)" onSubmit="popcollect()"> +EOF + +  my %itemhash = @collectitems; +  foreach my $input (keys %itemhash) { +    $OUT .= qq!<INPUT NAME="$input" TYPE="hidden" VALUE="$itemhash{$input}">!; +  } + +  $OUT .= qq!<INPUT NAME="submit" type="submit" value="Pay now">!; +  $OUT .= qq!</FORM>!; +} +%> + +<%= include('footer') %> diff --git a/fs_selfservice/FS-SelfService/cgi/map.gif b/fs_selfservice/FS-SelfService/cgi/map.gifBinary files differ new file mode 100644 index 000000000..ef884d8f9 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/map.gif diff --git a/fs_selfservice/FS-SelfService/cgi/misc/areacodes.cgi b/fs_selfservice/FS-SelfService/cgi/misc/areacodes.cgi new file mode 100755 index 000000000..b33e58c5a --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/misc/areacodes.cgi @@ -0,0 +1,18 @@ +#!/usr/bin/perl -w + +use strict; +use CGI; +use FS::SelfService qw( mason_comp ); + +my $cgi = new CGI; + +my $rv = mason_comp( 'comp'         => '/misc/areacodes.cgi', +                     'query_string' => $cgi->query_string, #pass CGI params... +                   ); + +#hmm. +my $output = $rv->{'error'} || $rv->{'output'}; + +print $cgi->header( '-expires' => 'now' ). +      $output; + diff --git a/fs_selfservice/FS-SelfService/cgi/misc/counties.cgi b/fs_selfservice/FS-SelfService/cgi/misc/counties.cgi new file mode 100755 index 000000000..476fe09a4 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/misc/counties.cgi @@ -0,0 +1,18 @@ +#!/usr/bin/perl -w + +use strict; +use CGI; +use FS::SelfService qw( mason_comp ); + +my $cgi = new CGI; + +my $rv = mason_comp( 'comp'         => '/misc/counties.cgi', +                     'query_string' => $cgi->query_string, #pass CGI params... +                   ); + +#hmm. +my $output = $rv->{'error'} || $rv->{'output'}; + +print $cgi->header( '-expires' => 'now' ). +      $output; + diff --git a/fs_selfservice/FS-SelfService/cgi/misc/exchanges.cgi b/fs_selfservice/FS-SelfService/cgi/misc/exchanges.cgi new file mode 100755 index 000000000..d8df970d9 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/misc/exchanges.cgi @@ -0,0 +1,18 @@ +#!/usr/bin/perl -w + +use strict; +use CGI; +use FS::SelfService qw( mason_comp ); + +my $cgi = new CGI; + +my $rv = mason_comp( 'comp'         => '/misc/exchanges.cgi', +                     'query_string' => $cgi->query_string, #pass CGI params... +                   ); + +#hmm. +my $output = $rv->{'error'} || $rv->{'output'}; + +print $cgi->header( '-expires' => 'now' ). +      $output; + diff --git a/fs_selfservice/FS-SelfService/cgi/misc/part_svc-columns.cgi b/fs_selfservice/FS-SelfService/cgi/misc/part_svc-columns.cgi new file mode 100755 index 000000000..4ee83ca96 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/misc/part_svc-columns.cgi @@ -0,0 +1,18 @@ +#!/usr/bin/perl -w + +use strict; +use CGI; +use FS::SelfService qw( mason_comp ); + +my $cgi = new CGI; + +my $rv = mason_comp( 'comp'         => '/misc/part_svc-columns.cgi', +                     'query_string' => $cgi->query_string, #pass CGI params... +                   ); + +#hmm. +my $output = $rv->{'error'} || $rv->{'output'}; + +print $cgi->header( '-expires' => 'now' ). +      $output; + diff --git a/fs_selfservice/FS-SelfService/cgi/misc/phonenums.cgi b/fs_selfservice/FS-SelfService/cgi/misc/phonenums.cgi new file mode 100755 index 000000000..e7d695d07 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/misc/phonenums.cgi @@ -0,0 +1,18 @@ +#!/usr/bin/perl -w + +use strict; +use CGI; +use FS::SelfService qw( mason_comp ); + +my $cgi = new CGI; + +my $rv = mason_comp( 'comp'         => '/misc/phonenums.cgi', +                     'query_string' => $cgi->query_string, #pass CGI params... +                   ); + +#hmm. +my $output = $rv->{'error'} || $rv->{'output'}; + +print $cgi->header( '-expires' => 'now' ). +      $output; + diff --git a/fs_selfservice/FS-SelfService/cgi/misc/states.cgi b/fs_selfservice/FS-SelfService/cgi/misc/states.cgi new file mode 100755 index 000000000..f75f2ae1d --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/misc/states.cgi @@ -0,0 +1,18 @@ +#!/usr/bin/perl -w + +use strict; +use CGI; +use FS::SelfService qw( mason_comp ); + +my $cgi = new CGI; + +my $rv = mason_comp( 'comp'         => '/misc/states.cgi', +                     'query_string' => $cgi->query_string, #pass CGI params... +                   ); + +#hmm. +my $output = $rv->{'error'} || $rv->{'output'}; + +print $cgi->header( '-expires' => 'now' ). +      $output; + diff --git a/fs_selfservice/FS-SelfService/cgi/misc/svc_acct-domains.cgi b/fs_selfservice/FS-SelfService/cgi/misc/svc_acct-domains.cgi new file mode 100755 index 000000000..c5413bac6 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/misc/svc_acct-domains.cgi @@ -0,0 +1,18 @@ +#!/usr/bin/perl -w + +use strict; +use CGI; +use FS::SelfService qw( mason_comp ); + +my $cgi = new CGI; + +my $rv = mason_comp( 'comp'         => '/misc/svc_acct-domains.cgi', +                     'query_string' => $cgi->query_string, #pass CGI params... +                   ); + +#hmm. +my $output = $rv->{'error'} || $rv->{'output'}; + +print $cgi->header( '-expires' => 'now' ). +      $output; + diff --git a/fs_selfservice/FS-SelfService/cgi/myaccount.html b/fs_selfservice/FS-SelfService/cgi/myaccount.html new file mode 100644 index 000000000..9b54794bc --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/myaccount.html @@ -0,0 +1,100 @@ +<%= $url = "$selfurl?session=$session_id;action="; ''; %> +<%= include('header') %> + +Hello <%= $name %>!<BR><BR> +<%= $small_custview %> +<BR> +<%= if ( $access_pkgnum ) { +      $OUT .= qq!Balance: <B>\$$balance</B><BR><BR>!; +    } +    ''; +%> + +<%= if ( $balance > 0 ) { +  if (scalar(grep $_, @hide_payment_fields)) { +    $OUT .= qq! <B><A HREF="${url}make_thirdparty_payment&payby_method=CC">Make a payment</A></B><BR><BR>!; +  } else { +    $OUT .= qq! <B><A HREF="${url}make_payment">Make a payment</A></B><BR><BR>!; +  } +} %> +<%= +  if ( @open_invoices ) { +    $OUT .= '<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=2 BGCOLOR="#eeeeee">'. +            '<TR><TH BGCOLOR="#ff6666" COLSPAN=5>Open Invoices</TH></TR>'; +    my $link = qq!<A HREF="<%= $url %>myaccount!; +    my $col1 = "ffffff"; +    my $col2 = "dddddd"; +    my $col = $col1; + +    foreach my $invoice ( @open_invoices ) { +      my $td = qq!<TD BGCOLOR="#$col">!; +      my $a=qq!<A HREF="${url}view_invoice;invnum=!. $invoice->{'invnum'}. '">'; +      $OUT .= +        "<TR>$td${a}Invoice #". $invoice->{'invnum'}. "</A></TD>$td</TD>". +        "$td$a". $invoice->{'date'}. "</A></TD>$td</TD>". +        qq!<TD BGCOLOR="#$col" ALIGN="right">$a\$!. $invoice->{'owed'}. +          '</A></TD>'. +        '</TR>'; +      $col = $col eq $col1 ? $col2 : $col1; +    } +    $OUT .= '</TABLE><BR>'; +  } else { +    $OUT .= 'You have no outstanding invoices.<BR><BR>'; +  } +%> + +<%= +  if ( @support_services ) { +    $OUT .= '<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=2 BGCOLOR="#eeeeee">'. +            '<TR><TH BGCOLOR="#ff6666" COLSPAN="3">Support Time Remaining</TH>'. +            '</TR><TR><TH ALIGN="left">#</TH><TH>Package</TH>'. +            '<TH>Time Remaining</TH></TR>'; +    my $col1 = "ffffff"; +    my $col2 = "dddddd"; +    my $col = $col1; + +    foreach my $support ( @support_services ) { +      my $td = qq!<TD BGCOLOR="#$col">!; +      my $a = qq!<A HREF="${url}view_support_details;svcnum=!. +              $support->{'svcnum'}. '">'; +      $OUT .= +        "<TR>$td$a". $support->{'pkgnum'}. "</A></TD>". +        $td.$a. $support->{'pkg'}. "</A></TD>". +        $td.$a. $support->{'time'}. "</A></TD>". +        '</TR>'; +      $col = $col eq $col1 ? $col2 : $col1; +    } +    $OUT .= '</TABLE><BR>'; +  } else { +    $OUT .= ''; +  } +%> + +<%= +  if ( @tickets ) { +    $OUT .= '<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=2 BGCOLOR="#eeeeee">'. +            '<TR><TH BGCOLOR="#ff6666" COLSPAN=5>Open Tickets</TH></TR>'. +            '<TR><TH>#</TH><TH>Subject</TH><TH>Priority</TH><TH>Queue</TH>'. +            '<TH>Status</TH></TR>'; +    my $col1 = "ffffff"; +    my $col2 = "dddddd"; +    my $col = $col1; + +    foreach my $ticket ( @tickets ) { +      my $td = qq!<TD BGCOLOR="#$col">!; +      $OUT .= +        "<TR>$td". $ticket->{'id'}. "</TD>". +        $td. $ticket->{'subject'}. "</TD>". +        $td. ($ticket->{'content'} || $ticket->{'priority'}). "</TD>". +        $td. $ticket->{'queue'}. "</TD>". +        $td. $ticket->{'status'}. "</TD>". +        '</TR>'; +      $col = $col eq $col1 ? $col2 : $col1; +    } +    $OUT .= '</TABLE>'; +  } else { +    $OUT .= ''; +  } +%> + +<%= include('footer') %> diff --git a/fs_selfservice/FS-SelfService/cgi/myaccount_menu.html b/fs_selfservice/FS-SelfService/cgi/myaccount_menu.html new file mode 100644 index 000000000..8765323fa --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/myaccount_menu.html @@ -0,0 +1,127 @@ +<%= $url = "$selfurl?session=$session_id;action="; ''; %> +<TABLE BORDER=0><TR> +<TD VALIGN="top" HEIGHT="100%" BGCOLOR="<%= $box_bgcolor || '#c0c0c0' %>"> + +<TABLE CELLSPACING=0 BORDER=0 HEIGHT="100%"> + +<%=  + +my @menu = ( +  { title=>' ' }, +  { title=>'Overview', url=>'myaccount', size=>'+1', }, +  { title=>' ' }, +  { title=>'Purchase', size=>'+1', }, +); + +unless ( $access_pkgnum ) { +  push @menu, +    { title=>'Purchase additional package', +      url=>'customer_order_pkg', 'indent'=>2 }; +} + +if ( 1 ) { #XXXFIXME "enable selfservice prepay features" flag or something, eventually per-pkg or something really fancy + +  #XXXFIXME still a bit sloppy for multi-gateway of differing namespace +  my $i = 0; +  while($i < scalar(@cust_paybys)) { last if $cust_paybys[$i] =~ /^CARD/; $i++ } +  if ( $cust_paybys[$i] =~ /^CARD/ ) { +    push @menu, { title  => 'Recharge my account with a credit card', +                  url    => $hide_payment_fields[$i] +                              ? 'make_thirdparty_payment&payby_method=CC' +                              : 'make_payment', +                  indent => 2, +                 } +  } + +  $i = 0; +  while($i < scalar(@cust_paybys)) { last if $cust_paybys[$i] =~ /^CHEK/; $i++ } +  if ( $cust_paybys[$i] =~ /^CHEK/ ) { +    push @menu, { title  => 'Recharge my account with a check', +                  url    => $hide_payment_fields[$i] +                              ? 'make_thirdparty_payment&payby_method=ECHECK' +                              : 'make_ach_payment', +                  indent => 2, +                } +  } + +  push @menu, { title  => 'Recharge my account with a prepaid card', +                url    => 'recharge_prepay', +                indent => 2, +              } +    if grep(/^PREP/, @cust_paybys); + +} + +push @menu, +  { title=>' ' }, +  { title=>'View my usage', url=>'view_usage', size=>'+1', }, +; + +unless ( $access_pkgnum ) { +  push @menu, +    { title=>'Setup my services', url=>'provision', size=>'+1', }, +  ; +} + +push @menu, +  { title=>' ' }; + +push @menu, +  { title=>'Change my information', size=>'+1', }; + +unless ( $access_pkgnum ) { +  push @menu, +    { title=>'Change billing address',      url=>'change_bill',     indent=>2 }, +    { title=>'Change service address',      url=>'change_ship',     indent=>2 }, +    { title=>'Change payment information',  url=>'change_pay',      indent=>2 }, +  ; +} + +push @menu, +  { title=>'Change password(s)',          url=>'change_password', indent=>2 }, +  { title=>' ' }, +  { title=>'Logout',   url=>'logout', size=>'+1', }, +; + +foreach my $item ( @menu ) { + +  $OUT .= '<TR><TD';  +  if ( exists $item->{'url'} && $action eq $item->{'url'} ) { +    $OUT .= ' BGCOLOR="'. ( $body_bgcolor || '#eeeeee' ). '" '. +            ' STYLE="border-top: 1px solid black;'. +                   ' border-left: 1px solid black;'. +                   ' border-bottom: 1px solid black"'; +  } else { +    $OUT .= ' STYLE="border-right: 1px solid black"'; +  } +  $OUT.='>'; + +  $OUT .= ' ' x $item->{'indent'} +    if exists $item->{'indent'}; + +  $OUT .= '<A HREF="'. $url. $item->{'url'}. '">' +    if exists $item->{'url'} && $action ne $item->{'url'}; + +  $OUT .= '<FONT SIZE="'. $item->{'size'}. '">' +    if exists $item->{'size'}; + +  $item->{'title'} =~ s/ / /g; +  $OUT .= $item->{'title'}; + +  $OUT .= '</FONT>' +    if exists $item->{'size'}; + +  $OUT .= '</A>' +    if exists $item->{'url'} && $action ne $item->{'url'}; + +  $OUT .= '</TD></TR>'; + +} + +%> + +<TR><TD STYLE="border-right: 1px solid black" HEIGHT="100%"><BR><BR><BR><BR></TD></TR> + +</TABLE> + +</TD> diff --git a/fs_selfservice/FS-SelfService/cgi/order_pkg.html b/fs_selfservice/FS-SelfService/cgi/order_pkg.html new file mode 100644 index 000000000..4abfd8440 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/order_pkg.html @@ -0,0 +1,47 @@ +<SCRIPT TYPE="text/javascript"> +function enable_order_pkg () { +  if ( document.OrderPkgForm.pkgpart_svcpart.selectedIndex > 0 ) { +    document.OrderPkgForm.submit.disabled = false; +  } else { +    document.OrderPkgForm.submit.disabled = true; +  } +} +</SCRIPT> +<FONT SIZE=4>Purchase additional package</FONT><BR><BR> +<%= if ( $error ) { +  $OUT .= qq!<FONT SIZE="+1" COLOR="#ff0000">$error</FONT><BR><BR>!; +} ''; %> +<FORM NAME="OrderPkgForm" ACTION="<%= $selfurl %>" METHOD=POST> +<INPUT TYPE="hidden" NAME="session" VALUE="<%= $session_id %>"> +<INPUT TYPE="hidden" NAME="action" VALUE="process_order_pkg"> +<INPUT TYPE="hidden" NAME="custnum" VALUE="<%= $custnum %>"> +<TABLE BGCOLOR="#cccccc" BORDER=0 CELLSPACING=0> + +<TR> +  <TD COLSPAN=2> +    <TABLE><TR><TD> <%= $pkg_selector %> + +  </TD> +</TR> + +<%= +  if ( 0 ) { +  if ( @svc_acct_pop ) { +    $OUT .= '<TR><TD ALIGN="right">Access number</TD><TD>'. +            popselector( 'popnum'        => $popnum, +                         'pops'          => \@svc_acct_pop, +                         'init_popstate' => $init_popstate, +                         'popac'         => $popac, +                         'acstate'       => $acstate, +                       ). +            '</TD></TR>'; +  } else { +    $OUT .= popselector(popnum=>$popnum, pops=>\@svc_acct_pop); +  } +  } +  ''; +%> +</TABLE> +<INPUT NAME="submit" TYPE="submit" VALUE="Purchase" DISABLED> +</FORM> + diff --git a/fs_selfservice/FS-SelfService/cgi/overlibmws.js b/fs_selfservice/FS-SelfService/cgi/overlibmws.js new file mode 100644 index 000000000..df2bd1db7 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/overlibmws.js @@ -0,0 +1,620 @@ +/*
 + Do not remove or change this notice.
 + overlibmws.js core module - Copyright Foteos Macrides 2002-2008. All rights reserved.
 +   Initial: August 18, 2002 - Last Revised: March 22, 2008
 + This module is subject to the same terms of usage as for Erik Bosrup's overLIB,
 + though only a minority of the code and API now correspond with Erik's version.
 + See the overlibmws Change History and Command Reference via:
 +
 +	http://www.macridesweb.com/oltest/
 +
 + Published under an open source license: http://www.macridesweb.com/oltest/license.html
 + Give credit on sites that use overlibmws and submit changes so others can use them as well.
 + You can get Erik's version via: http://www.bosrup.com/web/overlib/
 +*/
 +
 +// PRE-INIT -- Ignore these lines, configuration is below.
 +var OLloaded=0,OLbubblePI=0,OLcrossframePI=0,OLdebugPI=0,OLdraggablePI=0,OLexclusivePI=0,OLfilterPI=0,
 +OLfunctionPI=0,OLhidePI=0,OLiframePI=0,OLmodalPI=0,OLovertwoPI=0,OLscrollPI=0,OLshadowPI=0,OLprintPI=0,
 +pmCnt=1,pMtr=new Array(),OLcmdLine=new Array(),OLrunTime=new Array(),OLv,OLudf,OLrefXY,
 +OLpct=new Array("83%","67%","83%","100%","117%","150%","200%","267%");if(typeof OLgateOK=='undefined')var OLgateOK=1;
 +var OLp1or2c='inarray,caparray,caption,closetext,right,left,center,autostatuscap,padx,pady,below,above,vcenter,donothing',
 +OLp1or2co='nofollow,background,offsetx,offsety,fgcolor,bgcolor,cgcolor,textcolor,capcolor,width,wrap,wrapmax,height,border,'
 ++'base,status,autostatus,snapx,snapy,fixx,fixy,relx,rely,midx,midy,ref,refc,refp,refx,refy,fgbackground,bgbackground,'
 ++'cgbackground,fullhtml,capicon,textfont,captionfont,textsize,captionsize,timeout,delay,hauto,vauto,nojustx,nojusty,fgclass,'
 ++'bgclass,cgclass,capbelow,textpadding,textfontclass,captionpadding,captionfontclass,sticky,noclose,mouseoff,offdelay,'
 ++'closecolor,closefont,closesize,closeclick,closetitle,closefontclass,decode',OLp1or2o='text,cap,close,hpos,vpos,padxl,'
 ++'padxr,padyt,padyb',OLp1co='label',OLp1or2=OLp1or2co+','+OLp1or2o,OLp1=OLp1co+','+'frame';
 +OLregCmds(OLp1or2c+','+OLp1or2co+','+OLp1co);
 +function OLud(v){return eval('typeof ol_'+v+'=="undefined"')?1:0;}
 +
 +// DEFAULT CONFIGURATION -- See overlibConfig.txt for descriptions
 +if(OLud('fgcolor'))var ol_fgcolor="#ccccff";
 +if(OLud('bgcolor'))var ol_bgcolor="#333399";
 +if(OLud('cgcolor'))var ol_cgcolor="#333399";
 +if(OLud('textcolor'))var ol_textcolor="#000000";
 +if(OLud('capcolor'))var ol_capcolor="#ffffff";
 +if(OLud('closecolor'))var ol_closecolor="#eeeeff";
 +if(OLud('textfont'))var ol_textfont="Verdana,Arial,Helvetica";
 +if(OLud('captionfont'))var ol_captionfont="Verdana,Arial,Helvetica";
 +if(OLud('closefont'))var ol_closefont="Verdana,Arial,Helvetica";
 +if(OLud('textsize'))var ol_textsize=1;
 +if(OLud('captionsize'))var ol_captionsize=1;
 +if(OLud('closesize'))var ol_closesize=1;
 +if(OLud('fgclass'))var ol_fgclass="";
 +if(OLud('bgclass'))var ol_bgclass="";
 +if(OLud('cgclass'))var ol_cgclass="";
 +if(OLud('textpadding'))var ol_textpadding=2;
 +if(OLud('textfontclass'))var ol_textfontclass="";
 +if(OLud('captionpadding'))var ol_captionpadding=2;
 +if(OLud('captionfontclass'))var ol_captionfontclass="";
 +if(OLud('closefontclass'))var ol_closefontclass="";
 +if(OLud('close'))var ol_close="Close";
 +if(OLud('closeclick'))var ol_closeclick=0;
 +if(OLud('closetitle'))var ol_closetitle="Click to Close";
 +if(OLud('text'))var ol_text="Default Text";
 +if(OLud('cap'))var ol_cap="";
 +if(OLud('capbelow'))var ol_capbelow=0;
 +if(OLud('background'))var ol_background="";
 +if(OLud('width'))var ol_width=200;
 +if(OLud('wrap'))var ol_wrap=0;
 +if(OLud('wrapmax'))var ol_wrapmax=0;
 +if(OLud('height'))var ol_height= -1;
 +if(OLud('border'))var ol_border=1;
 +if(OLud('base'))var ol_base=0;
 +if(OLud('offsetx'))var ol_offsetx=10;
 +if(OLud('offsety'))var ol_offsety=10;
 +if(OLud('sticky'))var ol_sticky=0;
 +if(OLud('nofollow'))var ol_nofollow=0;
 +if(OLud('noclose'))var ol_noclose=0;
 +if(OLud('mouseoff'))var ol_mouseoff=0;
 +if(OLud('offdelay'))var ol_offdelay=300;
 +if(OLud('hpos'))var ol_hpos=RIGHT;
 +if(OLud('vpos'))var ol_vpos=BELOW;
 +if(OLud('status'))var ol_status="";
 +if(OLud('autostatus'))var ol_autostatus=0;
 +if(OLud('snapx'))var ol_snapx=0;
 +if(OLud('snapy'))var ol_snapy=0;
 +if(OLud('fixx'))var ol_fixx= -1;
 +if(OLud('fixy'))var ol_fixy= -1;
 +if(OLud('relx'))var ol_relx=null;
 +if(OLud('rely'))var ol_rely=null;
 +if(OLud('midx'))var ol_midx=null;
 +if(OLud('midy'))var ol_midy=null;
 +if(OLud('ref'))var ol_ref="";
 +if(OLud('refc'))var ol_refc='UL';
 +if(OLud('refp'))var ol_refp='UL';
 +if(OLud('refx'))var ol_refx=0;
 +if(OLud('refy'))var ol_refy=0;
 +if(OLud('fgbackground'))var ol_fgbackground="";
 +if(OLud('bgbackground'))var ol_bgbackground="";
 +if(OLud('cgbackground'))var ol_cgbackground="";
 +if(OLud('padxl'))var ol_padxl=1;
 +if(OLud('padxr'))var ol_padxr=1;
 +if(OLud('padyt'))var ol_padyt=1;
 +if(OLud('padyb'))var ol_padyb=1;
 +if(OLud('fullhtml'))var ol_fullhtml=0;
 +if(OLud('capicon'))var ol_capicon="";
 +if(OLud('frame'))var ol_frame=self;
 +if(OLud('timeout'))var ol_timeout=0;
 +if(OLud('delay'))var ol_delay=0;
 +if(OLud('hauto'))var ol_hauto=0;
 +if(OLud('vauto'))var ol_vauto=0;
 +if(OLud('nojustx'))var ol_nojustx=0;
 +if(OLud('nojusty'))var ol_nojusty=0;
 +if(OLud('label'))var ol_label="";
 +if(OLud('decode'))var ol_decode=0;
 +// ARRAY CONFIGURATION - See overlibConfig.txt for descriptions.
 +if(OLud('texts'))var ol_texts=new Array("Text 0","Text 1");
 +if(OLud('caps'))var ol_caps=new Array("Caption 0","Caption 1");
 +// END CONFIGURATION -- Don't change anything below, all configuration is above.
 +
 +// INIT -- Runtime variables.
 +var o3_text="",o3_cap="",o3_sticky=0,o3_nofollow=0,o3_background="",o3_noclose=0,o3_mouseoff=0,o3_offdelay=300,o3_hpos=RIGHT,
 +o3_offsetx=10,o3_offsety=10,o3_fgcolor="",o3_bgcolor="",o3_cgcolor="",o3_textcolor="",o3_capcolor="",o3_closecolor="",
 +o3_width=200,o3_wrap=0,o3_wrapmax=0,o3_height= -1,o3_border=1,o3_base=0,o3_status="",o3_autostatus=0,o3_snapx=0,o3_snapy=0,
 +o3_fixx= -1,o3_fixy= -1,o3_relx=null,o3_rely=null,o3_midx=null,o3_midy=null,o3_ref="",o3_refc='UL',o3_refp='UL',o3_refx=0,
 +o3_refy=0,o3_fgbackground="",o3_bgbackground="",o3_cgbackground="",o3_padxl=0,o3_padxr=0,o3_padyt=0,o3_padyb=0,o3_fullhtml=0,
 +o3_vpos=BELOW,o3_capicon="",o3_textfont="Verdana,Arial,Helvetica",o3_captionfont="",o3_closefont="",o3_textsize=1,OLcC=null,
 +o3_captionsize=1,o3_closesize=1,o3_frame=self,o3_timeout=0,o3_delay=0,o3_hauto=0,o3_vauto=0,o3_nojustx=0,o3_nojusty=0,
 +o3_close="",o3_closeclick=0,o3_closetitle="",o3_fgclass="",o3_bgclass="",o3_cgclass="",o3_textpadding=2,o3_textfontclass="",
 +o3_captionpadding=2,o3_captionfontclass="",o3_closefontclass="",o3_capbelow=0,o3_label="",o3_decode=0,
 +CSSOFF=DONOTHING,CSSCLASS=DONOTHING,over=null,OLdelayid=0,OLtimerid=0,OLshowid=0,OLndt=0,OLfnRef="",OLhover=0,OLx=0,OLy=0,
 +OLshowingsticky=0,OLallowmove=0,OLoverHTML="",OLover2HTML="",OLifRef="",OLo2Ref="",OLifX=0,OLifY=0,
 +OLua=(OLv=navigator.userAgent)?OLv.toLowerCase():'',
 +OLns4=(navigator.appName=='Netscape'&&parseInt(navigator.appVersion)==4)?1:0,
 +OLns6=(document.getElementById)?1:0,
 +OLie4=(document.all)?1:0,
 +OLgek=(OLv=OLua.match(/gecko\/(\d{8})/i))?parseInt(OLv[1]):0,
 +OLmac=(OLua.indexOf('mac')>=0)?1:0,
 +OLsaf=(OLua.indexOf('safari')>=0)?1:0,
 +OLkon=(OLua.indexOf('konqueror')>=0)?1:0,
 +OLkht=(OLsaf||OLkon)?1:0,
 +OLopr=(OLua.indexOf('opera')>=0)?1:0,
 +OLop7=(OLopr&&document.createTextNode)?1:0;
 +if(OLopr){OLns4=OLns6=OLgek=0;OLie4=(OLop7)?1:0;}
 +var OLieM=((OLie4&&OLmac)&&!(OLkht||OLopr))?1:0,
 +OLie5=0,OLie55=0;OLie7=0;if(OLie4&&!OLop7){
 +if((OLv=OLua.match(/msie (\d\.\d+)\.*/i))&&(OLv=parseFloat(OLv[1]))>=5.0){
 +OLie5=1;OLns6=0;if(OLv>=5.5)OLie55=1;if(OLv>=7.0)OLie7=1;}if(OLns6)OLie4=0;}
 +if(OLns4)window.onresize=function(){location.reload();};var OLchkMh=1,OLdw;
 +if(OLns4||OLie4||OLns6){OLmh();if(window.addEventListener)window.addEventListener("unload",
 +OLulCl,false);}else{overlib=nd=cClick=OLpageDefaults=no_overlib;}
 +function OLulCl(){if(over)cClick();window.removeEventListener("unload",OLulCl,false);}
 +
 +/*
 + PUBLIC FUNCTIONS
 +*/
 +// Loads defaults then args into runtime variables.
 +function overlib(){
 +if(!(OLloaded&&OLgateOK))return;if((OLexclusivePI)&&OLisExclusive(arguments))return true;if(OLchkMh)OLmh();
 +if(OLndt&&!OLtimerid)OLndt=0;if(over)cClick();if(parent!=self){if(parent.OLo2Ref){parent.OLeval(parent.OLo2Ref);
 +parent.OLo2Ref="";}if(parent.OLifRef){parent.OLeval(parent.OLifRef);parent.OLifRef="";}}if(OLo2Ref){eval(OLo2Ref);
 +OLo2Ref="";}if(OLifRef){eval(OLifRef);OLifRef="";}OLload(OLp1or2);OLload(OLp1);OLfnRef="";OLifX=0;OLifY=0;OLhover=0;
 +OLsetRunTimeVar();OLparseTokens('o3_',arguments);if(!(over=OLmkLyr()))return false;if(o3_decode)OLdecode();if(OLprintPI)
 +OLchkPrint();if(OLbubblePI)OLchkForBubbleEffect();if(OLdebugPI)OLsetDebugCanShow();if(OLshadowPI)OLinitShadow();
 +if(OLiframePI)OLinitIfs();if(OLfilterPI)OLinitFilterLyr();if(OLexclusivePI&&o3_exclusive&&o3_exclusivestatus!="")
 +o3_status=o3_exclusivestatus;else if(o3_autostatus==2&&o3_cap!="")o3_status=o3_cap;else if(o3_autostatus==1&&o3_text!="")
 +o3_status=o3_text;if(!o3_delay){return OLmain();}else{OLdelayid=setTimeout("OLmain()",o3_delay);if(o3_status!=""){
 +self.status=o3_status;return true;}else if(!(OLop7&&event&&event.type=='mouseover'))return false;}
 +}
 +function OLeval(s){eval(s);}
 +
 +// Clears popups if appropriate
 +function nd(time){
 +if(OLloaded&&OLgateOK){if(!((OLexclusivePI)&&OLisExclusive())){if(time&&over&&!o3_delay){
 +if(OLtimerid>0)clearTimeout(OLtimerid);OLtimerid=(OLhover&&o3_frame==self&&!OLcursorOff())?0:
 +setTimeout("cClick()",(o3_timeout=OLndt=time));}else{if(!OLshowingsticky){OLallowmove=0;
 +if(over)OLhideObject(over);}}}}return false;
 +}
 +
 +// Close function for stickies
 +function cClick(){
 +if(OLloaded&&OLgateOK){OLhover=0;if(over){if(OLo2Ref){eval(OLo2Ref);OLo2Ref="";}if(OLovertwoPI&&over==over2)cClick2();
 +OLhideObject(over);OLshowingsticky=0;OLallowmove=0;}if(OLmodalPI)OLclearModal();}return false;
 +}
 +
 +// Sets page-specific defaults.
 +function OLpageDefaults(){
 +OLparseTokens('ol_',arguments);
 +}
 +
 +// Gets object referenced by its id or name
 +function OLgetRef(l,d){var r=OLgetRefById(l,d);return (r)?r:OLgetRefByName(l,d);}
 +
 +// For unsupported browsers.
 +function no_overlib(){return false;}
 +
 +/*
 + OVERLIB MAIN FUNCTION SET
 +*/
 +function OLmain(){
 +o3_delay=0;if(parent!=self&&o3_frame==parent&&parent.OLscrollPI&&parent.over)parent.OLclearScroll();if(o3_frame==self){
 +if(o3_noclose)OLoptMOUSEOFF(0);else if(o3_mouseoff)OLoptMOUSEOFF(1);}if(o3_sticky){OLshowingsticky=1;if(OLfnRef&&
 +parent!=self&&o3_frame==parent&&parent.overlib){parent.OLifRef=OLfnRef+'cClick()';}}OLdoLyr();OLallowmove=0;if(o3_timeout>0){
 +if(OLtimerid>0)clearTimeout(OLtimerid);OLtimerid=setTimeout("cClick()",o3_timeout);}OLchkRef();OLdisp(o3_status);
 +if(OLdraggablePI)OLcheckDrag();if(o3_status!="")return true;else if(!(OLop7&&event&&event.type=='mouseover'))return false;
 +}
 +function OLchkRef(){
 +if(o3_ref){OLrefXY=OLgetRefXY(o3_ref);if(OLrefXY[0]==null&&OLcrossframePI)OLchkIfRef();
 +if(OLrefXY[0]==null){o3_ref="";o3_midx=0;o3_midy=0;}}
 +}
 +
 +// Loads o3_ variables
 +function OLload(c){var i,m=c.split(',');for(i=0;i<m.length;i++)eval('o3_'+m[i]+'=ol_'+m[i]);}
 +
 +// Chooses LGF 
 +function OLdoLGF(){
 +return (o3_background!=''||o3_fullhtml)?OLcontentBackground(o3_text,o3_background,o3_fullhtml):(o3_cap=="")?
 +OLcontentSimple(o3_text):(o3_sticky)?OLcontentCaption(o3_text,o3_cap,o3_close):OLcontentCaption(o3_text,o3_cap,'');
 +}
 +
 +// Makes Layer
 +function OLmkLyr(id,f,z){
 +id=(id||'overDiv');f=(f||o3_frame);z=(z||1000);var fd=f.document,d=OLgetRefById(id,fd);
 +if(!d){if(OLns4)d=fd.layers[id]=new Layer(1024,f);else if(OLie4&&!OLop7){
 +fd.body.insertAdjacentHTML('AfterBegin','<div id="'+id+'"></div>');d=fd.all[id];}else{d=fd.createElement('div');
 +if(d){d.id=id;fd.body.appendChild(d);}}if(!d)return null;if(OLns4)d.zIndex=z;else{var o=d.style;o.position='absolute';
 +o.visibility='hidden';o.zIndex=z;}}return d;
 +}
 +
 +// Creates and writes layer content
 +function OLdoLyr(){
 +if(o3_sticky&&OLtimerid>0){clearTimeout(OLtimerid);OLtimerid=0;}if(o3_background==''&&!o3_fullhtml){
 +if(o3_fgbackground!='')o3_fgbackground=' background="'+o3_fgbackground+'"';
 +if(o3_bgbackground!='')o3_bgbackground=' background="'+o3_bgbackground+'"';
 +if(o3_cgbackground!='')o3_cgbackground=' background="'+o3_cgbackground+'"';
 +if(o3_fgcolor!='')o3_fgcolor=' bgcolor="'+o3_fgcolor+'"';if(o3_bgcolor!='')o3_bgcolor=' bgcolor="'+o3_bgcolor+'"';
 +if(o3_cgcolor!='')o3_cgcolor=' bgcolor="'+o3_cgcolor+'"';if(o3_height>0)o3_height=' height="'+o3_height+'"';
 +else o3_height='';}if(!OLns4)OLrepositionTo(over,(OLns6?20:0),0);var lyrHtml=OLdoLGF();
 +if(o3_wrap&&!o3_fullhtml){OLlayerWrite(lyrHtml);o3_width=(OLns4?over.clip.width:over.offsetWidth);if(OLie4){
 +var w=OLfd().clientWidth;if(o3_width>=w){if(OLop7){if(OLovertwoPI&&over==over2){var z=over2.style.zIndex;
 +o3_frame.document.body.removeChild(over);over2=OLmkLyr('overDiv2',o3_frame,z);over=over2;}else{
 +o3_frame.document.body.removeChild(over);over=OLmkLyr();}}o3_width=w-20;}}
 +if(o3_wrapmax<1&&o3_frame.innerWidth)o3_wrapmax=o3_frame.innerWidth-40;
 +if(o3_wrapmax>0&&o3_width>o3_wrapmax)o3_width=o3_wrapmax;o3_wrap=0;lyrHtml=OLdoLGF();}OLlayerWrite(lyrHtml);
 +o3_width=(OLns4?over.clip.width:over.offsetWidth);if(OLbubblePI)OLgenerateBubble(lyrHtml);
 +}
 +
 +/*
 + LAYER GENERATION FUNCTIONS
 +*/
 +// Makes simple table without caption
 +function OLcontentSimple(txt){
 +var t=OLbgLGF()+OLfgLGF(txt)+OLbaseLGF();OLsetBackground('');return t;
 +}
 +
 +// Makes table with caption and optional close link
 +function OLcontentCaption(txt,title,close){
 +var closing=(OLprintPI?OLprintCapLGF():''),closeevent='onmouseover',caption,t,cC='javascript:return '+OLfnRef
 ++(OLovertwoPI&&over==over2?'cClick2();':'cClick();');if(o3_closeclick)closeevent=(o3_closetitle?'title="'
 ++o3_closetitle+'" ':'')+'onclick';if(o3_capicon!=''&&o3_capicon.indexOf('<img')!=0)o3_capicon='<img src="'+o3_capicon
 ++'" /> ';if(close){closing+='<td align="right"><a href="'+cC+'" '+closeevent+'="'+cC+'"'+(o3_closefontclass?' class="'
 ++o3_closefontclass+'">':(OLns4?'><':'')+OLlgfUtil(0,1,'','a',o3_closecolor,o3_closefont,o3_closesize))+close+
 +(o3_closefontclass?'':(OLns4?OLlgfUtil(1,1,'','a'):''))+'</a></td>';}caption='<table id="overCap'
 ++(OLovertwoPI&&over==over2?'2':'')+'"'+OLwd(0)+' border="0" cellpadding="'+o3_captionpadding+'" cellspacing="0"'
 ++(o3_cgclass?' class="'+o3_cgclass+'"':o3_cgcolor+o3_cgbackground)+'><tr><td'+OLwd(0)+(o3_cgclass?' class="'
 ++o3_cgclass+'">':'>')+(o3_captionfontclass?'<div'+OLhL(1)+' class="'+o3_captionfontclass+'">':OLlgfUtil(0,1,'','div',
 +o3_capcolor,o3_captionfont,o3_captionsize))+o3_capicon+title+OLlgfUtil(1,1,'','div')+'</td>'+closing+'</tr></table>';
 +t=OLbgLGF()+(o3_capbelow?OLfgLGF(txt)+caption:caption+OLfgLGF(txt))+OLbaseLGF();OLsetBackground('');return t;
 +}
 +
 +// For BACKGROUND and FULLHTML commands
 +function OLcontentBackground(txt,image,hasfullhtml){
 +var t;if(hasfullhtml){t=txt;}else{t='<table'+OLwd(1)+' border="0" cellpadding="0" '+'cellspacing="0" '+'height="'
 ++o3_height+'"><tr><td colspan="3" height="'+o3_padyt+'"></td></tr><tr><td width="'+o3_padxl+'"></td><td valign="top"'
 ++OLwd(2)+'>'+OLlgfUtil(0,0,o3_textfontclass,'div',o3_textcolor,o3_textfont,o3_textsize)+txt+OLlgfUtil(1,0,'','div')
 ++'</td><td width="'+o3_padxr+'"></td></tr><tr><td colspan="3" height="'+o3_padyb+'"></td></tr></table>';}
 +OLsetBackground(image);return t;
 +}
 +
 +// LGF utilities
 +function OLbgLGF(){
 +return '<table'+OLwd(1)+o3_height+' border="0" cellpadding="'+o3_border+'" cellspacing="0"'+(o3_bgclass?' class="'
 ++o3_bgclass+'"':o3_bgcolor+o3_bgbackground)+'><tr><td>';
 +}
 +function OLfgLGF(t){
 +return '<table'+OLwd(0)+o3_height+' border="0" cellpadding="'+o3_textpadding+'" cellspacing="0"'+(o3_fgclass?' class="'
 ++o3_fgclass+'"':o3_fgcolor+o3_fgbackground)+'><tr><td valign="top"'+(o3_fgclass?' class="'+o3_fgclass+'"':'')+'>'
 ++OLlgfUtil(0,0,o3_textfontclass,'div',o3_textcolor,o3_textfont,o3_textsize)+t+(OLprintPI?OLprintFgLGF():'')
 ++OLlgfUtil(1,0,'','div')+'</td></tr></table>';
 +}
 +function OLlgfUtil(end,stg,tfc,ele,col,fac,siz){
 +if(end)return('</'+(OLns4?'font'+(stg?'></strong':''):ele)+'>');else return(tfc?'<div'+OLhL(1)+' class="'+tfc+'">':
 +((ele=='a'?'':'<')+(OLns4?(stg?'strong><':'')+'font color="'+col+'" face="'+OLquoteMultiNameFonts(fac)+'" size="'
 ++siz:(ele=='a'?'':ele)+' style="'+((ele=='div')?OLhL(0):'')+'color:'+col+(stg?';font-weight:bold':'')+';font-family:'
 ++OLquoteMultiNameFonts(fac)+';font-size:'+siz+';'+(ele=='span'?'text-decoration:underline;':''))+'">'));
 +}
 +function OLquoteMultiNameFonts(f){
 +var i,v,pM=f.split(',');for(i=0;i<pM.length;i++){v=pM[i];v=v.replace(/^\s+/,'').replace(/\s+$/,'');
 +if(/\s/.test(v) && !/['"]/.test(v)){v="\'"+v+"\'";pM[i]=v;}}return pM.join();
 +}
 +function OLbaseLGF(){
 +return ((o3_base>0&&!o3_wrap)?('<table width="100%" border="0" cellpadding="0" cellspacing="0"'+(o3_bgclass?' class="'
 ++o3_bgclass+'"':'')+'><tr><td height="'+o3_base+'"></td></tr></table>'):'')+'</td></tr></table>';
 +}
 +function OLwd(a){return(o3_wrap?'':' width="'+(!a?'100%':(a==1?o3_width:(o3_width-o3_padxl-o3_padxr)))+'"');}
 +function OLhL(s){return(s?' style="width:100%;"':'width:100%;');}
 +
 +// Loads image into the div.
 +function OLsetBackground(i){
 +if(i==''){if(OLns4)over.background.src=null;else{if(OLns6)over.style.width='';over.style.backgroundImage='none';}}
 +else{if(OLns4)over.background.src=i;else{if(OLns6)over.style.width=o3_width+'px';over.style.backgroundImage='url('+i+')';}}
 +}
 +
 +/*
 + HANDLING FUNCTIONS
 +*/
 +// Displays layer
 +function OLdisp(s){
 +if(OLmodalPI&&!o3_modalscroll)OLchkModal();if(!OLallowmove){if(OLshadowPI)OLdispShadow();if(OLiframePI)OLdispIfs();
 +OLplaceLayer();if(OLmodalPI&&o3_modalscroll)OLchkModal();if(OLndt)OLshowObject(over);
 +else OLshowid=setTimeout("OLshowObject(over)",1);OLallowmove=(o3_sticky||o3_nofollow)?0:1;}OLndt=0;if(s!="")self.status=s;
 +}
 +
 +// Decides placement of layer.
 +function OLplaceLayer(){
 +var snp,X,Y,pgLeft,pgTop,pWd=o3_width,pHt,iWd=100,iHt=100,SB=0,LM=0,CX=0,TM=0,BM=0,CY=0,o=OLfd(),
 +nsb=(OLgek>=20010505&&!o3_frame.scrollbars.visible)?1:0;
 +if(!OLkht&&o&&o.clientWidth)iWd=o.clientWidth;
 +else if(o3_frame.innerWidth){SB=Math.ceil(1.4*(o3_frame.outerWidth-o3_frame.innerWidth));
 +if(SB>20)SB=20;iWd=o3_frame.innerWidth;}
 +pgLeft=(OLie4)?o.scrollLeft:o3_frame.pageXOffset;
 +if(OLie55&&OLfilterPI&&o3_filter&&o3_filtershadow)SB=CX=5;else
 +if((OLshadowPI)&&bkdrop&&o3_shadow&&o3_shadowx){SB+=((o3_shadowx>0)?o3_shadowx:0);
 +LM=((o3_shadowx<0)?Math.abs(o3_shadowx):0);CX=Math.abs(o3_shadowx);}
 +if(o3_ref!=""||o3_fixx> -1||o3_relx!=null||o3_midx!=null){
 +if(o3_ref!=""){X=OLrefXY[0];if(OLie55&&OLfilterPI&&o3_filter&&o3_filtershadow){
 +if(o3_refp=='UR'||o3_refp=='LR')X-=5;}
 +else if((OLshadowPI)&&bkdrop&&o3_shadow&&o3_shadowx){
 +if(o3_shadowx<0&&(o3_refp=='UL'||o3_refp=='LL'))X-=o3_shadowx;else
 +if(o3_shadowx>0&&(o3_refp=='UR'||o3_refp=='LR'))X-=o3_shadowx;}
 +}else{if(o3_midx!=null){
 +X=parseInt(pgLeft+((iWd-pWd-SB-LM)/2)+o3_midx);
 +}else{if(o3_relx!=null){
 +if(o3_relx>=0)X=pgLeft+o3_relx+LM;else X=pgLeft+o3_relx+iWd-pWd-SB;
 +}else{X=o3_fixx+LM;}}}
 +}else{
 +if(o3_hauto){
 +if(o3_hpos==LEFT&&OLx-pgLeft+OLifX<iWd/2&&OLx-pWd-o3_offsetx+OLifX<pgLeft+LM)o3_hpos=RIGHT;else
 +if(o3_hpos==RIGHT&&OLx-pgLeft+OLifX>iWd/2&&OLx+pWd+o3_offsetx+OLifX>pgLeft+iWd-SB)o3_hpos=LEFT;}
 +X=(o3_hpos==CENTER)?parseInt(OLx-((pWd+CX)/2)+o3_offsetx):
 +(o3_hpos==LEFT)?OLx-o3_offsetx-pWd:OLx+o3_offsetx;
 +if(o3_snapx>1){
 +snp=X % o3_snapx;
 +if(o3_hpos==LEFT){X=X-(o3_snapx+snp);}else{X=X+(o3_snapx-snp);}}X+=OLifX;}
 +if(!o3_nojustx&&X+pWd>pgLeft+iWd-SB)
 +X=iWd+pgLeft-pWd-SB;if(!o3_nojustx&&X-LM<pgLeft)X=pgLeft+LM;
 +pgTop=OLie4?o.scrollTop:o3_frame.pageYOffset;
 +if(!OLkht&&!nsb&&o&&o.clientHeight)iHt=o.clientHeight;
 +else if(o3_frame.innerHeight)iHt=o3_frame.innerHeight;
 +if(OLbubblePI&&o3_bubble)pHt=OLbubbleHt;else pHt=OLns4?over.clip.height:over.offsetHeight;
 +if((OLshadowPI)&&bkdrop&&o3_shadow&&o3_shadowy){TM=(o3_shadowy<0)?Math.abs(o3_shadowy):0;
 +if(OLie55&&OLfilterPI&&o3_filter&&o3_filtershadow)BM=CY=5;else
 +BM=(o3_shadowy>0)?o3_shadowy:0;CY=Math.abs(o3_shadowy);}
 +if(o3_ref!=""||o3_fixy> -1||o3_rely!=null||o3_midy!=null){
 +if(o3_ref!=""){Y=OLrefXY[1];if(OLie55&&OLfilterPI&&o3_filter&&o3_filtershadow){
 +if(o3_refp=='LL'||o3_refp=='LR')Y-=5;}else if((OLshadowPI)&&bkdrop&&o3_shadow&&o3_shadowy){
 +if(o3_shadowy<0&&(o3_refp=='UL'||o3_refp=='UR'))Y-=o3_shadowy;else
 +if(o3_shadowy>0&&(o3_refp=='LL'||o3_refp=='LR'))Y-=o3_shadowy;}
 +}else{if(o3_midy!=null){
 +Y=parseInt(pgTop+((iHt-pHt-CY)/2)+o3_midy);
 +}else{if(o3_rely!=null){
 +if(o3_rely>=0)Y=pgTop+o3_rely+TM;else Y=pgTop+o3_rely+iHt-pHt-BM;}else{
 +Y=o3_fixy+TM;}}}
 +}else{
 +if(o3_vauto){
 +if(o3_vpos==ABOVE&&OLy-pgTop+OLifY<iHt/2&&OLy-pHt-o3_offsety+OLifY<pgTop)o3_vpos=BELOW;else
 +if(o3_vpos==BELOW&&OLy-pgTop+OLifY>iHt/2&&OLy+pHt+o3_offsety+((OLns4||OLkht)?17:0)+OLifY>pgTop+iHt-BM)
 +o3_vpos=ABOVE;}Y=(o3_vpos==VCENTER)?parseInt(OLy-((pHt+CY)/2)+o3_offsety):
 +(o3_vpos==ABOVE)?OLy-(pHt+o3_offsety+BM):OLy+o3_offsety+TM;
 +if(o3_snapy>1){
 +snp=Y % o3_snapy;
 +if(pHt>0&&o3_vpos==ABOVE){Y=Y-(o3_snapy+snp);}else{Y=Y+(o3_snapy-snp);}}Y+=OLifY;}
 +if(!o3_nojusty&&Y+pHt+BM>pgTop+iHt)Y=pgTop+iHt-pHt-BM;if(!o3_nojusty&&Y-TM<pgTop)Y=pgTop+TM;
 +OLrepositionTo(over,X,Y);
 +if(OLshadowPI)OLrepositionShadow(X,Y);if(OLiframePI)OLrepositionIfs(X,Y);
 +if(OLns6&&o3_frame.innerHeight){iHt=o3_frame.innerHeight;OLrepositionTo(over,X,Y);}
 +if(OLscrollPI)OLchkScroll(X-pgLeft,Y-pgTop);
 +}
 +
 +// Chooses body or documentElement
 +function OLfd(f){
 +var fd=((f)?f:o3_frame).document,fdc=fd.compatMode,fdd=fd.documentElement;
 +return (!OLop7&&fdc&&fdc!='BackCompat'&&fdd&&fdd.clientWidth)?fd.documentElement:fd.body;
 +}
 +
 +// Gets location of REFerence object
 +function OLgetRefXY(r,d){
 +var o=OLgetRef(r,d),ob=o,rXY=[o3_refx,o3_refy],of;if(!o)return [null,null];if(OLns4){
 +if(typeof o.length!='undefined'&&o.length>1){ob=o[0];rXY[0]+=o[0].x+o[1].pageX;rXY[1]+=o[0].y+o[1].pageY;}else{
 +if((o.toString().indexOf('Image')!= -1)||(o.toString().indexOf('Anchor')!= -1)){rXY[0]+=o.x;rXY[1]+=o.y;}
 +else{rXY[0]+=o.pageX;rXY[1]+=o.pageY;}}}else{rXY[0]+=OLpageLoc(o,'Left');rXY[1]+=OLpageLoc(o,'Top');}
 +of=OLgetRefOffsets(ob);rXY[0]+=of[0];rXY[1]+=of[1];return rXY;
 +}
 +
 +// Seeks REFerence by id
 +function OLgetRefById(l,d){
 +l=(l||'overDiv');d=(d||o3_frame.document);var j,r;if(d.getElementById)return d.getElementById(l);
 +if(OLie4&&d.all)return d.all[l];if(d.layers&&d.layers.length>0){if(d.layers[l])return d.layers[l];
 +for(j=0;j<d.layers.length;j++){r=OLgetRefById(l,d.layers[j].document);if(r)return r;}}return null;
 +}
 +
 +// Seeks REFerence by name
 +function OLgetRefByName(l,d){
 +d=(d||o3_frame.document);var j,r,v=OLie4?d.all.tags('iframe'):OLns6?d.getElementsByTagName('iframe'):null;
 +if(typeof d.images!='undefined'&&d.images[l])return d.images[l];
 +if(typeof d.anchors!='undefined'&&d.anchors[l])return d.anchors[l];
 +if(v)for(j=0;j<v.length;j++)if(v[j].name==l)return v[j];if(d.layers&&d.layers.length>0)for(j=0;j<d.layers.length;j++){
 +r=OLgetRefByName(l,d.layers[j].document);if(r&&r.length>0)return r;else if(r)return [r,d.layers[j]];}return null;
 +}
 +
 +// Gets layer vs REFerence offsets
 +function OLgetRefOffsets(o){
 +var c=o3_refc.toUpperCase(),p=o3_refp.toUpperCase(),W=0,H=0,pW=0,pH=0,of=[0,0];pW=(OLbubblePI&&o3_bubble)?
 +o3_width:OLns4?over.clip.width:over.offsetWidth;pH=(OLbubblePI&&o3_bubble)?OLbubbleHt:OLns4?
 +over.clip.height:over.offsetHeight;if((!OLop7)&&o.toString().indexOf('Image')!= -1){W=o.width;H=o.height;}
 +else if((!OLop7)&&o.toString().indexOf('Anchor')!= -1){c=o3_refc='UL';}else{W=(OLns4)?o.clip.width:o.offsetWidth;
 +H=(OLns4)?o.clip.height:o.offsetHeight;}if((OLns4||(OLns6&&OLgek))&&o.border){W+=2*parseInt(o.border);
 +H+=2*parseInt(o.border);}if(c=='UL'){of=(p=='UR')?[-pW,0]:(p=='LL')?[0,-pH]:(p=='LR')?[-pW,-pH]:[0,0];}else if(c=='UR'){
 +of=(p=='UR')?[W-pW,0]:(p=='LL')?[W,-pH]:(p=='LR')?[W-pW,-pH]:[W,0];}else if(c=='LL'){of=(p=='UR')?[-pW,H]:(p=='LL')?[0,H-pH]:
 +(p=='LR')?[-pW,H-pH]:[0,H];}else if(c=='LR'){of=(p=='UR')?[W-pW,H]:(p=='LL')?[W,H-pH]:(p=='LR')?[W-pW,H-pH]:[W,H];}return of;
 +}
 +
 +// Gets x or y location of object
 +function OLpageLoc(o,t){
 +var l=0,s=o;while(o.offsetParent&&o.offsetParent.tagName.toLowerCase()!='html'){l+=o['offset'+t];o=o.offsetParent;}
 +l+=o['offset'+t];while(s=s.parentNode){if((s['scroll'+t]>0)&&s.tagName.toLowerCase()=='div')l-=s['scroll'+t];}return l;
 +}
 +
 +// Moves layer
 +function OLmouseMove(e){
 +var e=(e||event);OLcC=(OLovertwoPI&&over2&&over==over2?cClick2:cClick);OLx=(e.pageX||e.clientX+OLfd().scrollLeft);
 +OLy=(e.pageY||e.clientY+OLfd().scrollTop);if((OLallowmove&&over)&&(o3_frame==self||over==OLgetRefById()||(OLovertwoPI&&
 +over2==over&&over==OLgetRefById('overDiv2')))){OLplaceLayer();if(OLhidePI)OLhideUtil(0,1,1,0,0,0);}if(OLhover&&over&&
 +o3_frame==self&&OLcursorOff())if(o3_offdelay<1)OLcC();else{if(OLtimerid>0)clearTimeout(OLtimerid);
 +OLtimerid=setTimeout("OLcC()",o3_offdelay);}
 +}
 +
 +// Capture mouse and chain other scripts.
 +function OLmh(){
 +var fN,f,j,k,s,mh=OLmouseMove,w=(OLns4&&window.onmousemove),re=/function[ ]*(\w*)\(/;OLdw=document;if(document.onmousemove||
 +w){if(w)OLdw=window;f=OLdw.onmousemove.toString();fN=f.match(re);if(!fN||fN[1]=='anonymous'||fN[1]=='OLmouseMove'){OLchkMh=0;
 +return;}if(fN[1])s=fN[1]+'(e)';else{j=f.indexOf('{');k=f.lastIndexOf('}')+1;s=f.substring(j,k);}s+=';OLmouseMove(e);';
 +mh=new Function('e',s);}OLdw.onmousemove=mh;if(OLns4)OLdw.captureEvents(Event.MOUSEMOVE);
 +}
 +
 +/*
 + PARSING
 +*/
 +function OLparseTokens(pf,ar){
 +var i,v,md= -1,par=(pf!='ol_'),p=OLpar,q=OLparQuo,t=OLtoggle;OLudf=(par&&!ar.length?1:0);
 +for(i=0;i<ar.length;i++){if(md<0){if(typeof ar[i]=='number'){OLudf=(par?1:0);i--;}
 +else{switch(pf){case 'ol_':ol_text=ar[i];break;default:o3_text=ar[i];}}md=0;}else{
 +if(ar[i]==INARRAY){OLudf=0;eval(pf+'text=ol_texts['+ar[++i]+']');continue;}
 +if(ar[i]==CAPARRAY){eval(pf+'cap=ol_caps['+ar[++i]+']');continue;}
 +if(ar[i]==CAPTION){q(ar[++i],pf+'cap');continue;}
 +if(Math.abs(ar[i])==STICKY){t(ar[i],pf+'sticky');continue;}
 +if(Math.abs(ar[i])==NOFOLLOW){t(ar[i],pf+'nofollow');continue;}
 +if(ar[i]==BACKGROUND){q(ar[++i],pf+'background');continue;}
 +if(Math.abs(ar[i])==NOCLOSE){t(ar[i],pf+'noclose');continue;}
 +if(Math.abs(ar[i])==MOUSEOFF){t(ar[i],pf+'mouseoff');continue;}
 +if(ar[i]==OFFDELAY){p(ar[++i],pf+'offdelay');continue;}
 +if(ar[i]==RIGHT||ar[i]==LEFT||ar[i]==CENTER){p(ar[i],pf+'hpos');continue;}
 +if(ar[i]==OFFSETX){p(ar[++i],pf+'offsetx');continue;}
 +if(ar[i]==OFFSETY){p(ar[++i],pf+'offsety');continue;}
 +if(ar[i]==FGCOLOR){q(ar[++i],pf+'fgcolor');continue;}
 +if(ar[i]==BGCOLOR){q(ar[++i],pf+'bgcolor');continue;}
 +if(ar[i]==CGCOLOR){q(ar[++i],pf+'cgcolor');continue;}
 +if(ar[i]==TEXTCOLOR){q(ar[++i],pf+'textcolor');continue;}
 +if(ar[i]==CAPCOLOR){q(ar[++i],pf+'capcolor');continue;}
 +if(ar[i]==CLOSECOLOR){q(ar[++i],pf+'closecolor');continue;}
 +if(ar[i]==WIDTH){p(ar[++i],pf+'width');continue;}
 +if(Math.abs(ar[i])==WRAP){t(ar[i],pf+'wrap');continue;}
 +if(ar[i]==WRAPMAX){p(ar[++i],pf+'wrapmax');continue;}
 +if(ar[i]==HEIGHT){p(ar[++i],pf+'height');continue;}
 +if(ar[i]==BORDER){p(ar[++i],pf+'border');continue;}
 +if(ar[i]==BASE){p(ar[++i],pf+'base');continue;}
 +if(ar[i]==STATUS){q(ar[++i],pf+'status');continue;}
 +if(Math.abs(ar[i])==AUTOSTATUS){v=pf+'autostatus';
 +eval(v+'=('+ar[i]+'<0)?('+v+'==2?2:0):('+v+'==1?0:1)');continue;}
 +if(Math.abs(ar[i])==AUTOSTATUSCAP){v=pf+'autostatus';
 +eval(v+'=('+ar[i]+'<0)?('+v+'==1?1:0):('+v+'==2?0:2)');continue;}
 +if(ar[i]==CLOSETEXT){q(ar[++i],pf+'close');continue;}
 +if(ar[i]==SNAPX){p(ar[++i],pf+'snapx');continue;}
 +if(ar[i]==SNAPY){p(ar[++i],pf+'snapy');continue;}
 +if(ar[i]==FIXX){p(ar[++i],pf+'fixx');continue;}
 +if(ar[i]==FIXY){p(ar[++i],pf+'fixy');continue;}
 +if(ar[i]==RELX){p(ar[++i],pf+'relx');continue;}
 +if(ar[i]==RELY){p(ar[++i],pf+'rely');continue;}
 +if(ar[i]==MIDX){p(ar[++i],pf+'midx');continue;}
 +if(ar[i]==MIDY){p(ar[++i],pf+'midy');continue;}
 +if(ar[i]==REF){q(ar[++i],pf+'ref');continue;}
 +if(ar[i]==REFC){q(ar[++i],pf+'refc');continue;}
 +if(ar[i]==REFP){q(ar[++i],pf+'refp');continue;}
 +if(ar[i]==REFX){p(ar[++i],pf+'refx');continue;}
 +if(ar[i]==REFY){p(ar[++i],pf+'refy');continue;}
 +if(ar[i]==FGBACKGROUND){q(ar[++i],pf+'fgbackground');continue;}
 +if(ar[i]==BGBACKGROUND){q(ar[++i],pf+'bgbackground');continue;}
 +if(ar[i]==CGBACKGROUND){q(ar[++i],pf+'cgbackground');continue;}
 +if(ar[i]==PADX){p(ar[++i],pf+'padxl');p(ar[++i],pf+'padxr');continue;}
 +if(ar[i]==PADY){p(ar[++i],pf+'padyt');p(ar[++i],pf+'padyb');continue;}
 +if(Math.abs(ar[i])==FULLHTML){t(ar[i],pf+'fullhtml');continue;}
 +if(ar[i]==BELOW||ar[i]==ABOVE||ar[i]==VCENTER){p(ar[i],pf+'vpos');continue;}
 +if(ar[i]==CAPICON){q(ar[++i],pf+'capicon');continue;}
 +if(ar[i]==TEXTFONT){q(ar[++i],pf+'textfont');continue;}
 +if(ar[i]==CAPTIONFONT){q(ar[++i],pf+'captionfont');continue;}
 +if(ar[i]==CLOSEFONT){q(ar[++i],pf+'closefont');continue;}
 +if(ar[i]==TEXTSIZE){q(ar[++i],pf+'textsize');continue;}
 +if(ar[i]==CAPTIONSIZE){q(ar[++i],pf+'captionsize');continue;}
 +if(ar[i]==CLOSESIZE){q(ar[++i],pf+'closesize');continue;}
 +if(ar[i]==TIMEOUT){p(ar[++i],pf+'timeout');continue;}
 +if(ar[i]==DELAY){p(ar[++i],pf+'delay');continue;}
 +if(Math.abs(ar[i])==HAUTO){t(ar[i],pf+'hauto');continue;}
 +if(Math.abs(ar[i])==VAUTO){t(ar[i],pf+'vauto');continue;}
 +if(Math.abs(ar[i])==NOJUSTX){t(ar[i],pf+'nojustx');continue;}
 +if(Math.abs(ar[i])==NOJUSTY){t(ar[i],pf+'nojusty');continue;}
 +if(Math.abs(ar[i])==CLOSECLICK){t(ar[i],pf+'closeclick');continue;}
 +if(ar[i]==CLOSETITLE){q(ar[++i],pf+'closetitle');continue;}
 +if(ar[i]==FGCLASS){q(ar[++i],pf+'fgclass');continue;}
 +if(ar[i]==BGCLASS){q(ar[++i],pf+'bgclass');continue;}
 +if(ar[i]==CGCLASS){q(ar[++i],pf+'cgclass');continue;}
 +if(ar[i]==TEXTPADDING){p(ar[++i],pf+'textpadding');continue;}
 +if(ar[i]==TEXTFONTCLASS){q(ar[++i],pf+'textfontclass');continue;}
 +if(ar[i]==CAPTIONPADDING){p(ar[++i],pf+'captionpadding');continue;}
 +if(ar[i]==CAPTIONFONTCLASS){q(ar[++i],pf+'captionfontclass');continue;}
 +if(ar[i]==CLOSEFONTCLASS){q(ar[++i],pf+'closefontclass');continue;}
 +if(Math.abs(ar[i])==CAPBELOW){t(ar[i],pf+'capbelow');continue;}
 +if(ar[i]==LABEL){q(ar[++i],pf+'label');continue;}
 +if(Math.abs(ar[i])==DECODE){t(ar[i],pf+'decode');continue;}
 +if(ar[i]==DONOTHING){continue;}
 +i=OLparseCmdLine(pf,i,ar);}}
 +if((OLfunctionPI)&&OLudf&&o3_function)o3_text=o3_function();
 +if(pf=='o3_')OLfontSize();
 +}
 +function OLpar(a,v){eval(v+'='+a);}
 +function OLparQuo(a,v){eval(v+"='"+OLescSglQt(a)+"'");}
 +function OLescSglQt(s){return s.toString().replace(/\\/g,"\\\\").replace(/'/g,"\\'");}
 +function OLtoggle(a,v){eval(v+'=('+v+'==0&&'+a+'>=0)?1:0');}
 +function OLhasDims(s){return /[%\-a-z]+$/.test(s);}
 +function OLfontSize(){
 +var i;if(OLhasDims(o3_textsize)){if(OLns4)o3_textsize="2";}else
 +if(!OLns4){i=parseInt(o3_textsize);o3_textsize=(i>0&&i<8)?OLpct[i]:OLpct[0];}
 +if(OLhasDims(o3_captionsize)){if(OLns4)o3_captionsize="2";}else
 +if(!OLns4){i=parseInt(o3_captionsize);o3_captionsize=(i>0&&i<8)?OLpct[i]:OLpct[0];}
 +if(OLhasDims(o3_closesize)){if(OLns4)o3_closesize="2";}else
 +if(!OLns4){i=parseInt(o3_closesize);o3_closesize=(i>0&&i<8)?OLpct[i]:OLpct[0];}
 +if(OLprintPI)OLprintDims();
 +}
 +function OLdecode(){
 +var re=/%[0-9A-Fa-f]{2,}/,t=o3_text,c=o3_cap,u=unescape,d=!OLns4&&(!OLgek||OLgek>=20020826)&&typeof decodeURIComponent?
 +decodeURIComponent:u;if(typeof(window.TypeError)=='function'){if(re.test(t)){eval(new Array('try{','o3_text=d(t);',
 +'}catch(e){','o3_text=u(t);','}').join('\n'))};if(c&&re.test(c)){eval(new Array('try{','o3_cap=d(c);','}catch(e){',
 +'o3_cap=u(c);','}').join('\n'))}}else{if(re.test(t))o3_text=u(t);if(c&&re.test(c))o3_cap=u(c);}
 +}
 +
 +/*
 + LAYER FUNCTIONS
 +*/
 +// Writes to layer
 +function OLlayerWrite(t){
 +t+="\n";if(OLns4){over.document.write(t);over.document.close();}else if(typeof over.innerHTML!='undefined'){
 +if(OLieM)over.innerHTML='';over.innerHTML=t;}else{var range=o3_frame.document.createRange();range.setStartAfter(over);
 +var domfrag=range.createContextualFragment(t);while(over.hasChildNodes()){over.removeChild(over.lastChild);}
 +over.appendChild(domfrag);}if(OLovertwoPI&&over==over2)OLover2HTML=t;else OLoverHTML=t;
 +if(OLprintPI)over.print=o3_print?t:null;
 +}
 +
 +// Makes object visible
 +function OLshowObject(o){
 +OLshowid=0;o=(OLns4)?o:o.style;if(((OLfilterPI)&&!OLchkFilter(o))||!OLfilterPI)o.visibility="visible";
 +if(OLshadowPI)OLshowShadow();if(OLiframePI)OLshowIfs();if(OLhidePI)OLhideUtil(1,1,0);
 +}
 +
 +// Hides object
 +function OLhideObject(o){
 +if(OLshowid>0){clearTimeout(OLshowid);OLshowid=0;}if(OLtimerid>0)clearTimeout(OLtimerid);
 +if(OLdelayid>0)clearTimeout(OLdelayid);OLtimerid=0;OLdelayid=0;self.status="";o3_label=ol_label;
 +if(o3_frame!=self)o=OLgetRefById();if(o){if(o.onmouseover)o.onmouseover=null;if(OLscrollPI&&o==over)OLclearScroll();
 +if(OLdraggablePI)OLclearDrag();if(OLfilterPI)OLcleanupFilter(o);if(OLshadowPI)OLhideShadow();var os=(OLns4)?o:o.style;
 +if(((OLfilterPI)&&!OLchkFadeOut(os))||!OLfilterPI){os.visibility="hidden";if(!OLie55||!OLfilterPI||!o3_filter||
 +o3_fadeout<0)o.innerHTML='';}if(OLhidePI&&o==over)OLhideUtil(0,0,1);if(OLiframePI)OLhideIfs(o);}
 +}
 +
 +// Moves layer
 +function OLrepositionTo(o,xL,yL){
 +o=(OLns4)?o:o.style;o.left=(OLns4?xL:xL+'px');o.top=(OLns4?yL:yL+'px');
 +}
 +
 +// Handle NOCLOSE-MOUSEOFF
 +function OLoptMOUSEOFF(c){
 +if(!c)o3_close="";
 +over.onmouseover=function(){OLhover=1;if(OLtimerid>0){clearTimeout(OLtimerid);OLtimerid=0;}}
 +}
 +function OLcursorOff(){
 +var o=(OLns4?over:over.style),pHt=OLns4?over.clip.height:over.offsetHeight,left=parseInt(o.left),top=parseInt(o.top),
 +right=left+o3_width,bottom=top+((OLbubblePI&&o3_bubble)?OLbubbleHt:pHt);
 +if(OLx<left||OLx>right||OLy<top||OLy>bottom)return true;return false;
 +}
 +
 +/*
 + REGISTRATION
 +*/
 +function OLsetRunTimeVar(){
 +if(OLrunTime.length)for(var k=0;k<OLrunTime.length;k++)OLrunTime[k]();
 +}
 +function OLparseCmdLine(pf,i,ar){
 +if(OLcmdLine.length){for(var k=0;k<OLcmdLine.length;k++){var j=OLcmdLine[k](pf,i,ar);if(j>-1){i=j;break;}}}return i;
 +}
 +function OLregCmds(c){
 +if(typeof c!='string')return;var pM=c.split(',');pMtr=pMtr.concat(pM);
 +for(var i=0;i<pM.length;i++)eval(pM[i].toUpperCase()+'='+pmCnt++);
 +}
 +function OLregRunTimeFunc(f){
 +if(typeof f=='object')OLrunTime=OLrunTime.concat(f);else OLrunTime[OLrunTime.length++]=f;
 +}
 +function OLregCmdLineFunc(f){
 +if(typeof f=='object')OLcmdLine=OLcmdLine.concat(f);else OLcmdLine[OLcmdLine.length++]=f;
 +}
 +
 +OLloaded=1;
 diff --git a/fs_selfservice/FS-SelfService/cgi/overlibmws_crossframe.js b/fs_selfservice/FS-SelfService/cgi/overlibmws_crossframe.js new file mode 100644 index 000000000..dd6422313 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/overlibmws_crossframe.js @@ -0,0 +1,53 @@ +/*
 + overlibmws_crossframe.js plug-in module - Copyright Foteos Macrides 2003-2008. All rights reserved.
 +   For support of FRAME.
 +   Initial: August 3, 2003 - Last Revised: January 16, 2008
 + See the Change History and Command Reference for overlibmws via:
 +
 +	http://www.macridesweb.com/oltest/
 +
 + Published under an open source license: http://www.macridesweb.com/oltest/license.html
 +*/
 +
 +OLloaded=0;
 +OLregCmds('frame');
 +
 +function OLparseCrossframe(pf,i,ar){
 +var k=i,v;
 +if(k<ar.length){
 +if(ar[k]==FRAME){v=ar[++k];if(pf=='ol_')ol_frame=v;else OLoptFRAME(v);return k;}}
 +return -1;
 +}
 +
 +function OLgetFrameRef(thisFrame,ofrm){
 +var i,v,retVal='';for(i=0;i<thisFrame.length;i++){if((((thisFrame[i].length>0)))&&(((OLns4))||
 +((OLie4)&&(v=thisFrame[i].document.all.tags('iframe'))!=null&&v.length==0)||
 +((OLns6)&&(v=thisFrame[i].document.getElementsByTagName('iframe'))!=null&&v.length==0))){
 +retVal=OLgetFrameRef(thisFrame[i],ofrm);if(retVal=='')continue;}
 +else if(thisFrame[i]!=ofrm)continue;retVal='['+i+']'+retVal;break;}
 +return retVal;
 +}
 +
 +function OLoptFRAME(frm){
 +o3_frame=OLmkLyr('overDiv',frm)?frm:self;if(o3_frame!=self){var l,tFrm=OLgetFrameRef(top.frames,o3_frame),
 +sFrm=OLgetFrameRef(top.frames,ol_frame);if(sFrm.length==tFrm.length) {l=tFrm.lastIndexOf('[');if(l){
 +while(sFrm.substring(0,l)!=tFrm.substring(0,l))l=tFrm.lastIndexOf('[',l-1);tFrm=tFrm.substr(l);sFrm=sFrm.substr(l);}}
 +var i,k,cnt=0,p='',str=tFrm;while((k=str.lastIndexOf('['))!= -1){cnt++;str=str.substring(0,k);}
 +for(i=0;i<cnt;i++)p=p+'parent.';OLfnRef=p+'frames'+sFrm+'.';var n=window.name,o;
 +if((n&&parent!=self&&o3_frame==parent)&&(o=OLgetRef(n,parent.document))){if(OLie4&&!OLop7){
 +OLx=event.clientX+OLfd().scrollLeft;OLy=event.clientY+OLfd().scrollTop;}
 +OLifX=OLpageLoc(o,'Left')-(OLie4&&!OLop7?OLfd().scrollLeft:self.pageXOffset);
 +OLifY=OLpageLoc(o,'Top')-(OLie4&&!OLop7?OLfd().scrollTop:self.pageYOffset);}}
 +}
 +
 +function OLchkIfRef(){
 +var n=(parent!=self&&o3_frame==parent)?window.name:'',o=n?OLgetRef(n):null;
 +if(o){var oR=OLgetRef(o3_ref,document);if(oR){OLrefXY=OLgetRefXY(o3_ref,document);
 +OLrefXY[0]+=(OLpageLoc(o,'Left')-(OLie4&&!OLop7?OLfd(self).scrollLeft:self.pageXOffset));
 +OLrefXY[1]+=(OLpageLoc(o,'Top')-(OLie4&&!OLop7?OLfd(self).scrollTop:self.pageYOffset));}}
 +}
 +
 +OLregCmdLineFunc(OLparseCrossframe);
 +
 +OLcrossframePI=1;
 +OLloaded=1;
 diff --git a/fs_selfservice/FS-SelfService/cgi/overlibmws_draggable.js b/fs_selfservice/FS-SelfService/cgi/overlibmws_draggable.js new file mode 100644 index 000000000..1bf0ecfd1 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/overlibmws_draggable.js @@ -0,0 +1,85 @@ +/*
 + overlibmws_draggable.js plug-in module - Copyright Foteos Macrides 2002-2008. All rights reserved.
 +   For support of the DRAGGABLE feature.
 +   Initial: August 24, 2002 - Last Revised: January 26, 2008
 + See the Change History and Command Reference for overlibmws via:
 +
 +	http://www.macridesweb.com/oltest/
 +
 + Published under an open source license: http://www.macridesweb.com/oltest/license.html
 +*/
 +
 +OLloaded=0;
 +var OLdraggableCmds='draggable,dragcap,dragid';
 +OLregCmds(OLdraggableCmds);
 +
 +// DEFAULT CONFIGURATION
 +if(OLud('draggable'))var ol_draggable=0;
 +if(OLud('dragcap'))var ol_dragcap=0;
 +if(OLud('dragid'))var ol_dragid='';
 +// END CONFIGURATION
 +
 +var o3_draggable=0,o3_dragcap=0,o3_dragid='',o3_dragging=0,OLdrg=null,OLmMv,
 +OLcX,OLcY,OLcbX,OLcbY;function OLloadDraggable(){OLload(OLdraggableCmds);}
 +function OLparseDraggable(pf,i,ar){var t=OLtoggle,k=i;if(k<ar.length){
 +if(Math.abs(ar[k])==DRAGGABLE){t(ar[k],pf+'draggable');return k;}
 +if(Math.abs(ar[k])==DRAGCAP){t(ar[k],pf+'dragcap');return k;}
 +if(ar[k]==DRAGID){OLparQuo(ar[++k],pf+'dragid');return k;}}return -1;
 +}
 +
 +function OLcheckDrag(){
 +if(o3_draggable){if(o3_sticky&&(o3_frame==self))OLinitDrag();else o3_draggable=0;}
 +}
 +function OLinitDrag(){
 +OLmMv=OLdw.onmousemove;o3_dragging=0;
 +if(OLns4){document.captureEvents(Event.MOUSEDOWN|Event.CLICK);
 +document.onmousedown=OLgrabEl;document.onclick=function(e){return routeEvent(e);}}
 +else{var dvido=(o3_dragid)?OLgetRef(o3_dragid):null,capid=(OLovertwoPI&&over==over2?
 +'overCap2':'overCap');if(dvido)dvido.onscroll=function(){OLdw.onmousemove=OLmMv;
 +OLinitDrag();};OLdrg=(o3_cap&&o3_dragcap)?OLgetRef(capid):over;
 +if(!OLdrg||!OLdrg.style)OLdrg=over;OLdrg.onmousedown=OLgrabEl;OLsetDrgCur(1);}
 +}
 +function OLsetDrgCur(d){if(!OLns4&&OLdrg)OLdrg.style.cursor=(d?'move':'auto');}
 +
 +function OLgrabEl(e){
 +var e=(e||event);
 +var cKy=(OLns4?e.modifiers&Event.ALT_MASK:(e.altKey||(OLop7&&e.ctrlKey)));o3_dragging=1;
 +if(cKy){OLsetDrgCur(0);document.onmouseup=function(){OLsetDrgCur(1);o3_dragging=0;}
 +return(OLns4?routeEvent(e):true);}
 +OLx=(e.pageX||e.clientX+OLfd().scrollLeft);OLy=(e.pageY||e.clientY+OLfd().scrollTop);
 +if(OLie4)over.onselectstart=function(){return false;}
 +if(OLns4){OLcX=OLx;OLcY=OLy;document.captureEvents(Event.MOUSEUP)}else{
 +OLcX=OLx-(OLns4?over.left:parseInt(over.style.left));
 +OLcY=OLy-(OLns4?over.top:parseInt(over.style.top));
 +if((OLshadowPI)&&bkdrop&&o3_shadow){OLcbX=OLx-(parseInt(bkdrop.style.left));
 +OLcbY=OLy-(parseInt(bkdrop.style.top));}}OLdw.onmousemove=OLmoveEl;
 +document.onmouseup=function(){
 +if(OLie4)over.onselectstart=null;o3_dragging=0;OLdw.onmousemove=OLmMv;}
 +return(OLns4?routeEvent(e):false);
 +}
 +
 +function OLmoveEl(e){
 +var e=(e||event);
 +OLx=(e.pageX||e.clientX+OLfd().scrollLeft);OLy=(e.pageY||e.clientY+OLfd().scrollTop);
 +if(o3_dragging){if(OLns4){over.moveBy(OLx-OLcX,OLy-OLcY);
 +if(OLshadowPI&&bkdrop&&o3_shadow)bkdrop.moveBy(OLx-OLcX,OLy-OLcY);}
 +else{OLrepositionTo(over,OLx-OLcX,OLy-OLcY);
 +if((OLiframePI)&&OLie55&&OLifsP1)OLrepositionTo(OLifsP1,OLx-OLcX,OLy-OLcY);
 +if((OLshadowPI)&&bkdrop&&o3_shadow){OLrepositionTo(bkdrop,OLx-OLcbX,OLy-OLcbY);
 +if((OLiframePI)&&OLie55&&OLifsSh)OLrepositionTo(OLifsSh,OLx-OLcbX,OLy-OLcbY);}}
 +if(OLhidePI)OLhideUtil(0,1,1,0,0,0);}if(OLns4){OLcX=OLx;OLcY=OLy;}
 +return false;
 +}
 +
 +function OLclearDrag(){
 +if(OLns4){document.releaseEvents(Event.MOUSEDOWN|Event.MOUSEUP|Event.CLICK);
 +document.onmousedown=document.onclick=null;}else{
 +if(OLdrg)OLdrg.onmousedown=null;over.onmousedown=null;OLsetDrgCur(0);}
 +document.onmouseup=null;o3_dragging=0;
 +}
 +
 +OLregRunTimeFunc(OLloadDraggable);
 +OLregCmdLineFunc(OLparseDraggable);
 +
 +OLdraggablePI=1;
 +OLloaded=1;
 diff --git a/fs_selfservice/FS-SelfService/cgi/overlibmws_iframe.js b/fs_selfservice/FS-SelfService/cgi/overlibmws_iframe.js new file mode 100644 index 000000000..4c937d3d7 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/overlibmws_iframe.js @@ -0,0 +1,93 @@ +/*
 + overlibmws_iframe.js plug-in module - Copyright Foteos Macrides 2003-2008. All rights reserved.
 +   Masks system controls to prevent obscuring of popops for IE v5.5 or higher.
 +   Initial: October 19, 2003 - Last Revised: January 26, 2008
 + See the Change History and Command Reference for overlibmws via:
 +
 +	http://www.macridesweb.com/oltest/
 +
 + Published under an open source license: http://www.macridesweb.com/oltest/license.html
 +*/
 +
 +OLloaded=0;
 +
 +var OLifsP1=null,OLifsSh=null,OLifsP2=null;
 +
 +// IFRAME SHIM SUPPORT FUNCTIONS
 +function OLinitIfs(){
 +if(!OLie55)return;
 +if((OLovertwoPI)&&over2&&over==over2){
 +var o=o3_frame.document.all['overIframeOvertwo'];
 +if(!o||OLifsP2!=o){OLifsP2=null;OLgetIfsP2Ref();}return;}
 +o=o3_frame.document.all['overIframe'];
 +if(!o||OLifsP1!=o){OLifsP1=null;OLgetIfsRef();}
 +if((OLshadowPI)&&o3_shadow){o=o3_frame.document.all['overIframeShadow'];
 +if(!o||OLifsSh!=o){OLifsSh=null;OLgetIfsShRef();}}
 +}
 +
 +function OLsetIfsRef(o,i,z){
 +o.id=i;o.src='javascript:false;';o.scrolling='no';var os=o.style;os.position='absolute';
 +os.top='0px';os.left='0px';os.width='1px';os.height='1px';os.visibility='hidden';
 +os.zIndex=over.style.zIndex-z;os.filter='Alpha(style=0,opacity=0)';
 +}
 +
 +function OLgetIfsRef(){
 +if(OLifsP1||!OLie55)return;
 +OLifsP1=o3_frame.document.createElement('iframe');
 +OLsetIfsRef(OLifsP1,'overIframe',2);
 +o3_frame.document.body.appendChild(OLifsP1);
 +}
 +
 +function OLgetIfsShRef(){
 +if(OLifsSh||!OLie55)return;
 +OLifsSh=o3_frame.document.createElement('iframe');
 +OLsetIfsRef(OLifsSh,'overIframeShadow',3);
 +o3_frame.document.body.appendChild(OLifsSh);
 +}
 +
 +function OLgetIfsP2Ref(){
 +if(OLifsP2||!OLie55)return;
 +OLifsP2=o3_frame.document.createElement('iframe');
 +OLsetIfsRef(OLifsP2,'overIframeOvertwo',1);
 +o3_frame.document.body.appendChild(OLifsP2);
 +}
 +
 +function OLsetDispIfs(o,w,h){
 +var os=o.style;
 +os.width=w+'px';os.height=h+'px';os.clip='rect(0px '+w+'px '+h+'px 0px)';
 +o.filters.alpha.enabled=true;
 +}
 +
 +function OLdispIfs(){
 +if(!OLie55)return;
 +var wd=over.offsetWidth,ht=over.offsetHeight;
 +if(OLfilterPI&&o3_filter&&o3_filtershadow){wd+=5;ht+=5;}
 +if((OLovertwoPI)&&over2&&over==over2){
 +if(!OLifsP2)return;
 +OLsetDispIfs(OLifsP2,wd,ht);return;}
 +if(!OLifsP1)return;
 +OLsetDispIfs(OLifsP1,wd,ht);
 +if((!OLshadowPI)||!o3_shadow||!OLifsSh)return;
 +OLsetDispIfs(OLifsSh,wd,ht);
 +}
 +
 +function OLshowIfs(){
 +if(OLifsP1){OLifsP1.style.visibility="visible";
 +if((OLshadowPI)&&o3_shadow&&OLifsSh)OLifsSh.style.visibility="visible";}
 +}
 +
 +function OLhideIfs(o){
 +if(!OLie55||o!=over)return;
 +if(OLifsP1)OLifsP1.style.visibility="hidden";
 +if((OLshadowPI)&&o3_shadow&&OLifsSh)OLifsSh.style.visibility="hidden";
 +}
 +
 +function OLrepositionIfs(X,Y){
 +if(OLie55){if((OLovertwoPI)&&over2&&over==over2){
 +if(OLifsP2)OLrepositionTo(OLifsP2,X,Y);}
 +else{if(OLifsP1){OLrepositionTo(OLifsP1,X,Y);if((OLshadowPI)&&o3_shadow&&OLifsSh)
 +OLrepositionTo(OLifsSh,X+o3_shadowx,Y+o3_shadowy);}}}
 +}
 +
 +OLiframePI=1;
 +OLloaded=1;
 diff --git a/fs_selfservice/FS-SelfService/cgi/passwd.cgi b/fs_selfservice/FS-SelfService/cgi/passwd.cgi new file mode 100755 index 000000000..1e6e2e530 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/passwd.cgi @@ -0,0 +1,60 @@ +#!/usr/bin/perl -T +#!/usr/bin/perl -Tw + +use strict; +use FS::SelfService qw(passwd); +use CGI; +use CGI::Carp qw(fatalsToBrowser); + +my $freeside_uid = scalar(getpwnam('freeside')); + +$ENV{'PATH'} ='/usr/local/bin:/usr/bin:/usr/ucb:/bin'; +$ENV{'SHELL'} = '/bin/sh'; +$ENV{'IFS'} = " \t\n"; +$ENV{'CDPATH'} = ''; +$ENV{'ENV'} = ''; +$ENV{'BASH_ENV'} = ''; + +die "passwd.cgi isn't running as freeside user\n" if $> != $freeside_uid; + +my $cgi = new CGI; + +$cgi->param('username') =~ /^([^\n]{0,255}$)/ or die "Illegal username"; +my $me = $1; + +$cgi->param('domain') =~ /^([^\n]{0,255}$)/ or die "Illegal domain"; +my $domain = $1; + +$cgi->param('old_password') =~ /^([^\n]{0,255}$)/ or die "Illegal old_password"; +my $old_password = $1; + +$cgi->param('new_password') =~ /^([^\n]{0,255}$)/ or die "Illegal new_password"; +my $new_password = $1; + +die "New passwords don't match" +  unless $new_password eq $cgi->param('new_password2'); + +my $rv = passwd( +  'username'     => $me, +  'domain'       => $domain, +  'old_password' => $old_password, +  'new_password' => $new_password, +); + +my $error = $rv->{error}; + +if ($error) { +  die $error; +} else { +  print $cgi->header(), <<END; +<html> +  <head> +    <title>Password changed</title> +  </head> +  <body bgcolor="#e8e8e8"> +    <h3>Password changed</h3> +<br>Your password has been changed. +  </body> +</html> +END +} diff --git a/fs_selfservice/FS-SelfService/cgi/passwd.html b/fs_selfservice/FS-SelfService/cgi/passwd.html new file mode 100644 index 000000000..459c96aa8 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/passwd.html @@ -0,0 +1,28 @@ +<html> +  <head> +    <title>Change password</title> +  </head> +  <body bgcolor="#e8e8e8"> +    <h3>Change password</h3> +    <form action="passwd.cgi" method="post"> +    <table bgcolor="#cccccc" border=0 cellspacing=2> +      <tr><th align="right">Username</th> +        <td><input type="text" name="username" size="18"></td> +      </tr> +      <tr><th align="right">Domain</th> +        <td><input type="text" name="domain" size="18"></td> +      </tr> +      <tr><th align="right">Current password</th> +        <td><input type="password" name="old_password" size="18"></td> +      </tr> +      <tr><th align="right">New password</th> +        <td><input type="password" name="new_password" size="18"></td> +      </tr> +      <tr><th align="right">Re-enter new password</th> +        <td><input type="password" name="new_password2" size="18"></td> +      </tr> +    </table> +    <br><input type="submit" value="Change password"> +  </body> +</html> + diff --git a/fs_selfservice/FS-SelfService/cgi/payment_results.html b/fs_selfservice/FS-SelfService/cgi/payment_results.html new file mode 100644 index 000000000..987b97efb --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/payment_results.html @@ -0,0 +1,11 @@ +<%= $url = "$selfurl?session=$session_id;action="; ''; %> +<%= include('header') %> + +<FONT SIZE=4>Payment results</FONT><BR><BR> +<%= if ( $error ) { +  $OUT .= qq!<FONT SIZE="+1" COLOR="#ff0000">Error processing your payment: $error</FONT>!; +} else { +  $OUT .= 'Your payment was processed successfully.  Thank you.'; +} %> + +<%= include('footer') %> diff --git a/fs_selfservice/FS-SelfService/cgi/process_change_bill.html b/fs_selfservice/FS-SelfService/cgi/process_change_bill.html new file mode 100644 index 000000000..a4402848d --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/process_change_bill.html @@ -0,0 +1,6 @@ +<%= $url = "$selfurl?session=$session_id;action="; ''; %> +<%= include('header') %> + +<FONT SIZE=4>Information updated successfully.</FONT> + +<%= include('footer') %> diff --git a/fs_selfservice/FS-SelfService/cgi/process_change_password.html b/fs_selfservice/FS-SelfService/cgi/process_change_password.html new file mode 100644 index 000000000..ffe0cab35 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/process_change_password.html @@ -0,0 +1,6 @@ +<%= $url = "$selfurl?session=$session_id;action="; ''; %> +<%= include('header') %> + +<FONT SIZE=4>Password changed for <%= $value %> <%= $label %>.</FONT> + +<%= include('footer') %> diff --git a/fs_selfservice/FS-SelfService/cgi/process_change_pay.html b/fs_selfservice/FS-SelfService/cgi/process_change_pay.html new file mode 100644 index 000000000..a4402848d --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/process_change_pay.html @@ -0,0 +1,6 @@ +<%= $url = "$selfurl?session=$session_id;action="; ''; %> +<%= include('header') %> + +<FONT SIZE=4>Information updated successfully.</FONT> + +<%= include('footer') %> diff --git a/fs_selfservice/FS-SelfService/cgi/process_change_pkg.html b/fs_selfservice/FS-SelfService/cgi/process_change_pkg.html new file mode 100644 index 000000000..c7c69f0a5 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/process_change_pkg.html @@ -0,0 +1,6 @@ +<%= $url = "$selfurl?session=$session_id;action="; ''; %> +<%= include('header') %> + +<FONT SIZE=4>Package change successful.</FONT> + +<%= include('footer') %> diff --git a/fs_selfservice/FS-SelfService/cgi/process_change_ship.html b/fs_selfservice/FS-SelfService/cgi/process_change_ship.html new file mode 100644 index 000000000..a4402848d --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/process_change_ship.html @@ -0,0 +1,6 @@ +<%= $url = "$selfurl?session=$session_id;action="; ''; %> +<%= include('header') %> + +<FONT SIZE=4>Information updated successfully.</FONT> + +<%= include('footer') %> diff --git a/fs_selfservice/FS-SelfService/cgi/process_order_pkg.html b/fs_selfservice/FS-SelfService/cgi/process_order_pkg.html new file mode 100755 index 000000000..b86893715 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/process_order_pkg.html @@ -0,0 +1,6 @@ +<%= $url = "$selfurl?session=$session_id;action="; ''; %> +<%= include('header') %> + +<FONT SIZE=4>Package order successful.</FONT> + +<%= include('footer') %> diff --git a/fs_selfservice/FS-SelfService/cgi/process_order_recharge.html b/fs_selfservice/FS-SelfService/cgi/process_order_recharge.html new file mode 100644 index 000000000..9dfc32807 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/process_order_recharge.html @@ -0,0 +1,6 @@ +<%= $url = "$selfurl?session=$session_id;action="; ''; %> +<%= include('header') %> + +<FONT SIZE=4><%= $svc %> recharged successfully.</FONT> + +<%= include('footer') %> diff --git a/fs_selfservice/FS-SelfService/cgi/process_svc_acct.html b/fs_selfservice/FS-SelfService/cgi/process_svc_acct.html new file mode 100644 index 000000000..39920cb0d --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/process_svc_acct.html @@ -0,0 +1,6 @@ +<%= $url = "$selfurl?session=$session_id;action="; ''; %> +<%= include('header') %> + +<FONT SIZE=4><%= $svc %> setup successfully.</FONT> + +<%= include('footer') %> diff --git a/fs_selfservice/FS-SelfService/cgi/process_svc_external.html b/fs_selfservice/FS-SelfService/cgi/process_svc_external.html new file mode 100644 index 000000000..103eb9e35 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/process_svc_external.html @@ -0,0 +1,8 @@ +<%= $url = "$selfurl?session=$session_id;action="; ''; %> +<%= include('header') %> + +<FONT SIZE=4><%= $svc %> setup successfully.</FONT> + +<BR><BR>Your serial number is <%= sprintf("%010d-$title", $id) %> + +<%= include('footer') %> diff --git a/fs_selfservice/FS-SelfService/cgi/promocode.html b/fs_selfservice/FS-SelfService/cgi/promocode.html new file mode 100644 index 000000000..f8ee7f6eb --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/promocode.html @@ -0,0 +1,14 @@ +<HTML><HEAD><TITLE>ISP Signup</TITLE></HEAD> +<BODY BGCOLOR="#e8e8e8"><FONT SIZE=7>ISP Signup - promotional code</FONT><BR><BR> +<SCRIPT> +function gotoURL(object) { +    window.location.href =  'signup.cgi?promo_code=' + object.promo_code.value; +} +</SCRIPT> +<FORM> +Enter promotional code <INPUT TYPE="text" NAME="promo_code"> +<INPUT type="submit" VALUE="Signup" onClick="gotoURL(this.form)"> + +</FORM> +</BODY> +</HTML> diff --git a/fs_selfservice/FS-SelfService/cgi/provision.html b/fs_selfservice/FS-SelfService/cgi/provision.html new file mode 100644 index 000000000..f5b2c2b71 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/provision.html @@ -0,0 +1,6 @@ +<%= $url = "$selfurl?session=$session_id;action="; ''; %> +<%= include('header') %> + +<%= include('provision_list') %> + +<%= include('footer') %> diff --git a/fs_selfservice/FS-SelfService/cgi/provision_list.html b/fs_selfservice/FS-SelfService/cgi/provision_list.html new file mode 100644 index 000000000..88d1c848b --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/provision_list.html @@ -0,0 +1,92 @@ +<FONT SIZE=4>Setup services</FONT><BR><BR> + +<SCRIPT> +function areyousure(href, message) { +    if (confirm(message) == true) +        window.location.href = href; +} +</SCRIPT> + +<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=2 BGCOLOR="#ffffff"> + +<%= foreach my $pkg ( +      grep {    scalar(@{$_->{part_svc}}) +             || scalar(@{$_->{cust_svc}}) +           } @cust_pkg +    ) { + +  $OUT .= #'<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=2 BGCOLOR="#ffffff">'. +          '<TR><TH BGCOLOR="#6666ff" COLSPAN=2>'. +          $pkg->{'pkg'}. '</TH><TH BGCOLOR="#6666ff" >' . +          qq!(<A style="font-size: smaller;color: #000000" HREF="! . +          qq!${url}customer_change_pkg;pkgnum=$pkg->{'pkgnum'};pkg=$pkg->{'pkg'}">! . +          'change</A>)</TH></TR>'; + +  my $col1 = "ffffff"; +  my $col2 = "dddddd"; +  my $col = $col1; + +  foreach my $cust_svc ( @{ $pkg->{cust_svc} } ) { +    my $td = qq!<TD BGCOLOR="#$col"!; + +    $OUT .= '<TR>'. +              "$td ALIGN=right>". $cust_svc->{label}[0]. ': </TD>'. +              "$td><B>". $cust_svc->{label}[1]. '</B>'; +    $OUT .= '<BR><I>password: '. encode_entities($cust_svc->{_password}). '</I>' +      if exists($cust_svc->{_password}); +    $OUT .= '</TD>'. +              "$td><FONT SIZE=-1>"; +               +    #if ( $cust_svc->{label}[2] eq 'svc_acct' ) { +    #  $OUT .= qq!(<A HREF="${url}changepw;svcnum=$cust_svc->{'svcnum'}">!. +    #          'change pw) '; +    #} + +    unless ( $cust_svc->{'svcnum'} == $svcnum ) { +      $OUT .= qq!(<A HREF="javascript:areyousure('${url}delete_svc;svcnum=$cust_svc->{svcnum}', 'This will permanently delete the $cust_svc->{label}[1] $cust_svc->{label}[0].  Are you sure?')">!. +              'delete</A>)'; + +    } +    $OUT .= '</FONT></TD></TR>'; +    $col = $col eq $col1 ? $col2 : $col1; +  } + +  $OUT .= '<TR><TD COLSPAN=3 BGCOLOR="#000000"></TD></TR>' +    if scalar(@{$pkg->{part_svc}}) && scalar(@{$pkg->{cust_svc}}); + +  $col = $col1; + +  foreach my $part_svc ( @{ $pkg->{part_svc} } ) { + +    my $td = qq!<TD BGCOLOR="#$col"!; + +    my $link; + +    if ( $part_svc->{'svcdb'} eq 'svc_external' +         #&& $conf->exists('svc_external-skip_manual') +    ) { +      $link = "${url}process_svc_external;". +              "pkgnum=$pkg->{'pkgnum'};". +              "svcpart=$part_svc->{'svcpart'}"; +    } else { +      $link = "${url}provision_svc;". +              "pkgnum=$pkg->{'pkgnum'};". +              "svcpart=$part_svc->{'svcpart'}"; +    } + +    $OUT .= "<TR>$td COLSPAN=3 ALIGN=center>". +            qq!<A HREF="$link">!. 'Setup '. $part_svc->{'svc'}. '</A> '. +            '('. $part_svc->{'num_avail'}. ' available)'. +            '</TD></TR>' +      #self-service only supports these services so far +      if grep { $part_svc->{'svcdb'} eq $_ } qw( svc_acct svc_external ); + +    $col = $col eq $col1 ? $col2 : $col1; +  } + +  #$OUT .= '</TABLE><BR>'; +  $OUT .= '<TR><TD BGCOLOR="#eeeeee" COLSPAN=3> </TD></TR>'; + +} %> + +</TABLE> diff --git a/fs_selfservice/FS-SelfService/cgi/provision_svc_acct.html b/fs_selfservice/FS-SelfService/cgi/provision_svc_acct.html new file mode 100644 index 000000000..bffd22fd1 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/provision_svc_acct.html @@ -0,0 +1,6 @@ +<%= $url = "$selfurl?session=$session_id;action="; ''; %> +<%= include('header') %> + +<%= include('svc_acct') %> + +<%= include('footer') %> diff --git a/fs_selfservice/FS-SelfService/cgi/recharge_prepay.html b/fs_selfservice/FS-SelfService/cgi/recharge_prepay.html new file mode 100644 index 000000000..6f0aa1f62 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/recharge_prepay.html @@ -0,0 +1,31 @@ +<%= $url = "$selfurl?session=$session_id;action="; ''; %> +<%= include('header') %> + +<FONT SIZE=4>Recharge with prepaid card</FONT><BR><BR> +<FORM NAME="OneTrueForm" METHOD="POST" ACTION="<%=$selfurl%>" onSubmit="document.OneTrueForm.process.disabled=true"> +<INPUT TYPE="hidden" NAME="session" VALUE="<%=$session_id%>"> +<INPUT TYPE="hidden" NAME="action" VALUE="recharge_results"> +<TABLE BGCOLOR="#cccccc"> +<!-- +<TR> +  <TD ALIGN="right">Amount Due</TD> +  <TD> +    <TABLE><TR><TD BGCOLOR="#ffffff"> +      $<%=sprintf("%.2f",$balance)%> +    </TD></TR></TABLE> +  </TD> +</TR> +--> +<TR> +  <TD ALIGN="right">Prepaid card number</TD> +  <TD> +    <INPUT TYPE="text" NAME="prepaid_cardnum" SIZE=20 MAXLENGTH=19 VALUE="<%=$prepaid_cardnum%>"> +  </TD> +</TR> +</TABLE> +<BR> +<INPUT TYPE="hidden" NAME="paybatch" VALUE="<%=$paybatch%>"> +<INPUT TYPE="submit" NAME="process" VALUE="Recharge"> <!-- onClick="this.disabled=true"> --> +</FORM> + +<%= include('footer') %> diff --git a/fs_selfservice/FS-SelfService/cgi/recharge_results.html b/fs_selfservice/FS-SelfService/cgi/recharge_results.html new file mode 100644 index 000000000..af15365b0 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/recharge_results.html @@ -0,0 +1,19 @@ +<%= $url = "$selfurl?session=$session_id;action="; ''; %> +<%= include('header') %> + +<FONT SIZE=4>Recharge results</FONT><BR><BR> +<%= if ( $error ) { +  $OUT .= qq!<FONT SIZE="+1" COLOR="#ff0000">Error processing your prepaid card: $error</FONT>!; +} else { +  $OUT .= 'Prepaid card recharge successful!<BR><BR>'; + +  $OUT .= '$'. sprintf('%.2f', $amount). ' added to your account.<BR><BR>' +    if $amount; + +  $OUT .= $duration. ' added to your account.<BR><BR>' +    if $seconds; + +  $OUT .= 'Thank you.'; +} %> + +<%= include('footer') %> diff --git a/fs_selfservice/FS-SelfService/cgi/regcode.html b/fs_selfservice/FS-SelfService/cgi/regcode.html new file mode 100644 index 000000000..e639b9b53 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/regcode.html @@ -0,0 +1,14 @@ +<HTML><HEAD><TITLE>ISP Signup</TITLE></HEAD> +<BODY BGCOLOR="#e8e8e8"><FONT SIZE=7>ISP Signup - registration code</FONT><BR><BR> +<SCRIPT> +function gotoURL(object) { +    window.location.href =  'signup.cgi?reg_code=' + object.reg_code.value; +} +</SCRIPT> +<FORM> +Enter registration code <INPUT TYPE="text" NAME="reg_code"> +<INPUT type="submit" VALUE="Signup" onClick="gotoURL(this.form)"> + +</FORM> +</BODY> +</HTML> diff --git a/fs_selfservice/FS-SelfService/cgi/selfservice.cgi b/fs_selfservice/FS-SelfService/cgi/selfservice.cgi new file mode 100644 index 000000000..734563be7 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/selfservice.cgi @@ -0,0 +1,738 @@ +#!/usr/bin/perl -Tw + +use strict; +use vars qw($DEBUG $cgi $session_id $form_max $template_dir); +use subs qw(do_template); +use CGI; +use CGI::Carp qw(fatalsToBrowser); +use Text::Template; +use HTML::Entities; +use Date::Format; +use Number::Format 1.50; +use FS::SelfService qw( +  access_info login_info login customer_info edit_info invoice +  payment_info process_payment realtime_collect process_prepay +  list_pkgs order_pkg signup_info order_recharge +  part_svc_info provision_acct provision_external +  unprovision_svc change_pkg domainselector +  list_svcs list_svc_usage list_cdr_usage list_support_usage +  myaccount_passwd +  mason_comp +); + +$template_dir = '.'; + +$DEBUG = 1; + +$form_max = 255; + +$cgi = new CGI; + +unless ( defined $cgi->param('session') ) { +  my $login_info = login_info( 'agentnum' => scalar($cgi->param('agentnum')) ); + +  do_template('login', $login_info ); +  exit; +} + +if ( $cgi->param('session') eq 'login' ) { + +  $cgi->param('username') =~ /^\s*([a-z0-9_\-\.\&]{0,$form_max})\s*$/i +    or die "illegal username"; +  my $username = $1; + +  $cgi->param('domain') =~ /^\s*([\w\-\.]{0,$form_max})\s*$/ +    or die "illegal domain"; +  my $domain = $1; + +  $cgi->param('password') =~ /^(.{0,$form_max})$/ +    or die "illegal password"; +  my $password = $1; + +  my $rv = login( +    'username' => $username, +    'domain'   => $domain, +    'password' => $password, +  ); +  if ( $rv->{error} ) { +    my $login_info = login_info( 'agentnum' => $cgi->param('agentnum') ); +    do_template('login', { +      'error'    => $rv->{error}, +      'username' => $username, +      'domain'   => $domain, +      %$login_info, +    } ); +    exit; +  } else { +    $cgi->param('session' => $rv->{session_id} ); +    $cgi->param('action'  => 'myaccount' ); +  } +} + +$session_id = $cgi->param('session'); + +#order|pw_list XXX ??? +$cgi->param('action') =~ +    /^(myaccount|view_invoice|make_payment|make_ach_payment|make_thirdparty_payment|payment_results|ach_payment_results|recharge_prepay|recharge_results|logout|change_bill|change_ship|change_pay|process_change_bill|process_change_ship|process_change_pay|customer_order_pkg|process_order_pkg|customer_change_pkg|process_change_pkg|process_order_recharge|provision|provision_svc|process_svc_acct|process_svc_external|delete_svc|view_usage|view_usage_details|view_cdr_details|view_support_details|change_password|process_change_password)$/ +  or die "unknown action ". $cgi->param('action'); +my $action = $1; + +warn "calling $action sub\n" +  if $DEBUG; +$FS::SelfService::DEBUG = $DEBUG; +my $result = eval "&$action();"; +die $@ if $@; + +if ( $result->{error} eq "Can't resume session" +  || $result->{error} eq "Expired session" ) { #ick + +  my $login_info = login_info(); +  do_template('login', $login_info); +  exit; +} + +#warn $result->{'open_invoices'}; +#warn scalar(@{$result->{'open_invoices'}}); + +warn "processing template $action\n" +  if $DEBUG; +do_template($action, { +  'session_id' => $session_id, +  'action'     => $action, #so the menu knows what tab we're on... +  #%{ payment_info( 'session_id' => $session_id ) },  # cust_paybys for the menu +  %{$result} +}); + +#-- + +sub myaccount { customer_info( 'session_id' => $session_id ); } + +sub change_bill { my $payment_info = +                    payment_info( 'session_id' => $session_id ); +                  return $payment_info if ( $payment_info->{'error'} ); +                  my $customer_info = +                    customer_info( 'session_id' => $session_id ); +                  return {  +                    %$payment_info, +                    %$customer_info, +                  }; +                } +sub change_ship { change_bill(@_); } +sub change_pay { change_bill(@_); } + +sub _process_change_info {  +  my ($erroraction, @fields) = @_; + +  my $results = ''; + +  $results ||= edit_info ( +    'session_id' => $session_id, +    map { ($_ => $cgi->param($_)) } grep { defined($cgi->param($_)) } @fields, +  ); + + +  if ( $results->{'error'} ) { +    no strict 'refs'; +    $action = $erroraction; +    return { +      $cgi->Vars, +      %{&$action()}, +      'error' => '<FONT COLOR="#FF0000">'. $results->{'error'}. '</FONT>', +    }; +  } else { +    return $results; +  } +} + +sub process_change_bill { +        _process_change_info( 'change_bill',  +          qw( first last company address1 address2 city state +              county zip country daytime night fax ) +        ); +} + +sub process_change_ship { +        my @list = map { "ship_$_" } +                     qw( first last company address1 address2 city state +                         county zip country daytime night fax  +                       ); +        if ($cgi->param('same') eq 'Y') { +          foreach (@list) { $cgi->param($_, '') } +        } + +        _process_change_info( 'change_ship', @list ); +} + +sub process_change_pay { +        my $postal = $cgi->param( 'postal_invoicing' ); +        my $payby  = $cgi->param( 'payby' ); +        my @list = +          qw( payby payinfo payinfo1 payinfo2 month year payname +              address1 address2 city county state zip country auto paytype +              paystate ss stateid stateid_state invoicing_list +            ); +        push @list, 'postal_invoicing' if $postal; +        unless (    $payby ne 'BILL' +                 || $postal +                 || $cgi->param( 'invoicing_list' ) +               ) +        { +          $action = 'change_pay'; +          return { +            %{&change_pay()}, +            $cgi->Vars, +            'error' => '<FONT COLOR="#FF0000">Postal or email required.</FONT>', +          }; +        } +        _process_change_info( 'change_pay', @list ); +} + +sub view_invoice { + +  $cgi->param('invnum') =~ /^(\d+)$/ or die "illegal invnum"; +  my $invnum = $1; + +  invoice( 'session_id' => $session_id, +           'invnum'     => $invnum, +         ); + +} + +sub customer_order_pkg { +  my $init_data = signup_info( 'customer_session_id' => $session_id ); +  return $init_data if ( $init_data->{'error'} ); + +  my $customer_info = customer_info( 'session_id' => $session_id ); +  return $customer_info if ( $customer_info->{'error'} ); + +  my $pkgselect = mason_comp( +    'session_id' => $session_id, +    'comp'       => '/edit/cust_main/first_pkg/select-part_pkg.html', +    'args'       => [ 'password_verify' => 1, +                      'onchange'        => 'enable_order_pkg()', +                      'relurls'         => 1, +                      'empty_label'     => 'Select package', +                    ], +  ); + +  $pkgselect = $pkgselect->{'error'} || $pkgselect->{'output'}; + +  return { +    ( map { $_ => $init_data->{$_} } +          qw( part_pkg security_phrase svc_acct_pop ), +    ), +    %$customer_info, +    'pkg_selector' => $pkgselect, +  }; +} + +sub customer_change_pkg { +  my $init_data = signup_info( 'customer_session_id' => $session_id ); +  return $init_data if ( $init_data->{'error'} ); + +  my $customer_info = customer_info( 'session_id' => $session_id ); +  return $customer_info if ( $customer_info->{'error'} ); + +  return { +    ( map { $_ => $init_data->{$_} } +          qw( part_pkg security_phrase svc_acct_pop ), +    ), +    ( map { $_ => $cgi->param($_) } +        qw( pkgnum pkg ) +    ), +    %$customer_info, +  }; +} + +sub process_order_pkg { + +  my $results = ''; + +  my @params = (qw( custnum pkgpart )); +  my $svcdb = ''; +  if ( $cgi->param('pkgpart_svcpart') =~ /^(\d+)_(\d+)$/ ) { +    $cgi->param('pkgpart', $1); +    $cgi->param('svcpart', $2); +    push @params, 'svcpart'; +    $svcdb = $cgi->param('svcdb'); +    push @params, 'domsvc' if $svcdb eq 'svc_acct'; +  } else { +    $svcdb = 'svc_acct'; +  } + +  if ( $svcdb eq 'svc_acct' ) { + +    push @params, qw( username _password _password2 sec_phrase popnum ); + +    unless ( length($cgi->param('_password')) ) { +      my $init_data = signup_info( 'customer_session_id' => $session_id ); +      $results = { 'error' => $init_data->{msgcat}{empty_password} }; +      $results = { 'error' => $init_data->{error} } if($init_data->{error}); +    } +    if ( $cgi->param('_password') ne $cgi->param('_password2') ) { +      my $init_data = signup_info( 'customer_session_id' => $session_id ); +      $results = { 'error' => $init_data->{msgcat}{passwords_dont_match} }; +      $results = { 'error' => $init_data->{error} } if($init_data->{error}); +      $cgi->param('_password', ''); +      $cgi->param('_password2', ''); +    } + +  } elsif ( $svcdb eq 'svc_phone' ) { + +    push @params, qw( phonenum sip_password pin phone_name ); + +  } else { +    die "$svcdb not handled on process_order_pkg yet"; +  } + +  $results ||= order_pkg ( +    'session_id' => $session_id, +    map { $_ => $cgi->param($_) } @params +  ); + + +  if ( $results->{'error'} ) { +    $action = 'customer_order_pkg'; +    return { +      $cgi->Vars, +      %{customer_order_pkg()}, +      'error' => '<FONT COLOR="#FF0000">'. $results->{'error'}. '</FONT>', +    }; +  } else { +    return $results; +  } + +} + +sub process_change_pkg { + +  my $results = ''; + +  $results ||= change_pkg ( +    'session_id' => $session_id, +    map { $_ => $cgi->param($_) } +        qw( pkgpart pkgnum ) +  ); + + +  if ( $results->{'error'} ) { +    $action = 'customer_change_pkg'; +    return { +      $cgi->Vars, +      %{customer_change_pkg()}, +      'error' => '<FONT COLOR="#FF0000">'. $results->{'error'}. '</FONT>', +    }; +  } else { +    return $results; +  } + +} + +sub process_order_recharge { + +  my $results = ''; + +  $results ||= order_recharge ( +    'session_id' => $session_id, +    map { $_ => $cgi->param($_) } +        qw( svcnum ) +  ); + + +  if ( $results->{'error'} ) { +    $action = 'view_usage'; +    if ($results->{'error'} eq '_decline') { +      $results->{'error'} = "There has been an error processing your account.  Please contact customer support." +    } +    return { +      $cgi->Vars, +      %{view_usage()}, +      'error' => '<FONT COLOR="#FF0000">'. $results->{'error'}. '</FONT>', +    }; +  } else { +    return $results; +  } + +} + +sub make_payment { +  payment_info( 'session_id' => $session_id ); +} + +sub payment_results { + +  use Business::CreditCard 0.30; + +  #we should only do basic checking here for DoS attacks and things +  #that couldn't be constructed by the web form...  let process_payment() do +  #the rest, it gives better error messages + +  $cgi->param('amount') =~ /^\s*(\d+(\.\d{2})?)\s*$/ +    or die "Illegal amount: ". $cgi->param('amount'); #!!! +  my $amount = $1; + +  my $payinfo = $cgi->param('payinfo'); +  $payinfo =~ s/[^\dx]//g; +  $payinfo =~ /^([\dx]{13,16})$/ +    #or $error ||= $init_data->{msgcat}{invalid_card}; #. $self->payinfo; +    or die "illegal card"; #!!! +  $payinfo = $1; +  unless ( $payinfo =~ /x/ ) { +    validate($payinfo) +      #or $error ||= $init_data->{msgcat}{invalid_card}; #. $self->payinfo; +      or die "invalid card"; #!!! +  } + +  if ( $cgi->param('card_type') ) { +    cardtype($payinfo) eq $cgi->param('card_type') +      #or $error ||= $init_data->{msgcat}{not_a}. $cgi->param('CARD_type'); +      or die "not a ". $cgi->param('card_type'); +  } + +  $cgi->param('paycvv') =~ /^\s*(.{0,4})\s*$/ or die "illegal CVV2"; +  my $paycvv = $1; + +  $cgi->param('month') =~ /^(\d{2})$/ or die "illegal month"; +  my $month = $1; +  $cgi->param('year') =~ /^(\d{4})$/ or die "illegal year"; +  my $year = $1; + +  $cgi->param('payname') =~ /^(.{0,80})$/ or die "illegal payname"; +  my $payname = $1; + +  $cgi->param('address1') =~ /^(.{0,80})$/ or die "illegal address1"; +  my $address1 = $1; + +  $cgi->param('address2') =~ /^(.{0,80})$/ or die "illegal address2"; +  my $address2 = $1; + +  $cgi->param('city') =~ /^(.{0,80})$/ or die "illegal city"; +  my $city = $1; + +  $cgi->param('state') =~ /^(.{0,80})$/ or die "illegal state"; +  my $state = $1; + +  $cgi->param('zip') =~ /^(.{0,10})$/ or die "illegal zip"; +  my $zip = $1; + +  $cgi->param('country') =~ /^(.{0,2})$/ or die "illegal country"; +  my $country = $1; + +  my $save = 0; +  $save = 1 if $cgi->param('save'); + +  my $auto = 0; +  $auto = 1 if $cgi->param('auto'); + +  $cgi->param('paybatch') =~ /^([\w\-\.]+)$/ or die "illegal paybatch"; +  my $paybatch = $1; + +  process_payment( +    'session_id' => $session_id, +    'payby'      => 'CARD', +    'amount'     => $amount, +    'payinfo'    => $payinfo, +    'paycvv'     => $paycvv, +    'month'      => $month, +    'year'       => $year, +    'payname'    => $payname, +    'address1'   => $address1, +    'address2'   => $address2, +    'city'       => $city, +    'state'      => $state, +    'zip'        => $zip, +    'country'    => $country, +    'save'       => $save, +    'auto'       => $auto, +    'paybatch'   => $paybatch, +  ); + +} + +sub make_ach_payment { +  payment_info( 'session_id' => $session_id ); +} + +sub ach_payment_results { + +  #we should only do basic checking here for DoS attacks and things +  #that couldn't be constructed by the web form...  let process_payment() do +  #the rest, it gives better error messages + +  $cgi->param('amount') =~ /^\s*(\d+(\.\d{2})?)\s*$/ +    or die "illegal amount"; #!!! +  my $amount = $1; + +  my $payinfo1 = $cgi->param('payinfo1'); +  $payinfo1 =~ s/[^\dx]//g; +  $payinfo1 =~ /^([\dx]+)$/ +    or die "illegal account"; #!!! +  $payinfo1 = $1; + +  my $payinfo2 = $cgi->param('payinfo2'); +  $payinfo2 =~ s/[^\dx]//g; +  $payinfo2 =~ /^([\dx]+)$/ +    or die "illegal ABA/routing code"; #!!! +  $payinfo2 = $1; + +  $cgi->param('payname') =~ /^(.{0,80})$/ or die "illegal payname"; +  my $payname = $1; + +  $cgi->param('paystate') =~ /^(.{0,2})$/ or die "illegal paystate"; +  my $paystate = $1; + +  $cgi->param('paytype') =~ /^(.{0,80})$/ or die "illegal paytype"; +  my $paytype = $1; + +  $cgi->param('ss') =~ /^(.{0,80})$/ or die "illegal ss"; +  my $ss = $1; + +  $cgi->param('stateid') =~ /^(.{0,80})$/ or die "illegal stateid"; +  my $stateid = $1; + +  $cgi->param('stateid_state') =~ /^(.{0,2})$/ or die "illegal stateid_state"; +  my $stateid_state = $1; + +  my $save = 0; +  $save = 1 if $cgi->param('save'); + +  my $auto = 0; +  $auto = 1 if $cgi->param('auto'); + +  $cgi->param('paybatch') =~ /^([\w\-\.]+)$/ or die "illegal paybatch"; +  my $paybatch = $1; + +  process_payment( +    'session_id' => $session_id, +    'payby'      => 'CHEK', +    'amount'     => $amount, +    'payinfo1'   => $payinfo1, +    'payinfo2'   => $payinfo2, +    'month'      => '12', +    'year'       => '2037', +    'payname'    => $payname, +    'paytype'    => $paytype, +    'paystate'   => $paystate, +    'ss'         => $ss, +    'stateid'    => $stateid, +    'stateid_state' => $stateid_state, +    'save'       => $save, +    'auto'       => $auto, +    'paybatch'   => $paybatch, +  ); + +} + +sub make_thirdparty_payment { +  $cgi->param('payby_method') =~ /^(CC|ECHECK)$/ +    or die "illegal payby method"; +  realtime_collect( 'session_id' => $session_id, 'method' => $1 ); +} + +sub recharge_prepay { +  customer_info( 'session_id' => $session_id ); +} + +sub recharge_results { + +  my $prepaid_cardnum = $cgi->param('prepaid_cardnum'); +  $prepaid_cardnum =~ s/\W//g; +  $prepaid_cardnum =~ /^(\w*)$/ or die "illegal prepaid card number"; +  $prepaid_cardnum = $1; + +  process_prepay ( 'session_id'     => $session_id, +                   'prepaid_cardnum' => $prepaid_cardnum, +                 ); +} + +sub logout { +  FS::SelfService::logout( 'session_id' => $session_id ); +} + +sub provision { +  my $result = list_pkgs( 'session_id' => $session_id ); +  die $result->{'error'} if exists $result->{'error'} && $result->{'error'}; +  $result; +} + +sub provision_svc { + +  my $result = part_svc_info( +    'session_id' => $session_id, +    map { $_ => $cgi->param($_) } qw( pkgnum svcpart ), +  ); +  die $result->{'error'} if exists $result->{'error'} && $result->{'error'}; + +  $result->{'svcdb'} =~ /^svc_(.*)$/ +    #or return { 'error' => 'Unknown svcdb '. $result->{'svcdb'} }; +    or die 'Unknown svcdb '. $result->{'svcdb'}; +  $action .= "_$1"; + +  $result; +} + +sub process_svc_acct { + +  my $result = provision_acct ( +    'session_id' => $session_id, +    map { $_ => $cgi->param($_) } qw( +      pkgnum svcpart username domsvc _password _password2 sec_phrase popnum ) +  ); + +  if ( exists $result->{'error'} && $result->{'error'} ) {  +    #warn "$result $result->{'error'}";  +    $action = 'provision_svc_acct'; +    return { +      $cgi->Vars, +      %{ part_svc_info( 'session_id' => $session_id, +                        map { $_ => $cgi->param($_) } qw( pkgnum svcpart ) +                      ) +      }, +      'error' => $result->{'error'}, +    }; +  } else { +    #warn "$result $result->{'error'}";  +    return $result; +  } + +} + +sub process_svc_external { +  provision_external ( +    'session_id' => $session_id, +    map { $_ => $cgi->param($_) } qw( pkgnum svcpart ) +  ); +} + +sub delete_svc { +  unprovision_svc( +    'session_id' => $session_id, +    'svcnum'     => $cgi->param('svcnum'), +  ); +} + +sub view_usage { +  list_svcs( +    'session_id'  => $session_id, +    'svcdb'       => [ 'svc_acct', 'svc_phone' ], +    'ncancelled'  => 1, +  ); +} + +sub view_usage_details { +  list_svc_usage( +    'session_id'  => $session_id, +    'svcnum'      => $cgi->param('svcnum'), +    'beginning'   => $cgi->param('beginning') || '', +    'ending'      => $cgi->param('ending') || '', +  ); +} + +sub view_cdr_details { +  list_cdr_usage( +    'session_id'  => $session_id, +    'svcnum'      => $cgi->param('svcnum'), +    'beginning'   => $cgi->param('beginning') || '', +    'ending'      => $cgi->param('ending') || '', +  ); +} + +sub view_support_details { +  list_support_usage( +    'session_id'  => $session_id, +    'svcnum'      => $cgi->param('svcnum'), +    'beginning'   => $cgi->param('beginning') || '', +    'ending'      => $cgi->param('ending') || '', +  ); +} + +sub change_password { +  list_svcs( +    'session_id' => $session_id, +    'svcdb'      => 'svc_acct', +  ); +}; + +sub process_change_password { + +  my $result = myaccount_passwd( +    'session_id'    => $session_id, +    map { $_ => $cgi->param($_) } qw( svcnum new_password new_password2 ) +  ); + +  if ( exists $result->{'error'} && $result->{'error'} ) {  + +    $action = 'change_password'; +    return { +      $cgi->Vars, +      %{ list_svcs( 'session_id' => $session_id, +                    'svcdb'      => 'svc_acct', +                  ) +       }, +      #'svcnum' => $cgi->param('svcnum'), +      'error'  => $result->{'error'} +    }; + + } else { + +   return $result; + + } + +} + +#-- + +sub do_template { +  my $name = shift; +  my $fill_in = shift; + +  $cgi->delete_all(); +  $fill_in->{'selfurl'} = $cgi->self_url; +  $fill_in->{'cgi'} = \$cgi; + +  my $access_info = $session_id +                      ? access_info( 'session_id' => $session_id ) +                      : {}; +  $fill_in->{$_} = $access_info->{$_} foreach keys %$access_info; + +  my $source = "$template_dir/$name.html"; +  #warn "creating template for $source\n"; +  my $template = new Text::Template( TYPE       => 'FILE', +                                     SOURCE     => $source, +                                     DELIMITERS => [ '<%=', '%>' ], +                                     UNTAINT    => 1, +                                   ) +    or die $Text::Template::ERROR; + +  #warn "filling in $template with $fill_in\n"; +  print $cgi->header( '-expires' => 'now' ), +        $template->fill_in( PACKAGE => 'FS::SelfService::_selfservicecgi', +                            HASH    => $fill_in +                          ); +} + +#*FS::SelfService::_selfservicecgi::include = \&Text::Template::fill_in_file; + +package FS::SelfService::_selfservicecgi; + +#use FS::SelfService qw(regionselector expselect popselector); +use HTML::Entities; +use FS::SelfService qw(regionselector popselector domainselector location_form); + +#false laziness w/agent.cgi +sub include { +  my $name = shift; +  my $template = new Text::Template( TYPE   => 'FILE', +                                     SOURCE => "$main::template_dir/$name.html", +                                     DELIMITERS => [ '<%=', '%>' ], +                                     UNTAINT => 1,                    +                                   ) +    or die $Text::Template::ERROR; + +  $template->fill_in( PACKAGE => 'FS::SelfService::_selfservicecgi', +                      #HASH    => $fill_in +                    ); + +} + diff --git a/fs_selfservice/FS-SelfService/cgi/signup-agentselect.html b/fs_selfservice/FS-SelfService/cgi/signup-agentselect.html new file mode 100755 index 000000000..7851c5601 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/signup-agentselect.html @@ -0,0 +1,195 @@ +<HTML><HEAD><TITLE>ISP Signup form</TITLE></HEAD> +<BODY BGCOLOR="#e8e8e8"><FONT SIZE=7>ISP Signup form</FONT><BR><BR> +<FONT SIZE="+1" COLOR="#ff0000"><%= $error %></FONT> +<FORM NAME="OneTrueForm" ACTION="<%= $self_url %>" METHOD=POST onSubmit="document.OneTrueForm.signup.disabled=true"> +<INPUT TYPE="hidden" NAME="magic" VALUE="process"> +<INPUT TYPE="hidden" NAME="ref" VALUE="<%= $referral_custnum %>"> +<INPUT TYPE="hidden" NAME="ss" VALUE=""> +Agent <SELECT NAME="agentnum"> +<%= +  warn $init_data; +  warn $init_data->{'agent'}; +  foreach my $agent ( @{$init_data->{'agent'}} ) { +    $OUT .= '<OPTION VALUE="'. $agent->{'agentnum'}. '"'; +    $OUT .= ' SELECTED' if $agent->{'agentnum'} eq $agentnum; +    $OUT .= '>'. $agent->{'agent'}; +  } +%> +</SELECT><BR><BR> +Contact Information +<TABLE BGCOLOR="#c0c0c0" BORDER=0 CELLSPACING=0 WIDTH="100%"> +<TR> +  <TH ALIGN="right"><font color="#ff0000">*</font>Contact name<BR>(last, first)</TH> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="last" VALUE="<%= $last %>">, +                <INPUT TYPE="text" NAME="first" VALUE="<%= $first %>"></TD> +</TR> +<TR> +  <TD ALIGN="right">Company</TD> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="company" SIZE=70 VALUE="<%= $company %>"></TD> +</TR> +<TR> +  <TH ALIGN="right"><font color="#ff0000">*</font>Address</TH> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="address1" SIZE=70 VALUE="<%= $address1 %>"></TD> +</TR> +<TR> +  <TD ALIGN="right"> </TD> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="address2" SIZE=70 VALUE="<%= $address2 %>"></TD> +</TR> +<TR> +  <TH ALIGN="right"><font color="#ff0000">*</font>City</TH> +  <TD><INPUT TYPE="text" NAME="city" VALUE="<%= $city %>"></TD> +  <TH ALIGN="right"><font color="#ff0000">*</font>State/Country</TH> +  <TD> +    <%= +        ($county_html, $state_html, $country_html) = +          regionselector( $county, $state, $country ); +  +        "$county_html $state_html"; +    %> +  </TD> +  <TH><font color="#ff0000">*</font>Zip</TH> +  <TD><INPUT TYPE="text" NAME="zip" SIZE=10 VALUE="<%= $zip %>"></TD> +</TR> +<TR> +  <TH ALIGN="right"><font color="#ff0000">*</font>Country</TH> +  <TD><%= $country_html %></TD> +<TR> +  <TD ALIGN="right">Day Phone</TD> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="daytime" VALUE="<%= $daytime %>" SIZE=18></TD> +</TR> +<TR> +  <TD ALIGN="right">Night Phone</TD> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="night" VALUE="<%= $night %>" SIZE=18></TD> +</TR> +<TR> +  <TD ALIGN="right">Fax</TD> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="fax" VALUE="<%= $fax %>" SIZE=12></TD> +</TR> +</TABLE><font color="#ff0000">*</font> required fields<BR> +<BR>Billing information<TABLE BGCOLOR="#c0c0c0" BORDER=0 CELLSPACING=0 WIDTH="100%"> +<TR><TD> + +  <%= +    $OUT .= '<INPUT TYPE="checkbox" NAME="invoicing_list_POST" VALUE="POST"'; +    my @invoicing_list = split(', ', $invoicing_list ); +    $OUT .= ' CHECKED' +      if ! @invoicing_list || grep { $_ eq 'POST' } @invoicing_list; +    $OUT .= '>'; +  %> + +  Postal mail invoice +</TD></TR> +<TR><TD>Email invoice <INPUT TYPE="text" NAME="invoicing_list" VALUE="<%= join(', ', grep { $_ ne 'POST' } split(', ', $invoicing_list ) ) %>"> +</TD></TR> +<%= scalar(@payby) > 1 ? '<TR><TD>Billing type</TD></TR>' : '' %> +</TABLE> +<TABLE BGCOLOR="#c0c0c0" BORDER=1 WIDTH="100%"> +<TR> + +  <%= + +    my $cardselect = '<SELECT NAME="CARD_type"><OPTION></OPTION>'; +    my %types = ( +                  'VISA' => 'VISA card', +                  'MasterCard' => 'MasterCard', +                  'Discover' => 'Discover card', +                  'American Express' => 'American Express card', +                ); +    foreach ( keys %types ) { +      $selected = $cgi->param('CARD_type') eq $types{$_} ? 'SELECTED' : ''; +      $cardselect .= qq!<OPTION $selected VALUE="$types{$_}">$_</OPTION>!; +    } +    $cardselect .= '</SELECT>'; +   +    my %payby = ( +      'CARD' => qq!Credit card<BR><font color="#ff0000">*</font>$cardselect<INPUT TYPE="text" NAME="CARD_payinfo" VALUE="" MAXLENGTH=19><BR><font color="#ff0000">*</font>Exp !. expselect("CARD"). qq!<BR><font color="#ff0000">*</font>Name on card<BR><INPUT TYPE="text" NAME="CARD_payname" VALUE="">!, +      'DCRD' => qq!Credit card<BR><font color="#ff0000">*</font>$cardselect<INPUT TYPE="text" NAME="DCRD_payinfo" VALUE="" MAXLENGTH=19><BR><font color="#ff0000">*</font>Exp !. expselect("DCRD"). qq!<BR><font color="#ff0000">*</font>Name on card<BR><INPUT TYPE="text" NAME="DCRD_payname" VALUE="">!, +      'CHEK' => qq!Electronic check<BR>${r}Account number <INPUT TYPE="text" NAME="CHEK_payinfo1" VALUE="" MAXLENGTH=10><BR>${r}ABA/Routing code <INPUT TYPE="text" NAME="CHEK_payinfo2" VALUE="" SIZE=10 MAXLENGTH=9><INPUT TYPE="hidden" NAME="CHEK_month" VALUE="12"><INPUT TYPE="hidden" NAME="CHEK_year" VALUE="2037"><BR>${r}Bank name <INPUT TYPE="text" NAME="CHEK_payname" VALUE="">!, +      'DCHK' => qq!Electronic check<BR>${r}Account number <INPUT TYPE="text" NAME="DCHK_payinfo1" VALUE="" MAXLENGTH=10><BR>${r}ABA/Routing code <INPUT TYPE="text" NAME="DCHK_payinfo2" VALUE="" SIZE=10 MAXLENGTH=9><INPUT TYPE="hidden" NAME="DCHK_month" VALUE="12"><INPUT TYPE="hidden" NAME="DCHK_year" VALUE="2037"><BR>${r}Bank name <INPUT TYPE="text" NAME="DCHK_payname" VALUE="">!, +      'LECB' => qq!Phone bill billing<BR>${r}Phone number <INPUT TYPE="text" BANE="LECB_payinfo" VALUE="" MAXLENGTH=15 SIZE=16><INPUT TYPE="hidden" NAME="LECB_month" VALUE="12"><INPUT TYPE="hidden" NAME="LECB_year" VALUE="2037"><INPUT TYPE="hidden" NAME="LECB_payname" VALUE="">!, +      'BILL' => qq!Billing<BR>P.O. <INPUT TYPE="text" NAME="BILL_payinfo" VALUE=""><BR><font color="#ff0000">*</font>Exp !. expselect("BILL", "12-2037"). qq!<BR><font color="#ff0000">*</font>Attention<BR><INPUT TYPE="text" NAME="BILL_payname" VALUE="Accounts Payable">!, +      'COMP' => qq!Complimentary<BR><font color="#ff0000">*</font>Approved by<INPUT TYPE="text" NAME="COMP_payinfo" VALUE=""><BR><font color="#ff0000">*</font>Exp !. expselect("COMP"), +      'PREPAY' => qq!Prepaid card<BR><font color="#ff0000">*</font><INPUT TYPE="text" NAME="PREPAY_payinfo" VALUE="" MAXLENGTH=80>!, +    ); + +    my( $account, $aba ) = split('@', $payinfo); +    my %paybychecked = ( +      'CARD' => qq!Credit card<BR><font color="#ff0000">*</font>$cardselect<INPUT TYPE="text" NAME="CARD_payinfo" VALUE="$payinfo" MAXLENGTH=19><BR><font color="#ff0000">*</font>Exp !. expselect("CARD", $paydate). qq!<BR><font color="#ff0000">*</font>Name on card<BR><INPUT TYPE="text" NAME="CARD_payname" VALUE="$payname">!, +      'DCRD' => qq!Credit card<BR><font color="#ff0000">*</font>$cardselect<INPUT TYPE="text" NAME="DCRD_payinfo" VALUE="$payinfo" MAXLENGTH=19><BR><font color="#ff0000">*</font>Exp !. expselect("DCRD", $paydate). qq!<BR><font color="#ff0000">*</font>Name on card<BR><INPUT TYPE="text" NAME="DCRD_payname" VALUE="$payname">!, +      'CHEK' => qq!Electronic check<BR>${r}Account number <INPUT TYPE="text" NAME="CHEK_payinfo1" VALUE="$account" MAXLENGTH=10><BR>${r}ABA/Routing code <INPUT TYPE="text" NAME="CHEK_payinfo2" VALUE="$aba" SIZE=10 MAXLENGTH=9><INPUT TYPE="hidden" NAME="CHEK_month" VALUE="12"><INPUT TYPE="hidden" NAME="CHEK_year" VALUE="2037"><BR>${r}Bank name <INPUT TYPE="text" NAME="CHEK_payname" VALUE="$payname">!, +      'DCHK' => qq!Electronic check<BR>${r}Account number <INPUT TYPE="text" NAME="DCHK_payinfo1" VALUE="$account" MAXLENGTH=10><BR>${r}ABA/Routing code <INPUT TYPE="text" NAME="DCHK_payinfo2" VALUE="$aba" SIZE=10 MAXLENGTH=9><INPUT TYPE="hidden" NAME="DCHK_month" VALUE="12"><INPUT TYPE="hidden" NAME="DCHK_year" VALUE="2037"><BR>${r}Bank name <INPUT TYPE="text" NAME="DCHK_payname" VALUE="$payname">!, +      'LECB' => qq!Phone bill billing<BR>${r}Phone number <INPUT TYPE="text" BANE="LECB_payinfo" VALUE="$payinfo" MAXLENGTH=15 SIZE=16><INPUT TYPE="hidden" NAME="LECB_month" VALUE="12"><INPUT TYPE="hidden" NAME="LECB_year" VALUE="2037"><INPUT TYPE="hidden" NAME="LECB_payname" VALUE="">!, +      'BILL' => qq!Billing<BR>P.O. <INPUT TYPE="text" NAME="BILL_payinfo" VALUE="$payinfo"><BR><font color="#ff0000">*</font>Exp !. expselect("BILL", $paydate). qq!<BR><font color="#ff0000">*</font>Attention<BR><INPUT TYPE="text" NAME="BILL_payname" VALUE="$payname">!, +      'COMP' => qq!Complimentary<BR><font color="#ff0000">*</font>Approved by<INPUT TYPE="text" NAME="COMP_payinfo" VALUE="$payinfo"><BR><font color="#ff0000">*</font>Exp !. expselect("COMP", $paydate), +      'PREPAY' => qq!Prepaid card<BR><font color="#ff0000">*</font><INPUT TYPE="text" NAME="PREPAY_payinfo" VALUE="$payinfo" MAXLENGTH=80>!, +    ); + +    for (@payby) { +      if ( scalar(@payby) == 1) { +        $OUT .= '<TD VALIGN=TOP>'. +                qq!<INPUT TYPE="hidden" NAME="payby" VALUE="$_">!. +                "$paybychecked{$_}</TD>"; +      } else { +        $OUT .= qq!<TD VALIGN=TOP><INPUT TYPE="radio" NAME="payby" VALUE="$_"!; +        if ($payby eq $_) { +          $OUT .= qq! CHECKED> $paybychecked{$_}</TD>!; +        } else { +          $OUT .= qq!> $payby{$_}</TD>!; +        } + +      } +    } +  %> + +</TR></TABLE><font color="#ff0000">*</font> required fields for each billing type +<BR><BR>First package +<TABLE BGCOLOR="#c0c0c0" BORDER=0 CELLSPACING=0 WIDTH="100%"> +<TR> +  <TD COLSPAN=2><SELECT NAME="pkgpart"><OPTION VALUE="">(none) + +  <%= +    foreach my $package ( @{$packages} ) { +      $OUT .= '<OPTION VALUE="'. $package->{'pkgpart'}. '"'; +      $OUT .= ' SELECTED' if $pkgpart && $package->{'pkgpart'} == $pkgpart; +      $OUT .= '>'. $package->{'pkg'}; +    } +  %> + +  </SELECT></TD> +</TR> +<TR> +  <TD ALIGN="right">Username</TD> +  <TD><INPUT TYPE="text" NAME="username" VALUE="<%= $username %>"></TD> +</TR> +<TR> +  <TD ALIGN="right">Password</TD> +  <TD><INPUT TYPE="password" NAME="_password" VALUE="<%= $password %>"></TD> +</TR> +<TR> +  <TD ALIGN="right">Re-enter Password</TD> +  <TD><INPUT TYPE="password" NAME="_password2" VALUE="<%= $password2 %>"></TD> +</TR> +<%= +  if ( $init_data->{'security_phrase'} ) { +    $OUT .= <<ENDOUT; +<TR> +  <TD ALIGN="right">Security Phrase</TD> +  <TD><INPUT TYPE="text" NAME="sec_phrase" VALUE="$sec_phrase"> +  </TD> +</TR> +ENDOUT +  } else { +    $OUT .= '<INPUT TYPE="hidden" NAME="sec_phrase" VALUE="">'; +  } +%> +<%= +  if ( scalar(@$pops) ) { +    $OUT .= '<TR><TD ALIGN="right">Access number</TD><TD>'. +            popselector($popnum). '</TD></TR>'; +  } else { +    $OUT .= popselector($popnum); +  } +%> +</TABLE> +<BR><BR><INPUT TYPE="submit" NAME="signup" VALUE="Signup" > +</FORM></BODY></HTML> diff --git a/fs_selfservice/FS-SelfService/cgi/signup-alternate.html b/fs_selfservice/FS-SelfService/cgi/signup-alternate.html new file mode 100755 index 000000000..490cefa5e --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/signup-alternate.html @@ -0,0 +1,218 @@ +<HTML><HEAD><TITLE>ISP Signup form</TITLE></HEAD> +<BODY BGCOLOR="#e8e8e8"><FONT SIZE=7>ISP Signup form</FONT><BR><BR> +<FONT SIZE="+1" COLOR="#ff0000"><%= $error %></FONT> +<FORM NAME="dummy"> +<INPUT TYPE="hidden" NAME="magic" VALUE="process"> +<INPUT TYPE="hidden" NAME="ref" VALUE="<%= $referral_custnum %>"> +<INPUT TYPE="hidden" NAME="ss" VALUE=""> +<INPUT TYPE="hidden" NAME="agentnum" VALUE="3"> +Contact Information +<TABLE BGCOLOR="#c0c0c0" BORDER=0 CELLSPACING=0 WIDTH="100%"> +<TR> +  <TH ALIGN="right"><font color="#ff0000">*</font>Contact name<BR>(last, first)</TH> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="last" VALUE="<%= $last %>">, +                <INPUT TYPE="text" NAME="first" VALUE="<%= $first %>"></TD> +</TR> +<TR> +  <TD ALIGN="right">Company</TD> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="company" SIZE=70 VALUE="<%= $company %>"></TD> +</TR> +<TR> +  <TH ALIGN="right"><font color="#ff0000">*</font>Address</TH> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="address1" SIZE=70 VALUE="<%= $address1 %>"></TD> +</TR> +<TR> +  <TD ALIGN="right"> </TD> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="address2" SIZE=70 VALUE="<%= $address2 %>"></TD> +</TR> +<TR> +  <TH ALIGN="right"><font color="#ff0000">*</font>City</TH> +  <TD><INPUT TYPE="text" NAME="city" VALUE="<%= $city %>"></TD> +  <TH ALIGN="right"><font color="#ff0000">*</font>State/Country</TH> +  <TD><SELECT NAME="state" SIZE="1"> + +  <%= +    foreach ( @{$locales} ) { +      my $value = $_->{'state'}; +      $value .= ' ('. $_->{'county'}. ')' if $_->{'county'}; +      $value .= ' / '. $_->{'country'}; + +      $OUT .= qq(<OPTION VALUE="$value"); +      $OUT .= ' SELECTED' if ( $state eq $_->{'state'} +                               && $county eq $_->{'county'} +                               && $country eq $_->{'country'} +                             ); +      $OUT .= ">$value</OPTION>"; +    } +  %> + +  </SELECT></TD> +  <TH><font color="#ff0000">*</font>Zip</TH> +  <TD><INPUT TYPE="text" NAME="zip" SIZE=10 VALUE="<%= $zip %>"></TD> +</TR> +<TR> +  <TD ALIGN="right">Day Phone</TD> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="daytime" VALUE="<%= $daytime %>" SIZE=18></TD> +</TR> +<TR> +  <TD ALIGN="right">Night Phone</TD> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="night" VALUE="<%= $night %>" SIZE=18></TD> +</TR> +<TR> +  <TD ALIGN="right">Fax</TD> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="fax" VALUE="<%= $fax %>" SIZE=12></TD> +</TR> +</TABLE><font color="#ff0000">*</font> required fields<BR> + +<BR><BR> +<TABLE BGCOLOR="#c0c0c0" BORDER=0 CELLSPACING=0> +<TR> +  <TH ALIGN="right"><font color="#ff0000">*</font>Username</TH> +  <TD><INPUT TYPE="text" NAME="username" VALUE="<%= $username %>"></TD> +</TR> +<TR> +  <TH ALIGN="right"><font color="#ff0000">*</font>Password</TH> +  <TD><INPUT TYPE="password" NAME="_password" VALUE="<%= $password %>"></TD> +</TR> +<TR> +  <TH ALIGN="right"><font color="#ff0000">*</font>Re-enter Password</TH> +  <TD><INPUT TYPE="password" NAME="_password2" VALUE="<%= $password2 %>"></TD> +</TR> + +<%= if ( $init_data->{'security_phrase'} ) { +      <<ENDOUT; +<TR> +  <TD ALIGN="right">Security Phrase</TD> +  <TD><INPUT TYPE="text" NAME="sec_phrase" VALUE="$sec_phrase"> +  </TD> +</TR> +ENDOUT +    } else { +      '<INPUT TYPE="hidden" NAME="sec_phrase" VALUE="">'; +    } +%> + +<%= if ( scalar(@$pops) ) { +      '<TR><TD ALIGN="right">Access number</TD><TD>'. +           popselector($popnum). '</TD></TR>'; +    } else { +      popselector($popnum); +    } +%> + +</TABLE><font color="#ff0000">*</font> required fields + +<BR><BR>First package + +  <%= use Tie::IxHash; +      my %pkgpart2payby = map { $_->{pkgpart} => $_->{payby}[0] } @{$packages}; +      tie my %options, 'Tie::IxHash', +        '' => '(none)', +        map { $_->{pkgpart} => $_->{pkg} } +          sort { $a->{recur} <=> $b->{recur} } +            @{$packages}  +      ; + +      use HTML::Widgets::SelectLayers 0.02; +      my @form_text = qw( magic ref ss agentnum +                          last first company address1 address2 +                          city zip daytime night fax +                          username _password _password2 sec_phrase ); +      my @form_select = qw( state ); #county country +      if ( scalar(@$pops) == 0 or scalar(@$pops) == 1 ) { +        push @form_text, 'popnum', +      } else { +        push @form_select, 'popnum', +      } +      my $widget = new HTML::Widgets::SelectLayers( +        options => \%options, +        selected_layer => $pkgpart, +        form_name => 'dummy', +        form_action => $self_url, +        form_text => \@form_text, +        form_select => \@form_select, +        layer_callback => sub { +          my $layer = shift; +          my $html = qq( <INPUT TYPE="hidden" NAME="pkgpart" VALUE="$layer">); + +          if ( $pkgpart2payby{$layer} eq 'BILL' ) { +            $html .= <<ENDOUT; +<INPUT TYPE="hidden" NAME="payby" VALUE="BILL"> +<INPUT TYPE="hidden" NAME="invoicing_list_POST" VALUE=""> +<INPUT TYPE="hidden" NAME="BILL_payinfo" VALUE=""> +<INPUT TYPE="hidden" NAME="BILL_month" VALUE="12"> +<INPUT TYPE="hidden" NAME="BILL_year" VALUE="2037"> +<INPUT TYPE="hidden" NAME="BILL_payname" VALUE=""> +<BR><BR><INPUT TYPE="submit" VALUE="Signup"> +ENDOUT +          } elsif ( $pkgpart2payby{$layer} eq 'CARD' ) { +            my $postal_checked = ''; +            my @invoicing_list = split(', ', $invoicing_list ); +            $postal_checked = 'CHECKED' +              if ! @invoicing_list || grep { $_ eq 'POST' } @invoicing_list; + +            $invoicing_list= join(', ', grep { $_ ne 'POST' } @invoicing_list ); + +            my $expselect = expselect("CARD", $paydate); + +            my $cardselect = '<SELECT NAME="CARD_type"><OPTION></OPTION>'; +            my %types = ( +                          'VISA' => 'VISA card', +                          'MasterCard' => 'MasterCard', +                          'Discover' => 'Discover card', +                          'American Express' => 'American Express card', +                        ); +            foreach ( keys %types ) { +              $selected = +                $cgi->param('CARD_type') eq $types{$_} ? 'SELECTED' : ''; +              $cardselect .= +                qq!<OPTION $selected VALUE="$types{$_}">$_</OPTION>!; +            } +            $cardselect .= '</SELECT>'; + +            $html .= <<ENDOUT; +<INPUT TYPE="hidden" NAME="payby" VALUE="CARD"> +<BR><BR>Billing information +<TABLE BGCOLOR="#c0c0c0" BORDER=0 CELLSPACING=0> +<INPUT TYPE="hidden" NAME="invoicing_list_POST" VALUE=""> +<TR> +  <TD ALIGN="right">Email statement to </TD> +  <TD><INPUT TYPE="text" NAME="invoicing_list" VALUE="$invoicing_list"></TD> +</TR> +<TR> +  <TH ALIGN="right"><font color="#ff0000">*</font>Credit card type</TH> +  <TD>$cardselect</TD> +</TR> +<TR> +  <TH ALIGN="right"><font color="#ff0000">*</font>Card number</TH> +  <TD><INPUT TYPE="text" NAME="CARD_payinfo" VALUE="$payinfo" MAXLENGTH=19></TD> +</TR> +<TR> +  <TH ALIGN="right"><font color="#ff0000">*</font>*</font>Exp</TH> +  <TD>$expselect</TD> +</TR> +<TR> +  <TH ALIGN="right"><font color="#ff0000">*</font>Name on card</TH> +  <TD><INPUT TYPE="text" NAME="CARD_payname" VALUE="$payname"></TD> +</TR> +</TABLE> +<font color="#ff0000">*</font> required fields +<BR><BR><INPUT TYPE="submit" VALUE="Signup"> +ENDOUT +          } else { +            $html = <<ENDOUT; +<BR>Please select a package.<BR> +ENDOUT + +          } + +          $html; + +        }, +      ); + +      $widget->html; + + + %> +</BODY></HTML> diff --git a/fs_selfservice/FS-SelfService/cgi/signup-billaddress.html b/fs_selfservice/FS-SelfService/cgi/signup-billaddress.html new file mode 100755 index 000000000..3cf9d2505 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/signup-billaddress.html @@ -0,0 +1,307 @@ +<HTML><HEAD><TITLE>ISP Signup form</TITLE></HEAD> +<BODY BGCOLOR="#e8e8e8" onUnload="myclose()"> +<script language="JavaScript"><!-- +  var mywindow = -1; +  function myopen(filename,windowname,properties) { +    myclose(); +    mywindow = window.open(filename,windowname,properties); +  } +  function myclose() { +    if ( mywindow != -1 ) +      mywindow.close(); +    mywindow = -1 +  } +//--></script> +<FONT SIZE=7>ISP Signup form</FONT><BR><BR> +<FONT SIZE="+1" COLOR="#ff0000"><%= $error %></FONT> +<FORM NAME="OneTrueForm" ACTION="<%= $self_url %>" METHOD=POST onSubmit="document.OneTrueForm.signup.disabled=true"> +<INPUT TYPE="hidden" NAME="magic" VALUE="process"> +<INPUT TYPE="hidden" NAME="ref" VALUE="<%= $referral_custnum %>"> +<INPUT TYPE="hidden" NAME="ss" VALUE=""> +Where did you hear about our service? <SELECT NAME="refnum"> +<%= +  $OUT .= '<OPTION VALUE="">' unless $refnum; +  foreach my $part_referral ( @{$init_data->{'part_referral'}} ) { +    $OUT .= '<OPTION VALUE="'. $part_referral->{'refnum'}. '"'; +    $OUT .= ' SELECTED' if $part_referral->{'refnum'} eq $refnum; +    $OUT .= '>'. $part_referral->{'referral'}; +  } +%> +</SELECT><BR><BR> +Billing Address (where credit card statement is sent) +<TABLE BGCOLOR="#c0c0c0" BORDER=0 CELLSPACING=0 WIDTH="100%"> +<TR> +  <TH ALIGN="right"><font color="#ff0000">*</font>Exact name on card<BR>(last, first)</TH> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="last" VALUE="<%= $last %>" onChange="changed(this)">, +                <INPUT TYPE="text" NAME="first" VALUE="<%= $first %>" onChange="changed(this)"></TD> +</TR> +<TR> +  <TD ALIGN="right">Company</TD> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="company" SIZE=70 VALUE="<%= $company %>" onChange="changed(this)"></TD> +</TR> +<TR> +  <TH ALIGN="right"><font color="#ff0000">*</font>Address</TH> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="address1" SIZE=70 VALUE="<%= $address1 %>" onChange="changed(this)"></TD> +</TR> +<TR> +  <TD ALIGN="right"> </TD> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="address2" SIZE=70 VALUE="<%= $address2 %>" onChange="changed(this)"></TD> +</TR> +<TR> +  <TH ALIGN="right"><font color="#ff0000">*</font>City</TH> +  <TD><INPUT TYPE="text" NAME="city" VALUE="<%= $city %>" onChange="changed(this)"></TD> +  <TH ALIGN="right"><font color="#ff0000">*</font>State/Country</TH> +  <TD> +    <%= +        ($county_html, $state_html, $country_html) = +          regionselector( $county, $state, $country, '', 'changed(this)' ); +  +        "$county_html $state_html"; +    %> +  </TD> +  <TH><font color="#ff0000">*</font>Zip</TH> +  <TD><INPUT TYPE="text" NAME="zip" SIZE=10 VALUE="<%= $zip %>" onChange="changed(this)"></TD> +</TR> +<TR> +  <TH ALIGN="right"><font color="#ff0000">*</font>Country</TH> +  <TD><%= $country_html %></TD> +<TR> +  <TD ALIGN="right">Day Phone</TD> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="daytime" VALUE="<%= $daytime %>" SIZE=18 onChange="changed(this)"></TD> +</TR> +<TR> +  <TD ALIGN="right">Night Phone</TD> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="night" VALUE="<%= $night %>" SIZE=18 onChange="changed(this)"></TD> +</TR> +<TR> +  <TD ALIGN="right">Fax</TD> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="fax" VALUE="<%= $fax %>" SIZE=12 onChange="changed(this)"></TD> +</TR> +</TABLE> + +<SCRIPT> +function changed(what) { +  what.form.same.checked = false; +} +function samechanged(what) { +  if ( what.checked ) { + +    <%= foreach (qw( +          last first company address1 address2 city zip daytime night fax +        )) { +          $OUT .= "what.form.ship_$_.value = what.form.$_.value;\n"; +        } +    %> + +    what.form.ship_country.selectedIndex = what.form.country.selectedIndex; +    ship_country_changed(what.form.ship_country); +    what.form.ship_state.selectedIndex = what.form.state.selectedIndex; +    ship_state_changed(what.form.ship_state); +    what.form.ship_county.selectedIndex = what.form.county.selectedIndex; +  } +} +</SCRIPT> + +<BR><BR> +Service Address +(<INPUT TYPE="checkbox" NAME="same" VALUE="Y" onClick="samechanged(this)" <%= $same eq 'Y' ? 'CHECKED' : '' %>>same as billing address)<BR> +<TABLE BGCOLOR="#c0c0c0" BORDER=0 CELLSPACING=0 WIDTH="100%"> +<TR> +  <TH ALIGN="right"><font color="#ff0000">*</font>Contact name<BR>(last, first)</TH> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="ship_last" VALUE="<%= $ship_last %>" onChange="changed(this)">, +                <INPUT TYPE="text" NAME="ship_first" VALUE="<%= $ship_first %>" onChange="changed(this)"></TD> +</TR> +<TR> +  <TD ALIGN="right">Company</TD> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="ship_company" SIZE=70 VALUE="<%= $ship_company %>" onChange="changed(this)"></TD> +</TR> +<TR> +  <TH ALIGN="right"><font color="#ff0000">*</font>Address</TH> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="ship_address1" SIZE=70 VALUE="<%= $ship_address1 %>" onChange="changed(this)"></TD> +</TR> +<TR> +  <TD ALIGN="right"> </TD> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="ship_address2" SIZE=70 VALUE="<%= $ship_address2 %>" onChange="changed(this)"></TD> +</TR> +<TR> +  <TH ALIGN="right"><font color="#ff0000">*</font>City</TH> +  <TD><INPUT TYPE="text" NAME="ship_city" VALUE="<%= $ship_city %>" onChange="changed(this)"></TD> +  <TH ALIGN="right"><font color="#ff0000">*</font>State/Country</TH> +  <TD> +    <%= +        ($ship_county_html, $ship_state_html, $ship_country_html) = +          regionselector( $ship_county, +                          $ship_state, +                          $ship_country, +                          'ship_', +                          'changed(this)', +                        ); +  +        "$ship_county_html $ship_state_html"; +    %> +  </TD> +  <TH><font color="#ff0000">*</font>Zip</TH> +  <TD><INPUT TYPE="text" NAME="ship_zip" SIZE=10 VALUE="<%= $ship_zip %>" onChange="changed(this)"></TD> +</TR> +<TR> +  <TH ALIGN="right"><font color="#ff0000">*</font>Country</TH> +  <TD><%= $ship_country_html %></TD> +<TR> +  <TD ALIGN="right">Day Phone</TD> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="ship_daytime" VALUE="<%= $ship_daytime %>" SIZE=18 onChange="changed(this)"></TD> +</TR> +<TR> +  <TD ALIGN="right">Night Phone</TD> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="ship_night" VALUE="<%= $ship_night %>" SIZE=18 onChange="changed(this)"></TD> +</TR> +<TR> +  <TD ALIGN="right">Fax</TD> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="ship_fax" VALUE="<%= $ship_fax %>" SIZE=12 onChange="changed(this)"></TD> +</TR> +</TABLE> + +<font color="#ff0000">*</font> required fields<BR> + +<BR>Billing information<TABLE BGCOLOR="#c0c0c0" BORDER=0 CELLSPACING=0 WIDTH="100%"> +<TR><TD> + +  <%= +    $OUT .= '<INPUT TYPE="checkbox" NAME="invoicing_list_POST" VALUE="POST"'; +    my @invoicing_list = split(', ', $invoicing_list ); +    $OUT .= ' CHECKED' +      if ! @invoicing_list || grep { $_ eq 'POST' } @invoicing_list; +    $OUT .= '>'; +  %> + +  Postal mail invoice +</TD></TR> +<TR><TD>Email invoice <INPUT TYPE="text" NAME="invoicing_list" VALUE="<%= join(', ', grep { $_ ne 'POST' } split(', ', $invoicing_list ) ) %>"> +</TD></TR> +<%= scalar(@payby) > 1 ? '<TR><TD>Billing type</TD></TR>' : '' %> +</TABLE> +<TABLE BGCOLOR="#c0c0c0" BORDER=1 WIDTH="100%"> +<TR> + +  <%= + +    my $cardselect = '<SELECT NAME="CARD_type"><OPTION></OPTION>'; +    my %types = ( +                  'VISA' => 'VISA card', +                  'MasterCard' => 'MasterCard', +                  'Discover' => 'Discover card', +                  'American Express' => 'American Express card', +                ); +    foreach ( keys %types ) { +      $selected = $cgi->param('CARD_type') eq $types{$_} ? 'SELECTED' : ''; +      $cardselect .= qq!<OPTION $selected VALUE="$types{$_}">$_</OPTION>!; +    } +    $cardselect .= '</SELECT>'; +   +    my %payby = ( +      'CARD' => qq!Credit card<BR><font color="#ff0000">*</font>$cardselect<INPUT TYPE="text" NAME="CARD_payinfo" VALUE="" MAXLENGTH=19><BR><font color="#ff0000">*</font>Exp !. expselect("CARD"), #. qq!<BR><font color="#ff0000">*</font>Name on card<BR><INPUT TYPE="text" NAME="CARD_payname" VALUE="">!, +      'DCRD' => qq!Credit card<BR><font color="#ff0000">*</font>$cardselect<INPUT TYPE="text" NAME="DCRD_payinfo" VALUE="" MAXLENGTH=19><BR><font color="#ff0000">*</font>Exp !. expselect("DCRD"), #. qq!<BR><font color="#ff0000">*</font>Name on card<BR><INPUT TYPE="text" NAME="DCRD_payname" VALUE="">!, +      'CHEK' => qq!Electronic check<BR>${r}Account number <INPUT TYPE="text" NAME="CHEK_payinfo1" VALUE="" MAXLENGTH=10><BR>${r}ABA/Routing code <INPUT TYPE="text" NAME="CHEK_payinfo2" VALUE="" SIZE=10 MAXLENGTH=9><INPUT TYPE="hidden" NAME="CHEK_month" VALUE="12"><INPUT TYPE="hidden" NAME="CHEK_year" VALUE="2037"><BR>${r}Bank name <INPUT TYPE="text" NAME="CHEK_payname" VALUE="">!, +      'DCHK' => qq!Electronic check<BR>${r}Account number <INPUT TYPE="text" NAME="DCHK_payinfo1" VALUE="" MAXLENGTH=10><BR>${r}ABA/Routing code <INPUT TYPE="text" NAME="DCHK_payinfo2" VALUE="" SIZE=10 MAXLENGTH=9><INPUT TYPE="hidden" NAME="DCHK_month" VALUE="12"><INPUT TYPE="hidden" NAME="DCHK_year" VALUE="2037"><BR>${r}Bank name <INPUT TYPE="text" NAME="DCHK_payname" VALUE="">!, +      'LECB' => qq!Phone bill billing<BR>${r}Phone number <INPUT TYPE="text" BANE="LECB_payinfo" VALUE="" MAXLENGTH=15 SIZE=16><INPUT TYPE="hidden" NAME="LECB_month" VALUE="12"><INPUT TYPE="hidden" NAME="LECB_year" VALUE="2037"><INPUT TYPE="hidden" NAME="LECB_payname" VALUE="">!, +      'BILL' => qq!Billing<BR>P.O. <INPUT TYPE="text" NAME="BILL_payinfo" VALUE=""><BR><font color="#ff0000">*</font>Exp !. expselect("BILL", "12-2037"). qq!<BR><font color="#ff0000">*</font>Attention<BR><INPUT TYPE="text" NAME="BILL_payname" VALUE="Accounts Payable">!, +      'COMP' => qq!Complimentary<BR><font color="#ff0000">*</font>Approved by<INPUT TYPE="text" NAME="COMP_payinfo" VALUE=""><BR><font color="#ff0000">*</font>Exp !. expselect("COMP"), +      'PREPAY' => qq!Prepaid card<BR><font color="#ff0000">*</font><INPUT TYPE="text" NAME="PREPAY_payinfo" VALUE="" MAXLENGTH=80>!, +    ); + +    if ( $init_data->{'cvv_enabled'} ) { +      foreach my $payby ( grep { exists $payby{$_} } qw(CARD DCRD) ) { #1.4/1.5 +        $payby{$payby} .= qq!<BR>CVV2 (<A HREF="javascript:myopen('cvv2.html','cvv2','toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=yes,copyhistory=no,width=480,height=288')">help</A>) <INPUT TYPE="text" NAME=${payby}_paycvv VALUE="" SIZE=4 MAXLENGTH=4>!; +      } +    } + +    my( $account, $aba ) = split('@', $payinfo); +    my %paybychecked = ( +      'CARD' => qq!Credit card<BR><font color="#ff0000">*</font>$cardselect<INPUT TYPE="text" NAME="CARD_payinfo" VALUE="$payinfo" MAXLENGTH=19><BR><font color="#ff0000">*</font>Exp !. expselect("CARD", $paydate), #. qq!<BR><font color="#ff0000">*</font>Name on card<BR><INPUT TYPE="text" NAME="CARD_payname" VALUE="$payname">!, +      'DCRD' => qq!Credit card<BR><font color="#ff0000">*</font>$cardselect<INPUT TYPE="text" NAME="DCRD_payinfo" VALUE="$payinfo" MAXLENGTH=19><BR><font color="#ff0000">*</font>Exp !. expselect("DCRD", $paydate), #. qq!<BR><font color="#ff0000">*</font>Name on card<BR><INPUT TYPE="text" NAME="DCRD_payname" VALUE="$payname">!, +      'CHEK' => qq!Electronic check<BR>${r}Account number <INPUT TYPE="text" NAME="CHEK_payinfo1" VALUE="$account" MAXLENGTH=10><BR>${r}ABA/Routing code <INPUT TYPE="text" NAME="CHEK_payinfo2" VALUE="$aba" SIZE=10 MAXLENGTH=9><INPUT TYPE="hidden" NAME="CHEK_month" VALUE="12"><INPUT TYPE="hidden" NAME="CHEK_year" VALUE="2037"><BR>${r}Bank name <INPUT TYPE="text" NAME="CHEK_payname" VALUE="$payname">!, +      'DCHK' => qq!Electronic check<BR>${r}Account number <INPUT TYPE="text" NAME="DCHK_payinfo1" VALUE="$account" MAXLENGTH=10><BR>${r}ABA/Routing code <INPUT TYPE="text" NAME="DCHK_payinfo2" VALUE="$aba" SIZE=10 MAXLENGTH=9><INPUT TYPE="hidden" NAME="DCHK_month" VALUE="12"><INPUT TYPE="hidden" NAME="DCHK_year" VALUE="2037"><BR>${r}Bank name <INPUT TYPE="text" NAME="DCHK_payname" VALUE="$payname">!, +      'LECB' => qq!Phone bill billing<BR>${r}Phone number <INPUT TYPE="text" BANE="LECB_payinfo" VALUE="$payinfo" MAXLENGTH=15 SIZE=16><INPUT TYPE="hidden" NAME="LECB_month" VALUE="12"><INPUT TYPE="hidden" NAME="LECB_year" VALUE="2037"><INPUT TYPE="hidden" NAME="LECB_payname" VALUE="">!, +      'BILL' => qq!Billing<BR>P.O. <INPUT TYPE="text" NAME="BILL_payinfo" VALUE="$payinfo"><BR><font color="#ff0000">*</font>Exp !. expselect("BILL", $paydate). qq!<BR><font color="#ff0000">*</font>Attention<BR><INPUT TYPE="text" NAME="BILL_payname" VALUE="$payname">!, +      'COMP' => qq!Complimentary<BR><font color="#ff0000">*</font>Approved by<INPUT TYPE="text" NAME="COMP_payinfo" VALUE="$payinfo"><BR><font color="#ff0000">*</font>Exp !. expselect("COMP", $paydate), +      'PREPAY' => qq!Prepaid card<BR><font color="#ff0000">*</font><INPUT TYPE="text" NAME="PREPAY_payinfo" VALUE="$payinfo" MAXLENGTH=80>!, +    ); + +    if ( $init_data->{'cvv_enabled'} ) { +      foreach my $payby ( grep { exists $payby{$_} } qw(CARD DCRD) ) { #1.4/1.5 +        $paybychecked{$payby} .= qq!<BR>CVV2 (<A HREF="javascript:myopen('cvv2.html','cvv2','toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=yes,copyhistory=no,width=480,height=288')">help</A>) <INPUT TYPE="text" NAME=${payby}_paycvv VALUE="$paycvv" SIZE=4 MAXLENGTH=4>!; +      } +    } + +    for (@payby) { +      if ( scalar(@payby) == 1) { +        $OUT .= '<TD VALIGN=TOP>'. +                qq!<INPUT TYPE="hidden" NAME="payby" VALUE="$_">!. +                "$paybychecked{$_}</TD>"; +      } else { +        $OUT .= qq!<TD VALIGN=TOP><INPUT TYPE="radio" NAME="payby" VALUE="$_"!; +        if ($payby eq $_) { +          $OUT .= qq! CHECKED> $paybychecked{$_}</TD>!; +        } else { +          $OUT .= qq!> $payby{$_}</TD>!; +        } + +      } +    } +  %> + +</TR></TABLE><font color="#ff0000">*</font> required fields for each billing type +<BR><BR>First package +<INPUT TYPE="hidden" NAME="promo_code" VALUE="<%= $cgi->param('promo_code') %>"> +<TABLE BGCOLOR="#c0c0c0" BORDER=0 CELLSPACING=0 WIDTH="100%"> +<TR> +  <TD COLSPAN=2><SELECT NAME="pkgpart"> + +  <%= +    $OUT .= '<OPTION VALUE="">(none)' unless scalar(@$packages) == 1; +    foreach my $package ( @{$packages} ) { +      $OUT .= '<OPTION VALUE="'. $package->{'pkgpart'}. '"'; +      $OUT .= ' SELECTED' +        if ( $pkgpart && $package->{'pkgpart'} == $pkgpart ) +           || scalar(@$packages) == 1; +      $OUT .= '>'. $package->{'pkg'}; +    } +  %> + +  </SELECT></TD> +</TR> +<TR> +  <TD ALIGN="right">Username</TD> +  <TD><INPUT TYPE="text" NAME="username" VALUE="<%= $username %>"></TD> +</TR> +<TR> +  <TD ALIGN="right">Password</TD> +  <TD><INPUT TYPE="password" NAME="_password" VALUE="<%= $password %>"></TD> +</TR> +<TR> +  <TD ALIGN="right">Re-enter Password</TD> +  <TD><INPUT TYPE="password" NAME="_password2" VALUE="<%= $password2 %>"></TD> +</TR> +<%= +  if ( $init_data->{'security_phrase'} ) { +    $OUT .= <<ENDOUT; +<TR> +  <TD ALIGN="right">Security Phrase</TD> +  <TD><INPUT TYPE="text" NAME="sec_phrase" VALUE="$sec_phrase"> +  </TD> +</TR> +ENDOUT +  } else { +    $OUT .= '<INPUT TYPE="hidden" NAME="sec_phrase" VALUE="">'; +  } +%> +<%= +  if ( scalar(@$pops) ) { +    $OUT .= '<TR><TD ALIGN="right">Access number</TD><TD>'. +            popselector($popnum). '</TD></TR>'; +  } else { +    $OUT .= popselector($popnum); +  } +%> +</TABLE> +<BR><BR><INPUT TYPE="submit" NAME="signup" VALUE="Signup"> +</FORM></BODY></HTML> diff --git a/fs_selfservice/FS-SelfService/cgi/signup-freeoption.html b/fs_selfservice/FS-SelfService/cgi/signup-freeoption.html new file mode 100755 index 000000000..40ad03c0b --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/signup-freeoption.html @@ -0,0 +1,262 @@ +<HTML><HEAD><TITLE>ISP Signup form</TITLE></HEAD> +<BODY BGCOLOR="#e8e8e8" onUnload="myclose()"> +<script language="JavaScript"><!-- +  var mywindow = -1; +  function myopen(filename,windowname,properties) { +    myclose(); +    mywindow = window.open(filename,windowname,properties); +  } +  function myclose() { +    if ( mywindow != -1 ) +      mywindow.close(); +    mywindow = -1 +  } +//--></script> +<FONT SIZE=7>ISP Signup form</FONT><BR><BR> +<FONT SIZE="+1" COLOR="#ff0000"><%= $error %></FONT> +<FORM NAME="OneTrueForm" ACTION="<%= $self_url %>" METHOD=POST onSubmit="document.OneTrueForm.signup.disabled=true"> +<INPUT TYPE="hidden" NAME="magic" VALUE="process"> +<INPUT TYPE="hidden" NAME="ref" VALUE="<%= $referral_custnum %>"> +<INPUT TYPE="hidden" NAME="ss" VALUE=""> +Where did you hear about our service? <SELECT NAME="refnum"> +<%= +  $OUT .= '<OPTION VALUE="">' unless $refnum; +  foreach my $part_referral ( @{$init_data->{'part_referral'}} ) { +    $OUT .= '<OPTION VALUE="'. $part_referral->{'refnum'}. '"'; +    $OUT .= ' SELECTED' if $part_referral->{'refnum'} eq $refnum; +    $OUT .= '>'. $part_referral->{'referral'}; +  } +%> +</SELECT><BR><BR> +Contact Information +<TABLE BGCOLOR="#c0c0c0" BORDER=0 CELLSPACING=0 WIDTH="100%"> +<TR> +  <TH ALIGN="right"><font color="#ff0000">*</font>Contact name<BR>(last, first)</TH> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="last" VALUE="<%= $last %>">, +                <INPUT TYPE="text" NAME="first" VALUE="<%= $first %>"></TD> +</TR> +<TR> +  <TD ALIGN="right">Company</TD> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="company" SIZE=70 VALUE="<%= $company %>"></TD> +</TR> +<TR> +  <TH ALIGN="right"><font color="#ff0000">*</font>Address</TH> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="address1" SIZE=70 VALUE="<%= $address1 %>"></TD> +</TR> +<TR> +  <TD ALIGN="right"> </TD> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="address2" SIZE=70 VALUE="<%= $address2 %>"></TD> +</TR> +<TR> +  <TH ALIGN="right"><font color="#ff0000">*</font>City</TH> +  <TD><INPUT TYPE="text" NAME="city" VALUE="<%= $city %>"></TD> +  <TH ALIGN="right"><font color="#ff0000">*</font>State/Country</TH> +  <TD> +    <%= +        ($county_html, $state_html, $country_html) = +          regionselector( $county, $state, $country ); +  +        "$county_html $state_html"; +    %> +  </TD> +  <TH><font color="#ff0000">*</font>Zip</TH> +  <TD><INPUT TYPE="text" NAME="zip" SIZE=10 VALUE="<%= $zip %>"></TD> +</TR> +<TR> +  <TH ALIGN="right"><font color="#ff0000">*</font>Country</TH> +  <TD><%= $country_html %></TD> +<TR> +  <TD ALIGN="right">Day Phone</TD> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="daytime" VALUE="<%= $daytime %>" SIZE=18></TD> +</TR> +<TR> +  <TD ALIGN="right">Night Phone</TD> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="night" VALUE="<%= $night %>" SIZE=18></TD> +</TR> +<TR> +  <TD ALIGN="right">Fax</TD> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="fax" VALUE="<%= $fax %>" SIZE=12></TD> +</TR> +</TABLE><font color="#ff0000">*</font> required fields<BR> +<BR> +<%= +  my $first_payby = $packages->[0]{'payby'}[0]; +  unless ( grep { scalar( @{$_->{'payby'}} ) > 1 +                    || $_->{'payby'}->[0] ne $first_payby +                } @$packages +  ) {  +    @payby = ( $first_payby ); +  } + +  unless ( scalar(@payby) == 1 && $payby[0] eq 'BILL' ) { + +    $OUT .= ' Billing information +            <TABLE BGCOLOR="#c0c0c0" BORDER=0 CELLSPACING=0 WIDTH="100%"> +            <TR><TD> +            <INPUT TYPE="checkbox" NAME="invoicing_list_POST" VALUE="POST"'; + +    my @invoicing_list = split(', ', $invoicing_list ); + +    $OUT .= ' CHECKED' +      if ! @invoicing_list || grep { $_ eq 'POST' } @invoicing_list; + +    $OUT .= '> Postal mail invoice +            </TD></TR> +            <TR><TD>Email invoice  +            <INPUT TYPE="text" NAME="invoicing_list" VALUE="' +              .join(', ', grep { $_ ne 'POST' } split(', ', $invoicing_list ) ). +            '"></TD></TR>'; + +    $OUT .= '<TR><TD>Billing type</TD></TR>' +      if scalar(@payby) > 1; + +    $OUT .= '</TABLE>'; + +  } else { +    $OUT .= '<INPUT TYPE="hidden" NAME="invoicing_list" VALUE=""> +             <INPUT TYPE="hidden" NAME="invoicing_list_POST" VALUE="">'; +  } + +%> + +<TABLE BGCOLOR="#c0c0c0" BORDER=1 WIDTH="100%"> +<TR> + +  <%= + +    my $cardselect = '<SELECT NAME="CARD_type"><OPTION></OPTION>'; +    my %types = ( +                  'VISA' => 'VISA card', +                  'MasterCard' => 'MasterCard', +                  'Discover' => 'Discover card', +                  'American Express' => 'American Express card', +                ); +    foreach ( keys %types ) { +      $selected = $cgi->param('CARD_type') eq $types{$_} ? 'SELECTED' : ''; +      $cardselect .= qq!<OPTION $selected VALUE="$types{$_}">$_</OPTION>!; +    } +    $cardselect .= '</SELECT>'; +   +    my %payby = ( +      'CARD' => qq!Credit card<BR><font color="#ff0000">*</font>$cardselect<INPUT TYPE="text" NAME="CARD_payinfo" VALUE="" MAXLENGTH=19><BR><font color="#ff0000">*</font>Exp !. expselect("CARD"). qq!<BR><font color="#ff0000">*</font>Name on card<BR><INPUT TYPE="text" NAME="CARD_payname" VALUE="">!, +      'DCRD' => qq!Credit card<BR><font color="#ff0000">*</font>$cardselect<INPUT TYPE="text" NAME="DCRD_payinfo" VALUE="" MAXLENGTH=19><BR><font color="#ff0000">*</font>Exp !. expselect("DCRD"). qq!<BR><font color="#ff0000">*</font>Name on card<BR><INPUT TYPE="text" NAME="DCRD_payname" VALUE="">!, +      'CHEK' => qq!Electronic check<BR>${r}Account number <INPUT TYPE="text" NAME="CHEK_payinfo1" VALUE="" MAXLENGTH=10><BR>${r}ABA/Routing code <INPUT TYPE="text" NAME="CHEK_payinfo2" VALUE="" SIZE=10 MAXLENGTH=9><INPUT TYPE="hidden" NAME="CHEK_month" VALUE="12"><INPUT TYPE="hidden" NAME="CHEK_year" VALUE="2037"><BR>${r}Bank name <INPUT TYPE="text" NAME="CHEK_payname" VALUE="">!, +      'DCHK' => qq!Electronic check<BR>${r}Account number <INPUT TYPE="text" NAME="DCHK_payinfo1" VALUE="" MAXLENGTH=10><BR>${r}ABA/Routing code <INPUT TYPE="text" NAME="DCHK_payinfo2" VALUE="" SIZE=10 MAXLENGTH=9><INPUT TYPE="hidden" NAME="DCHK_month" VALUE="12"><INPUT TYPE="hidden" NAME="DCHK_year" VALUE="2037"><BR>${r}Bank name <INPUT TYPE="text" NAME="DCHK_payname" VALUE="">!, +      'LECB' => qq!Phone bill billing<BR>${r}Phone number <INPUT TYPE="text" BANE="LECB_payinfo" VALUE="" MAXLENGTH=15 SIZE=16><INPUT TYPE="hidden" NAME="LECB_month" VALUE="12"><INPUT TYPE="hidden" NAME="LECB_year" VALUE="2037"><INPUT TYPE="hidden" NAME="LECB_payname" VALUE="">!, +      'BILL' => <<'END', +<INPUT TYPE="hidden" NAME="BILL_payinfo" VALUE=""> +<INPUT TYPE="hidden" NAME="BILL_month" VALUE="12"> +<INPUT TYPE="hidden" NAME="BILL_year" VALUE="2037"> +<INPUT TYPE="hidden" NAME="BILL_payname" VALUE=""> +END +      'COMP' => qq!Complimentary<BR><font color="#ff0000">*</font>Approved by<INPUT TYPE="text" NAME="COMP_payinfo" VALUE=""><BR><font color="#ff0000">*</font>Exp !. expselect("COMP"), +      'PREPAY' => qq!Prepaid card<BR><font color="#ff0000">*</font><INPUT TYPE="text" NAME="PREPAY_payinfo" VALUE="" MAXLENGTH=80>!, +    ); + +    if ( $init_data->{'cvv_enabled'} ) { +      foreach my $payby ( grep { exists $payby{$_} } qw(CARD DCRD) ) { #1.4/1.5 +        $payby{$payby} .= qq!<BR>CVV2 (<A HREF="javascript:myopen('cvv2.html','cvv2','toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=yes,copyhistory=no,width=480,height=288')">help</A>) <INPUT TYPE="text" NAME=${payby}_paycvv VALUE="" SIZE=4 MAXLENGTH=4>!; +      } +    } + +    my( $account, $aba ) = split('@', $payinfo); +    my %paybychecked = ( +      'CARD' => qq!Credit card<BR><font color="#ff0000">*</font>$cardselect<INPUT TYPE="text" NAME="CARD_payinfo" VALUE="$payinfo" MAXLENGTH=19><BR><font color="#ff0000">*</font>Exp !. expselect("CARD", $paydate). qq!<BR><font color="#ff0000">*</font>Name on card<BR><INPUT TYPE="text" NAME="CARD_payname" VALUE="$payname">!, +      'DCRD' => qq!Credit card<BR><font color="#ff0000">*</font>$cardselect<INPUT TYPE="text" NAME="DCRD_payinfo" VALUE="$payinfo" MAXLENGTH=19><BR><font color="#ff0000">*</font>Exp !. expselect("DCRD", $paydate). qq!<BR><font color="#ff0000">*</font>Name on card<BR><INPUT TYPE="text" NAME="DCRD_payname" VALUE="$payname">!, +      'CHEK' => qq!Electronic check<BR>${r}Account number <INPUT TYPE="text" NAME="CHEK_payinfo1" VALUE="$account" MAXLENGTH=10><BR>${r}ABA/Routing code <INPUT TYPE="text" NAME="CHEK_payinfo2" VALUE="$aba" SIZE=10 MAXLENGTH=9><INPUT TYPE="hidden" NAME="CHEK_month" VALUE="12"><INPUT TYPE="hidden" NAME="CHEK_year" VALUE="2037"><BR>${r}Bank name <INPUT TYPE="text" NAME="CHEK_payname" VALUE="$payname">!, +      'DCHK' => qq!Electronic check<BR>${r}Account number <INPUT TYPE="text" NAME="DCHK_payinfo1" VALUE="$account" MAXLENGTH=10><BR>${r}ABA/Routing code <INPUT TYPE="text" NAME="DCHK_payinfo2" VALUE="$aba" SIZE=10 MAXLENGTH=9><INPUT TYPE="hidden" NAME="DCHK_month" VALUE="12"><INPUT TYPE="hidden" NAME="DCHK_year" VALUE="2037"><BR>${r}Bank name <INPUT TYPE="text" NAME="DCHK_payname" VALUE="$payname">!, +      'LECB' => qq!Phone bill billing<BR>${r}Phone number <INPUT TYPE="text" BANE="LECB_payinfo" VALUE="$payinfo" MAXLENGTH=15 SIZE=16><INPUT TYPE="hidden" NAME="LECB_month" VALUE="12"><INPUT TYPE="hidden" NAME="LECB_year" VALUE="2037"><INPUT TYPE="hidden" NAME="LECB_payname" VALUE="">!, +      'BILL' => <<'END', +<INPUT TYPE="hidden" NAME="BILL_payinfo" VALUE=""> +<INPUT TYPE="hidden" NAME="BILL_month" VALUE="12"> +<INPUT TYPE="hidden" NAME="BILL_year" VALUE="2037"> +<INPUT TYPE="hidden" NAME="BILL_payname" VALUE=""> +END + +      'COMP' => qq!Complimentary<BR><font color="#ff0000">*</font>Approved by<INPUT TYPE="text" NAME="COMP_payinfo" VALUE="$payinfo"><BR><font color="#ff0000">*</font>Exp !. expselect("COMP", $paydate), +      'PREPAY' => qq!Prepaid card<BR><font color="#ff0000">*</font><INPUT TYPE="text" NAME="PREPAY_payinfo" VALUE="$payinfo" MAXLENGTH=80>!, +    ); + +    if ( $init_data->{'cvv_enabled'} ) { +      foreach my $payby ( grep { exists $payby{$_} } qw(CARD DCRD) ) { #1.4/1.5 +        $paybychecked{$payby} .= qq!<BR>CVV2 (<A HREF="javascript:myopen('cvv2.html','cvv2','toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=yes,copyhistory=no,width=480,height=288')">help</A>) <INPUT TYPE="text" NAME=${payby}_paycvv VALUE="$paycvv" SIZE=4 MAXLENGTH=4>!; +      } +    } + +    for (@payby) { +      if ( scalar(@payby) == 1) { +        $OUT .= '<TD VALIGN=TOP>'. +                qq!<INPUT TYPE="hidden" NAME="payby" VALUE="$_">!. +                "$paybychecked{$_}</TD>"; +      } else { +        $OUT .= qq!<TD VALIGN=TOP><INPUT TYPE="radio" NAME="payby" VALUE="$_"!; +        if ($payby eq $_) { +          $OUT .= qq! CHECKED> $paybychecked{$_}</TD>!; +        } else { +          $OUT .= qq!> $payby{$_}</TD>!; +        } + +      } +    } +  %> + +</TR></TABLE> +<%= unless ( scalar(@payby) == 1 && $payby[0] eq 'BILL' ) { +      $OUT .= '<font color="#ff0000">*</font> required fields for each billing type'; +    } +    ''; +%> +<BR><BR>First package +<INPUT TYPE="hidden" NAME="promo_code" VALUE="<%= $cgi->param('promo_code') %>"><TABLE BGCOLOR="#c0c0c0" BORDER=0 CELLSPACING=0 WIDTH="100%"> +<TR> +  <TD COLSPAN=2><SELECT NAME="pkgpart"> + +  <%= +    $OUT .= '<OPTION VALUE="">(none)' unless scalar(@$packages) == 1; +    foreach my $package ( @{$packages} ) { +      $OUT .= '<OPTION VALUE="'. $package->{'pkgpart'}. '"'; +      $OUT .= ' SELECTED' +        if ( $pkgpart && $package->{'pkgpart'} == $pkgpart ) +           || scalar(@$packages) == 1; +      $OUT .= '>'. $package->{'pkg'}; +    } +  %> + +  </SELECT></TD> +</TR> +<TR> +  <TD ALIGN="right">Username</TD> +  <TD><INPUT TYPE="text" NAME="username" VALUE="<%= $username %>"></TD> +</TR> +<TR> +  <TD ALIGN="right">Password</TD> +  <TD><INPUT TYPE="password" NAME="_password" VALUE="<%= $password %>"></TD> +</TR> +<TR> +  <TD ALIGN="right">Re-enter Password</TD> +  <TD><INPUT TYPE="password" NAME="_password2" VALUE="<%= $password2 %>"></TD> +</TR> +<%= +  if ( $init_data->{'security_phrase'} ) { +    $OUT .= <<ENDOUT; +<TR> +  <TD ALIGN="right">Security Phrase</TD> +  <TD><INPUT TYPE="text" NAME="sec_phrase" VALUE="$sec_phrase"> +  </TD> +</TR> +ENDOUT +  } else { +    $OUT .= '<INPUT TYPE="hidden" NAME="sec_phrase" VALUE="">'; +  } +%> +<%= +  if ( scalar(@$pops) ) { +    $OUT .= '<TR><TD ALIGN="right">Access number</TD><TD>'. +            popselector($popnum). '</TD></TR>'; +  } else { +    $OUT .= popselector($popnum); +  } +%> +</TABLE> +<BR><BR><INPUT TYPE="submit" NAME="signup" VALUE="Signup"> +</FORM></BODY></HTML> diff --git a/fs_selfservice/FS-SelfService/cgi/signup-snarf.html b/fs_selfservice/FS-SelfService/cgi/signup-snarf.html new file mode 100755 index 000000000..d167efbf9 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/signup-snarf.html @@ -0,0 +1,228 @@ +<HTML><HEAD><TITLE>ISP Signup form</TITLE></HEAD> +<BODY BGCOLOR="#e8e8e8" onUnload="myclose()"> +<script language="JavaScript"><!-- +  var mywindow = -1; +  function myopen(filename,windowname,properties) { +    myclose(); +    mywindow = window.open(filename,windowname,properties); +  } +  function myclose() { +    if ( mywindow != -1 ) +      mywindow.close(); +    mywindow = -1 +  } +//--></script> +<FONT SIZE=7>ISP Signup form</FONT><BR><BR> +<FONT SIZE="+1" COLOR="#ff0000"><%= $error %></FONT> +<FORM ACTION="<%= $self_url %>" METHOD=POST> +<INPUT TYPE="hidden" NAME="magic" VALUE="process"> +<INPUT TYPE="hidden" NAME="ref" VALUE="<%= $referral_custnum %>"> +<INPUT TYPE="hidden" NAME="ss" VALUE=""> +Contact Information +<TABLE BGCOLOR="#c0c0c0" BORDER=0 CELLSPACING=0 WIDTH="100%"> +<TR> +  <TH ALIGN="right"><font color="#ff0000">*</font>Contact name<BR>(last, first)</TH> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="last" VALUE="<%= $last %>">, +                <INPUT TYPE="text" NAME="first" VALUE="<%= $first %>"></TD> +</TR> +<TR> +  <TD ALIGN="right">Company</TD> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="company" SIZE=70 VALUE="<%= $company %>"></TD> +</TR> +<TR> +  <TH ALIGN="right"><font color="#ff0000">*</font>Address</TH> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="address1" SIZE=70 VALUE="<%= $address1 %>"></TD> +</TR> +<TR> +  <TD ALIGN="right"> </TD> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="address2" SIZE=70 VALUE="<%= $address2 %>"></TD> +</TR> +<TR> +  <TH ALIGN="right"><font color="#ff0000">*</font>City</TH> +  <TD><INPUT TYPE="text" NAME="city" VALUE="<%= $city %>"></TD> +  <TH ALIGN="right"><font color="#ff0000">*</font>State/Country</TH> +  <TD> +    <%= +        ($county_html, $state_html, $country_html) = +          regionselector( $county, $state, $country ); +  +        "$county_html $state_html"; +    %> +  </TD> +  <TH><font color="#ff0000">*</font>Zip</TH> +  <TD><INPUT TYPE="text" NAME="zip" SIZE=10 VALUE="<%= $zip %>"></TD> +</TR> +<TR> +  <TH ALIGN="right"><font color="#ff0000">*</font>Country</TH> +  <TD><%= $country_html %></TD> +<TR> +  <TD ALIGN="right">Day Phone</TD> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="daytime" VALUE="<%= $daytime %>" SIZE=18></TD> +</TR> +<TR> +  <TD ALIGN="right">Night Phone</TD> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="night" VALUE="<%= $night %>" SIZE=18></TD> +</TR> +<TR> +  <TD ALIGN="right">Fax</TD> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="fax" VALUE="<%= $fax %>" SIZE=12></TD> +</TR> +</TABLE><font color="#ff0000">*</font> required fields<BR> +<BR>Billing information<TABLE BGCOLOR="#c0c0c0" BORDER=0 CELLSPACING=0 WIDTH="100%"> +<TR><TD> + +  <%= +    $OUT .= '<INPUT TYPE="checkbox" NAME="invoicing_list_POST" VALUE="POST"'; +    my @invoicing_list = split(', ', $invoicing_list ); +    $OUT .= ' CHECKED' +      if ! @invoicing_list || grep { $_ eq 'POST' } @invoicing_list; +    $OUT .= '>'; +  %> + +  Postal mail invoice +</TD></TR> +<TR><TD>Email invoice <INPUT TYPE="text" NAME="invoicing_list" VALUE="<%= join(', ', grep { $_ ne 'POST' } split(', ', $invoicing_list ) ) %>"> +</TD></TR> +<%= scalar(@payby) > 1 ? '<TR><TD>Billing type</TD></TR>' : '' %> +</TABLE> +<TABLE BGCOLOR="#c0c0c0" BORDER=1 WIDTH="100%"> +<TR> + +  <%= + +    my $cardselect = '<SELECT NAME="CARD_type"><OPTION></OPTION>'; +    my %types = ( +                  'VISA' => 'VISA card', +                  'MasterCard' => 'MasterCard', +                  'Discover' => 'Discover card', +                  'American Express' => 'American Express card', +                ); +    foreach ( keys %types ) { +      $selected = $cgi->param('CARD_type') eq $types{$_} ? 'SELECTED' : ''; +      $cardselect .= qq!<OPTION $selected VALUE="$types{$_}">$_</OPTION>!; +    } +    $cardselect .= '</SELECT>'; +   +    my %payby = ( +      'CARD' => qq!Credit card<BR><font color="#ff0000">*</font>$cardselect<INPUT TYPE="text" NAME="CARD_payinfo" VALUE="" MAXLENGTH=19><BR><font color="#ff0000">*</font>Exp !. expselect("CARD"). qq!<BR><font color="#ff0000">*</font>Name on card<BR><INPUT TYPE="text" NAME="CARD_payname" VALUE="">!, +      'DCRD' => qq!Credit card<BR><font color="#ff0000">*</font>$cardselect<INPUT TYPE="text" NAME="DCRD_payinfo" VALUE="" MAXLENGTH=19><BR><font color="#ff0000">*</font>Exp !. expselect("DCRD"). qq!<BR><font color="#ff0000">*</font>Name on card<BR><INPUT TYPE="text" NAME="DCRD_payname" VALUE="">!, +      'CHEK' => qq!Electronic check<BR>${r}Account number <INPUT TYPE="text" NAME="CHEK_payinfo1" VALUE="" MAXLENGTH=10><BR>${r}ABA/Routing code <INPUT TYPE="text" NAME="CHEK_payinfo2" VALUE="" SIZE=10 MAXLENGTH=9><INPUT TYPE="hidden" NAME="CHEK_month" VALUE="12"><INPUT TYPE="hidden" NAME="CHEK_year" VALUE="2037"><BR>${r}Bank name <INPUT TYPE="text" NAME="CHEK_payname" VALUE="">!, +      'DCHK' => qq!Electronic check<BR>${r}Account number <INPUT TYPE="text" NAME="DCHK_payinfo1" VALUE="" MAXLENGTH=10><BR>${r}ABA/Routing code <INPUT TYPE="text" NAME="DCHK_payinfo2" VALUE="" SIZE=10 MAXLENGTH=9><INPUT TYPE="hidden" NAME="DCHK_month" VALUE="12"><INPUT TYPE="hidden" NAME="DCHK_year" VALUE="2037"><BR>${r}Bank name <INPUT TYPE="text" NAME="DCHK_payname" VALUE="">!, +      'LECB' => qq!Phone bill billing<BR>${r}Phone number <INPUT TYPE="text" BANE="LECB_payinfo" VALUE="" MAXLENGTH=15 SIZE=16><INPUT TYPE="hidden" NAME="LECB_month" VALUE="12"><INPUT TYPE="hidden" NAME="LECB_year" VALUE="2037"><INPUT TYPE="hidden" NAME="LECB_payname" VALUE="">!, +      'BILL' => qq!Billing<BR>P.O. <INPUT TYPE="text" NAME="BILL_payinfo" VALUE=""><BR><font color="#ff0000">*</font>Exp !. expselect("BILL", "12-2037"). qq!<BR><font color="#ff0000">*</font>Attention<BR><INPUT TYPE="text" NAME="BILL_payname" VALUE="Accounts Payable">!, +      'COMP' => qq!Complimentary<BR><font color="#ff0000">*</font>Approved by<INPUT TYPE="text" NAME="COMP_payinfo" VALUE=""><BR><font color="#ff0000">*</font>Exp !. expselect("COMP"), +      'PREPAY' => qq!Prepaid card<BR><font color="#ff0000">*</font><INPUT TYPE="text" NAME="PREPAY_payinfo" VALUE="" MAXLENGTH=80>!, +    ); + +    if ( $init_data->{'cvv_enabled'} ) { +      foreach my $payby ( grep { exists $payby{$_} } qw(CARD DCRD) ) { #1.4/1.5 +        $payby{$payby} .= qq!<BR>CVV2 (<A HREF="javascript:myopen('cvv2.html','cvv2','toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=yes,copyhistory=no,width=480,height=288')">help</A>) <INPUT TYPE="text" NAME=${payby}_paycvv VALUE="" SIZE=4 MAXLENGTH=4>!; +      } +    } + +    my( $account, $aba ) = split('@', $payinfo); +    my %paybychecked = ( +      'CARD' => qq!Credit card<BR><font color="#ff0000">*</font>$cardselect<INPUT TYPE="text" NAME="CARD_payinfo" VALUE="$payinfo" MAXLENGTH=19><BR><font color="#ff0000">*</font>Exp !. expselect("CARD", $paydate). qq!<BR><font color="#ff0000">*</font>Name on card<BR><INPUT TYPE="text" NAME="CARD_payname" VALUE="$payname">!, +      'DCRD' => qq!Credit card<BR><font color="#ff0000">*</font>$cardselect<INPUT TYPE="text" NAME="DCRD_payinfo" VALUE="$payinfo" MAXLENGTH=19><BR><font color="#ff0000">*</font>Exp !. expselect("DCRD", $paydate). qq!<BR><font color="#ff0000">*</font>Name on card<BR><INPUT TYPE="text" NAME="DCRD_payname" VALUE="$payname">!, +      'CHEK' => qq!Electronic check<BR>${r}Account number <INPUT TYPE="text" NAME="CHEK_payinfo1" VALUE="$account" MAXLENGTH=10><BR>${r}ABA/Routing code <INPUT TYPE="text" NAME="CHEK_payinfo2" VALUE="$aba" SIZE=10 MAXLENGTH=9><INPUT TYPE="hidden" NAME="CHEK_month" VALUE="12"><INPUT TYPE="hidden" NAME="CHEK_year" VALUE="2037"><BR>${r}Bank name <INPUT TYPE="text" NAME="CHEK_payname" VALUE="$payname">!, +      'DCHK' => qq!Electronic check<BR>${r}Account number <INPUT TYPE="text" NAME="DCHK_payinfo1" VALUE="$account" MAXLENGTH=10><BR>${r}ABA/Routing code <INPUT TYPE="text" NAME="DCHK_payinfo2" VALUE="$aba" SIZE=10 MAXLENGTH=9><INPUT TYPE="hidden" NAME="DCHK_month" VALUE="12"><INPUT TYPE="hidden" NAME="DCHK_year" VALUE="2037"><BR>${r}Bank name <INPUT TYPE="text" NAME="DCHK_payname" VALUE="$payname">!, +      'LECB' => qq!Phone bill billing<BR>${r}Phone number <INPUT TYPE="text" BANE="LECB_payinfo" VALUE="$payinfo" MAXLENGTH=15 SIZE=16><INPUT TYPE="hidden" NAME="LECB_month" VALUE="12"><INPUT TYPE="hidden" NAME="LECB_year" VALUE="2037"><INPUT TYPE="hidden" NAME="LECB_payname" VALUE="">!, +      'BILL' => qq!Billing<BR>P.O. <INPUT TYPE="text" NAME="BILL_payinfo" VALUE="$payinfo"><BR><font color="#ff0000">*</font>Exp !. expselect("BILL", $paydate). qq!<BR><font color="#ff0000">*</font>Attention<BR><INPUT TYPE="text" NAME="BILL_payname" VALUE="$payname">!, +      'COMP' => qq!Complimentary<BR><font color="#ff0000">*</font>Approved by<INPUT TYPE="text" NAME="COMP_payinfo" VALUE="$payinfo"><BR><font color="#ff0000">*</font>Exp !. expselect("COMP", $paydate), +      'PREPAY' => qq!Prepaid card<BR><font color="#ff0000">*</font><INPUT TYPE="text" NAME="PREPAY_payinfo" VALUE="$payinfo" MAXLENGTH=80>!, +    ); + +    if ( $init_data->{'cvv_enabled'} ) { +      foreach my $payby ( grep { exists $payby{$_} } qw(CARD DCRD) ) { #1.4/1.5 +        $paybychecked{$payby} .= qq!<BR>CVV2 (<A HREF="javascript:myopen('cvv2.html','cvv2','toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=yes,copyhistory=no,width=480,height=288')">help</A>) <INPUT TYPE="text" NAME=${payby}_paycvv VALUE="$paycvv" SIZE=4 MAXLENGTH=4>!; +      } +    } + +    for (@payby) { +      if ( scalar(@payby) == 1) { +        $OUT .= '<TD VALIGN=TOP>'. +                qq!<INPUT TYPE="hidden" NAME="payby" VALUE="$_">!. +                "$paybychecked{$_}</TD>"; +      } else { +        $OUT .= qq!<TD VALIGN=TOP><INPUT TYPE="radio" NAME="payby" VALUE="$_"!; +        if ($payby eq $_) { +          $OUT .= qq! CHECKED> $paybychecked{$_}</TD>!; +        } else { +          $OUT .= qq!> $payby{$_}</TD>!; +        } + +      } +    } +  %> + +</TR></TABLE><font color="#ff0000">*</font> required fields for each billing type +<BR><BR>First package +<TABLE BGCOLOR="#c0c0c0" BORDER=0 CELLSPACING=0 WIDTH="100%"> +<TR> +  <TD COLSPAN=2><SELECT NAME="pkgpart"><OPTION VALUE="">(none) + +  <%= +    foreach my $package ( @{$packages} ) { +      $OUT .= '<OPTION VALUE="'. $package->{'pkgpart'}. '"'; +      $OUT .= ' SELECTED' if $pkgpart && $package->{'pkgpart'} == $pkgpart; +      $OUT .= '>'. $package->{'pkg'}; +    } +  %> + +  </SELECT></TD> +</TR> +<TR> +  <TD ALIGN="right">Username</TD> +  <TD><INPUT TYPE="text" NAME="username" VALUE="<%= $username %>"></TD> +</TR> +<TR> +  <TD ALIGN="right">Password</TD> +  <TD><INPUT TYPE="password" NAME="_password" VALUE="<%= $password %>"></TD> +</TR> +<TR> +  <TD ALIGN="right">Re-enter Password</TD> +  <TD><INPUT TYPE="password" NAME="_password2" VALUE="<%= $password2 %>"></TD> +</TR> +<%= +  if ( $init_data->{'security_phrase'} ) { +    $OUT .= <<ENDOUT; +<TR> +  <TD ALIGN="right">Security Phrase</TD> +  <TD><INPUT TYPE="text" NAME="sec_phrase" VALUE="$sec_phrase"> +  </TD> +</TR> +ENDOUT +  } else { +    $OUT .= '<INPUT TYPE="hidden" NAME="sec_phrase" VALUE="">'; +  } +%> +<%= +  if ( scalar(@$pops) ) { +    $OUT .= '<TR><TD ALIGN="right">Access number</TD><TD>'. +            popselector($popnum). '</TD></TR>'; +  } else { +    $OUT .= popselector($popnum); +  } +%> +</TABLE> +<BR><BR>Enter up to ten external accounts from which to retrieve email +<TABLE BGCOLOR="#c0c0c0" BORDER=0 CELLSPACING=0 WIDTH="100%"> +<TR> +  <TH ALIGN="left">Mail server</TH> +  <TH ALIGN="left">Username</TH> +  <TH ALIGN="left">Password</TH> +</TR> +<%= +  for my $num ( 1..10 ) { +    no strict 'vars'; +    $OUT .= qq!<TR><TD><INPUT TYPE="text" NAME="snarf_machine$num" VALUE="${"snarf_machine$num"}"></TD>!. +            qq!<INPUT TYPE="hidden" NAME="snarf_protocol$num" VALUE="pop3">!. +            qq!<TD><INPUT TYPE="text" NAME="snarf_username$num" VALUE="${"snarf_username$num"}"></TD>!. +            qq!<TD><INPUT TYPE="password" NAME="snarf_password$num" VALUE="${"snarf_password$num"}"></TD>!. +            qq!</TR>!; +  } +%> +</TABLE> + +<BR><BR><INPUT TYPE="submit" VALUE="Signup"> +</FORM></BODY></HTML> diff --git a/fs_selfservice/FS-SelfService/cgi/signup.cgi b/fs_selfservice/FS-SelfService/cgi/signup.cgi new file mode 100755 index 000000000..7d1679b5c --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/signup.cgi @@ -0,0 +1,487 @@ +#!/usr/bin/perl -T +#!/usr/bin/perl -Tw + +use strict; +use vars qw( @payby $cgi $init_data +             $self_url $error $agentnum + +             $ieak_file $ieak_template +             $signup_html $signup_template +             $success_html $success_template +             $collect_html $collect_template +             $decline_html $decline_template +           ); + +use subs qw( print_form print_okay print_decline +             success_default collect_default decline_default +           ); +use CGI; +#use CGI::Carp qw(fatalsToBrowser); +use Tie::IxHash; +use Text::Template; +use Business::CreditCard; +use HTTP::BrowserDetect; +use HTML::Widgets::SelectLayers; +use FS::SelfService qw( signup_info new_customer ); + +#acceptable payment methods +# +#@payby = qw( CARD BILL COMP ); +#@payby = qw( CARD BILL ); +#@payby = qw( CARD ); +@payby = qw( CARD PREPAY ); + +$ieak_file = '/usr/local/freeside/ieak.template'; +$signup_html = -e 'signup.html' +                 ? 'signup.html' +                 : '/usr/local/freeside/signup.html'; +$success_html = -e 'success.html' +                  ? 'success.html' +                  : '/usr/local/freeside/success.html'; +$collect_html = -e 'collect.html' +                  ? 'collect.html' +                  : '/usr/local/freeside/collect.html'; +$decline_html = -e 'decline.html' +                  ? 'decline.html' +                  : '/usr/local/freeside/decline.html'; + + +if ( -e $ieak_file ) { +  my $ieak_txt = Text::Template::_load_text($ieak_file) +    or die $Text::Template::ERROR; +  $ieak_txt =~ /^(.*)$/s; #untaint the template source - it's trusted +  $ieak_txt = $1; +  $ieak_txt =~ s/\r//g; # don't double \r on old templates +  $ieak_txt =~ s/\n/\r\n/g; +  $ieak_template = new Text::Template ( TYPE => 'STRING', SOURCE => $ieak_txt ) +    or die $Text::Template::ERROR; +} else { +  $ieak_template = ''; +} + +$agentnum = ''; +if ( -e $signup_html ) { +  my $signup_txt = Text::Template::_load_text($signup_html) +    or die $Text::Template::ERROR; +  $signup_txt =~ /^(.*)$/s; #untaint the template source - it's trusted +  $signup_txt = $1; +  $signup_template = new Text::Template ( TYPE => 'STRING', +                                          SOURCE => $signup_txt, +                                          DELIMITERS => [ '<%=', '%>' ] +                                        ) +    or die $Text::Template::ERROR; +  if ( $signup_txt =~ +         /<\s*INPUT TYPE="?hidden"?\s+NAME="?agentnum"?\s+VALUE="?(\d+)"?\s*\/?\s*>/si +  ) { +    $agentnum = $1; +  } +} else { +  #too much maintenance hassle to keep in this file +  die "can't find ./signup.html or /usr/local/freeside/signup.html"; +  #$signup_template = new Text::Template ( TYPE => 'STRING', +  #                                        SOURCE => &signup_default, +  #                                        DELIMITERS => [ '<%=', '%>' ] +  #                                      ) +  #  or die $Text::Template::ERROR; +} + +if ( -e $success_html ) { +  my $success_txt = Text::Template::_load_text($success_html) +    or die $Text::Template::ERROR; +  $success_txt =~ /^(.*)$/s; #untaint the template source - it's trusted +  $success_txt = $1; +  $success_template = new Text::Template ( TYPE => 'STRING', +                                           SOURCE => $success_txt, +                                           DELIMITERS => [ '<%=', '%>' ], +                                         ) +    or die $Text::Template::ERROR; +} else { +  $success_template = new Text::Template ( TYPE => 'STRING', +                                           SOURCE => &success_default, +                                           DELIMITERS => [ '<%=', '%>' ], +                                         ) +    or die $Text::Template::ERROR; +} + +if ( -e $collect_html ) { +  my $collect_txt = Text::Template::_load_text($collect_html) +    or die $Text::Template::ERROR; +  $collect_txt =~ /^(.*)$/s; #untaint the template source - it's trusted +  $collect_txt = $1; +  $collect_template = new Text::Template ( TYPE => 'STRING', +                                           SOURCE => $collect_txt, +                                           DELIMITERS => [ '<%=', '%>' ], +                                         ) +    or die $Text::Template::ERROR; +} else { +  $collect_template = new Text::Template ( TYPE => 'STRING', +                                           SOURCE => &collect_default, +                                           DELIMITERS => [ '<%=', '%>' ], +                                         ) +    or die $Text::Template::ERROR; +} + +if ( -e $decline_html ) { +  my $decline_txt = Text::Template::_load_text($decline_html) +    or die $Text::Template::ERROR; +  $decline_txt =~ /^(.*)$/s; #untaint the template source - it's trusted +  $decline_txt = $1; +  $decline_template = new Text::Template ( TYPE => 'STRING', +                                           SOURCE => $decline_txt, +                                           DELIMITERS => [ '<%=', '%>' ], +                                         ) +    or die $Text::Template::ERROR; +} else { +  $decline_template = new Text::Template ( TYPE => 'STRING', +                                           SOURCE => &decline_default, +                                           DELIMITERS => [ '<%=', '%>' ], +                                         ) +    or die $Text::Template::ERROR; +} + +$cgi = new CGI; + +$init_data = signup_info( 'agentnum'   => $agentnum || scalar($cgi->param('agentnum')), +                          'promo_code' => scalar($cgi->param('promo_code')), +                          'reg_code'   => uc(scalar($cgi->param('reg_code'))), +                        ); + +my $magic  = $cgi->param('magic') || ''; +my $action = $cgi->param('action') || ''; + +if ( $magic eq 'process' || $action eq 'process_signup' ) { + +    $error = ''; + +    $cgi->param('agentnum', $agentnum) if $agentnum; +    $cgi->param('reg_code', uc(scalar($cgi->param('reg_code'))) ); + +    #false laziness w/agent.cgi, identical except for agentnum +    my $payby = $cgi->param('payby'); +    if ( $payby eq 'CHEK' || $payby eq 'DCHK' ) { +      #$payinfo = join('@', map { $cgi->param( $payby. "_payinfo$_" ) } (1,2) ); +      $cgi->param('payinfo' => $cgi->param($payby. '_payinfo1'). '@'.  +                               $cgi->param($payby. '_payinfo2') +                 ); +    } else { +      $cgi->param('payinfo' => $cgi->param( $payby. '_payinfo' ) ); +    } +    $cgi->param('paydate' => $cgi->param( $payby. '_month' ). '-'. +                             $cgi->param( $payby. '_year' ) +               ); +    $cgi->param('payname' => $cgi->param( $payby. '_payname' ) ); +    $cgi->param('paycvv' => defined $cgi->param( $payby. '_paycvv' ) +                              ? $cgi->param( $payby. '_paycvv' ) +                              : '' +               ); +    $cgi->param('paytype' => defined $cgi->param( $payby. '_paytype' ) +                              ? $cgi->param( $payby. '_paytype' ) +                              : '' +               ); +    $cgi->param('paystate' => defined $cgi->param( $payby. '_paystate' ) +                              ? $cgi->param( $payby. '_paystate' ) +                              : '' +               ); + +    if ( $cgi->param('invoicing_list') ) { +      $cgi->param('invoicing_list' => $cgi->param('invoicing_list'). ', POST') +        if $cgi->param('invoicing_list_POST'); +    } else { +      $cgi->param('invoicing_list' => 'POST' ); +    } + +    #if ( $svc_x eq 'svc_acct' ) { +    if ( $cgi->param('_password') ne $cgi->param('_password2') ) { +      $error = $init_data->{msgcat}{passwords_dont_match}; #msgcat +      $cgi->param('_password', ''); +      $cgi->param('_password2', ''); +    } + +    if ( $payby =~ /^(CARD|DCRD)$/ && $cgi->param('CARD_type') ) { +      my $payinfo = $cgi->param('payinfo'); +      $payinfo =~ s/\D//g; + +      $payinfo =~ /^(\d{13,16})$/ +        or $error ||= $init_data->{msgcat}{invalid_card}; #. $self->payinfo; +      $payinfo = $1; +      validate($payinfo) +        or $error ||= $init_data->{msgcat}{invalid_card}; #. $self->payinfo; +      cardtype($payinfo) eq $cgi->param('CARD_type') +        or $error ||= $init_data->{msgcat}{not_a}. $cgi->param('CARD_type'); +    } + +    if ($init_data->{emailinvoiceonly} && (length $cgi->param('invoicing_list') < 1)) { +	$error ||= $init_data->{msgcat}{illegal_or_empty_text}; +    } + +    my $rv = ''; +    unless ( $error ) { +      $rv = new_customer( { +        ( map { $_ => scalar($cgi->param($_)) } +            qw( last first ss company +                address1 address2 city county state zip country +                daytime night fax stateid stateid_state + +                ship_last ship_first ship_company +                ship_address1 ship_address2 ship_city ship_county ship_state +                  ship_zip ship_country +                ship_daytime ship_night ship_fax + +                payby payinfo paycvv paydate payname paystate paytype +                invoicing_list referral_custnum promo_code reg_code +                pkgpart refnum agentnum +                username sec_phrase _password popnum +                mac_addr +                countrycode phonenum sip_password pin +              ), +            grep { /^snarf_/ } $cgi->param +        ), +        'payip' => $cgi->remote_host(), +      } ); +      $error = $rv->{'error'}; +    } +    #eslaf +     +    if ( $error eq '_decline' ) { +      print_decline(); +    } elsif ( $error eq '_collect' ) { +      map { $cgi->param($_, $rv->{$_}) } +        qw( popup_url reference collectitems amount ); +      print_collect(); +    } elsif ( $error ) { +      #fudge the snarf info +      no strict 'refs'; +      ${$_} = $cgi->param($_) foreach grep { /^snarf_/ } $cgi->param; +      print_form(); +    } else { +      print_okay( +        'pkgpart' => scalar($cgi->param('pkgpart')), +        %$rv, +      ); +    } + +} elsif ( $magic eq 'success' || $action eq 'success' ) { + +  $cgi->param('username', 'username');  #hmmm temp kludge +  $cgi->param('_password', 'password'); +  print_okay( map { /^([\w ]+)$/ ? ( $_ => $1 ) : () } $cgi->param ); #hmmm + +} elsif ( $magic eq 'decline' || $action eq 'decline' ) { + +  print_decline(); + +} else { +  $error = ''; +  print_form; +} + +sub print_form { + +  $error = "Error: $error" if $error; + +  my $r = { +    $cgi->Vars, +    %{$init_data}, +    'error' => $error, +  }; + +  $r->{pkgpart} ||= $r->{default_pkgpart}; + +  $r->{referral_custnum} = $r->{'ref'}; +  #$cgi->delete('ref'); +  #$cgi->delete('init_popstate'); +  $r->{self_url} = $cgi->self_url; + +  print $cgi->header( '-expires' => 'now' ), +        $signup_template->fill_in( PACKAGE => 'FS::SelfService::_signupcgi', +                                   HASH    => $r +                                 ); +} + +sub print_collect { + +  $error = "Error: $error" if $error; + +  my $r = { +    $cgi->Vars, +    %{$init_data}, +    'error' => $error, +  }; + +  $r->{pkgpart} ||= $r->{default_pkgpart}; + +  $r->{referral_custnum} = $r->{'ref'}; +  $r->{self_url} = $cgi->self_url; + +  print $cgi->header( '-expires' => 'now' ), +        $collect_template->fill_in( PACKAGE => 'FS::SelfService::_signupcgi', +                                    HASH    => $r +                                  ); +} + +sub print_decline { +  my $r = { +    %{$init_data}, +  }; + +  print $cgi->header( '-expires' => 'now' ), +        $decline_template->fill_in( PACKAGE => 'FS::SelfService::_signupcgi', +                                    HASH    => $r +                                  ); +} + +sub print_okay { +  my %param = @_; +  my $user_agent = new HTTP::BrowserDetect $ENV{HTTP_USER_AGENT}; + +  my( $username, $password ) = ( '', '' ); +  my( $countrycode, $phonenum, $sip_password, $pin ) = ( '', '', '', '' ); + +  my $svc_x = $param{signup_service} || 'svc_acct'; #just in case +  if ( $svc_x eq 'svc_acct' ) { + +    $cgi->param('username') =~ /^(.+)$/ +      or die "fatal: invalid username got past FS::SelfService::new_customer"; +    $username = $1; +    $cgi->param('_password') =~ /^(.+)$/ +      or die "fatal: invalid password got past FS::SelfService::new_customer"; +    $password = $1; + +  } elsif ( $svc_x eq 'svc_phone' ) { + +    $countrycode  = $param{countrycode}; +    $phonenum     = $param{phonenum}; +    $sip_password = $param{sip_password}; +    $pin          = $param{pin}; + +  } else { +    die "unknown signup service $svc_x"; +  } + +  ( $cgi->param('first'). ' '. $cgi->param('last') ) =~ /^(.*)$/ +    or die "fatal: invalid email_name got past FS::SelfService::new_customer"; +  my $email_name = $1; #global for template + +  #my %pop = (); +  my %popnum2pop = (); +  foreach ( @{ $init_data->{'svc_acct_pop'} } ) { +    #push @{ $pop{ $_->{state} }->{ $_->{ac} } }, $_; +    $popnum2pop{$_->{popnum}} = $_; +  } + +  my( $ac, $exch, $loc); +  my $pop = $popnum2pop{$cgi->param('popnum')}; +    #or die "fatal: invalid popnum got past FS::SelfService::new_customer"; +  if ( $pop ) { +    ( $ac, $exch, $loc ) = ( $pop->{'ac'}, $pop->{'exch'}, $pop->{'loc'} ); +  } else { +    ( $ac, $exch, $loc ) = ( '', '', ''); #presumably you're not using them. +  } + +  #global for template +  my $part_pkg = ( grep { $_->{'pkgpart'} eq $param{'pkgpart'} } +                        @{ $init_data->{'part_pkg'} } +                 )[0]; +  my $pkg =  $part_pkg->{'pkg'}; + +  if ( $ieak_template && $user_agent->windows && $user_agent->ie ) { + +    #send an IEAK config +    print $cgi->header('application/x-Internet-signup'), +          $ieak_template->fill_in(); + +  } else { #send a simple confirmation + +    print $cgi->header( '-expires' => 'now' ), +          $success_template->fill_in( HASH => { + +            %{$init_data}, + +            email_name     => $email_name, +            pkg            => $pkg, +            part_pkg       => \$part_pkg, + +            signup_service => $svc_x, + +            #for svc_acct +            username       => $username, +            password       => $password, +            _password      => $password, +            ac             => $ac,   #for dialup POP +            exch           => $exch, # +            loc            => $loc,  # + +            #for svc_phone +            countrycode    => $countrycode, +            phonenum       => $phonenum, +            sip_password   => $sip_password, +            pin            => $pin, + +          }); +  } + +} + +sub success_default { #html to use if you don't specify a success file +  <<'END'; +<HTML><HEAD><TITLE>Signup successful</TITLE></HEAD> +<BODY BGCOLOR="#e8e8e8"><FONT SIZE=7>Signup successful</FONT><BR><BR> +Thanks for signing up! +<BR><BR> +Signup information for <%= $email_name %>: +<BR><BR> +Username: <%= $username %><BR> +Password: <%= $password %><BR> +Access number: (<%= $ac %>) / <%= $exch %> - <%= $local %><BR> +Package: <%= $pkg %><BR> +</BODY></HTML> +END +} + +sub collect_default { #html to use if there is a collect phase +  <<'END'; +<HTML><HEAD><TITLE>Pay now</TITLE></HEAD> +<BODY BGCOLOR="#e8e8e8"><FONT SIZE=7>Pay now</FONT><BR><BR> +<SCRIPT TYPE="text/javascript"> +  function popcollect() { +    overlib( OLiframeContent('<%= $popup_url %>', 336, 550, 'Secure Payment Area', 0, 'auto' ), CAPTION, 'Pay now', STICKY, AUTOSTATUSCAP, MIDX, 0, MIDY, 0, DRAGGABLE, CLOSECLICK, BGCOLOR, '#333399', CGCOLOR, '#333399', CLOSETEXT, 'Close' ); +    return false; +  } +</SCRIPT> +<SCRIPT TYPE="text/javascript" SRC="overlibmws.js"></SCRIPT> +<SCRIPT TYPE="text/javascript" SRC="overlibmws_iframe.js"></SCRIPT> +<SCRIPT TYPE="text/javascript" SRC="overlibmws_draggable.js"></SCRIPT> +<SCRIPT TYPE="text/javascript" SRC="overlibmws_crossframe.js"></SCRIPT> +<SCRIPT TYPE="text/javascript" SRC="iframecontentmws.js"></SCRIPT> +You are about to contact our payment processor to pay <%= $amount %> for +<%= $pkg %>.<BR><BR> +Your transaction reference number is <%= $reference %><BR><BR> +<FORM NAME="collect_popper" method="post" action="javascript:void(0)" onSubmit="popcollect()"> +<%= +  my %itemhash = @collectitems; +  foreach my $input (keys %itemhash) { +    $OUT .= qq!<INPUT NAME="$input" TYPE="hidden" VALUE="$itemhash{$input}">!; +  } +%> +<INPUT NAME="submit" type="submit" value="Pay now"> +</FORM> +</BODY></HTML> +END +} + +sub decline_default { #html to use if there is a decline +  <<'END'; +<HTML><HEAD><TITLE>Processing error</TITLE></HEAD> +<BODY BGCOLOR="#e8e8e8"><FONT SIZE=7>Processing error</FONT><BR><BR> +There has been an error processing your account.  Please contact customer +support. +</BODY></HTML> +END +} + +# subs for the templates... + +package FS::SelfService::_signupcgi; +use HTML::Entities; +use FS::SelfService qw(regionselector expselect popselector didselector); + diff --git a/fs_selfservice/FS-SelfService/cgi/signup.html b/fs_selfservice/FS-SelfService/cgi/signup.html new file mode 100755 index 000000000..375137b3c --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/signup.html @@ -0,0 +1,435 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<HTML> +<HEAD> +  <TITLE><%= $agent || ( $signup_service eq 'svc_phone' ? 'ITSP' : 'ISP' ) %> Signup form</TITLE> +  <%= $head %> +</HEAD> +<BODY BGCOLOR="<%= $body_bgcolor || '#e8e8e8' %>" onUnload="myclose()"> + +<script type="text/javascript"> +  var mywindow = -1; +  function myopen(filename,windowname,properties) { +    myclose(); +    mywindow = window.open(filename,windowname,properties); +  } +  function myclose() { +    if ( mywindow != -1 ) +      mywindow.close(); +    mywindow = -1 +  } +</script> + +<%= $OUT .= $body_header +      || '<FONT SIZE=7>'. +         ( $agent || ( $signup_service eq 'svc_phone' ? 'ITSP' : 'ISP' ) ). +         ' Signup form</FONT><BR><BR>'; +%> + +<FONT SIZE="+1" COLOR="#ff0000"><%= $error %></FONT> + +<FORM NAME="OneTrueForm" ACTION="<%= $self_url %>" METHOD=POST onSubmit="document.OneTrueForm.signup.disabled=true"> +<INPUT TYPE="hidden" NAME="session" VALUE="<%= $session_id %>"> +<INPUT TYPE="hidden" NAME="action" VALUE="process_signup"> +<INPUT TYPE="hidden" NAME="agentnum" VALUE="<%= $agentnum %>"> +<INPUT TYPE="hidden" NAME="referral_custnum" VALUE="<%= $referral_custnum %>"> +<INPUT TYPE="hidden" NAME="ss" VALUE=""> +<input type="hidden" name="payby"> +<%= +  $OUT = join("\n",map { my $method = $_ ; map { qq|<input type="hidden" name="${method}_$_" />| } qw / payinfo payinfo1 payinfo2 payname paystate paytype paycvv month year type  /  } @payby); +%> + +<%= +  $OUT = join("\n", map { qq|<input type="hidden" name="$_" />| } qw / promo_code reg_code pkgpart username _password _password2 sec_phrase popnum mac_addr countrycode phonenum sip_password pin / ); +%> + +Where did you hear about our service? <SELECT NAME="refnum"> +<%= +  $OUT .= '<OPTION VALUE="">' unless $refnum; +  foreach my $part_referral ( @part_referral ) { +    $OUT .= '<OPTION VALUE="'. $part_referral->{'refnum'}. '"'; +    $OUT .= ' SELECTED' if $part_referral->{'refnum'} == $refnum; +    $OUT .= '>'. $part_referral->{'referral'}; +  } +%> +</SELECT><BR><BR> +Contact Information +<TABLE BGCOLOR="<%= $box_bgcolor || '#c0c0c0' %>" BORDER=0 CELLSPACING=0 WIDTH="100%"> +<TR> +  <TH ALIGN="right"><font color="#ff0000">*</font>Contact name<BR>(last, first)</TH> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="last" VALUE="<%= $last %>">, +                <INPUT TYPE="text" NAME="first" VALUE="<%= $first %>"></TD> +</TR> +<TR> +  <TD ALIGN="right">Company</TD> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="company" SIZE=70 VALUE="<%= $company %>"></TD> +</TR> +<TR> +  <TH ALIGN="right"><font color="#ff0000">*</font>Address</TH> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="address1" SIZE=70 VALUE="<%= $address1 %>"></TD> +</TR> +<TR> +  <TD ALIGN="right"> </TD> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="address2" SIZE=70 VALUE="<%= $address2 %>"></TD> +</TR> +<TR> +  <TH ALIGN="right"><font color="#ff0000">*</font>City</TH> +  <TD><INPUT TYPE="text" NAME="city" VALUE="<%= $city %>"></TD> +  <TH ALIGN="right"><font color="#ff0000">*</font>State/Country</TH> +  <TD> +    <%= +        ($county_html, $state_html, $country_html) = +          regionselector( { +            selected_county  => $county, +            selected_state   => $state, +            selected_country => $country, +            default_state    => $statedefault, +            default_country  => $countrydefault, +            locales          => \@cust_main_county, +          } ); +  +        "$county_html $state_html"; +    %> +  </TD> +  <TH><font color="#ff0000">*</font>Zip</TH> +  <TD><INPUT TYPE="text" NAME="zip" SIZE=10 VALUE="<%= $zip %>"></TD> +</TR> +<TR> +  <TH ALIGN="right"><font color="#ff0000">*</font>Country</TH> +  <TD><%= $country_html %></TD> +<TR> +  <TD ALIGN="right">Day Phone</TD> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="daytime" VALUE="<%= $daytime %>" SIZE=18></TD> +</TR> +<TR> +  <TD ALIGN="right">Night Phone</TD> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="night" VALUE="<%= $night %>" SIZE=18></TD> +</TR> +<TR> +  <TD ALIGN="right">Fax</TD> +  <TD COLSPAN=5><INPUT TYPE="text" NAME="fax" VALUE="<%= $fax %>" SIZE=12></TD> +</TR> +<%= +  $OUT = ''; +  if ( $stateid_enabled ) { +    my ($county_html, $state_html, $country_html) = +      regionselector( { +        prefix           => 'stateid_', +        default_state    => $statedefault, +        default_country  => $countrydefault, +        locales          => \@cust_main_county, +      } ); +    $OUT .= qq!<TR><TD ALIGN="right">!. $label{stateid}.'</TD>'; +    $OUT .= qq!<TD><INPUT TYPE="text" NAME="stateid" VALUE="$stateid" SIZE=12></TD>!; +    $OUT .= qq!<TD ALIGN="right">!. $label{stateid_state} .'</TD>'; +    $OUT .="<TD COLSPAN=3>$county_html $state_html</TD></TR>"; +  } +%> +</TABLE><font color="#ff0000">*</font> required fields<BR> +<BR>Billing information<TABLE BGCOLOR="<%= $box_bgcolor || '#c0c0c0' %>" BORDER=0 CELLSPACING=0 WIDTH="100%"> +<TR><TD> + +  <%= +    $OUT =''; +    unless ( $emailinvoiceonly ) {  +    $OUT .= '<INPUT TYPE="checkbox" NAME="invoicing_list_POST" VALUE="POST"'; +    my @invoicing_list = split(', ', $invoicing_list ); +    $OUT .= ' CHECKED' +      if ! @invoicing_list || grep { $_ eq 'POST' } @invoicing_list; +    $OUT .= '>   Postal mail invoice'; }  +  %> + + +</TD></TR> +<TR><TD><%= $OUT = ( $emailinvoiceonly ? q|<font color="#ff0000">*</font>| : q|| ) %> Email invoice <INPUT TYPE="text" NAME="invoicing_list" VALUE="<%= join(', ', grep { $_ ne 'POST' } split(', ', $invoicing_list ) ) %>"> +</TD></TR> +<%= ( scalar(@payby) > 1 or 1 ) ? '<TR><TD>Billing type ' : '' %> +<!--</TABLE> +<TABLE BGCOLOR="#c0c0c0" BORDER=1 WIDTH="100%"> +<TR>--> + +  <%= + +    my $cardselect = '<SELECT NAME="CARD_type"><OPTION></OPTION>'; +    foreach ( keys %card_types ) { +      $selected = $CARD_type eq $card_types{$_} ? 'SELECTED' : ''; +      $cardselect .= qq!<OPTION $selected VALUE="$card_types{$_}">$_</OPTION>!; +    } +    $cardselect .= '</SELECT>'; +   +    my %payby = ( +      'CARD' => qq!Credit card<BR><font color="#ff0000">*</font>$cardselect<INPUT TYPE="text" NAME="CARD_payinfo" VALUE="" MAXLENGTH=19><BR><font color="#ff0000">*</font>Exp !. expselect("CARD"). qq!<BR><font color="#ff0000">*</font>Name on card<BR><INPUT TYPE="text" NAME="CARD_payname" VALUE="">!, +      'DCRD' => qq!Credit card<BR><font color="#ff0000">*</font>$cardselect<INPUT TYPE="text" NAME="DCRD_payinfo" VALUE="" MAXLENGTH=19><BR><font color="#ff0000">*</font>Exp !. expselect("DCRD"). qq!<BR><font color="#ff0000">*</font>Name on card<BR><INPUT TYPE="text" NAME="DCRD_payname" VALUE="">!, +      'CHEK' => qq!Electronic check<BR>${r}Account number <INPUT TYPE="text" NAME="CHEK_payinfo1" VALUE="" MAXLENGTH=10><BR>${r}ABA/Routing code <INPUT TYPE="text" NAME="CHEK_payinfo2" VALUE="" SIZE=10 MAXLENGTH=9> Type <SELECT NAME="CHEK_paytype">!. join('', map {qq!<OPTION VALUE="$_">$_</OPTION>!} @paytypes). qq!</SELECT><BR>{$r}Bank State <INPUT TYPE="text" NAME="CHEK_paystate" VALUE="" SIZE=5 MAXLENGTH=4><INPUT TYPE="hidden" NAME="CHEK_month" VALUE="12"><INPUT TYPE="hidden" NAME="CHEK_year" VALUE="2037"><BR>${r}Bank name <INPUT TYPE="text" NAME="CHEK_payname" VALUE="">!, +      'DCHK' => qq!Electronic check<BR>${r}Account number <INPUT TYPE="text" NAME="DCHK_payinfo1" VALUE="" MAXLENGTH=10> Type <SELECT NAME="DCHK_paytype">!. join('', map {qq!<OPTION VALUE="$_">$_</OPTION>!} @paytypes). qq!</SELECT><BR>${r}ABA/Routing code <INPUT TYPE="text" NAME="DCHK_payinfo2" VALUE="" SIZE=10 MAXLENGTH=9><BR>{$r}Bank State <INPUT TYPE="text" NAME="DCHK_paystate" VALUE="" SIZE=5 MAXLENGTH=4><INPUT TYPE="hidden" NAME="DCHK_month" VALUE="12"><INPUT TYPE="hidden" NAME="DCHK_year" VALUE="2037"><BR>${r}Bank name <INPUT TYPE="text" NAME="DCHK_payname" VALUE="">!, +      'LECB' => qq!Phone bill billing<BR>${r}Phone number <INPUT TYPE="text" NAME="LECB_payinfo" VALUE="" MAXLENGTH=15 SIZE=16><INPUT TYPE="hidden" NAME="LECB_month" VALUE="12"><INPUT TYPE="hidden" NAME="LECB_year" VALUE="2037"><INPUT TYPE="hidden" NAME="LECB_payname" VALUE="">!, +      'BILL' => qq!Billing<BR>P.O. <INPUT TYPE="text" NAME="BILL_payinfo" VALUE=""><BR><INPUT TYPE="hidden" NAME="BILL_month" VALUE="12"><INPUT TYPE="hidden" NAME="BILL_year" VALUE="2037">Attention<INPUT TYPE="text" NAME="BILL_payname" VALUE="Accounts Payable">!, +      'COMP' => qq!Complimentary<BR><font color="#ff0000">*</font>Approved by<INPUT TYPE="text" NAME="COMP_payinfo" VALUE=""><BR><font color="#ff0000">*</font>Exp !. expselect("COMP"), +      'PREPAY' => qq!Prepaid card<BR><font color="#ff0000">*</font><INPUT TYPE="text" NAME="PREPAY_payinfo" VALUE="" MAXLENGTH=80>!, +    ); + +    if ( $cvv_enabled ) { +      foreach my $payby ( grep { exists $payby{$_} } qw(CARD DCRD) ) { #1.4/1.5 +        $payby{$payby} .= qq!<TR><TD ALIGN="right">CVV2 (<A HREF="javascript:myopen('cvv2.html','cvv2','toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=yes,copyhistory=no,width=480,height=288')">help</A>)</TD><TD><INPUT TYPE="text" NAME=${payby}_paycvv VALUE="" SIZE=4 MAXLENGTH=4></TD></TR>!; +      } +    } +    if ( $paystate_enabled ) { +      foreach my $payby ( grep { exists $payby{$_} } qw(CHEK DCHK) ) {  +        my ($county_html, $state_html, $country_html) = +          regionselector( { +            prefix           => "${payby}_pay", +            default_state    => $statedefault, +            default_country  => $countrydefault, +            locales          => \@cust_main_county, +          } ); +        $payby{$payby} .= "<BR>${r}Bank state $county_html $state_html"; +      } +    } + +    my( $account, $aba ) = split('@', $payinfo); +    my %paybychecked = ( +      'CARD' => '<TABLE BGCOLOR="'. ( $box_bgcolor || '#c0c0c0' ). qq!" BORDER=0 CELLSPACING=0 WIDTH="100%"><TR><TD ALIGN="right"><font color="#ff0000">*</font> Card type</TD><TD>$cardselect</TD></TR><TR><TD ALIGN="right"><font color="#ff0000">*</font> Card number</TD><TD><INPUT TYPE="text" NAME="CARD_payinfo" VALUE="$payinfo" MAXLENGTH=19></TD></TR><TR><TD ALIGN="right"><font color="#ff0000">*</font> Expration</TD><TD>!. expselect("CARD", $paydate). qq!</TD></TR><TR><TD ALIGN="right"><font color="#ff0000">*</font> Name on card</TD><TD><INPUT TYPE="text" NAME="CARD_payname" VALUE="$payname"></TD></TR>!, +      'DCRD' => qq!Credit card<BR><font color="#ff0000">*</font>$cardselect<INPUT TYPE="text" NAME="DCRD_payinfo" VALUE="$payinfo" MAXLENGTH=19><BR><font color="#ff0000">*</font>Exp !. expselect("DCRD", $paydate). qq!<BR><font color="#ff0000">*</font>Name on card<BR><INPUT TYPE="text" NAME="DCRD_payname" VALUE="$payname">!, +      'CHEK' => qq!Electronic check<BR>${r}Account number <INPUT TYPE="text" NAME="CHEK_payinfo1" VALUE="$account" MAXLENGTH=10> Type <SELECT NAME="CHEK_paytype">!. join('', map {qq!<OPTION VALUE="$_"!.($paytype eq $_ ? 'SELECTED' : '').">$_</OPTION>"} @paytypes). qq!</SELECT><BR>${r}ABA/Routing code <INPUT TYPE="text" NAME="CHEK_payinfo2" VALUE="$aba" SIZE=10 MAXLENGTH=9><INPUT TYPE="hidden" NAME="CHEK_month" VALUE="12"><INPUT TYPE="hidden" NAME="CHEK_year" VALUE="2037"><BR>${r}Bank name <INPUT TYPE="text" NAME="CHEK_payname" VALUE="$payname">!, +      'DCHK' => qq!Electronic check<BR>${r}Account number <INPUT TYPE="text" NAME="DCHK_payinfo1" VALUE="$account" MAXLENGTH=10> Type <SELECT NAME="DCHK_paytype">!. join('', map {qq!<OPTION VALUE="$_"!.($paytype eq $_ ? 'SELECTED' : '').">$_</OPTION>"} @paytypes). qq!</SELECT><BR>${r}ABA/Routing code <INPUT TYPE="text" NAME="DCHK_payinfo2" VALUE="$aba" SIZE=10 MAXLENGTH=9><INPUT TYPE="hidden" NAME="DCHK_month" VALUE="12"><INPUT TYPE="hidden" NAME="DCHK_year" VALUE="2037"><BR>${r}Bank name <INPUT TYPE="text" NAME="DCHK_payname" VALUE="">!, +      'LECB' => qq!Phone bill billing<BR>${r}Phone number <INPUT TYPE="text" BANE="LECB_payinfo" VALUE="$payinfo" MAXLENGTH=15 SIZE=16><INPUT TYPE="hidden" NAME="LECB_month" VALUE="12"><INPUT TYPE="hidden" NAME="LECB_year" VALUE="2037"><INPUT TYPE="hidden" NAME="LECB_payname" VALUE="">!, +      'BILL' => qq!Billing<BR>P.O. <INPUT TYPE="text" NAME="BILL_payinfo" VALUE="$payinfo"><BR><INPUT TYPE="hidden" NAME="BILL_month" VALUE="12"><INPUT TYPE="hidden" NAME="BILL_year" VALUE="2037">Attention<INPUT TYPE="text" NAME="BILL_payname" VALUE="$payname">!, +      'COMP' => qq!Complimentary<BR><font color="#ff0000">*</font>Approved by<INPUT TYPE="text" NAME="COMP_payinfo" VALUE="$payinfo"><BR><font color="#ff0000">*</font>Exp !. expselect("COMP", $paydate), +      'PREPAY' => qq!Prepaid card<BR><font color="#ff0000">*</font><INPUT TYPE="text" NAME="PREPAY_payinfo" VALUE="$payinfo" MAXLENGTH=80>!, +    ); + +    if ( $cvv_enabled ) { +      foreach my $payby ( grep { exists $payby{$_} } qw(CARD DCRD) ) { #1.4/1.5 +        $paybychecked{$payby} .= qq!<TR><TD ALIGN="right">CVV2 (<A HREF="javascript:myopen('cvv2.html','cvv2','toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=yes,copyhistory=no,width=480,height=288')">help</A>)</TD><TD><INPUT TYPE="text" NAME=${payby}_paycvv VALUE="$paycvv" SIZE=4 MAXLENGTH=4></TD></TR>!; +      } +    } +    if ( $paystate_enabled ) { +      foreach my $payby ( grep { exists $payby{$_} } qw(CHEK DCHK) ) {  +        my ($county_html, $state_html, $country_html) = +          regionselector( { +            prefix           => "${payby}_pay", +            selected_county  => $county, +            selected_state   => $state, +            selected_country => $country, +            default_state    => $statedefault, +            default_country  => $countrydefault, +            locales          => \@cust_main_county, +          } ); +        $paybychecked{$payby} .= "<BR>${r}Bank state $county_html $state_html"; +      } +    } + +  my %payby_index = ( 'CARD'   => qq/Credit Card/, +                      'DCRD'   => qq/Credit Card/, +                      'CHEK'   => qq/Check/, +                      'DCHK'   => qq/Check/, +                      'LECB'   => qq/Phone Bill Billing/, +                      'BILL'   => qq/Billing/, +                      'COMP'   => qq/Complimentary/, +                      'PREPAY' => qq/Prepaid Card/, +                    ); +   + +tie my %options, 'Tie::IxHash', (); + +foreach my $payby_option ( @payby ) { +  $options{$payby_option} = $payby_index{$payby_option}; +} + +my $selected_layer = ( grep { $_ eq 'CARD' } @payby ) ? 'CARD' : $payby[0]; + +HTML::Widgets::SelectLayers->new( +  options => \%options, +  selected_layer => $selected_layer, +  form_name => 'dummy', +  html_between => '</td></tr></table>', +  form_action => 'dummy.cgi', +  layer_callback => sub { my $layer = shift; return ( shift @hide_payment_fields ? '' : $paybychecked{$layer} ) . '</TABLE>'; }, +)->html; + + +  %> + +</TR></TABLE><font color="#ff0000">*</font> required fields +<FORM name="signup_form" action="<%= $self_url %>" METHOD="POST" onsubmit="return fixup_form();"><BR><BR>First package +<INPUT TYPE="hidden" NAME="promo_code" VALUE="<%= $promo_code %>"> +<INPUT TYPE="hidden" NAME="reg_code" VALUE="<%= $reg_code %>"> +<TABLE BGCOLOR="<%= $box_bgcolor || '#c0c0c0' %>" BORDER=0 CELLSPACING=0 WIDTH="100%"> +<TR> +  <TD COLSPAN=2><SELECT NAME="pkgpart"> + +  <%= +    $OUT .= '<OPTION VALUE="">(none)' +      unless scalar(@part_pkg) == 1 or $default_pkgpart; +    foreach my $part_pkg ( @part_pkg ) { +      $OUT .= '<OPTION VALUE="'. $part_pkg->{'pkgpart'}. '"'; +      $OUT .= ' SELECTED' if $pkgpart && $part_pkg->{'pkgpart'} == $pkgpart; +      $OUT .= '>'. $part_pkg->{'pkg'}; +    } +  %> + +  </SELECT></TD> +</TR> +<%= +  if ( $signup_service eq 'svc_phone' ) { + +    $OUT .= '<TR><TD ALIGN="right">Phone number</TD><TD>'. +            didselector( 'field'   => 'phonenum', +                         'svcpart' => $default_svcpart, +                       ). +            '</TD></TR>'; + +    $OUT .= <<ENDOUT; +<TR> +  <TD ALIGN="right">Voicemail PIN</TD> +  <TD><INPUT TYPE="pin" NAME="pin" VALUE="$pin"></TD> +</TR> +ENDOUT + +  } else { + +    $OUT .= <<ENDOUT; +<TR> +  <TD ALIGN="right">Username</TD> +  <TD><INPUT TYPE="text" NAME="username" VALUE="$username"></TD> +</TR> +<TR> +  <TD ALIGN="right">Password</TD> +  <TD><INPUT TYPE="password" NAME="_password" VALUE="$_password"></TD> +</TR> +<TR> +  <TD ALIGN="right">Re-enter Password</TD> +  <TD><INPUT TYPE="password" NAME="_password2" VALUE="$_password2"></TD> +</TR> +ENDOUT + +    if ( $security_phrase ) { +      $OUT .= <<SECPHRASE; +<TR> +  <TD ALIGN="right">Security Phrase</TD> +  <TD><INPUT TYPE="text" NAME="sec_phrase" VALUE="$sec_phrase"> +  </TD> +</TR> +SECPHRASE +    } else { +      $OUT .= '<INPUT TYPE="hidden" NAME="sec_phrase" VALUE="">'; +    } + +    if ( $nomadix ) { + +      warn $mac_addr; +      $mac_addr ||= $MA; +      warn $mac_addr; + +      $OUT .= <<NOMADIX; +        <INPUT TYPE="hidden" NAME="mac_addr" VALUE="$mac_addr"> +NOMADIX + +    } + +  } + +  if ( @svc_acct_pop ) { +    $OUT .= '<TR><TD ALIGN="right">Access number</TD><TD>'. +            popselector( 'popnum'        => $popnum, +                         'pops'          => \@svc_acct_pop, +                         'init_popstate' => $init_popstate, +                         'popac'         => $popac, +                         'acstate'       => $acstate, +                       ). +            '</TD></TR>'; +  } else { +    $OUT .= popselector(popnum=>$popnum, pops=>\@svc_acct_pop); +  } + +%> + +</TABLE> + +<%=  +if ( @optional_packages ) {  +  my @html; +  foreach my $ii ( 0 .. $#optional_packages) { +  my $friendly_index = $ii + 1;  +  if ($optional_packages[$ii]) { +    push @html, qq|<BR>Optional Package #$friendly_index <br />|,'<table bgcolor="#c0c0c0"><tr><td>'; + +    push @html, qq|<select name="optional_package${ii}">|; +    push @html, qq|<option value="none"></option>|; +    push @html, map { qq|<option value="$_->{pkgpart}">$_->{pkg}</option>| } @{$optional_packages[$ii]}; +    push @html, q|</select>|; +     +    push @html, '</td></tr></table>'; +    } +    $OUT = join("\n", @html); +  }   +} else { +$OUT = '' +} +%> + +<BR><INPUT TYPE="submit" NAME="signup" VALUE="Signup"> +<script language="JavaScript"> + +function fixup_form() { +     +    // copy payment method data up to OneTrueForm +     +    var payment_method_elements = new Array( 'payinfo', 'payinfo1', 'payinfo2', 'payname', 'paycvv' , 'paystate', 'paytype', 'month', 'year','type' ); +    var payment_method_form_name = document.OneTrueForm.select.options[document.OneTrueForm.select.selectedIndex].value; +    document.OneTrueForm.elements['payby'].value = payment_method_form_name; +    var payment_method_form = document.forms[payment_method_form_name]; + +    for ( ii = 0 ; ii < payment_method_elements.length ; ii++ ) { +	var true_element_name = payment_method_form_name + '_' + payment_method_elements[ii]; +	copyelement ( payment_method_form.elements[true_element_name], +		      document.OneTrueForm.elements[true_element_name] ); +    } +     +    // Copy signup details to OneTrueForm +     +    var signup_elements = new Array ( +      'promo_code', 'reg_code', 'pkgpart', +      'username', '_password', '_password2', 'sec_phrase', 'popnum', +      'mac_addr', +      'countrycode', 'phonenum', 'sip_password', 'pin' +    ); + +    for ( ii = 0 ; ii < signup_elements.length ; ii ++ ) { +	copyelement ( document.signup_form.elements[signup_elements[ii]], +		      document.OneTrueForm.elements[signup_elements[ii]]); +    } + +    document.OneTrueForm.submit(); +    return false; +} + +function copyelement(from, to) { +//    alert ( from + ' ' + to ); +     +    if ( from == undefined ) { +	to.value = ''; +    } else {  +	if ( from.type == 'select-one' ) { +	    to.value = from.options[from.selectedIndex].value; +	} else if ( from.type == 'checkbox' ) { +	    if ( from.checked ) { +		to.value = from.value; +	    } else { +		to.value = ''; +	    } +	} else { +	    if ( from.value == undefined ) { +		to.value = ''; +	    } else { +		to.value = from.value; +	    } +	} +//	alert(from.name + " (" + from.type + "): " + to.name + " => " + to.value); +    } +} + +</script> +</FORM> +<%= $OUT .= $body_footer %> +</BODY> +</HTML> diff --git a/fs_selfservice/FS-SelfService/cgi/stateselect.html b/fs_selfservice/FS-SelfService/cgi/stateselect.html new file mode 100644 index 000000000..ba55bff74 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/stateselect.html @@ -0,0 +1,134 @@ +<HTML><HEAD><TITLE>ISP Signup</TITLE></HEAD> +<BODY BGCOLOR="#e8e8e8"><FONT SIZE=7>ISP Signup - state selection</FONT><BR><BR> +<SCRIPT> +function gotoURL(object) { +    window.location.href = object.options[object.selectedIndex].value; +} +</SCRIPT> +<FORM> +Select your state from the map or dropdown:  +<MAP NAME=usmap> +<area shape=poly COORDS="264,157,286,155,292,193,276,195,270,199,264,157" href="signup.cgi?init_popstate=AL"> +<area shape=poly COORDS="28,197,46,185,72,199,72,241,88,243,102,261,92,263,70,241,42,243,28,257,12,259,34,243,20,233,16,223,34,215,22,207,30,205,28,197" href="../states/Alaska.html"> +<area shape=poly COORDS="70,137,106,137,100,189,84,187,60,173,70,133,70,137,70,137" href="signup.cgi?init_popstate=AZ"> +<area shape=poly COORDS="250,153,242,179,220,177,218,171,216,145,252,143,250,155,250,153" href="signup.cgi?init_popstate=AR"> +<area shape=poly COORDS="10,79,38,81,30,109,62,151,56,173,40,169,20,145,4,101,10,75,26,79,10,79,10,79" href="signup.cgi?init_popstate=CA"> +<area shape=poly COORDS="108,103,158,107,154,141,104,137,110,101,128,103,108,103" href="signup.cgi?init_popstate=CO"> +<area shape=poly COORDS="374,107,405,105,405,123,372,125,374,107" href="signup.cgi?init_popstate=CT"> +<area shape=poly COORDS="370,143,402,145,405,157,362,157,370,143" href="signup.cgi?init_popstate=DE"> +<area shape=poly COORDS="275,193,325,187,327,197,341,219,341,233,335,237,317,215,315,205,307,195,293,203,275,193" href="signup.cgi?init_popstate=FL"> +<area shape=poly COORDS="297,153,283,155,297,191,321,189,321,169,297,153" href="signup.cgi?init_popstate=GA"> +<area shape=poly COORDS="98,233,142,263,156,251,162,239,164,229,136,231,94,221,100,235,98,233" href="signup.cgi?init_popstate=HI"> +<area shape=poly COORDS="68,21,76,21,72,35,80,47,80,55,84,65,100,69,94,93,56,83,66,51,70,19,68,21" href="signup.cgi?init_popstate=ID"> +<area shape=poly COORDS="242,91,258,89,266,123,256,139,234,109,248,87,242,91" href="signup.cgi?init_popstate=IL"> +<area shape=poly COORDS="261,95,265,123,265,131,285,117,277,91,261,95" href="signup.cgi?init_popstate=IN"> +<area shape=poly COORDS="198,87,206,111,232,109,240,99,240,91,232,79,198,87" href="signup.cgi?init_popstate=IA"> +<area shape=poly COORDS="158,111,158,135,214,139,214,127,208,113,158,111" href="signup.cgi?init_popstate=KS"> +<area shape=poly COORDS="263,133,275,129,289,115,303,121,307,129,299,135,251,141,269,131,263,133" href="signup.cgi?init_popstate=KY"> +<area shape=poly COORDS="222,179,246,179,244,197,258,193,262,213,226,209,224,177,222,179" href="signup.cgi?init_popstate=LA"> +<area shape=poly COORDS="363,37,373,59,373,47,387,31,377,9,365,15,363,37" href="signup.cgi?init_popstate=ME"> +<area shape=poly COORDS="376,159,405,159,405,175,374,177,376,159" href="signup.cgi?init_popstate=MD"> +<area shape=poly COORDS="378,74,380,88,404,88,404,72,378,74" href="signup.cgi?init_popstate=MA"> +<area shape=poly COORDS="265,73,269,83,265,93,293,91,295,71,281,53,271,53,267,69,265,73,265,73" href="signup.cgi?init_popstate=MI"> +<area shape=poly COORDS="194,31,222,33,242,35,224,51,222,63,222,73,234,79,196,85,194,31" href="signup.cgi?init_popstate=MN"> +<area shape=poly COORDS="265,159,271,199,257,201,259,195,241,197,251,155,265,159" href="signup.cgi?init_popstate=MS"> +<area shape=poly COORDS="206,113,234,111,256,139,248,147,214,145,208,111,206,113" href="signup.cgi?init_popstate=MO"> +<area shape=poly COORDS="78,23,148,31,146,67,84,63,78,35,80,19,78,23" href="signup.cgi?init_popstate=MT"> +<area shape=poly COORDS="146,85,148,103,158,105,164,109,206,109,198,85,144,87,146,85" href="signup.cgi?init_popstate=NE"> +<area shape=poly COORDS="40,83,76,87,64,151,32,109,40,83,40,83" href="signup.cgi?init_popstate=NV"> +<area shape=poly COORDS="298,11,330,9,330,25,298,25,298,11" href="signup.cgi?init_popstate=NH"> +<area shape=poly COORDS="372,127,404,125,405,141,368,139,376,125,372,127" href="signup.cgi?init_popstate=NJ"> +<area shape=poly COORDS="106,137,100,191,122,187,148,187,150,139,106,137,106,137" href="signup.cgi?init_popstate=NM"> +<area shape=poly COORDS="313,79,331,63,337,45,349,45,359,65,357,79,345,65,315,77,313,79,313,79" href="signup.cgi?init_popstate=NY"> +<area shape=poly COORDS="309,137,295,151,319,149,337,153,357,131,351,129,309,137,309,137" href="signup.cgi?init_popstate=NC"> +<area shape=poly COORDS="146,31,148,57,198,57,190,31,146,31,146,31" href="signup.cgi?init_popstate=ND"> +<area shape=poly COORDS="281,93,285,113,299,121,311,101,309,85,299,93,281,93,281,93" href="signup.cgi?init_popstate=OH"> +<area shape=poly COORDS="148,145,174,145,174,163,218,171,216,143,150,139,150,145,156,143,148,145,148,145" href="signup.cgi?init_popstate=OK"> +<area shape=poly COORDS="20,41,8,73,16,77,22,77,28,77,36,79,42,81,48,83,56,83,66,49,20,41,20,41" href="signup.cgi?init_popstate=OR"> +<area shape=poly COORDS="309,83,345,71,351,93,313,105,309,83,309,83" href="signup.cgi?init_popstate=PA"> +<area shape=poly COORDS="376,93,405,93,405,107,376,105,376,93" href="signup.cgi?init_popstate=RI"> +<area shape=poly COORDS="301,155,321,149,337,155,325,175,301,157,301,155,301,155" href="signup.cgi?init_popstate=SC"> +<area shape=poly COORDS="146,59,198,61,198,83,146,83,148,57,146,59,146,59" href="signup.cgi?init_popstate=SD"> +<area shape=poly COORDS="255,145,251,157,297,153,311,133,255,145,255,145" href="signup.cgi?init_popstate=TN"> +<area shape=poly COORDS="150,145,172,145,174,167,198,173,218,173,228,207,204,221,198,231,202,247,180,241,154,207,146,219,120,189,154,189,152,145,150,145,150,145" href="signup.cgi?init_popstate=TX"> +<area shape=poly COORDS="78,89,96,91,96,103,110,103,106,135,70,133,78,89,78,89" href="signup.cgi?init_popstate=UT"> +<area shape=poly COORDS="298,29,332,29,332,47,294,45,298,29" href="signup.cgi?init_popstate=VT"> +<area shape=poly COORDS="307,127,297,137,351,127,349,113,341,111,341,105,329,107,315,131,307,127,307,127" href="signup.cgi?init_popstate=VA"> +<area shape=poly COORDS="32,13,68,19,64,47,20,39,20,13,30,19,32,13,32,13" href="signup.cgi?init_popstate=WA"> +<area shape=poly COORDS="303,119,313,129,329,103,311,105,299,121,313,127,303,119,303,119" href="signup.cgi?init_popstate=WV"> +<area shape=poly COORDS="228,51,256,55,254,89,238,89,234,77,224,71,230,49,236,53,228,51,228,51" href="signup.cgi?init_popstate=WI"> +<area shape=poly COORDS="146,71,144,103,96,99,102,63,148,69,146,71,146,71" href="signup.cgi?init_popstate=WY"> +</MAP> +<IMG SRC="map.gif" usemap=#usmap WIDTH=405 HEIGHT=270 border=0><BR> +<SELECT NAME="init_popstate" onChange="gotoURL(this.form.init_popstate)"> +<OPTION VALUE="stateselect.html"></OPTION> +<OPTION VALUE="signup.cgi?init_popstate=AL">Alabama</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=AK">Alaska</OPTION> +<!--<OPTION VALUE="signup.cgi?init_popstate=AS">American Samoa</OPTION>--> +<OPTION VALUE="signup.cgi?init_popstate=AZ">Arizona</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=AR">Arkansas</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=CA">California</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=CO">Colorado</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=CT">Connecticut</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=DE">Delaware</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=DC">District of Columbia</OPTION> +<!--<OPTION VALUE="signup.cgi?init_popstate=FM">Federated States of Micronesia</OPTION>--> +<OPTION VALUE="signup.cgi?init_popstate=FL">Florida</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=GA">Georgia</OPTION> +<!--<OPTION VALUE="signup.cgi?init_popstate=GU">Guam</OPTION>--> +<OPTION VALUE="signup.cgi?init_popstate=HI">Hawaii</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=ID">Idaho</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=IL">Illinois</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=IN">Indiana</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=IA">Iowa</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=KS">Kansas</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=KY">Kentucky</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=LA">Louisiana</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=ME">Maine</OPTION> +<!--<OPTION VALUE="signup.cgi?init_popstate=MH">Marshall Islands</OPTION>--> +<OPTION VALUE="signup.cgi?init_popstate=MD">Maryland</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=MA">Massachusetts</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=MI">Michigan</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=MN">Minnesota</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=MS">Mississippi</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=MO">Missouri</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=MT">Montana</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=NE">Nebraska</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=NV">Nevada</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=NH">New Hampshire</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=NJ">New Jersey</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=NM">New Mexico</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=NY">New York</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=NC">North Carolina</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=ND">North Dakota</OPTION> +<!--<OPTION VALUE="signup.cgi?init_popstate=MP">Northern Mariana Islands</OPTION>--> +<OPTION VALUE="signup.cgi?init_popstate=OH">Ohio</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=OK">Oklahoma</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=OR">Oregon</OPTION> +<!--<OPTION VALUE="signup.cgi?init_popstate=PW">Palau</OPTION>--> +<OPTION VALUE="signup.cgi?init_popstate=PA">Pennsylvania</OPTION> +<!--<OPTION VALUE="signup.cgi?init_popstate=PR">Puerto Rico</OPTION>--> +<OPTION VALUE="signup.cgi?init_popstate=RI">Rhode Island</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=SC">South Carolina</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=SD">South Dakota</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=TN">Tennessee</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=TX">Texas</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=UT">Utah</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=VT">Vermont</OPTION> +<!--<OPTION VALUE="signup.cgi?init_popstate=VI">Virgin Islands</OPTION>--> +<OPTION VALUE="signup.cgi?init_popstate=VA">Virginia</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=WA">Washington</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=WV">West Virginia</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=WI">Wisconsin</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=WY">Wyoming</OPTION> +<!--<OPTION VALUE="signup.cgi?init_popstate=AE">Armed Forces Africa</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=AA">Armed Forces Americas</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=AE">Armed Forces Canada</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=AE">Armed Forces Europe</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=AE">Armed Forces Middle East</OPTION> +<OPTION VALUE="signup.cgi?init_popstate=AP">Armed Forces Pacific</OPTION> +--> +</SELECT> +</FORM> +</BODY> +</HTML> diff --git a/fs_selfservice/FS-SelfService/cgi/success-delayed.html b/fs_selfservice/FS-SelfService/cgi/success-delayed.html new file mode 100644 index 000000000..5eeed5957 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/success-delayed.html @@ -0,0 +1,16 @@ +<HTML><HEAD><TITLE>Signup successful</TITLE></HEAD> +<BODY BGCOLOR="#e8e8e8"><FONT SIZE=7>Signup successful</FONT><BR><BR> +Thanks for signing up! +<BR><BR> +Signup information for <%= $email_name %>: +<BR><BR> +Username: <%= $username %><BR> +Password: <%= $password %><BR> +Access number: (<%= $ac %>) / <%= $exch %> - <%= $local %><BR> +Package: <%= $pkg %><BR> +Charge: <%= sprintf('$%.2f', $part_pkg->{'options'}->{'setup_fee'}) %><BR> +In <%= $part_pkg->{'options'}->{'free_days'} %> days you will be charged +        <%= sprintf('$%.2f', $part_pkg->{'options'}->{'recur_fee'}) %> +and <%= $part_pkg->{'freq_pretty'} %> thereafter.<BR> + +</BODY></HTML> diff --git a/fs_selfservice/FS-SelfService/cgi/success.html b/fs_selfservice/FS-SelfService/cgi/success.html new file mode 100644 index 000000000..ccbcc62b9 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/success.html @@ -0,0 +1,40 @@ +<HTML> +  <HEAD> +    <TITLE>Signup successful</TITLE> +    <%= $head %> +  </HEAD> +  <BODY BGCOLOR="<%= $body_bgcolor || '#eeeeee' %>"> +  <%= $body_header %> + +<FONT SIZE=7>Signup successful</FONT><BR><BR> + +Thanks for signing up!  Save this information for future reference. +<BR><BR> + +Signup information for <%= $email_name %>: +<BR><BR> + +<%= +    if ($signup_service eq 'svc_acct' || !$signup_service ) { #just in case +      $OUT .= <<END +        Username: $username<BR> +        Password: $password<BR> +        Access number: ($ac) / $exch - $local <BR> +END +    } elsif ( $signup_service eq 'svc_phone' ) { +      $OUT .= <<END +        <!-- Countrycode: $countrycode <BR>--> +        Phone number: $phonenum<BR> +        SIP Server: itsp.sip.server.name<BR> +        SIP Login: $phonenum<BR> +        SIP Password: $sip_password<BR> +        Voicemail PIN: $pin<BR> +END +    } else { +      die "unknown signup service $signup_service"; +    } +%> + +  Package: <%= $pkg %><BR> + +<%= $body_footer %> diff --git a/fs_selfservice/FS-SelfService/cgi/svc_acct.html b/fs_selfservice/FS-SelfService/cgi/svc_acct.html new file mode 100644 index 000000000..00244386b --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/svc_acct.html @@ -0,0 +1,58 @@ +<FONT SIZE=4>Setup <%= $svc %></FONT><BR><BR> + +<%= if ( $error ) { +  $OUT .= qq!<FONT SIZE="+1" COLOR="#ff0000">Error setting up $svc: $error!. +          '</FONT><BR><BR>'; +} ''; %> +<FORM ACTION="<%= $selfurl %>" METHOD=POST> +<INPUT TYPE="hidden" NAME="session" VALUE="<%= $session_id %>"> +<INPUT TYPE="hidden" NAME="action" VALUE="process_svc_acct"> +<INPUT TYPE="hidden" NAME="custnum" VALUE="<%= $custnum %>"> +<INPUT TYPE="hidden" NAME="pkgnum" VALUE="<%= $pkgnum %>"> +<INPUT TYPE="hidden" NAME="svcpart" VALUE="<%= $svcpart %>"> +<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=2 BGCOLOR="#cccccc"> +<TR> +  <TD ALIGN="right">Username</TD> +  <TD><INPUT TYPE="text" NAME="username" VALUE="<%= $username %>"></TD> +</TR> +<%= +   $OUT .= domainselector(pkgnum=>$pkgnum, svcpart=>$svcpart); +%> +<TR> +  <TD ALIGN="right">Password</TD> +  <TD><INPUT TYPE="password" NAME="_password" VALUE="<%= $_password %>"></TD> +</TR> +<TR> +  <TD ALIGN="right">Re-enter Password</TD> +  <TD><INPUT TYPE="password" NAME="_password2" VALUE="<%= $_password2 %>"></TD> +</TR> +<%= +  if ( $security_phrase ) { +    $OUT .= <<ENDOUT; +<TR> +  <TD ALIGN="right">Security Phrase</TD> +  <TD><INPUT TYPE="text" NAME="sec_phrase" VALUE="$sec_phrase"> +  </TD> +</TR> +ENDOUT +  } else { +    $OUT .= '<INPUT TYPE="hidden" NAME="sec_phrase" VALUE="">'; +  } +%> +<%= +  if ( @svc_acct_pop ) { +    $OUT .= '<TR><TD ALIGN="right">Access number</TD><TD>'. +            popselector( 'popnum'        => $popnum, +                         'pops'          => \@svc_acct_pop, +                         'init_popstate' => $init_popstate, +                         'popac'         => $popac, +                         'acstate'       => $acstate, +                       ). +            '</TD></TR>'; +  } else { +    $OUT .= popselector(popnum=>$popnum, pops=>\@svc_acct_pop); +  } +%> +</TABLE> +<INPUT TYPE="submit" VALUE="Setup"> +</FORM> diff --git a/fs_selfservice/FS-SelfService/cgi/verify.cgi b/fs_selfservice/FS-SelfService/cgi/verify.cgi new file mode 100755 index 000000000..d9346b897 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/verify.cgi @@ -0,0 +1,177 @@ +#!/usr/bin/perl -T +#!/usr/bin/perl -Tw + +use strict; +use vars qw( $cgi $self_url $error +             $verify_html $verify_template +             $success_html $success_template +             $decline_html $decline_template +           ); + +use subs qw( print_verify print_okay print_decline +             verify_default success_default decline_default +           ); +use CGI; +use Text::Template; +use FS::SelfService qw( capture_payment ); + +$verify_html =  -e 'verify.html' +                  ? 'verify.html' +                  : '/usr/local/freeside/verify.html'; +$success_html = -e 'verify_success.html' +                  ? 'success.html' +                  : '/usr/local/freeside/success.html'; +$decline_html = -e 'verify_decline.html' +                  ? 'decline.html' +                  : '/usr/local/freeside/decline.html'; + + +if ( -e $verify_html ) { +  my $verify_txt = Text::Template::_load_text($verify_html) +    or die $Text::Template::ERROR; +  $verify_txt =~ /^(.*)$/s; #untaint the template source - it's trusted +  $verify_txt = $1; +  $verify_template = new Text::Template ( TYPE => 'STRING', +                                          SOURCE => $verify_txt, +                                          DELIMITERS => [ '<%=', '%>' ], +                                        ) +    or die $Text::Template::ERROR; +} else { +  $verify_template = new Text::Template ( TYPE => 'STRING', +                                          SOURCE => &verify_default, +                                          DELIMITERS => [ '<%=', '%>' ], +                                        ) +    or die $Text::Template::ERROR; +} + +if ( -e $success_html ) { +  my $success_txt = Text::Template::_load_text($success_html) +    or die $Text::Template::ERROR; +  $success_txt =~ /^(.*)$/s; #untaint the template source - it's trusted +  $success_txt = $1; +  $success_template = new Text::Template ( TYPE => 'STRING', +                                           SOURCE => $success_txt, +                                           DELIMITERS => [ '<%=', '%>' ], +                                         ) +    or die $Text::Template::ERROR; +} else { +  $success_template = new Text::Template ( TYPE => 'STRING', +                                           SOURCE => &success_default, +                                           DELIMITERS => [ '<%=', '%>' ], +                                         ) +    or die $Text::Template::ERROR; +} + +if ( -e $decline_html ) { +  my $decline_txt = Text::Template::_load_text($decline_html) +    or die $Text::Template::ERROR; +  $decline_txt =~ /^(.*)$/s; #untaint the template source - it's trusted +  $decline_txt = $1; +  $decline_template = new Text::Template ( TYPE => 'STRING', +                                           SOURCE => $decline_txt, +                                           DELIMITERS => [ '<%=', '%>' ], +                                         ) +    or die $Text::Template::ERROR; +} else { +  $decline_template = new Text::Template ( TYPE => 'STRING', +                                           SOURCE => &decline_default, +                                           DELIMITERS => [ '<%=', '%>' ], +                                         ) +    or die $Text::Template::ERROR; +} + +$cgi = new CGI; + +my $rv = capture_payment( +           data => { 'manual' => 1, +                     map { $_ => scalar($cgi->param($_)) } $cgi->param +                   }, +           url  => $cgi->self_url, +); + +$error = $rv->{error}; +   +if ( $error eq '_decline' ) { +  print_decline(); +} elsif ( $error ) { +  print_verify(); +} else { +  print_okay(%$rv); +} + + +sub print_verify { + +  $error = "Error: $error" if $error; + +  my $r = { $cgi->Vars, 'error' => $error }; + +  $r->{self_url} = $cgi->self_url; + +  print $cgi->header( '-expires' => 'now' ), +        $verify_template->fill_in( PACKAGE => 'FS::SelfService::_signupcgi', +                                   HASH    => $r +                                 ); +} + +sub print_decline { +  print $cgi->header( '-expires' => 'now' ), +        $decline_template->fill_in(); +} + +sub print_okay { +  my %param = @_; + +  my @success_url = split '/', $cgi->url(-path); +  pop @success_url; + +  my $success_url  = join '/', @success_url; +  if ($param{session_id}) { +    my $session_id = lc($param{session_id}); +    $success_url .= "/selfservice.cgi?action=myaccount&session=$session_id"; +  } else { +    $success_url .= '/signup.cgi?action=success'; +  } + +  print $cgi->header( '-expires' => 'now' ), +        $success_template->fill_in( HASH => { success_url => $success_url } ); +} + +sub success_default { #html to use if you don't specify a success file +  <<'END'; +<HTML><HEAD><TITLE>Signup successful</TITLE></HEAD> +<BODY BGCOLOR="#e8e8e8"><FONT SIZE=7>Signup successful</FONT><BR><BR> +Thanks for signing up! +<BR><BR> +<SCRIPT TYPE="text/javascript"> +  window.top.location="<%= $success_url %>"; +</SCRIPT> +</BODY></HTML> +END +} + +sub verify_default { #html to use for verification response +  <<'END'; +<HTML><HEAD><TITLE>Processing error</TITLE></HEAD> +<BODY BGCOLOR="#e8e8e8"><FONT SIZE=7>Processing error</FONT><BR><BR> +There has been an error processing your account.  Please contact customer +support. +</BODY></HTML> +END +} + +sub decline_default { #html to use if there is a decline +  <<'END'; +<HTML><HEAD><TITLE>Processing error</TITLE></HEAD> +<BODY BGCOLOR="#e8e8e8"><FONT SIZE=7>Processing error</FONT><BR><BR> +There has been an error processing your account.  Please contact customer +support. +</BODY></HTML> +END +} + +# subs for the templates... + +package FS::SelfService::_signupcgi; +use HTML::Entities; + diff --git a/fs_selfservice/FS-SelfService/cgi/view_cdr_details.html b/fs_selfservice/FS-SelfService/cgi/view_cdr_details.html new file mode 100644 index 000000000..32bd632b4 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/view_cdr_details.html @@ -0,0 +1,54 @@ +<%= $url = "$selfurl?session=$session_id;action="; ''; %> +<%= include('header') %> + +<FONT SIZE=4>Call usage for +<%= Date::Format::time2str('%b %o %Y', $beginning) %> - +<%= Date::Format::time2str('%b %o %Y', $ending) %> +</FONT><BR><BR> + +<%= if ( $error ) { +  $OUT .= qq!<FONT SIZE="+1" COLOR="#ff0000">$error</FONT><BR><BR>!; +} ''; %> +  +<TABLE WIDTH="100%"> +  <TR> +    <TD WIDTH="50%"> +<%= if ($previous < $beginning) { +    $OUT .= qq!<A HREF="${url}view_cdr_details;svcnum=$svcnum;beginning=!; +    $OUT .= qq!$previous;ending=$beginning">Previous period</A>!; +    }else{ +      ''; +    } %> +    </TD> +    <TD  WIDTH="50%" ALIGN="right"> +<%= if ($next > $ending) { +    $OUT .= qq!<A HREF="${url}view_cdr_details;svcnum=$svcnum;beginning=!; +    $OUT .= qq!$ending;ending=$next">Next period</A>!; +    }else{ +      ''; +    }%> +    </TD> +  </TR> +</TABLE> +<TABLE BGCOLOR="#cccccc"> +  <TR> +<%= foreach my $header (@header) { +      $OUT .= qq(<TH ALIGN="right">$header</TH>); +    } +%> +  </TR> +<%= my $total = 0; +    my $utotal = 0; +    my $dtotal = 0; +    foreach my $usage ( @usage ) { +      $OUT .= '<TR>'; +      $OUT .= qq(<TD>$_</TD>) foreach @{$usage}; +      $OUT .= '</TR>'; +    } +%> + +</TABLE> +<BR> + +</TD></TR></TABLE> +<%= include('footer') %> diff --git a/fs_selfservice/FS-SelfService/cgi/view_customer.html b/fs_selfservice/FS-SelfService/cgi/view_customer.html new file mode 100644 index 000000000..5bfb9b6fd --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/view_customer.html @@ -0,0 +1,24 @@ +<HTML><HEAD><TITLE>Reseller</TITLE></HEAD> +<BODY BGCOLOR="#eeeeee"><FONT SIZE=5>Reseller</FONT><BR><BR> +<%= $url = "$selfurl?session=$session_id;action="; ''; %> +<TABLE BORDER=0 CELLPADDING=4><TR> +<%= include('agent_menu') %> +<TD VALIGN="top"> + +<%= $message +      ? "<FONT SIZE=\"+2\"><B>$message</B></FONT><BR><BR>" +      : '' +%> + +<%= $small_custview %> + +<BR> + +<TABLE BORDER=0 CELLPADDING=4><TR> +<%= include('agent_customer_menu') %> +<TD VALIGN="top"> + +</TD></TR></TABLE> + +</TD></TR></TABLE> +<%= include('footer') %> diff --git a/fs_selfservice/FS-SelfService/cgi/view_invoice.html b/fs_selfservice/FS-SelfService/cgi/view_invoice.html new file mode 100644 index 000000000..8a1c1c73d --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/view_invoice.html @@ -0,0 +1,6 @@ +<%= $url = "$selfurl?session=$session_id;action="; ''; %> +<%= include('header') %> + +<%= $invoice_html %> + +<%= include('footer') %> diff --git a/fs_selfservice/FS-SelfService/cgi/view_support_details.html b/fs_selfservice/FS-SelfService/cgi/view_support_details.html new file mode 100644 index 000000000..ea218749c --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/view_support_details.html @@ -0,0 +1,78 @@ +<HTML><HEAD><TITLE>MyAccount</TITLE></HEAD> +<BODY BGCOLOR="#eeeeee"><FONT SIZE=5>MyAccount</FONT><BR><BR> +<%= $url = "$selfurl?session=$session_id;action="; ''; %> +<%= include('myaccount_menu') %> +<TD VALIGN="top"> + +<FONT SIZE=4>Support usage details for +<%= Date::Format::time2str('%b %o %Y', $beginning) %> - +<%= Date::Format::time2str('%b %o %Y', $ending) %> +</FONT><BR><BR> + +<%= if ( $error ) { +  $OUT .= qq!<FONT SIZE="+1" COLOR="#ff0000">$error</FONT><BR><BR>!; +} ''; %> +  +<TABLE WIDTH="100%"> +  <TR> +    <TD WIDTH="50%"> +<%= if ($previous < $beginning) { +    $OUT .= qq!<A HREF="${url}view_support_details;svcnum=$svcnum;beginning=!; +    $OUT .= qq!$previous;ending=$beginning">Previous period</A>!; +    }else{ +      ''; +    } %> +    </TD> +    <TD  WIDTH="50%" ALIGN="right"> +<%= if ($next > $ending) { +    $OUT .= qq!<A HREF="${url}view_support_details;svcnum=$svcnum;beginning=!; +    $OUT .= qq!$ending;ending=$next">Next period</A>!; +    }else{ +      ''; +    }%> +    </TD> +  </TR> +</TABLE> +<TABLE BGCOLOR="#cccccc"> +  <TR> +    <TH ALIGN="left">Ticket</TH> +    <TH ALIGN="center">Subject</TH> +    <TH ALIGN="center">Staff</TH> +    <TH ALIGN="center">Date</TH> +    <TH ALIGN="center">Status</TH> +    <TH ALIGN="right">Time</TH> +  </TR> +<%= my $total = 0; +    foreach my $usage ( @usage ) { +  $OUT .= '<TR><TD ALIGN="left">'; +    $OUT .= $usage->{'ticketid'}; +    $OUT .= '</TD><TD ALIGN="right">'; +    $OUT .= $usage->{'subject'}; +    $OUT .= '</TD><TD ALIGN="right">'; +    $OUT .= $usage->{'creator'}; +    $OUT .= '</TD><TD ALIGN="left">'; +    $OUT .= Date::Format::time2str('%T%P %a %b %o %Y', $usage->{'_date'}); +    $OUT .= '</TD><TD ALIGN="right">'; +    $OUT .= $usage->{'status'}; +    $OUT .= '</TD><TD ALIGN="right">'; +    my $duration =  $usage->{'support'}; +    $total += $usage->{'support'}; +    my $h = int($duration/3600); +    my $m = sprintf("%02d", int(($duration % 3600) / 60)); +    my $s = sprintf("%02d", $duration % 60); +    $OUT .=  $usage->{'support'} < 0 ? '-' : ''; +    $OUT .=  "$h:$m:$s"; +  $OUT .= '</TD></TR>'; +  } +  my $h = int($total/3600); +  my $m = sprintf("%02d", int(($total % 3600) / 60)); +  my $s = sprintf("%02d", $total % 60); +  $OUT .=  qq!<TR><TD COLSPAN="5"></TD><TD ALIGN="right"><HR></TD></TR>!; +  $OUT .=  qq!<TR><TD COLSPAN="5"></TD><TD ALIGN="right">$h:$m:$s</TD></TR>!; +  %> + +</TABLE> +<BR> + +</TD></TR></TABLE> +<%= include('footer') %> diff --git a/fs_selfservice/FS-SelfService/cgi/view_usage.html b/fs_selfservice/FS-SelfService/cgi/view_usage.html new file mode 100644 index 000000000..b492102ce --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/view_usage.html @@ -0,0 +1,86 @@ +<%= $url = "$selfurl?session=$session_id;action="; +    @svc_acct  = grep { $_->{svcdb} eq 'svc_acct'  } @svcs; +    @svc_phone = grep { $_->{svcdb} eq 'svc_phone' } @svcs; +    ''; +%> +<%= include('header') %> + +<%= if ( $error ) { +  $OUT .= qq!<FONT SIZE="+1" COLOR="#ff0000">$error</FONT><BR><BR>!; +} ''; %> + +<%= if ( @svc_acct ) { +      $OUT.= '<FONT SIZE="4">Account usage</FONT><BR><BR> +              <TABLE BGCOLOR="#cccccc"> +                <TR> +                  <TH ALIGN="left">Account</TH> +                  <TH ALIGN="right">Time remaining</TH> +                  <TH ALIGN="right">Upload remaining</TH> +                  <TH ALIGN="right">Download remaining</TH> +                  <TH ALIGN="right">Total remaining</TH> +                </TR>'; +    } else { +      $OUT .= ''; +    } +%> + +<%= foreach my $svc ( @svc_acct ) { +      my $link = "${url}view_usage_details;". +        "svcnum=$svc->{'svcnum'};beginning=0;ending=0"; +  $OUT .= '<TR><TD>'; +    $OUT .= qq!<A HREF="$link">!. $svc->{'label'}. ': '. $svc->{'value'}.'</A>'; +    $OUT .= '</TD><TD ALIGN="right">'; +    $OUT .= $svc->{'seconds'}; +    $OUT .= '</TD><TD ALIGN="right">'; +    $OUT .=  $svc->{'upbytes'}; +    $OUT .= '</TD><TD ALIGN="right">'; +    $OUT .= $svc->{'downbytes'}; +    $OUT .= '</TD><TD ALIGN="right">'; +    $OUT .= $svc->{'totalbytes'}; +  $OUT .= '</TD></TR>'; +    if ( $svc->{'recharge_amount'} ) { +      my $link = "${url}process_order_recharge;". +                 "svcnum=$svc->{'svcnum'}"; +    $OUT .= '<TR><TD ALIGN="right">'; +      $OUT .= qq!<A HREF="$link">!.'Recharge for $'; +      $OUT .= $svc->{'recharge_amount'} . '</A> with'; +      $OUT .= '</TD><TD ALIGN="right">'; +      $OUT .= $svc->{'recharge_seconds'} if $svc->{'recharge_seconds'}; +      $OUT .= '</TD><TD ALIGN="right">'; +      $OUT .=  $svc->{'recharge_upbytes'} if $svc->{'recharge_upbytes'}; +      $OUT .= '</TD><TD ALIGN="right">'; +      $OUT .= $svc->{'recharge_downbytes'} if $svc->{'recharge_downbytes'}; +      $OUT .= '</TD><TD ALIGN="right">'; +      $OUT .= $svc->{'recharge_totalbytes'} if $svc->{'recharge_totalbytes'}; +    $OUT .= '</TD></TR>'; +    } +  } +%> + +<%= scalar(@svc_acct) ? '</TABLE><BR><BR>' : '' %> + +<%= if ( @svc_phone ) { +      $OUT.= '<FONT SIZE="4">Call usage</FONT><BR><BR> +              <TABLE BGCOLOR="#cccccc"> +                <TR> +                  <TH ALIGN="left">Number</TH>'; #"Account" ? +                                                 #what else? +      $OUT .= '</TR>'; +    } else { +      $OUT .= ''; +    } +%> + +<%= foreach my $svc_phone ( @svc_phone ) { +      my $link = "${url}view_cdr_details;". +        "svcnum=$svc_phone->{'svcnum'};beginning=0;ending=0"; +  $OUT .= '<TR><TD>'; +    $OUT .= qq!<A HREF="$link">!. $svc_phone->{'label'}. ': '. $svc_phone->{'value'}.'</A>'; +  $OUT .= '</TD></TR>'; +  } +%> + +<%= scalar(@svc_phone) ? '</TABLE><BR><BR>' : '' %> + +</TD></TR></TABLE> +<%= include('footer') %> diff --git a/fs_selfservice/FS-SelfService/cgi/view_usage_details.html b/fs_selfservice/FS-SelfService/cgi/view_usage_details.html new file mode 100644 index 000000000..9f02eba79 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/view_usage_details.html @@ -0,0 +1,80 @@ +<%= $url = "$selfurl?session=$session_id;action="; ''; %> +<%= include('header') %> + +<FONT SIZE=4>Service usage details for +<%= Date::Format::time2str('%b %o %Y', $beginning) %> - +<%= Date::Format::time2str('%b %o %Y', $ending) %> +</FONT><BR><BR> + +<%= if ( $error ) { +  $OUT .= qq!<FONT SIZE="+1" COLOR="#ff0000">$error</FONT><BR><BR>!; +} ''; %> +  +<TABLE WIDTH="100%"> +  <TR> +    <TD WIDTH="50%"> +<%= if ($previous < $beginning) { +    $OUT .= qq!<A HREF="${url}view_usage_details;svcnum=$svcnum;beginning=!; +    $OUT .= qq!$previous;ending=$beginning">Previous period</A>!; +    }else{ +      ''; +    } %> +    </TD> +    <TD  WIDTH="50%" ALIGN="right"> +<%= if ($next > $ending) { +    $OUT .= qq!<A HREF="${url}view_usage_details;svcnum=$svcnum;beginning=!; +    $OUT .= qq!$ending;ending=$next">Next period</A>!; +    }else{ +      ''; +    }%> +    </TD> +  </TR> +</TABLE> +<TABLE BGCOLOR="#cccccc"> +  <TR> +    <TH ALIGN="left">Account</TH> +    <TH ALIGN="right">Start Time</TH> +    <TH ALIGN="right">Duration</TH> +    <TH ALIGN="right">Upload</TH> +    <TH ALIGN="right">Download</TH> +  </TR> +<%= my $total = 0; +    my $utotal = 0; +    my $dtotal = 0; +    foreach my $usage ( @usage ) { +  $OUT .= '<TR><TD>'; +    $OUT .= $usage->{'username'}; +    $OUT .= '</TD><TD ALIGN="right">'; +    $OUT .= Date::Format::time2str('%T%P %a %b %o %Y', $usage->{'acctstarttime'}); +    $OUT .= '</TD><TD ALIGN="right">'; +    my $duration =  $usage->{'acctstoptime'} - $usage->{'acctstarttime'}; +    $total += $duration; +    my $h = int($duration/3600); +    my $m = sprintf("%02d", int(($duration % 3600) / 60)); +    my $s = sprintf("%02d", $duration % 60); +    $OUT .=  "$h:$m:$s"; +    $OUT .= '</TD><TD ALIGN="right">'; +    $OUT .= Number::Format::format_bytes($usage->{'acctinputoctets'}, precision => 2); +    $utotal += $usage->{'acctinputoctets'}; +    $OUT .= '</TD><TD ALIGN="right">'; +    $OUT .= Number::Format::format_bytes($usage->{'acctoutputoctets'}, precision => 2); +    $dtotal += $usage->{'acctoutputoctets'}; +  $OUT .= '</TD></TR>'; +  } +  my $h = int($total/3600); +  my $m = sprintf("%02d", int(($total % 3600) / 60)); +  my $s = sprintf("%02d", $total % 60); +  $OUT .=  qq!<TR><TD></TD><TD></TD>!; +  $OUT .=  qq!<TD ALIGN="right"><HR></TD>! x 3; +  $OUT .=  qq!</TR>!; +  $OUT .=  qq!<TR><TD></TD><TD></TD><TD ALIGN="right">$h:$m:$s</TD>!; +  $OUT .=  qq!<TD ALIGN="right">!; +  $OUT .=  Number::Format::format_bytes($utotal, precision => 2). qq!</TD>!; +  $OUT .=  qq!<TD ALIGN="right">!; +  $OUT .=  Number::Format::format_bytes($dtotal, precision => 2). qq!</TD>!; +  $OUT .=  qq!</TR>!; %> + +</TABLE> +<BR> + +<%= include('footer') %> diff --git a/fs_selfservice/FS-SelfService/cgi/xmlrpc.cgi b/fs_selfservice/FS-SelfService/cgi/xmlrpc.cgi new file mode 100644 index 000000000..559ae04d8 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/xmlrpc.cgi @@ -0,0 +1,18 @@ +#!/usr/bin/perl -Tw + +use strict; +use XMLRPC::Transport::HTTP; +use XMLRPC::Lite; # for XMLRPC::Serializer +use FS::SelfService::XMLRPC; + +my %typelookup = ( +  base64 => [10, sub {$_[0] =~ /[^\x09\x0a\x0d\x20-\x7f]/}, 'as_base64'], +  dateTime => [35, sub {$_[0] =~ /^\d{8}T\d\d:\d\d:\d\d$/}, 'as_dateTime'], +  string => [40, sub {1}, 'as_string'], +); +my $serializer = new XMLRPC::Serializer(typelookup => \%typelookup); +  +XMLRPC::Transport::HTTP::CGI->dispatch_to('FS::SelfService::XMLRPC') +                            ->serializer($serializer) +                            ->handle; + diff --git a/fs_selfservice/FS-SelfService/freeside-selfservice-clientd b/fs_selfservice/FS-SelfService/freeside-selfservice-clientd new file mode 100644 index 000000000..0819d9d67 --- /dev/null +++ b/fs_selfservice/FS-SelfService/freeside-selfservice-clientd @@ -0,0 +1,377 @@ +#!/usr/bin/perl -w +# +# freeside-selfservice-clientd +# +# This is run REMOTELY over ssh by freeside-selfservice-server + +use strict; +use subs qw(spawn logmsg lock_write unlock_write); +use Fcntl qw(:flock); +use POSIX qw(:sys_wait_h); +use Socket; +use Storable 2.09 qw(nstore_fd fd_retrieve); +use IO::Handle qw(_IONBF); +use IO::Select; +use IO::File; +use Text::CSV_XS; + +#STDOUT->setbuf(''); + +my $tag = scalar(@ARGV) ? '.'.shift : ''; + +use vars qw( $Debug ); +$Debug = 2; #2 will turn on child logging +            #3 will log packet contents,#including passwords +            #4 will log receipts of all packets from server including +            #  keepalives (big!) + +my $socket = "/usr/local/freeside/selfservice_socket$tag"; +my $pid_file = "$socket.pid"; + +my $log_file = "/usr/local/freeside/selfservice$tag.log"; + +my $lock_file = "/usr/local/freeside/selfservice$tag.writelock"; + +#my $me = '[client]'; + +$|=1; + +$SIG{__WARN__} = \&_logmsg; +#$SIG{__DIE__} = sub { &_logmsg(@_); exit }; + +#read data to be cached or something +#warn "$me Reading init data\n" if $Debug; +#my $signup_init =  + +warn "Creating $lock_file\n" if $Debug; +open(LOCKFILE,">$lock_file") or die "can't open $lock_file: $!"; +close LOCKFILE; + +warn "Creating $socket\n" if $Debug; +my $uaddr = sockaddr_un($socket); +my $proto = getprotobyname('tcp'); +socket(Server,PF_UNIX,SOCK_STREAM,0) or die "socket: $!"; +unlink($socket); +bind(Server, $uaddr) or die "bind: $!"; +listen(Server,SOMAXCONN) or die "listen: $!"; + +if ( -e $pid_file ) { +  open(PIDFILE,"<$pid_file"); +  my $old_pid = <PIDFILE>; +  close PIDFILE; +  if ( $old_pid =~ /^(\d+)$/ ) { +    kill 'TERM', $1; +  } +} +open(PIDFILE,">$pid_file"); +print PIDFILE "$$\n"; +close PIDFILE; + +#my $waitedpid; +#sub REAPER { $waitedpid = wait; $SIG{CHLD} = \&REAPER; } +#$SIG{CHLD} =  \&REAPER; + +warn "enabling keep alives\n" if $Debug; +nstore_fd( { _packet => '_enable_keepalive' } , \*STDOUT ); + +warn "entering main loop\n" if $Debug; + +my %kids; +my %ftp_scan_dir; +my %ftp_scan_map; + +my $s = new IO::Select; +$s->add(\*STDIN); +$s->add(\*Server); + +#for ( $waitedpid = 0; +#      accept(Client,Server) || $waitedpid; +#      $waitedpid = 0, close Client) +#{ +#  next if $waitedpid; + +#$SIG{PIPE} = sub { warn "SIGPIPE received" }; +#$SIG{CHLD} = sub { warn "SIGCHLD received" }; + +#sub REAPER { warn "SIGCHLD received"; my $pid = wait; $SIG{CHLD} = \&REAPER; } +#sub REAPER { my $pid = wait; $SIG{CHLD} = \&REAPER; } +#sub REAPER { my $pid = wait; delete $kids{$pid}; $SIG{CHLD} = \&REAPER; } +#$SIG{CHLD} =  \&REAPER; + +my $undisp = 0; +while (1) { + +  &reap_kids; + +  warn "waiting for connection\n" if $Debug && !$undisp; + +  #my @handles = $s->can_read(); +  my @handles = $s->can_read(5); +  $undisp = !scalar(@handles); +  foreach my $handle ( @handles ) { + +    if ( $handle == \*STDIN ) { + +      warn "receiving packet from server\n" if $Debug > 3; + +      my $packet = fd_retrieve(\*STDIN); +      my $token = $packet->{'_token'}; + +      if ( $token eq '_keepalive' ) { +        $undisp = 1; +        next; +      } + +      warn "received packet from server with token $token\n". +           ( $Debug > 2 +             ? join('', map { " $_=>$packet->{$_}\n" } keys %$packet ) +             : '' ) +        if $Debug; + +      if ( $token eq '_ftp_scan' ) { +        if ( $ftp_scan_dir{$packet->{dir}} ) { +          warn "already processing ". $packet->{dir}. "\n" if $Debug; +        } else { +          $ftp_scan_dir{$packet->{dir}} = 1; +          spawn \&ftp_scan, $packet; +        } +        $undisp = 1; +        next; +      } + +      if ( exists($kids{$token}) ) { +        warn "sending return packet to $token via $kids{$token}\n" +          if $Debug; +        nstore_fd($packet, $kids{$token}); +        warn "flushing to $token\n" if $Debug; +        until ( $kids{$token}->flush ) { +          warn "WARNING: error flushing: $!"; +          sleep 1; +        } +        #no close or delete here - will block waiting for child +        warn "done with $token\n" if $Debug; +      } else { +        warn "WARNING: unknown token $token, discarding message"; +      } + +    } elsif ( $handle == \*Server ) { + +      until ( accept(Client, Server) ) { +        warn "WARNING: accept failed: $!"; +        next; +      } + +      warn "received local connection; forking\n" if $Debug; + +      spawn sub { #child +        warn "[child-$$] reading packet from local client" if $Debug > 1; +        my $packet = fd_retrieve(\*Client); +        warn "[child-$$] packet received:\n". +             join('', map { " $_=>$packet->{$_}\n" } keys %$packet ) +          if $Debug > 2; +        my $command = $packet->{'command'}; +        #handle some commands weirdly? +        $packet->{_token}=$$; + +        my $rv = send_and_wait( $packet ); + +        warn "[child-$$] closing write stream\n" if $Debug > 1; +        close STDOUT or die "FATAL: can't close write stream: $!"; #??! + +        #close STDIN; + +        warn "[child-$$] sending response to local client" if $Debug > 1; +        nstore_fd($rv, \*Client); +        Client->flush or die "FATAL: can't flush to local client: $!"; +        close Client or die "FATAL: can't close connection to local client: $!"; + +        warn "[child-$$] child exiting" if $Debug > 1; +        exit; + +      }; #eo child + +      #close Client; + +    } else { +      die "wtf?  $handle"; +    } + +  } +   +} + +sub reap_kids { +  #warn "reaping kids\n"; +  foreach my $pid ( keys %kids ) { +    my $kid = waitpid($pid, WNOHANG); +    if ( $kid > 0 ) { +      close $kids{$kid}; +      delete $kids{$kid}; +      if ( $ftp_scan_map{$kid} ) { +        delete($ftp_scan_dir{$ftp_scan_map{$kid}}); +        delete($ftp_scan_map{$kid}); +      } +    } +  } +  #warn "done reaping\n"; +} + +sub spawn { +    my ( $coderef, $packet ) = ( shift, shift ); + +    unless (@_ == 0 && $coderef && ref($coderef) eq 'CODE') { +        use Carp; +        confess "usage: spawn CODEREF"; +    } + +    my $pid; +    #if (!defined($pid = fork)) { +    my $kid = new IO::Handle; +    if (!defined($pid = open($kid, '|-'))) { +        warn "WARNING: cannot fork: $!"; +        return; +    } elsif ($pid) { +        warn "begat $pid" if $Debug; +        $ftp_scan_map{$pid} = $packet->{dir} if $coderef == \&ftp_scan; +        $kids{$pid} = $kid; +        #$kids{$pid}->autoflush; +        return; # I'm the parent +    } +    # else I'm the child -- go spawn + +#    open(STDIN,  "<&Client")   || die "can't dup client to stdin"; +#    open(STDOUT, ">&Client")   || die "can't dup client to stdout"; +#     open(STDERR, ">&STDOUT") || die "can't dup stdout to stderr"; +    exit &$coderef($packet); +} + +sub _logmsg { +  chomp( my $msg = shift ); +  my $log = new IO::File ">>$log_file"; +  die "can't open $log_file: $!" unless defined($log); +  flock($log, LOCK_EX); +  seek($log, 0, 2); +  print $log "[client] [". scalar(localtime). "] [$$] $msg\n"; +  flock($log, LOCK_UN); +  close $log; +} + +sub send_and_wait { +  my $packet = shift; + +  warn "[child-$$] locking write stream\n" if $Debug > 1; +  lock_write; + +  warn "[child-$$] sending packet to remote server\n" if $Debug > 1; +  nstore_fd($packet, \*STDOUT) or die "FATAL: can't send response: $!"; +         +  warn "[child-$$] flushing write stream\n" if $Debug > 1; +  STDOUT->flush or die "FATAL: can't flush: $!"; +         +  warn "[child-$$] releasing write lock\n" if $Debug > 1; +  unlock_write; + +  warn "[child-$$] waiting for response from parent\n" if $Debug > 1; +  my $w = new IO::Select; +  $w->add(\*STDIN); +  until ( $w->can_read ) { +    warn "[child-$$] WARNING: interrupted select: $!\n"; +  } + +  fd_retrieve(\*STDIN); +} + +sub lock_write { +  #broken on freebsd? +  #flock(STDOUT, LOCK_EX) or die "FATAL: can't lock write stream: $!"; + +  #open a new one for each kid to get a unique lock +  open(LOCKFILE,">$lock_file") or die "can't open $lock_file: $!"; + +  flock(LOCKFILE, LOCK_EX) or die "FATAL: can't lock $lock_file: $!"; +} + +sub unlock_write { +  #broken on freebsd? +  #flock(STDOUT, LOCK_UN) or die "FATAL: can't release write lock: $!"; + +  flock(LOCKFILE, LOCK_UN) or die "FATAL: can't unlock $lock_file: $!"; +} + +sub ftp_scan { +  my $packet = shift; + +  warn "[child-$$] performing ftp scan" if $Debug > 1; + +  warn "[child-$$] packet received:\n". +       join('', map { " $_=>$packet->{$_}\n" } keys %$packet ) +    if $Debug > 2; + +  $packet->{_token}=$$; + +  my $dir; +  $packet->{dir} =~ /^(.*)$/ && ($dir = $1); # we trust ourselves +  opendir(DIR, $dir) or die "failed to open directory $dir: $!\n"; +  my @files = grep(/\.csv$/, readdir(DIR)); +  closedir(DIR); + +  foreach my $file ( @files ) { +    warn "Processing $file ...\n"; +    my $csv = Text::CSV_XS->new(); +    my $err = ""; +    my @records = (); +    open(CSV, "<$dir/$file") or die "can't open input file for $file: $!\n"; +    open(RESULT, ">$dir/result/$file") +      or die "can't open result file for $file: $!\n"; + +    while (<CSV>) { +      if ( $csv->parse($_) ) { +        my @columns = $csv->fields(); +        push(@records, \@columns); +      } else { +        $err = $csv->error_input; +        last; +      } +    } +    close(CSV); +    if ( $err ) { +      rename("$dir/$file", "$dir/rejected/$file"); +    } else { +      foreach my $record ( @records ) { + +        $packet->{row} = $record; +        $packet->{_packet} = 'Bulk/processrow'; +        my $result = send_and_wait( $packet ); + +        if ( $result->{error} ) { +          my $name; +          $record->[1] =~ /^(\w+)$/ && ( $name = $1 ); + +          if ($name) { +            my $filename = "$dir/rejected/$name"; +            open(REC, ">$filename") or die "can't open $filename: $!\n"; +            print REC join(',', @$record); +            close REC or die $!; +            open(ERR, ">$filename.err") or die "can't open $filename.err: $!\n"; +            print ERR $result->{error}; +            close ERR or die $!; +          }else{ +            warn "bad agent_custid"; +          } + +        } +        print RESULT $result->{message}, "\n"; +      } + +      rename("$dir/$file", "$dir/processed/$file"); +      warn "$file processed.\n" if $Debug; +    } +    close(RESULT); +  } + +  close STDOUT or die "FATAL: can't close write stream: $!"; #??! + +  warn "[child-$$] child exiting" if $Debug > 1; +  exit; + +} diff --git a/fs_selfservice/FS-SelfService/freeside-selfservice-soap-server b/fs_selfservice/FS-SelfService/freeside-selfservice-soap-server new file mode 100644 index 000000000..869a8aecc --- /dev/null +++ b/fs_selfservice/FS-SelfService/freeside-selfservice-soap-server @@ -0,0 +1,53 @@ +#!/usr/bin/perl -w +# +# freeside-selfservice-soap-server +# + +use strict; +use Fcntl qw(:flock); +use POSIX; +use Getopt::Std; +use SOAP::Transport::HTTP; +use FS::SelfService; + +use vars qw( $opt_p $opt_d $opt_s ); +use vars qw( $DEBUG ); + +getopts("s:p:d"); +$DEBUG = $opt_d; +my $tag = $opt_s ? $opt_s : ''; +$tag = ($opt_s ? ':' : '') . $opt_p ? ':'.$opt_p : ''; + +my $log_file = "/usr/local/freeside/selfservice.soap$tag.log"; + +my $pid = fork; +defined($pid) or die "Can't fork to start: $!"; +print "Started daemon with pid $pid\n" if $pid; +exit if $pid; + +POSIX::setsid(); +open STDIN, "/dev/null" or die "Can't get rid of STDIN"; +open STDOUT, ">/dev/null" or die "Can't get rid of STDOUT"; +open STDERR, ">&STDOUT" or die "Can't get rid of STDERR"; + +$SIG{__WARN__} = \&_logmsg; +$SIG{__DIE__} = sub { &_logmsg(@_); exit }; + +my $daemon = SOAP::Transport::HTTP::Daemon +  ->new($opt_s ? (LocalAddr => $opt_s) : (), LocalPort => $opt_p ? $opt_p : 8080) +  ->dispatch_to('/usr/local/freeside/SOAP/') #, 'FS::SelfService' +  ->objects_by_reference('iZoomOnlineProvisionService') +  ->handle; + +warn "Handling request at ", $daemon->url, "\n"; +$daemon->handle; + +sub _logmsg { +  chomp( my $msg = shift ); +  my $log = new IO::File ">>$log_file"; +  flock($log, LOCK_EX); +  seek($log, 0, 2); +  print $log "[". scalar(localtime). "] [$$] $msg\n"; +  flock($log, LOCK_UN); +  close $log; +} diff --git a/fs_selfservice/FS-SelfService/freeside-selfservice-xmlrpc-server b/fs_selfservice/FS-SelfService/freeside-selfservice-xmlrpc-server new file mode 100644 index 000000000..bd4f83b3c --- /dev/null +++ b/fs_selfservice/FS-SelfService/freeside-selfservice-xmlrpc-server @@ -0,0 +1,59 @@ +#!/usr/bin/perl -w +# +# freeside-selfservice-xmlrpc-server +# + +use strict; +use Fcntl qw(:flock); +use POSIX; +use Getopt::Std; +use XMLRPC::Transport::HTTP; +use XMLRPC::Lite; # for XMLRPC::Serializer; +use FS::SelfService::XMLRPC; + +use vars qw( $opt_p $opt_d ); +use vars qw( $DEBUG ); + +getopts("p:d"); +$DEBUG = $opt_d; +my $tag = $opt_p ? ':'.$opt_p : ''; + +my %typelookup = ( +  base64 => [10, sub {$_[0] =~ /[^\x09\x0a\x0d\x20-\x7f]/}, 'as_base64'], +  dateTime => [35, sub {$_[0] =~ /^\d{8}T\d\d:\d\d:\d\d$/}, 'as_dateTime'], +  string => [40, sub {1}, 'as_string'], +); +my $serializer = new XMLRPC::Serializer(typelookup => \%typelookup); + +my $log_file = "/usr/local/freeside/selfservice.xmlrpc$tag.log"; + +my $pid = fork; +defined($pid) or die "Can't fork to start: $!"; +print "Started daemon with pid $pid\n" if $pid; +exit if $pid; + +POSIX::setsid(); +open STDIN, "/dev/null" or die "Can't get rid of STDIN"; +open STDOUT, ">/dev/null" or die "Can't get rid of STDOUT"; +open STDERR, ">&STDOUT" or die "Can't get rid of STDERR"; + +$SIG{__WARN__} = \&_logmsg; +$SIG{__DIE__} = sub { &_logmsg(@_); exit }; + +my $daemon = XMLRPC::Transport::HTTP::Daemon +  ->new(LocalPort => $opt_p ? $opt_p : 8080) +  ->dispatch_to('FS::SelfService::XMLRPC') +  ->serializer($serializer); + +warn "Handling request at ", $daemon->url, "\n"; +$daemon->handle; + +sub _logmsg { +  chomp( my $msg = shift ); +  my $log = new IO::File ">>$log_file"; +  flock($log, LOCK_EX); +  seek($log, 0, 2); +  print $log "[". scalar(localtime). "] [$$] $msg\n"; +  flock($log, LOCK_UN); +  close $log; +} diff --git a/fs_selfservice/FS-SelfService/iZoomOnlineProvisionService.pm b/fs_selfservice/FS-SelfService/iZoomOnlineProvisionService.pm new file mode 100644 index 000000000..f4c586969 --- /dev/null +++ b/fs_selfservice/FS-SelfService/iZoomOnlineProvisionService.pm @@ -0,0 +1,75 @@ +package iZoomOnlineProvisionService; + +use strict; + +#BEGIN { push @INC, '/usr/lib/perl/5.8.8/' }; +use FS::SelfService qw( bulk_processrow check_username agent_login ); +    +=begin WSDL + +_IN agent_username $string agent username +_IN agent_password $string agent password +_IN agent_custid $string customer id in agent system +_IN username $string customer service username +_IN password $string customer service password +_IN daytime $string phone number +_IN first $string first name +_IN last $string last name +_IN address1 $string address line 1 +_IN address2 $string address line 2 +_IN city $string city +_IN state $string state +_IN zip $string zip +_IN pkg $string package name +_IN action $string one of (R|P|D|S)(reconcile, provision, provision with disk, send disk) +_IN adjourn $string day to terminate service +_IN mobile $string mobile phone +_IN sms $string (T|F) acceptable to send SMS messages to mobile? +_IN ship_addr1 $string shipping address line 1 +_IN ship_addr2 $string shipping address line 2  +_IN ship_city $string shipping address city +_IN ship_state $string shipping address state +_IN ship_zip $string shipping address zip +_RETURN @string array [status, message]. status is one of OK, ERR + +=cut + +my $DEBUG = 0; + +sub Provision { +  my $class = shift; + +  my $session = agent_login( map { $_ => shift @_ } qw( username password ) ); +  return [ 'ERR', $session->{error} ] if $session->{error}; + +  my $result = +    bulk_processrow( session_id => $session->{session_id}, row => [ @_ ] ); +     +  return $result->{error} ? [ 'ERR', $result->{error} ] +                          : [ 'OK',  $result->{message} ]; +} + +=begin WSDL + +_IN agent_username $string agent username +_IN agent_password $string agent password +_IN username $string customer service username +_IN domain $string user domain name +_RETURN @string [OK|ERR]  + +=cut +sub CheckUserName { +  my $class = shift; + +  my $session = agent_login( map { $_ => shift @_ } qw( username password ) ); +  return [ 'ERR', $session->{error} ] if $session->{error}; + +  my $result = check_username( session_id => $session->{session_id}, +                               map { $_ => shift @_ } qw( user domain ) +               ); +     +  return $result->{error} ? [ 'ERR', $result->{error} ] +                          : [ 'OK',  $result->{message} ]; +} + +1; diff --git a/fs_selfservice/FS-SelfService/ieak.template b/fs_selfservice/FS-SelfService/ieak.template new file mode 100755 index 000000000..52edaa951 --- /dev/null +++ b/fs_selfservice/FS-SelfService/ieak.template @@ -0,0 +1,40 @@ +[Entry] +Entry_Name = The Internet +[Phone] +Dial_As_Is=no +Phone_Number = { $exch. $loc } +Area_Code = { $ac } +Country_Code = 1 +Country_Id = 1 +[Server] +Type = PPP +SW_Compress = Yes +PW_Encrypt = Yes +Negotiate_TCP/IP = Yes +Disable_LCP = No +[TCP/IP] +Specify_IP_Address = No +Specity_Server_Address = No +IP_Header_Compress = Yes +Gateway_On_Remote = Yes +[User] +Name = { $username } +Password = { $password } +Display_Password = Yes +[Internet_Mail] +Email_Name = { $email_name } +Email_Address = { $username }\@domain.tld +POP_Server = mail.domain.tld +POP_Server_Port_Number = 110 +POP_Login_Name = { $username } +POP_Login_Password = { $password } +SMTP_Server = mail.domain.tld +SMTP_Server_Port_Number = 25 +Install_Mail = 1 +[Internet_News] +NNTP_Server = news.domain.tld +NNTP_Server_Port_Number = 119 +Logon_Required = No +Install_News = 1 +[Branding] +Window_Title = The Internet diff --git a/fs_selfservice/FS-SelfService/test.pl b/fs_selfservice/FS-SelfService/test.pl new file mode 100644 index 000000000..7468ea471 --- /dev/null +++ b/fs_selfservice/FS-SelfService/test.pl @@ -0,0 +1,17 @@ +# Before `make install' is performed this script should be runnable with +# `make test'. After `make install' it should work as `perl test.pl' + +######################### + +# change 'tests => 1' to 'tests => last_test_to_print'; + +use Test; +BEGIN { plan tests => 1 }; +use FS::SelfService; +ok(1); # If we made it this far, we're ok. + +######################### + +# Insert your test code below, the Test module is use()ed here so read +# its man page ( perldoc Test ) for help writing this test script. + | 
