fix pod nits in doc, RT81515
[freeside.git] / fs_selfservice / FS-SelfService / SelfService.pm
index 7e6821b..fdee0d2 100644 (file)
@@ -26,25 +26,63 @@ $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',
+  'customer_recurring'        => 'MyAccount/customer_recurring',
+
+  'contact_passwd'            => 'MyAccount/contact/contact_passwd',
+  'list_contacts'             => 'MyAccount/contact/list_contacts',
+  'edit_contact'              => 'MyAccount/contact/edit_contact',
+  'delete_contact'            => 'MyAccount/contact/delete_contact',
+  'new_contact'               => 'MyAccount/contact/new_contact',
+
+  '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', #?
+  'list_payments'             => 'MyAccount/list_payments',
+  'payment_receipt'           => 'MyAccount/payment_receipt',
+  'list_payby'                => 'MyAccount/list_payby',
+  'insert_payby'              => 'MyAccount/insert_payby',
+  'update_payby'              => 'MyAccount/update_payby',
+  'delete_payby'              => 'MyAccount/delete_payby', 
   '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',
   'process_prepay'            => 'MyAccount/process_prepay',
   'realtime_collect'          => 'MyAccount/realtime_collect',
   'list_pkgs'                 => 'MyAccount/list_pkgs',     #add to ss (added?)
+  'pkg_info'                  => 'MyAccount/pkg_info',
   '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,42 +91,61 @@ $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_pbx'             => 'MyAccount/provision_pbx',
   'provision_external'        => 'MyAccount/provision_external',
+  'provision_forward'         => 'MyAccount/provision_forward',
   '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',
+  'validate_passwd'           => 'MyAccount/validate_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',
+  'new_prospect'              => 'Signup/new_prospect',
+  #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',
   'agent_list_customers'      => 'Agent/agent_list_customers',
+  'check_username'            => 'Agent/check_username',
+  'suspend_username'          => 'Agent/suspend_username',
+  'unsuspend_username'        => 'Agent/unsuspend_username',
   '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',
+
+  'start_thirdparty'          => 'MyAccount/start_thirdparty',
+  'finish_thirdparty'         => 'MyAccount/finish_thirdparty',
+
+  'list_quotations'           => 'MyAccount/quotation/list_quotations',
+  'quotation_new'             => 'MyAccount/quotation/quotation_new',
+  'quotation_delete'          => 'MyAccount/quotation/quotation_delete',
+  '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',
+
+  'freesideinc_service'       => 'Freeside/freesideinc_service',
+
 );
 @EXPORT_OK = (
   keys(%autoload),
@@ -177,34 +234,107 @@ 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 } );
 
-  #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
+  #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',
+                      }
+                    );
+
+  #quoting a package, then ordering after confirmation
+
+  my $rv = quotation_new({ 'session_id' => $session_id });
+  my $qnum = $rv->{quotationnum};
+  #  add packages to the quotation
+  $rv = quotation_add_pkg({ 'session_id'   => $session_id,
+                            'quotationnum' => $qnum,
+                            'pkgpart'      => $pkgpart,
+                            'quantity'     => $quantity, # defaults to 1
+                          });
+  #  repeat until all packages are added
+  #  view the pricing information
+  $rv = quotation_info({ 'session_id'   => $session_id,
+                         'quotationnum' => $qnum,
+                      });
+  print "Total setup charges: ".$rv->{total_setup}."\n".
+        "Total recurring charges: ".$rv->{total_recur}."\n";
+  #  quotation_info also provides a detailed breakdown of charges, in
+  #  $rv->{sections}.
+
+  #  ask customer for confirmation, then:
+  $rv = quotation_order({ 'session_id'   => $session_id,
+                          'quotationnum' => $qnum,
+                        });
 
   #!!! 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;
 
@@ -267,6 +397,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
@@ -284,6 +445,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
@@ -345,6 +511,31 @@ first last company address1 address2 city county state zip country daytime night
 
 =back
 
