package FS::SelfService;
use strict;
-use vars qw($VERSION @ISA @EXPORT_OK $dir $socket %autoload $tag);
+use vars qw( $VERSION @ISA @EXPORT_OK $DEBUG
+ $skip_uid_check $dir $socket %autoload $tag );
use Exporter;
use Socket;
use FileHandle;
@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' => 'MyAccount/login',
- 'logout' => 'MyAccount/logout',
- 'customer_info' => 'MyAccount/customer_info',
- 'edit_info' => 'MyAccount/edit_info', #add to ss cgi!
- 'invoice' => 'MyAccount/invoice',
- 'list_invoices' => 'MyAccount/list_invoices', #?
- 'cancel' => 'MyAccount/cancel', #add to ss cgi!
- 'payment_info' => 'MyAccount/payment_info',
- 'process_payment' => 'MyAccount/process_payment',
- 'process_prepay' => 'MyAccount/process_prepay',
- 'list_pkgs' => 'MyAccount/list_pkgs', #add to ss cgi!
- 'order_pkg' => 'MyAccount/order_pkg', #add to ss cgi!
- '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',
- 'signup_info' => 'Signup/signup_info',
- 'new_customer' => 'Signup/new_customer',
- 'agent_login' => 'Agent/agent_login',
- 'agent_logout' => 'Agent/agent_logout',
- 'agent_info' => 'Agent/agent_info',
- 'agent_list_customers' => 'Agent/agent_list_customers',
+ '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!
+ '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',
+ 'create_ticket' => 'MyAccount/create_ticket',
+ 'get_ticket' => 'MyAccount/get_ticket',
+ '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',
+ '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',
+ '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',
+ #izoom
+ #'bulk_processrow' => 'Bulk/processrow',
+ #conflicts w/Agent one# '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
+ )
);
-@EXPORT_OK = ( keys(%autoload), qw( regionselector expselect popselector ) );
$ENV{'PATH'} ='/usr/bin:/usr/ucb:/bin';
$ENV{'SHELL'} = '/bin/sh';
$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;
+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!";
if ( ref($_[0]) ) {
$param = shift;
} else {
+ #warn scalar(@_). ": ". join(" / ", @_);
$param = { @_ };
}
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: $!";
# 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;
}
'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,
- 'agentnum' => $agentnum,
+ #OR
+ 'countrycode' => 1,
+ 'phonenum' => $phonenum,
+ 'pin' => $pin,
}
);
=item username
+Username
+
=item domain
+Domain
+
=item password
+Password
+
=back
Returns a hash reference with the following keys:
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
+=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 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.
Hash reference of card types; keys are card types, values are the exact strings
passed to the process_payment function
-=item paybatch
+=cut
-Unique transaction identifier (prevents multiple charges), passed to the
-process_payment function
+#this doesn't actually work yet
+#
+#=item paybatch
+#
+#Unique transaction identifier (prevents multiple charges), passed to the
+#process_payment function
=back
=item session_id
+Session identifier
+
+=item amount
+
+Amount
+
=item save
If true, address and card information entered will be saved for subsequent
=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
Card expiration year
-=item paybatch
+=cut
-Unique transaction identifier, returned from the payment_info function.
-Prevents multiple charges.
+#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
+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.
+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>
=over 4
+=item custnum
+
+Customer number
+
+=item error
+
+Empty on success, or an error message on errors.
=item cust_pkg HASHREF
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.
-=item all fields of part_pkg (XXXpare this down to a secure subset)
+=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
-=item part_svc - An array of hash references, each of which has the following keys:
+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 all fields of part_svc (XXXpare this down to a secure subset)
+=item part_svc fields
-=item avail
+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 error
+=item cust_svc
-Empty on success, or an error message on errors.
+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 session_id
+Session identifier
+
=item pkgpart
+Package to order (see L<FS::part_pkg>).
+
=item svcpart
-optional svcpart, required only if the package definition does not contain
-one svc_acct service definition with quantity 1 (it may contain others with
-quantity >1)
+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.
=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
=over 4
-=item CARD (credit card - automatic)
+=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
-=item DCRD (credit card - on-demand - version 1.5+ only)
+Phone bill billing
-=item CHEK (electronic check - automatic)
+=item BILL
-=item DCHK (electronic check - on-demand - version 1.5+ only)
+billing, not recommended for signups
-=item LECB (Phone bill billing)
+=item COMP
-=item BILL (billing, not recommended for signups)
+free, definitely not recommended for signups
-=item COMP (free, definately not recommended for signups)
+=item PREPAY
-=item PREPAY (special billing type: applies a credit (see FS::prepay_credit) and sets billing type to BILL)
+special billing type: applies a credit (see FS::prepay_credit) and sets billing type to BILL
=back
=over 4
-=item first - first name (required)
+=item first
-=item last - last name (required)
+first name (required)
-=item ss (not typically collected; mostly used for ACH transactions)
+=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)
-=item daytime - phone
+Zip or postal code
+
+=item daytime
+
+Daytime phone number
+
+=item night
+
+Evening phone number
-=item night - phone
+=item fax
-=item fax - phone
+Fax number
-=item payby - CARD, DCRD, CHEK, DCHK, LECB, BILL, COMP or PREPAY (see L</signup_info> (required)
+=item payby
+
+CARD, DCRD, CHEK, DCHK, LECB, BILL, COMP or PREPAY (see L</signup_info> (required)
+
+=item payinfo
-=item payinfo - Card number for CARD/DCRD, account_number@aba_number for CHEK/DCHK, prepaid "pin" for PREPAY, purchase order number for BILL
+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 paycvv
-=item paydate - Expiration date for CARD/DCRD
+Credit card CVV2 number (1.5+ or 1.4.2 with CVV schema patch)
-=item payname - Exact name on credit card for CARD/DCRD, bank name for CHEK/DCHK
+=item paydate
+
+Expiration date for CARD/DCRD
+
+=item payname
-=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),
+Exact name on credit card for CARD/DCRD, bank name for CHEK/DCHK
-=item referral_custnum - referring customer number
+=item invoicing_list
-=item pkgpart - pkgpart of initial package
+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
-=item sec_phrase - security phrase
+Password
+
+=item sec_phrase
+
+Security phrase
+
+=item popnum
-=item popnum - access number (index, not the literal number)
+Access number (index, not the literal number)
-=item agentnum - agent 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
=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 Sysadmin | View/Edit message catalog)
+=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 selected_county
+Currently selected county
+
=item selected_state
+Currently selected state
+
=item selected_country
-=item prefix - Specify a unique prefix string if you intend to use the HTML output multiple time son one page.
+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
-=item onchange - Specify a javascript subroutine to call on changes
+Specify a javascript subroutine to call on changes
=item default_state
+Default state
+
=item 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>.
+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
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 .=
}
$state_html .= '</SELECT>';
- $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]. '">';
- my $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>';
($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:
}
my $return = qq!<SELECT NAME="$prefix!. qq!_month" SIZE="1">!;
for ( 1 .. 12 ) {
- $return .= "<OPTION";
+ $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) .. 2037 ) {
- $return .= "<OPTION";
+ for ( ($thisYear > $y && $y > 0 ? $y : $thisYear) .. ($thisYear+10) ) {
+ $return .= qq!<OPTION VALUE="$_"!;
$return .= " SELECTED" if $_ == $y;
$return .= ">$_";
}
=item popnum
-=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>.
+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
$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!;
}
+=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 additonal I<custnum> parameter.
+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