Merge branch 'master' of git.freeside.biz:/home/git/freeside
[freeside.git] / fs_selfservice / FS-SelfService / SelfService.pm
index fc9a37a..765d611 100644 (file)
@@ -26,17 +26,27 @@ $socket .= '.'.$tag if defined $tag && length($tag);
   'chfn'                      => 'passwd/passwd',
   'chsh'                      => 'passwd/passwd',
   'login_info'                => 'MyAccount/login_info',
+  'login_banner_image'        => 'MyAccount/login_banner_image',
   'login'                     => 'MyAccount/login',
   'logout'                    => 'MyAccount/logout',
+  'switch_acct'               => 'MyAccount/switch_acct',
+  'switch_cust'               => 'MyAccount/switch_cust',
   'customer_info'             => 'MyAccount/customer_info',
+  'customer_info_short'       => 'MyAccount/customer_info_short',
+  'billing_history'           => 'MyAccount/billing_history',
   'edit_info'                 => 'MyAccount/edit_info',     #add to ss cgi!
   'invoice'                   => 'MyAccount/invoice',
+  'invoice_pdf'               => 'MyAccount/invoice_pdf',
+  'legacy_invoice'            => 'MyAccount/legacy_invoice',
+  'legacy_invoice_pdf'        => 'MyAccount/legacy_invoice_pdf',
   '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',
+  'store_payment'             => 'MyAccount/store_payment',
+  'process_stored_payment'    => 'MyAccount/process_stored_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',
@@ -45,6 +55,19 @@ $socket .= '.'.$tag if defined $tag && length($tag);
   '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',   
+  'svc_status_html'           => 'MyAccount/svc_status_html',
+  'svc_status_hash'           => 'MyAccount/svc_status_hash',
+  'set_svc_status_hash'       => 'MyAccount/set_svc_status_hash',
+  'set_svc_status_listadd'    => 'MyAccount/set_svc_status_listadd',
+  'set_svc_status_listdel'    => 'MyAccount/set_svc_status_listdel',
+  'set_svc_status_vacationadd'=> 'MyAccount/set_svc_status_vacationadd',
+  'set_svc_status_vacationdel'=> 'MyAccount/set_svc_status_vacationdel',
+  'acct_forward_info'         => 'MyAccount/acct_forward_info',
+  'process_acct_forward'      => 'MyAccount/process_acct_forward',
+  'list_dsl_devices'          => 'MyAccount/list_dsl_devices',   
+  'add_dsl_device'            => 'MyAccount/add_dsl_device',   
+  'delete_dsl_device'         => 'MyAccount/delete_dsl_device',   
+  'port_graph'                => 'MyAccount/port_graph',   
   'list_cdr_usage'            => 'MyAccount/list_cdr_usage',   
   'list_support_usage'        => 'MyAccount/list_support_usage',   
   'order_pkg'                 => 'MyAccount/order_pkg',     #add to ss cgi!
@@ -53,19 +76,31 @@ $socket .= '.'.$tag if defined $tag && length($tag);
   'renew_info'                => 'MyAccount/renew_info',
   'order_renew'               => 'MyAccount/order_renew',
   'cancel_pkg'                => 'MyAccount/cancel_pkg',    #add to ss cgi!
+  'suspend_pkg'               => 'MyAccount/suspend_pkg',   #add to ss cgi!
   'charge'                    => 'MyAccount/charge',        #?
   'part_svc_info'             => 'MyAccount/part_svc_info',
   'provision_acct'            => 'MyAccount/provision_acct',
+  'provision_phone'           => 'MyAccount/provision_phone',
   'provision_external'        => 'MyAccount/provision_external',
   'unprovision_svc'           => 'MyAccount/unprovision_svc',
   'myaccount_passwd'          => 'MyAccount/myaccount_passwd',
+  'reset_passwd'              => 'MyAccount/reset_passwd',
+  'check_reset_passwd'        => 'MyAccount/check_reset_passwd',
+  'process_reset_passwd'      => 'MyAccount/process_reset_passwd',
+  'list_tickets'              => 'MyAccount/list_tickets',
   'create_ticket'             => 'MyAccount/create_ticket',
+  'get_ticket'                => 'MyAccount/get_ticket',
+  'adjust_ticket_priority'    => 'MyAccount/adjust_ticket_priority',
+  'did_report'                => 'MyAccount/did_report',
   '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',
+  'new_customer_minimal'      => 'Signup/new_customer_minimal',
   'capture_payment'           => 'Signup/capture_payment',