+=item customer_recurring HASHREF
+
+Takes a hash reference as parameter with a single key B<session_id>
+or keys B<agent_session_id> and B<custnum>.
+
+Returns a hash reference with the keys error, custnum and display_recurring.
+
+display_recurring is an arrayref of hashrefs with the following keys:
+
+=over 4
+
+=item freq
+
+frequency of charge, in months unless units are specified
+
+=item freq_pretty
+
+frequency of charge, suitable for display
+
+=item amount
+
+amount charged at this frequency
+
+=back
+
 =item edit_info HASHREF
 
 Takes a hash reference as parameter with any of the following keys:
@@ -383,7 +574,7 @@ Invoice text
 
 =item list_invoices HASHREF
 
-Returns a list of all customer invoices.  Takes a hash references with a single
+Returns a list of all customer invoices.  Takes a hash reference with a single
 key, session_id.
 
 Returns a hash reference with the following keys:
@@ -412,6 +603,197 @@ Invoice date, in UNIX epoch time
 
 =back
 
+=item list_payments HASHREF
+
+Returns a list of all customer payments.  Takes a hash reference 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 payments
+
+Reference to array of hash references with the following keys:
+
+=over 4
+
+=item paynum
+
+Payment #
+
+=item _date
+
+Payument date, in UNIX epoch time
+
+=item date
+
+Payment date, in a human-readable format
+
+=item date_short
+
+Payment date, in a shorter human-readable format
+
+=item paid
+
+Amount paid
+
+=item payby
+
+Payment method: CARD, CHEK (electronic check), or BILL (physical check).
+
+=item paycardtype
+
+Payment card type
+
+=item paymask
+
+Payment card mask
+
+=item processor
+
+Processor for cards and electronic checks
+
+=item auth
+
+Authorization number
+
+=item order_number
+
+Order number
+
+=back
+
+=back
+
+=item list_payby HASHREF
+
+Returns a list of all stored customer payment information (credit cards and
+electronic check accounts).  Takes a hash reference 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 payby
+
+Reference to array of hash references with the following keys:
+
+=over 4
+
+=item custpaybynum
+
+=item weight
+
+Numeric weighting.  Stored payment information with a lower weight is attempted
+first.
+
+=item payby
+
+CARD (Automatic credit card), CHEK (Automatic electronic check), DCRD
+(on-demand credit card) or DCHK (on-demand electronic check).
+
+=item paymask
+
+Masked credit card number (or, masked account and routing numbers)
+
+=item paydate
+
+Credit card expiration date
+
+=item payname
+
+Exact name on card (or bank name, for electronic checks)
+
+=item paystate
+
+For electronic checks, bank state
+
+=item paytype
+
+For electronic checks, account type (Personal/Business, Checking/Savings)
+
+=back
+
+=back
+
+=item insert_payby HASHREF
+
+Adds new stored payment information for this customer.  Takes a hash reference
+with the following keys:
+
+=over 4
+
+=item session_id
+
+=item weight
+
+Numeric weighting.  Stored payment information with a lower weight is attempted
+first.
+
+=item payby
+
+CARD (Automatic credit card), CHEK (Automatic electronic check), DCRD
+(on-demand credit card) or DCHK (on-demand electronic check).
+
+=item payinfo
+
+Credit card number (or electronic check "account@routing")
+
+=item paycvv
+
+CVV2 number / security code
+
+=item paydate
+
+Credit card expiration date
+
+=item payname
+
+Exact name on card (or bank name, for electronic checks)
+
+=item paystate
+
+For electronic checks, bank state
+
+=item paytype
+
+For electronic checks, account type (i.e. "Personal Savings", "Personal Checking", "Business Checking")A
+
+=item payip
+
+Optional IP address from which payment was submitted
+
+=back
+
+If there is an error, returns a hash reference with a single key, B<error>,
+otherwise returns a hash reference with a single key, B<custpaybynum>.
+
+=item update_payby HASHREF
+
+Updates stored payment information.  Takes a hash reference with the same
+keys as insert_payby, as well as B<custpaybynum> to specify which record
+to update.  All keys except B<session_id> and B<custpaybynum> are optional;
+if omitted, the previous values in the record will be preserved.
+
+If there is an error, returns a hash reference with a single key, B<error>,
+otherwise returns a hash reference with a single key, B<custpaybynum>.
+
+=item delete_payby HASHREF
+
+Removes stored payment information.  Takes a hash reference with two keys,
+B<session_id> and B<custpaybynum>.  Returns a hash reference with a single key,
+B<error>, which is an error message or empty for successful removal.
+
 =item cancel HASHREF
 
 Cancels this customer.
