summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FS/FS/Setup.pm422
-rwxr-xr-xFS/bin/freeside-setup73
-rwxr-xr-xbin/populate-msgcat135
-rwxr-xr-xhttemplate/docs/admin.html45
-rw-r--r--httemplate/docs/install.html11
5 files changed, 434 insertions, 252 deletions
diff --git a/FS/FS/Setup.pm b/FS/FS/Setup.pm
new file mode 100644
index 000000000..8e89be5eb
--- /dev/null
+++ b/FS/FS/Setup.pm
@@ -0,0 +1,422 @@
+package FS::Setup;
+
+use strict;
+use vars qw( @ISA @EXPORT_OK );
+use Exporter;
+#use Tie::DxHash;
+use Tie::IxHash;
+use FS::UID qw( dbh );
+use FS::Record;
+
+use FS::svc_domain;
+$FS::svc_domain::whois_hack = 1;
+$FS::svc_domain::whois_hack = 1;
+
+@ISA = qw( Exporter );
+@EXPORT_OK = qw( create_initial_data );
+
+=head1 NAME
+
+FS::Setup - Database setup
+
+=head1 SYNOPSIS
+
+ use FS::Setup;
+
+=head1 DESCRIPTION
+
+Currently this module simply provides a place to store common subroutines for
+database setup.
+
+=head1 SUBROUTINES
+
+=over 4
+
+=item
+
+=cut
+
+sub create_initial_data {
+ my %opt = @_;
+
+ my $oldAutoCommit = $FS::UID::AutoCommit;
+ local $FS::UID::AutoCommit = 0;
+ $FS::UID::AutoCommit = 0;
+
+ populate_locales();
+
+ #initial_data data
+ populate_initial_data(%opt);
+
+ populate_msgcat();
+
+ if ( $oldAutoCommit ) {
+ dbh->commit or die dbh->errstr;
+ }
+
+}
+
+sub populate_locales {
+
+ use Locale::Country;
+ use Locale::SubCountry;
+ use FS::cust_main_county;
+
+ #cust_main_county
+ foreach my $country ( sort map uc($_), all_country_codes ) {
+
+ my $subcountry = eval { new Locale::SubCountry($country) };
+ my @states = $subcountry ? $subcountry->all_codes : undef;
+
+ if ( !scalar(@states) || ( scalar(@states)==1 && !defined($states[0]) ) ) {
+
+ my $cust_main_county = new FS::cust_main_county({
+ 'tax' => 0,
+ 'country' => $country,
+ });
+ my $error = $cust_main_county->insert;
+ die $error if $error;
+
+ } else {
+
+ if ( $states[0] =~ /^(\d+|\w)$/ ) {
+ @states = map $subcountry->full_name($_), @states
+ }
+
+ foreach my $state ( @states ) {
+
+ my $cust_main_county = new FS::cust_main_county({
+ 'state' => $state,
+ 'tax' => 0,
+ 'country' => $country,
+ });
+ my $error = $cust_main_county->insert;
+ die $error if $error;
+
+ }
+
+ }
+ }
+
+}
+
+sub populate_initial_data {
+ my %opt = @_;
+
+ my $data = initial_data(%opt);
+
+ foreach my $table ( keys %$data ) {
+
+ my $class = "FS::$table";
+ eval "use $class;";
+ die $@ if $@;
+
+ my @records = @{ $data->{$table} };
+
+ foreach my $record ( @records ) {
+ my $args = delete($record->{'_insert_args'}) || [];
+ my $object = $class->new( $record );
+ my $error = $object->insert( @$args );
+ die "error inserting record into $table: $error\n"
+ if $error;
+ }
+
+ }
+
+}
+
+sub initial_data {
+ my %opt = @_;
+
+ #tie my %hash, 'Tie::DxHash',
+ tie my %hash, 'Tie::IxHash',
+
+ #billing events
+ 'part_bill_event' => [
+ { 'payby' => 'CARD',
+ 'event' => 'Batch card',
+ 'seconds' => 0,
+ 'eventcode' => '$cust_bill->batch_card();',
+ 'weight' => 40,
+ 'plan' => 'batch-card',
+ },
+ { 'payby' => 'BILL',
+ 'event' => 'Send invoice',
+ 'seconds' => 0,
+ 'eventcode' => '$cust_bill->send();',
+ 'weight' => 50,
+ 'plan' => 'send',
+ },
+ { 'payby' => 'DCRD',
+ 'event' => 'Send invoice',
+ 'seconds' => 0,
+ 'eventcode' => '$cust_bill->send();',
+ 'weight' => 50,
+ 'plan' => 'send',
+ },
+ { 'payby' => 'DCHK',
+ 'event' => 'Send invoice',
+ 'seconds' => 0,
+ 'eventcode' => '$cust_bill->send();',
+ 'weight' => 50,
+ 'plan' => 'send',
+ },
+ ],
+
+ #you must create a service definition. An example of a service definition
+ #would be a dial-up account or a domain. First, it is necessary to create a
+ #domain definition. Click on View/Edit service definitions and Add a new
+ #service definition with Table svc_domain (and no modifiers).
+ 'part_svc' => [
+ { 'svc' => 'Domain',
+ 'svcdb' => 'svc_domain',
+ }
+ ],
+
+ #Now that you have created your first service, you must create a package
+ #including this service which you can sell to customers. Zero, one, or many
+ #services are bundled into a package. Click on View/Edit package
+ #definitions and Add a new package definition which includes quantity 1 of
+ #the svc_domain service you created above.
+ 'part_pkg' => [
+ { 'pkg' => 'System Domain',
+ 'comment' => '(NOT FOR CUSTOMERS)',
+ 'freq' => '0',
+ 'plan' => 'flat',
+ '_insert_args' => [
+ 'pkg_svc' => { 1 => 1 }, # XXX
+ 'primary_svc' => 1, #XXX
+ 'options' => {
+ 'setup_fee' => '0',
+ 'recur_fee' => '0',
+ },
+ ],
+ },
+ ],
+
+ #After you create your first package, then you must define who is able to
+ #sell that package by creating an agent type. An example of an agent type
+ #would be an internal sales representitive which sells regular and
+ #promotional packages, as opposed to an external sales representitive
+ #which would only sell regular packages of services. Click on View/Edit
+ #agent types and Add a new agent type.
+ 'agent_type' => [
+ { 'atype' => 'internal' },
+ ],
+
+ #Allow this agent type to sell the package you created above.
+ 'type_pkgs' => [
+ { 'typenum' => 1, #XXX
+ 'pkgpart' => 1, #XXX
+ },
+ ],
+
+ #After creating a new agent type, you must create an agent. Click on
+ #View/Edit agents and Add a new agent.
+ 'agent' => [
+ { 'agent' => 'Internal',
+ 'typenum' => 1, # XXX
+ },
+ ],
+
+ #Set up at least one Advertising source. Advertising sources will help you
+ #keep track of how effective your advertising is, tracking where customers
+ #heard of your service offerings. You must create at least one advertising
+ #source. If you do not wish to use the referral functionality, simply
+ #create a single advertising source only. Click on View/Edit advertising
+ #sources and Add a new advertising source.
+ 'part_referral' => [
+ { 'referral' => 'Internal', },
+ ],
+
+ #Click on New Customer and create a new customer for your system accounts
+ #with billing type Complimentary. Leave the First package dropdown set to
+ #(none).
+ 'cust_main' => [
+ { 'agentnum' => 1, #XXX
+ 'refnum' => 1, #XXX
+ 'first' => 'System',
+ 'last' => 'Accounts',
+ 'address1' => '1234 System Lane',
+ 'city' => 'Systemtown',
+ 'state' => 'CA',
+ 'zip' => '54321',
+ 'country' => 'US',
+ 'payby' => 'COMP',
+ 'payinfo' => 'system', #or something
+ 'paydate' => '1/2037',
+ },
+ ],
+
+ #From the Customer View screen of the newly created customer, order the
+ #package you defined above.
+ 'cust_pkg' => [
+ { 'custnum' => 1, #XXX
+ 'pkgpart' => 1, #XXX
+ },
+ ],
+
+ #From the Package View screen of the newly created package, choose
+ #(Provision) to add the customer's service for this new package.
+ #Add your own domain.
+ 'svc_domain' => [
+ { 'domain' => $opt{'domain'},
+ 'pkgnum' => 1, #XXX
+ 'svcpart' => 1, #XXX
+ 'action' => 'N', #pseudo-field
+ },
+ ],
+
+ #Go back to View/Edit service definitions on the main menu, and Add a new
+ #service definition with Table svc_acct. Select your domain in the domsvc
+ #Modifier. Set Fixed to define a service locked-in to this domain, or
+ #Default to define a service which may select from among this domain and
+ #the customer's domains.
+
+ #not yet....
+
+ #)
+ ;
+
+ \%hash;
+
+}
+
+sub populate_msgcat {
+
+ use FS::Record qw(qsearch);
+ use FS::msgcat;
+
+ foreach my $del_msgcat ( qsearch('msgcat', {}) ) {
+ my $error = $del_msgcat->delete;
+ die $error if $error;
+ }
+
+ my %messages = msgcat_messages();
+
+ foreach my $msgcode ( keys %messages ) {
+ foreach my $locale ( keys %{$messages{$msgcode}} ) {
+ my $msgcat = new FS::msgcat( {
+ 'msgcode' => $msgcode,
+ 'locale' => $locale,
+ 'msg' => $messages{$msgcode}{$locale},
+ });
+ my $error = $msgcat->insert;
+ die $error if $error;
+ }
+ }
+
+}
+
+sub msgcat_messages {
+
+ # 'msgcode' => {
+ # 'en_US' => 'Message',
+ # },
+
+ (
+
+ 'passwords_dont_match' => {
+ 'en_US' => "Passwords don't match",
+ },
+
+ 'invalid_card' => {
+ 'en_US' => 'Invalid credit card number',
+ },
+
+ 'unknown_card_type' => {
+ 'en_US' => 'Unknown card type',
+ },
+
+ 'not_a' => {
+ 'en_US' => 'Not a ',
+ },
+
+ 'empty_password' => {
+ 'en_US' => 'Empty password',
+ },
+
+ 'no_access_number_selected' => {
+ 'en_US' => 'No access number selected',
+ },
+
+ 'illegal_text' => {
+ 'en_US' => 'Illegal (text)',
+ #'en_US' => 'Only letters, numbers, spaces, and the following punctuation symbols are permitted: ! @ # $ % & ( ) - + ; : \' " , . ? / in field',
+ },
+
+ 'illegal_or_empty_text' => {
+ 'en_US' => 'Illegal or empty (text)',
+ #'en_US' => 'Only letters, numbers, spaces, and the following punctuation symbols are permitted: ! @ # $ % & ( ) - + ; : \' " , . ? / in required field',
+ },
+
+ 'illegal_username' => {
+ 'en_US' => 'Illegal username',
+ },
+
+ 'illegal_password' => {
+ 'en_US' => 'Illegal password (',
+ },
+
+ 'illegal_password_characters' => {
+ 'en_US' => ' characters)',
+ },
+
+ 'username_in_use' => {
+ 'en_US' => 'Username in use',
+ },
+
+ 'illegal_email_invoice_address' => {
+ 'en_US' => 'Illegal email invoice address',
+ },
+
+ 'illegal_name' => {
+ 'en_US' => 'Illegal (name)',
+ #'en_US' => 'Only letters, numbers, spaces and the following punctuation symbols are permitted: , . - \' in field',
+ },
+
+ 'illegal_phone' => {
+ 'en_US' => 'Illegal (phone)',
+ #'en_US' => '',
+ },
+
+ 'illegal_zip' => {
+ 'en_US' => 'Illegal (zip)',
+ #'en_US' => '',
+ },
+
+ 'expired_card' => {
+ 'en_US' => 'Expired card',
+ },
+
+ 'daytime' => {
+ 'en_US' => 'Day Phone',
+ },
+
+ 'night' => {
+ 'en_US' => 'Night Phone',
+ },
+
+ 'svc_external-id' => {
+ 'en_US' => 'External ID',
+ },
+
+ 'svc_external-title' => {
+ 'en_US' => 'Title',
+ },
+
+ );
+}
+
+=back
+
+=head1 BUGS
+
+Sure.
+
+=head1 SEE ALSO
+
+=cut
+
+1;
+
diff --git a/FS/bin/freeside-setup b/FS/bin/freeside-setup
index a16e51749..bff2bcc63 100755
--- a/FS/bin/freeside-setup
+++ b/FS/bin/freeside-setup
@@ -4,23 +4,20 @@
BEGIN { $FS::Schema::setup_hack = 1; }
use strict;
-use vars qw($opt_s);
+use vars qw($opt_s $opt_d $opt_v);
use Getopt::Std;
-use Locale::Country;
-use Locale::SubCountry;
use FS::UID qw(adminsuidsetup datasrc checkeuid getsecrets);
use FS::Schema qw( dbdef_dist reload_dbdef );
use FS::Record;
-use FS::cust_main_county;
#use FS::raddb;
-use FS::part_bill_event;
+use FS::Setup qw(create_initial_data);
die "Not running uid freeside!" unless checkeuid();
#my %attrib2db =
# map { lc($FS::raddb::attrib{$_}) => $_ } keys %FS::raddb::attrib;
-getopts("s");
+getopts("svd:");
my $user = shift or die &usage;
getsecrets($user);
@@ -94,6 +91,7 @@ my $dbh = adminsuidsetup $user;
$|=1;
foreach my $statement ( $dbdef->sql($dbh) ) {
+ warn $statement if $statement =~ /TABLE cdr/;
$dbh->do( $statement )
or die "CREATE error: ". $dbh->errstr. "\ndoing statement: $statement";
}
@@ -104,69 +102,14 @@ dbdef_create($dbh, $dbdef_file);
delete $FS::Schema::dbdef_cache{$dbdef_file}; #force an actual reload
reload_dbdef($dbdef_file);
-#cust_main_county
-foreach my $country ( sort map uc($_), all_country_codes ) {
+create_initial_data('domain' => $opt_d);
- my $subcountry = eval { new Locale::SubCountry($country) };
- my @states = $subcountry ? $subcountry->all_codes : undef;
-
- if ( !scalar(@states) || ( scalar(@states) == 1 && !defined($states[0]) ) ) {
-
- my $cust_main_county = new FS::cust_main_county({
- 'tax' => 0,
- 'country' => $country,
- });
- my $error = $cust_main_county->insert;
- die $error if $error;
-
- } else {
-
- if ( $states[0] =~ /^(\d+|\w)$/ ) {
- @states = map $subcountry->full_name($_), @states
- }
-
- foreach my $state ( @states ) {
-
- my $cust_main_county = new FS::cust_main_county({
- 'state' => $state,
- 'tax' => 0,
- 'country' => $country,
- });
- my $error = $cust_main_county->insert;
- die $error if $error;
-
- }
-
- }
-}
-
-#billing events
-foreach my $aref (
- #[ 'COMP', 'Comp invoice', '$cust_bill->comp();', 30, 'comp' ],
- [ 'CARD', 'Batch card', '$cust_bill->batch_card();', 40, 'batch-card' ],
- [ 'BILL', 'Send invoice', '$cust_bill->send();', 50, 'send' ],
- [ 'DCRD', 'Send invoice', '$cust_bill->send();', 50, 'send' ],
- [ 'DCHK', 'Send invoice', '$cust_bill->send();', 50, 'send' ],
-) {
-
- my $part_bill_event = new FS::part_bill_event({
- 'payby' => $aref->[0],
- 'event' => $aref->[1],
- 'eventcode' => $aref->[2],
- 'seconds' => 0,
- 'weight' => $aref->[3],
- 'plan' => $aref->[4],
- });
- my($error);
- $error=$part_bill_event->insert;
- die $error if $error;
-
-}
+warn "Freeside database initialized - commiting transaction\n" if $opt_v;
$dbh->commit or die $dbh->errstr;
$dbh->disconnect or die $dbh->errstr;
-#print "Freeside database initialized sucessfully\n";
+warn "Database initialization committed sucessfully\n" if $opt_v;
sub dbdef_create { # reverse engineer the schema from the DB and save to file
my( $dbh, $file ) = @_;
@@ -175,7 +118,7 @@ sub dbdef_create { # reverse engineer the schema from the DB and save to file
}
sub usage {
- die "Usage:\n freeside-setup user\n";
+ die "Usage:\n freeside-setup -d domain.name [ -v ] user\n";
}
1;
diff --git a/bin/populate-msgcat b/bin/populate-msgcat
deleted file mode 100755
index adac92dd0..000000000
--- a/bin/populate-msgcat
+++ /dev/null
@@ -1,135 +0,0 @@
-#!/usr/bin/perl -Tw
-
-use strict;
-use FS::UID qw(adminsuidsetup);
-use FS::Record qw(qsearch);
-use FS::msgcat;
-
-my $user = shift or die &usage;
-adminsuidsetup $user;
-
-foreach my $del_msgcat ( qsearch('msgcat', {}) ) {
- my $error = $del_msgcat->delete;
- die $error if $error;
-}
-
-my %messages = messages();
-
-foreach my $msgcode ( keys %messages ) {
- foreach my $locale ( keys %{$messages{$msgcode}} ) {
- my $msgcat = new FS::msgcat( {
- 'msgcode' => $msgcode,
- 'locale' => $locale,
- 'msg' => $messages{$msgcode}{$locale},
- });
- my $error = $msgcat->insert;
- die $error if $error;
- }
-}
-
-#print "Message catalog initialized sucessfully\n";
-
-sub messages {
-
- # 'msgcode' => {
- # 'en_US' => 'Message',
- # },
-
- (
-
- 'passwords_dont_match' => {
- 'en_US' => "Passwords don't match",
- },
-
- 'invalid_card' => {
- 'en_US' => 'Invalid credit card number',
- },
-
- 'unknown_card_type' => {
- 'en_US' => 'Unknown card type',
- },
-
- 'not_a' => {
- 'en_US' => 'Not a ',
- },
-
- 'empty_password' => {
- 'en_US' => 'Empty password',
- },
-
- 'no_access_number_selected' => {
- 'en_US' => 'No access number selected',
- },
-
- 'illegal_text' => {
- 'en_US' => 'Illegal (text)',
- #'en_US' => 'Only letters, numbers, spaces, and the following punctuation symbols are permitted: ! @ # $ % & ( ) - + ; : \' " , . ? / in field',
- },
-
- 'illegal_or_empty_text' => {
- 'en_US' => 'Illegal or empty (text)',
- #'en_US' => 'Only letters, numbers, spaces, and the following punctuation symbols are permitted: ! @ # $ % & ( ) - + ; : \' " , . ? / in required field',
- },
-
- 'illegal_username' => {
- 'en_US' => 'Illegal username',
- },
-
- 'illegal_password' => {
- 'en_US' => 'Illegal password (',
- },
-
- 'illegal_password_characters' => {
- 'en_US' => ' characters)',
- },
-
- 'username_in_use' => {
- 'en_US' => 'Username in use',
- },
-
- 'illegal_email_invoice_address' => {
- 'en_US' => 'Illegal email invoice address',
- },
-
- 'illegal_name' => {
- 'en_US' => 'Illegal (name)',
- #'en_US' => 'Only letters, numbers, spaces and the following punctuation symbols are permitted: , . - \' in field',
- },
-
- 'illegal_phone' => {
- 'en_US' => 'Illegal (phone)',
- #'en_US' => '',
- },
-
- 'illegal_zip' => {
- 'en_US' => 'Illegal (zip)',
- #'en_US' => '',
- },
-
- 'expired_card' => {
- 'en_US' => 'Expired card',
- },
-
- 'daytime' => {
- 'en_US' => 'Day Phone',
- },
-
- 'night' => {
- 'en_US' => 'Night Phone',
- },
-
- 'svc_external-id' => {
- 'en_US' => 'External ID',
- },
-
- 'svc_external-title' => {
- 'en_US' => 'Title',
- },
-
- );
-}
-
-sub usage {
- die "Usage:\n\n populate-msgcat user\n";
-}
-
diff --git a/httemplate/docs/admin.html b/httemplate/docs/admin.html
index 9ce259c2b..2aa934812 100755
--- a/httemplate/docs/admin.html
+++ b/httemplate/docs/admin.html
@@ -11,49 +11,8 @@
/home/httpd/html, open https://your_host/freeside/. Replace
"your_host" with the name or network address of your web server.
<li>Select <u>Configuration</u> from the main menu and update your configuration values.
- <li>Next you must create a service definition. An example of a service
- definition would be a dial-up account or a domain. First, it is
- necessary to create a domain definition. Click on <u>View/Edit service
- definitions</u> and <u>Add a new service definition</u> with <i>Table</i>
- <b>svc_domain</b> (and no modifiers).
- <li>Now that you have created your first service, you must create a package
- including this service which you can sell to customers. Zero, one, or many
- services are bundled into a package. Click on <u>View/Edit package
- definitions</u> and <u>Add a new package definition</u> which includes
- quantity <b>1</b> of the svc_domain service you created above.
-
- <li>After you create your first package, then you must define who is
- able to sell that package by creating an agent type. An example of
- an agent type would be an internal sales representitive which sells
- regular and promotional packages, as opposed to an external sales
- representitive which would only sell regular packages of services. Click on
- <u>View/Edit agent types</u> and <u>Add a new agent type</u>. Allow this
- agent type to sell the package you created above.
-
- <li>After creating a new agent type, you must create an agent. Click on
- <u>View/Edit agents</u> and <u>Add a new agent</u>.
-
- <li>Set up at least one Advertising source. Advertising sources will help
- you keep track of how effective your advertising is, tracking where customers
- heard of your service offerings. You must create at least one advertising
- source. If you do not wish to use the referral functionality, simply create
- a single advertising source only. Click on <u>View/Edit advertising
- sources</u> and <u>Add a new advertising source</u>.
-
- <li>Click on <u>New Customer</u> and create a new customer for your system
- accounts with billing type <b>Complimentary</b>. Leave the <i>First
- package</i> dropdown set to <b>(none)</b>.
-
- <li>From the Customer View screen of the newly created customer, order the
- package you defined above.
-
- <li>From the Package View screen of the newly created package, choose
- <u>(Provision)</u> to add the customer's service for this new package.
-
- <li>Add your own domain.
-
- <li>Go back to <u>View/Edit service definitions</u> on the main menu, and
+ <li>Go to <u>View/Edit service definitions</u> on the main menu, and
<u>Add a new service definition</u> with <i>Table</i> <b>svc_acct</b>.
Select your domain in the <b>domsvc</b> Modifier. Set <b>Fixed</b> to define
a service locked-in to this domain, or <b>Default</b> to define a service
@@ -69,7 +28,7 @@
<li>If you are using Freeside to keep track of sales taxes, define tax
information for your locales by clicking on the <u>View/Edit locales and tax
- rates</b> on the main menu.
+ rates</u> on the main menu.
<li>If you would like Freeside to notify your customers when their credit
cards and other billing arrangements are about to expire, arrange for
diff --git a/httemplate/docs/install.html b/httemplate/docs/install.html
index 1f80db1a7..02572759e 100644
--- a/httemplate/docs/install.html
+++ b/httemplate/docs/install.html
@@ -196,17 +196,10 @@ require valid-user
<pre>$ su
# <a href="man/bin/freeside-adduser.html">freeside-adduser</a> fs_queue
# <a href="man/bin/freeside-adduser.html">freeside-adduser</a> fs_selfservice</pre>
- <li>As the freeside UNIX user, run <tt>freeside-setup <b>username</b></tt> to create the database tables, passing the username of a Freeside user you created above:
+ <li>As the freeside UNIX user, run <tt>freeside-setup -d <b>domain.name</b> <b>username</b></tt> to create the database tables and initial data, passing the username of a Freeside user you created above:
<pre>
$ su freeside
-$ freeside-setup <b>username</b>
-</pre>
- Alternately, use the -s option to enable shipping addresses: <tt>freeside-setup -s <b>username</b></tt>
- <li>As the freeside UNIX user, run <tt>bin/populate-msgcat <b>username</b></tt> (in the untar'ed freeside directory) to populate the message catalog, passing the username of a Freeside user you created above:
-<pre>
-$ su freeside
-$ cd <b>/path/to/freeside/</b>
-$ bin/populate-msgcat <b>username</b>
+$ freeside-setup -d </b>example.com</b> <b>username</b>
</pre>
<li><tt>freeside-queued</tt> was installed with the Perl modules. Start it now and ensure that is run upon system startup (Do this manually, or edit the top-level Makefile, replacing INIT_FILE with the appropriate location on your systemand QUEUED_USER with the username of a Freeside user you created above, and run <tt>make install-init</tt>)
<li>Now proceed to the initial <a href="admin.html">administration</a> of your installation.