From: ivan Date: Thu, 16 Feb 2006 21:43:02 +0000 (+0000) Subject: automate more of the initial data adding... X-Git-Tag: BEFORE_FINAL_MASONIZE~212 X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=commitdiff_plain;h=a2b0b3e8500b08a5cf017c85693d9649853f8569 automate more of the initial data adding... --- 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.
  • Select Configuration from the main menu and update your configuration values. -
  • 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 View/Edit service - definitions and Add a new service definition with Table - svc_domain (and no modifiers). -
  • 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. - -
  • 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. Allow this - agent type to sell the package you created above. - -
  • After creating a new agent type, you must create an agent. Click on - View/Edit agents and Add a new agent. - -
  • 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. - -
  • 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). - -
  • From the Customer View screen of the newly created customer, order the - package you defined above. - -
  • 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. - -
  • Go back to View/Edit service definitions on the main menu, and +
  • Go 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 @@ -69,7 +28,7 @@
  • If you are using Freeside to keep track of sales taxes, define tax information for your locales by clicking on the View/Edit locales and tax - rates on the main menu. + rates on the main menu.
  • 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
    $ su
     # freeside-adduser fs_queue
     # freeside-adduser fs_selfservice
    -
  • As the freeside UNIX user, run freeside-setup username to create the database tables, passing the username of a Freeside user you created above: +
  • As the freeside UNIX user, run freeside-setup -d domain.name username to create the database tables and initial data, passing the username of a Freeside user you created above:
     $ su freeside
    -$ freeside-setup username
    -
    - Alternately, use the -s option to enable shipping addresses: freeside-setup -s username -
  • As the freeside UNIX user, run bin/populate-msgcat username (in the untar'ed freeside directory) to populate the message catalog, passing the username of a Freeside user you created above: -
    -$ su freeside
    -$ cd /path/to/freeside/
    -$ bin/populate-msgcat username
    +$ freeside-setup -d example.com username
     
  • freeside-queued 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 make install-init)
  • Now proceed to the initial administration of your installation.