@@ -425,7 +807,21 @@ success or an error message on errors.
 
 Returns information that may be useful in displaying a payment page.
 
-Takes a hash reference as parameter with a single key: B<session_id>.
+Takes a hash reference as parameter with the following keys:
+
+=over 4
+
+=item session_id
+
+Required session ID
+
+=item payment_payby
+
+=item omit_cust_main_county
+
+Optional, pass a true value to omit cust_main_county data for performance.
+
+=back
 
 Returns a hash reference with the following keys:
 
@@ -704,6 +1100,46 @@ Blank if the service is not over limit, or the date the service exceeded its usa
 
 =back
 
+=item pkg_info
+
+Returns package information for package.
+
+Takes a hash reference as parameter with the following keys:
+
+=over 4
+
+=item session_id
+
+Session identifier
+
+=item pkgnum
+
+Package Number
+
+=back
+
+Returns a hash reference containing customer package information.  The hash reference contains the following keys:
+
+=over 4
+
+=item pkg_label
+
+Name of this package
+
+=item pkgpart
+
+Part package primary key
+
+=item classnum
+
+Package class number
+
+=item error
+
+error message if errror.
+
+=back
+
 =item list_svcs
 
 Returns service information for this customer.
@@ -796,6 +1232,10 @@ Number of total bytes gained by recharge
 
 Orders a package for this customer.
 
+If signup_server-realtime is set, bills the new package, attemps to collect
+payment and (for auto-payment customers) cancels the package if the payment is
+declined.
+
 Takes a hash reference as parameter with the following keys:
 
 =over 4
@@ -808,6 +1248,39 @@ Session identifier
 
 Package to order (see L<FS::part_pkg>).
 