+  #N/A 'clear_signup_cache'        => 'Signup/clear_cache',
+  'new_agent'                 => 'Agent/new_agent',
   'agent_login'               => 'Agent/agent_login',
   'agent_logout'              => 'Agent/agent_logout',
   'agent_info'                => 'Agent/agent_info',
@@ -77,21 +112,16 @@ $socket .= '.'.$tag if defined $tag && length($tag);
   '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',
+
+  'start_thirdparty'          => 'MyAccount/start_thirdparty',
+  'finish_thirdparty'         => 'MyAccount/finish_thirdparty',
+
+  'quotation_info'            => 'MyAccount/quotation/quotation_info',
+  'quotation_print'           => 'MyAccount/quotation/quotation_print',
+  'quotation_add_pkg'         => 'MyAccount/quotation/quotation_add_pkg',
+  'quotation_remove_pkg'      => 'MyAccount/quotation/quotation_remove_pkg',
+  'quotation_order'           => 'MyAccount/quotation/quotation_order',
+
 );
 @EXPORT_OK = (
   keys(%autoload),
@@ -180,17 +210,43 @@ FS::SelfService - Freeside self-service API
   # "my account" functionality
   use FS::SelfService qw( login customer_info invoice cancel payment_info process_payment );
 
+  #new-style login with an email address and password
+  # can also be used for svc_acct login, set $emailaddress to username@domain
+  my $rv = login ( { 'email'    => $emailaddress,
+                     'password' => $password,
+                   },
+                 );
+  if ( $rv->{'error'} ) {
+    #handle login error...
+  } else {
+    #successful login
+    $session_id = $rv->{'session_id'};
+  }
+
+  #classic svc_acct-based login with separate username and password
   my $rv = login( { 'username' => $username,
                     'domain'   => $domain,
                     'password' => $password,
                   }
                 );
+  if ( $rv->{'error'} ) {
+    #handle login error...
+  } else {
+    #successful login
+    $session_id = $rv->{'session_id'};
+  }
 
+  #svc_phone login with phone number and PIN
+  my $rv = login( { 'username' => $phone_number,
+                    'domain'   => 'svc_phone',
+                    'password' => $pin,
+                  }
+                );
   if ( $rv->{'error'} ) {
     #handle login error...
   } else {
     #successful login
-    my $session_id = $rv->{'session_id'};
+    $session_id = $rv->{'session_id'};
   }
 
   my $customer_info = customer_info( { 'session_id' => $session_id } );
@@ -202,12 +258,35 @@ FS::SelfService - Freeside self-service API
 
   #!!! list_pkgs example
 
-  #!!! order_pkg example
+  #ordering a package with an svc_acct service
+  my $rv = order_pkg( { 'session_id' => $session_id,
+                        'pkgpart'    => $pkgpart,
+                        'svcpart'    => $svcpart,
+                        'username'   => $username,
+                        'domsvc'     => $domsvc, #svcnum of svc_domain
+                        '_password'  => $password,
+                      }
+                    );
+
+  #!!! ordering a package with an svc_domain service example
+
+  #!!! ordering a package with an svc_phone service example
+
+  #!!! ordering a package with an svc_external service example
+
+  #!!! ordering a package with an svc_pbx service
+
+  #ordering a package with no service
+  my $rv = order_pkg( { 'session_id' => $session_id,
+                        'pkgpart'    => $pkgpart,
+                        'svcpart'    => 'none',
+                      }
+                    );
 
   #!!! cancel_pkg example
 
   # signup functionality
-  use FS::SelfService qw( signup_info new_customer );
+  use FS::SelfService qw( signup_info new_customer new_customer_minimal );
 
   my $signup_info = signup_info;
 
@@ -270,6 +349,37 @@ see XXXX instead.
 
 =item passwd
 
+Changes the password for an existing user in svc_acct.  Takes a hash
+reference with the following keys:
+
+=over 4
+
+=item username
+
+Username of the account (required)
+
+=item domain
+
+Domain of the account (required)
+
+=item old_password
+
+Old password (required)
+
+=item new_password
+New password (required)
+
+=item new_gecos
+
+New gecos
+
+=item new_shell
+
+New Shell
+
+=back 
+
 =item chfn
 
 =item chsh
@@ -287,6 +397,11 @@ following keys:
 
 =over 4
 
+=item email
+
+Email address (username@domain), instead of username and domain.  Required for
+contact-based self-service login, can also be used for svc_acct-based login.
+
 =item username
 
 Username
@@ -811,6 +926,25 @@ Session identifier
 
 Package to order (see L<FS::part_pkg>).
 
+=item quantity
+
+Quantity for this package order (default 1).
+
+=item locationnum
+
+Optional locationnum for this package order, for existing locations.
+
+Or, for new locations, pass the following fields: address1*, address2, city*,
+county, state*, zip*, country.  (* = required in this case)
+
+=item address1
+
+=item address 2
+
+=item city
+
+=item 
+
 =item svcpart
 
 Service to order (see L<FS::part_svc>).
@@ -886,6 +1020,20 @@ External text title.
 
 =back
 
+Fields used when provisioning an svc_pbx service:
+
+=over 4
+
+=item id
+
+Numeric ID.
+
+=item name
+
+Text name.
+
+=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.
@@ -910,10 +1058,26 @@ Existing customer package.
 
 New package to order (see L<FS::part_pkg>).
 
+=item quantity
+
+Quantity for this package order (default 1).
+
+=back
+
+Returns a hash reference with the following keys:
+
+=over 4
+
+=item error
+
+Empty on success, or an error message on errors.  
+
+=item pkgnum
+
+On success, the new pkgnum
+
 =back
 
-Returns a hash reference with a single key, B<error>, empty on success, or an
-error message on errors.  
 
 =item renew_info
 
@@ -1021,6 +1185,102 @@ pkgpart of package to cancel
 Returns a hash reference with a single key, B<error>, empty on success, or an
 error message on errors.
 
+=item provision_acct 
+
+Provisions an account (svc_acct).
+
+Takes a hash references as parameter with the following keys:
+
+=over 4
+
+=item session_id
+
+Session identifier
+
+=item pkgnum
+
+pkgnum of package into which this service is provisioned
+
+=item svcpart
+
+svcpart or service definition to provision
+
+=item username
+
+=item domsvc
+
+=item _password
+
+=back
+
+=item provision_phone
+
+Provisions a phone number (svc_phone).
+
+Takes a hash references as parameter with the following keys:
+
+=over 4
+
+=item session_id
+
+Session identifier
+
+=item pkgnum
+
+pkgnum of package into which this service is provisioned
+
+=item svcpart
+
+svcpart or service definition to provision
+
+=item countrycode
+
+=item phonenum
+
+=item address1
+
+=item address2
+
+=item city
+
+=item county
+
+=item state
+
+=item zip
+
+=item country
+
+E911 Address (optional)
+
+=back
+
+=item provision_external
+
+Provisions an external service (svc_external).
+
+Takes a hash references as parameter with the following keys:
+
+=over 4
+
+=item session_id
+
+Session identifier
+
+=item pkgnum
+
+pkgnum of package into which this service is provisioned
+
+=item svcpart
+
+svcpart or service definition to provision
+
+=item id
+
+=item title
+
+=back
+
 =back
 
 =head1 SIGNUP FUNCTIONS
@@ -1126,6 +1386,147 @@ Default country
 
 =back
 
+=item new_customer_minimal HASHREF
+
+Creates a new customer.
+
+Current differences from new_customer: An address is not required.  promo_code
+and reg_code are not supported.  If invoicing_list and _password is passed, a
+contact will be created with self-service access (no pkgpart or username is
+necessary).  No initial billing is run (this may change in a future version).
+
+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
+
+Address line one
+
+=item address2
+
+Address line two
+
+=item city
+
+City
+
+=item county
+
+County
+
+=item state
+
+State
+
+=item zip
+
+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 new_customer HASHREF
 
 Creates a new customer.  Takes a hash reference as parameter with the
@@ -1419,7 +1820,7 @@ END
   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 .= "\n<OPTION $selected VALUE=\"$state\">$text</OPTION>"
   }
   $state_html .= '</SELECT>';
 
@@ -1439,7 +1840,7 @@ END
       my $selected = $country eq $param->{'selected_country'}
                        ? ' SELECTED'
                        : '';
-      $country_html .= "\n<OPTION$selected>$country</OPTION>"
+      $country_html .= "\n<OPTION $selected>$country</OPTION>"
     }
     $country_html .= '</SELECT>';
   } else {
@@ -1756,8 +2157,9 @@ sub domainselector {
            '<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)!;
+  my $text .= qq!<TR><TD ALIGN="right">Domain</TD><TD><SELECT NAME="domsvc" SIZE=1 STYLE="width: 20em">!;
 
+  $text .= '<OPTION>(Choose Domain)' unless $domsvc;
 
   foreach my $domain ( sort { $domains->{$a} cmp $domains->{$b} } keys %$domains ) {
     $text .= qq!<OPTION VALUE="!. $domain. '"'.