4 use vars qw( @ISA @EXPORT_OK );
12 $FS::svc_domain::whois_hack = 1;
13 $FS::svc_domain::whois_hack = 1;
15 @ISA = qw( Exporter );
16 @EXPORT_OK = qw( create_initial_data );
20 FS::Setup - Database setup
28 Currently this module simply provides a place to store common subroutines for
39 sub create_initial_data {
42 my $oldAutoCommit = $FS::UID::AutoCommit;
43 local $FS::UID::AutoCommit = 0;
44 $FS::UID::AutoCommit = 0;
49 populate_initial_data(%opt);
53 if ( $oldAutoCommit ) {
54 dbh->commit or die dbh->errstr;
59 sub populate_locales {
62 use Locale::SubCountry;
63 use FS::cust_main_county;
66 foreach my $country ( sort map uc($_), all_country_codes ) {
68 my $subcountry = eval { new Locale::SubCountry($country) };
69 my @states = $subcountry ? $subcountry->all_codes : undef;
71 if ( !scalar(@states) || ( scalar(@states)==1 && !defined($states[0]) ) ) {
73 my $cust_main_county = new FS::cust_main_county({
75 'country' => $country,
77 my $error = $cust_main_county->insert;
82 if ( $states[0] =~ /^(\d+|\w)$/ ) {
83 @states = map $subcountry->full_name($_), @states
86 foreach my $state ( @states ) {
88 my $cust_main_county = new FS::cust_main_county({
91 'country' => $country,
93 my $error = $cust_main_county->insert;
103 sub populate_initial_data {
106 my $data = initial_data(%opt);
108 foreach my $table ( keys %$data ) {
110 my $class = "FS::$table";
114 my @records = @{ $data->{$table} };
116 foreach my $record ( @records ) {
117 my $args = delete($record->{'_insert_args'}) || [];
118 my $object = $class->new( $record );
119 my $error = $object->insert( @$args );
120 die "error inserting record into $table: $error\n"
131 #tie my %hash, 'Tie::DxHash',
132 tie my %hash, 'Tie::IxHash',
135 'part_bill_event' => [
137 'event' => 'Batch card',
139 'eventcode' => '$cust_bill->batch_card();',
141 'plan' => 'batch-card',
144 'event' => 'Send invoice',
146 'eventcode' => '$cust_bill->send();',
151 'event' => 'Send invoice',
153 'eventcode' => '$cust_bill->send();',
158 'event' => 'Send invoice',
160 'eventcode' => '$cust_bill->send();',
166 #you must create a service definition. An example of a service definition
167 #would be a dial-up account or a domain. First, it is necessary to create a
168 #domain definition. Click on View/Edit service definitions and Add a new
169 #service definition with Table svc_domain (and no modifiers).
172 'svcdb' => 'svc_domain',
176 #Now that you have created your first service, you must create a package
177 #including this service which you can sell to customers. Zero, one, or many
178 #services are bundled into a package. Click on View/Edit package
179 #definitions and Add a new package definition which includes quantity 1 of
180 #the svc_domain service you created above.
182 { 'pkg' => 'System Domain',
183 'comment' => '(NOT FOR CUSTOMERS)',
187 'pkg_svc' => { 1 => 1 }, # XXX
188 'primary_svc' => 1, #XXX
197 #After you create your first package, then you must define who is able to
198 #sell that package by creating an agent type. An example of an agent type
199 #would be an internal sales representitive which sells regular and
200 #promotional packages, as opposed to an external sales representitive
201 #which would only sell regular packages of services. Click on View/Edit
202 #agent types and Add a new agent type.
204 { 'atype' => 'internal' },
207 #Allow this agent type to sell the package you created above.
209 { 'typenum' => 1, #XXX
214 #After creating a new agent type, you must create an agent. Click on
215 #View/Edit agents and Add a new agent.
217 { 'agent' => 'Internal',
218 'typenum' => 1, # XXX
222 #Set up at least one Advertising source. Advertising sources will help you
223 #keep track of how effective your advertising is, tracking where customers
224 #heard of your service offerings. You must create at least one advertising
225 #source. If you do not wish to use the referral functionality, simply
226 #create a single advertising source only. Click on View/Edit advertising
227 #sources and Add a new advertising source.
229 { 'referral' => 'Internal', },
232 #Click on New Customer and create a new customer for your system accounts
233 #with billing type Complimentary. Leave the First package dropdown set to
236 { 'agentnum' => 1, #XXX
239 'last' => 'Accounts',
240 'address1' => '1234 System Lane',
241 'city' => 'Systemtown',
246 'payinfo' => 'system', #or something
247 'paydate' => '1/2037',
251 #From the Customer View screen of the newly created customer, order the
252 #package you defined above.
254 { 'custnum' => 1, #XXX
259 #From the Package View screen of the newly created package, choose
260 #(Provision) to add the customer's service for this new package.
261 #Add your own domain.
263 { 'domain' => $opt{'domain'},
266 'action' => 'N', #pseudo-field
270 #Go back to View/Edit service definitions on the main menu, and Add a new
271 #service definition with Table svc_acct. Select your domain in the domsvc
272 #Modifier. Set Fixed to define a service locked-in to this domain, or
273 #Default to define a service which may select from among this domain and
274 #the customer's domains.
285 sub populate_msgcat {
287 use FS::Record qw(qsearch);
290 foreach my $del_msgcat ( qsearch('msgcat', {}) ) {
291 my $error = $del_msgcat->delete;
292 die $error if $error;
295 my %messages = msgcat_messages();
297 foreach my $msgcode ( keys %messages ) {
298 foreach my $locale ( keys %{$messages{$msgcode}} ) {
299 my $msgcat = new FS::msgcat( {
300 'msgcode' => $msgcode,
302 'msg' => $messages{$msgcode}{$locale},
304 my $error = $msgcat->insert;
305 die $error if $error;
311 sub msgcat_messages {
314 # 'en_US' => 'Message',
319 'passwords_dont_match' => {
320 'en_US' => "Passwords don't match",
324 'en_US' => 'Invalid credit card number',
327 'unknown_card_type' => {
328 'en_US' => 'Unknown card type',
335 'empty_password' => {
336 'en_US' => 'Empty password',
339 'no_access_number_selected' => {
340 'en_US' => 'No access number selected',
344 'en_US' => 'Illegal (text)',
345 #'en_US' => 'Only letters, numbers, spaces, and the following punctuation symbols are permitted: ! @ # $ % & ( ) - + ; : \' " , . ? / in field',
348 'illegal_or_empty_text' => {
349 'en_US' => 'Illegal or empty (text)',
350 #'en_US' => 'Only letters, numbers, spaces, and the following punctuation symbols are permitted: ! @ # $ % & ( ) - + ; : \' " , . ? / in required field',
353 'illegal_username' => {
354 'en_US' => 'Illegal username',
357 'illegal_password' => {
358 'en_US' => 'Illegal password (',
361 'illegal_password_characters' => {
362 'en_US' => ' characters)',
365 'username_in_use' => {
366 'en_US' => 'Username in use',
369 'illegal_email_invoice_address' => {
370 'en_US' => 'Illegal email invoice address',
374 'en_US' => 'Illegal (name)',
375 #'en_US' => 'Only letters, numbers, spaces and the following punctuation symbols are permitted: , . - \' in field',
379 'en_US' => 'Illegal (phone)',
384 'en_US' => 'Illegal (zip)',
389 'en_US' => 'Expired card',
393 'en_US' => 'Day Phone',
397 'en_US' => 'Night Phone',
400 'svc_external-id' => {
401 'en_US' => 'External ID',
404 'svc_external-title' => {