+=item quantity
+
+Quantity for this package order (default 1).
+
+=item run_bill_events
+
+If true, runs billing events for the customer after ordering and billing the
+package (signup_server-realtime must be set).
+
+=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)
+
+(None of this is required at all if you are just ordering a package
+at the customer's existing default service location.)
+
+=item address1
+
+=item address2
+
+=item city
+
+=item county
+
+=item state
+
+=item zip
+
+=item country
+
 =item svcpart
 
 Service to order (see L<FS::part_svc>).
@@ -883,13 +1356,27 @@ 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.
+Fields used when provisioning an svc_pbx service:
 
-=item change_pkg
+=over 4
 
-Changes a package for this customer.
+=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.
+
+=item change_pkg
+
+Changes a package for this customer.
 
 Takes a hash reference as parameter with the following keys:
 
@@ -907,10 +1394,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
 
@@ -936,7 +1439,7 @@ following keys:
 =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>
+Specified as an integer UNIX timestamp.  Pass this value to the B<order_renew>
 function.
 
 =item bill_date_pretty
@@ -952,7 +1455,7 @@ Base amount which will be charged if renewed early as of this 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.
+Specified as an integer UNIX timestamp.
 
 =item renew_date_pretty
 
@@ -1013,11 +1516,446 @@ Session identifier
 
 pkgpart of package to cancel
 
+=item date
+
+Optional date, for future cancellation (expiration) instead of immediate
+cancellation.  Specified as an integer UNIX timestamp ("epoch time").
+
 =back
 
 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 reference 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 reference 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_pbx
+
+Provisions a customer PBX (svc_pbx).
+
+Takes a hash reference 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
+
+=item max_extensions
+
+=item max_simultaneous
+
+=item ip_addr
+
+=back
+
+=item provision_external
+
+Provisions an external service (svc_external).
+
+Takes a hash reference 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
+
+=head2 "MY ACCOUNT" CONTACT FUNCTIONS
+
+=over 4
+
+=item contact_passwd
+
+Changes the password for the currently-logged in contact.
+
+Takes a hash reference as parameter with the following keys:
+
+=over 4
+
+=item session_id
+
+=item new_password
+
+=back
+
+Returns a hash reference with a single parameter, B<error>, which contains an
+error message, or empty on success.
+
+=item list_contacts
+
+Takes a hash reference as parameter with a single key, B<session_id>.
+
+Returns a hash reference with two parameters: B<error>, which contains an error
+message, or empty on success, and B<contacts>, a list of contacts.
+
+B<contacts> is an array reference of hash references (i.e. an array of structs,
+ in XML-RPC).  Each hash reference (struct) has the following keys:
+
+=over 4
+
+=item contactnum
+
+=item class
+
+Contact class name (contact type).
+
+=item first
+
+First name
+
+=item last
+
+Last name
+
+=item title
+
+Position ("Director of Silly Walks"), NOT honorific ("Mr." or "Mrs.")
+
+=item emailaddress
+
+Comma-separated list of email addresses
+
+=item comment
+
+=item selfservice_access
+
+Y when enabled
+
+=back
+
+=item edit_contact
+
+Updates information for the currently-logged in contact, or (optionally) the
+specified contact.
+
+Takes a hash reference as parameter with the following keys:
+
+=over 4
+
+=item session_id
+
+=item contactnum
+
+If already logged in as a contact, this is optional.
+
+=item first
+
+=item last
+
+=item emailaddress
+
+=back
+
+Returns a hash reference with a single parameter, B<error>, which contains an
+error message, or empty on success.
+
+=item new_contact
+
+Creates a new contact.
+
+Takes a hash reference as parameter with the following keys:
+
+=over 4
+
+=item session_id
+
+=item first
+
+=item last
+
+=item emailaddress
+
+=item classnum
+
+Optional contact classnum (TODO: or name)
+
+=item comment
+
+=item selfservice_access
+
+Y to enable self-service access
+
+=item _password
+
+=back
+
+Returns a hash reference with a single parameter, B<error>, which contains an
+error message, or empty on success.
+
+=item delete_contact
+
+Deletes a contact.  (Note: Cannot at this time delete the currently-logged in
+contact.)
+
+Takes a hash reference as parameter with the following keys:
+
+=over 4
+
+=item session_id
+
+=item contactnum
+
+=back
+
+Returns a hash reference with a single parameter, B<error>, which contains an
+error message, or empty on success.
+
+=back
+
+=head2 "MY ACCOUNT" QUOTATION FUNCTIONS
+
+All of these functions require the user to be logged in, and the 'session_id'
+key to be included in the argument hashref.`
+
+=over 4
+
+=item list_quotations HASHREF
+
+Returns a hashref listing this customer's active self-service quotations.
+Contents are:
+
+=over 4
+
+=item quotations
+
+an arrayref containing an element for each quotation.
+
+=item quotationnum
+
+the primary key
+
+=item _date
+
+the date it was started
+
+=item num_pkgs
+
+the number of packages
+
+=item total_setup
+
+the sum of setup fees
+
+=item total_recur
+
+the sum of recurring charges
+
+=back
+
+=item quotation_new HASHREF
+
+Creates an empty quotation and returns a hashref containing 'quotationnum',
+the primary key of the new quotation.
+
+=item quotation_delete HASHREF
+
+Disables (does not really delete) a quotation. Takes the following arguments:
+
+=over 4
+
+=item session_id
+
+=item quotationnum - the quotation to delete
+
+=back
+
+Returns 'error' => a string, which will be empty on success.
+
+=item quotation_info HASHREF
+
+Returns total and detailed pricing information on a quotation.
+
+Takes the following arguments:
+
+=over 4
+
+=item session_id
+
+=item quotationnum - the quotation to return
+
+=back
+
+Returns a hashref containing:
+
+- total_setup, the total of setup fees (and their taxes)
+- total_recur, the total of all recurring charges (and their taxes)
+- sections, an arrayref containing an element for each quotation section.
+  - description, a line of text describing the group of charges
+  - subtotal, the total of charges in this group (if appropriate)
+  - detail_items, an arrayref of line items
+    - pkgnum, the reference number of the package
+    - description, the package name (or tax name)
+    - quantity
+    - amount, the amount charged
+    If the detail item represents a subtotal, it will instead contain:
+    - total_item: description of the subtotal
+    - total_amount: the subtotal amount
+
+
+=item quotation_print HASHREF
+
+Renders the quotation as HTML or PDF. Takes the following arguments:
+
+=over 4
+
+=item session_id
+
+=item quotationnum - the quotation to return
+
+=item format - 'html' or 'pdf'
+
+=back
+
+Returns a hashref containing 'document', the contents of the file.
+
+=item quotation_add_pkg HASHREF
+
+Adds a package to a quotation. Takes the following arguments:
+
+=over 4
+
+=item session_id
+
+=item pkgpart - the package to add
+
+=item quotationnum - the quotation to add it to
+
+=item quantity - the package quantity (defaults to 1)
+
+=item address1, address2, city, state, zip, country - address fields to set
+the service location
+
+=back
+
+Returns 'error' => a string, which will be empty on success.
+
+=item quotation_remove_pkg HASHREF
+
+Removes a package from a quotation. Takes the following arguments:
+
+=over 4
+
+=item session_id
+
+=item pkgnum - the primary key (quotationpkgnum) of the package to remove
+
+=item quotationnum - the quotation to remove it from
+
+=back
+
+Returns 'error' => a string, which will be empty on success.
+
+=item quotation_order HASHREF
+
+Converts the packages in a quotation into real packages. Takes the following
+arguments:
+
+Takes the following arguments:
+
+=over 4
+
+=item session_id
+
+=item quotationnum - the quotation to order
+
+=back
+
 =back
 
 =head1 SIGNUP FUNCTIONS
@@ -1123,6 +2061,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
@@ -1170,6 +2249,21 @@ State
 
 Zip or postal code
 
+=item ship_address1
+
+=item ship_address2
+
+=item ship_city
+
+=item ship_county
+
+=item ship_state
+
+=item ship_zip
+
+Optional shipping address fields.  If sending an optional shipping address,
+ship_address1, ship_city, ship_state and ship_zip are required.
+
 =item daytime
 
 Daytime phone number
@@ -1393,6 +2487,18 @@ END
   my $county_html = $script_html;
   if ( $countyflag ) {
     $county_html .= qq!<SELECT NAME="${prefix}county" onChange="$param->{'onchange'}">!;
+    foreach my $county ( 
+      sort keys %{ $cust_main_county{$param->{'selected_country'}}{$param->{'selected_state'}} }
+    ) {
+      my $text = $county || '(n/a)';
+      $county_html .= qq!<OPTION VALUE="$county"!.
+                      ($county eq $param->{'selected_county'} ? 
+                        ' SELECTED>' : 
+                        '>'
+                      ).
+                      $text.
+                      '</OPTION>';
+    }
     $county_html .= '</SELECT>';
   } else {
     $county_html .=
@@ -1404,7 +2510,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>';
 
@@ -1424,7 +2530,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 {
@@ -1741,8 +2847,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. '"'.