fix big in RADIUS session viewing when using an ignored-accounting export
[freeside.git] / FS / bin / freeside-setup
1 #!/usr/bin/perl -Tw
2
3 #to delay loading dbdef until we're ready
4 BEGIN { $FS::Record::setup_hack = 1; }
5
6 use strict;
7 use vars qw($opt_s);
8 use Getopt::Std;
9 use Locale::Country;
10 use Locale::SubCountry;
11 use DBI;
12 use DBIx::DBSchema 0.21;
13 use DBIx::DBSchema::Table;
14 use DBIx::DBSchema::Column;
15 use DBIx::DBSchema::ColGroup::Unique;
16 use DBIx::DBSchema::ColGroup::Index;
17 use FS::UID qw(adminsuidsetup datasrc checkeuid getsecrets);
18 use FS::Record;
19 use FS::cust_main_county;
20 use FS::raddb;
21 use FS::part_bill_event;
22
23 die "Not running uid freeside!" unless checkeuid();
24
25 my %attrib2db =
26   map { lc($FS::raddb::attrib{$_}) => $_ } keys %FS::raddb::attrib;
27
28 getopts("s");
29 my $user = shift or die &usage;
30 getsecrets($user);
31
32 #needs to match FS::Record
33 my($dbdef_file) = "/usr/local/etc/freeside/dbdef.". datasrc;
34
35 ###
36
37 #print "\nEnter the maximum username length: ";
38 #my($username_len)=&getvalue;
39 my $username_len = 32; #usernamemax config file
40
41 #print "\n\n", <<END, ":";
42 #Freeside tracks the RADIUS User-Name, check attribute Password and
43 #reply attribute Framed-IP-Address for each user.  You can specify additional
44 #check and reply attributes (or you can add them later with the
45 #fs-radius-add-check and fs-radius-add-reply programs).
46 #
47 #First enter any additional RADIUS check attributes you need to track for each 
48 #user, separated by whitespace.
49 #END
50 #my @check_attributes = map { $attrib2db{lc($_)} or die "unknown attribute $_"; }
51 #                         split(" ",&getvalue);
52 #
53 #print "\n\n", <<END, ":";
54 #Now enter any additional reply attributes you need to track for each user,
55 #separated by whitespace.
56 #END
57 #my @attributes = map { $attrib2db{lc($_)} or die "unknown attribute $_"; }
58 #                   split(" ",&getvalue);
59 #
60 #print "\n\n", <<END, ":";
61 #Do you wish to enable the tracking of a second, separate shipping/service
62 #address?
63 #END
64 #my $ship = &_yesno;
65 #
66 #sub getvalue {
67 #  my($x)=scalar(<STDIN>);
68 #  chop $x;
69 #  $x;
70 #}
71 #
72 #sub _yesno {
73 #  print " [y/N]:";
74 #  my $x = scalar(<STDIN>);
75 #  $x =~ /^y/i;
76 #}
77
78 my @check_attributes = (); #add later
79 my @attributes = (); #add later
80 my $ship = $opt_s;
81
82 ###
83
84 my($char_d) = 80; #default maxlength for text fields
85
86 #my(@date_type)  = ( 'timestamp', '', ''     );
87 my(@date_type)  = ( 'int', 'NULL', ''     );
88 my(@perl_type) = ( 'text', 'NULL', ''  ); 
89 my @money_type = ( 'decimal',   '', '10,2' );
90
91 ###
92 # create a dbdef object from the old data structure
93 ###
94
95 my(%tables)=&tables_hash_hack;
96
97 #turn it into objects
98 my($dbdef) = new DBIx::DBSchema ( map {  
99   my(@columns);
100   while (@{$tables{$_}{'columns'}}) {
101     my($name,$type,$null,$length)=splice @{$tables{$_}{'columns'}}, 0, 4;
102     push @columns, new DBIx::DBSchema::Column ( $name,$type,$null,$length );
103   }
104   DBIx::DBSchema::Table->new(
105     $_,
106     $tables{$_}{'primary_key'},
107     DBIx::DBSchema::ColGroup::Unique->new($tables{$_}{'unique'}),
108     DBIx::DBSchema::ColGroup::Index->new($tables{$_}{'index'}),
109     @columns,
110   );
111 } (keys %tables) );
112
113 my $cust_main = $dbdef->table('cust_main');
114 unless ($ship) { #remove ship_ from cust_main
115   $cust_main->delcolumn($_) foreach ( grep /^ship_/, $cust_main->columns );
116 } else { #add indices
117   push @{$cust_main->index->lol_ref},
118     map { [ "ship_$_" ] } qw( last company daytime night fax );
119 }
120
121 #add radius attributes to svc_acct
122
123 my($svc_acct)=$dbdef->table('svc_acct');
124
125 my($attribute);
126 foreach $attribute (@attributes) {
127   $svc_acct->addcolumn ( new DBIx::DBSchema::Column (
128     'radius_'. $attribute,
129     'varchar',
130     'NULL',
131     $char_d,
132   ));
133 }
134
135 foreach $attribute (@check_attributes) {
136   $svc_acct->addcolumn( new DBIx::DBSchema::Column (
137     'rc_'. $attribute,
138     'varchar',
139     'NULL',
140     $char_d,
141   ));
142 }
143
144 #create history tables (false laziness w/create-history-tables)
145 foreach my $table ( grep { ! /^h_/ } $dbdef->tables ) {
146   my $tableobj = $dbdef->table($table)
147     or die "unknown table $table";
148
149   die "unique->lol_ref undefined for $table"
150     unless defined $tableobj->unique->lol_ref;
151   die "index->lol_ref undefined for $table"
152     unless defined $tableobj->index->lol_ref;
153
154   my $h_tableobj = DBIx::DBSchema::Table->new( {
155     name        => "h_$table",
156     primary_key => 'historynum',
157     unique      => DBIx::DBSchema::ColGroup::Unique->new( [] ),
158     'index'     => DBIx::DBSchema::ColGroup::Index->new( [
159                      @{$tableobj->unique->lol_ref},
160                      @{$tableobj->index->lol_ref}
161                    ] ),
162     columns     => [
163                      DBIx::DBSchema::Column->new( {
164                        'name'    => 'historynum',
165                        'type'    => 'serial',
166                        'null'    => 'NOT NULL',
167                        'length'  => '',
168                        'default' => '',
169                        'local'   => '',
170                      } ),
171                      DBIx::DBSchema::Column->new( {
172                        'name'    => 'history_date',
173                        'type'    => 'int',
174                        'null'    => 'NULL',
175                        'length'  => '',
176                        'default' => '',
177                        'local'   => '',
178                      } ),
179                      DBIx::DBSchema::Column->new( {
180                        'name'    => 'history_user',
181                        'type'    => 'varchar',
182                        'null'    => 'NOT NULL',
183                        'length'  => '80',
184                        'default' => '',
185                        'local'   => '',
186                      } ),
187                      DBIx::DBSchema::Column->new( {
188                        'name'    => 'history_action',
189                        'type'    => 'varchar',
190                        'null'    => 'NOT NULL',
191                        'length'  => '80',
192                        'default' => '',
193                        'local'   => '',
194                      } ),
195                      map {
196                        my $column = $tableobj->column($_);
197
198                        #clone so as to not disturb the original
199                        $column = DBIx::DBSchema::Column->new( {
200                          map { $_ => $column->$_() }
201                            qw( name type null length default local )
202                        } );
203
204                        $column->type('int')
205                          if $column->type eq 'serial';
206                        #$column->default('')
207                        #  if $column->default =~ /^nextval\(/i;
208                        #( my $local = $column->local ) =~ s/AUTO_INCREMENT//i;
209                        #$column->local($local);
210                        $column;
211                      } $tableobj->columns
212                    ],
213   } );
214   $dbdef->addtable($h_tableobj);
215 }
216
217 #important
218 $dbdef->save($dbdef_file);
219 &FS::Record::reload_dbdef($dbdef_file);
220
221 ###
222 # create 'em
223 ###
224
225 my($dbh)=adminsuidsetup $user;
226
227 #create tables
228 $|=1;
229
230 foreach my $statement ( $dbdef->sql($dbh) ) {
231   $dbh->do( $statement )
232     or die "CREATE error: ". $dbh->errstr. "\ndoing statement: $statement";
233 }
234
235 #cust_main_county
236 foreach my $country ( sort map uc($_), all_country_codes ) {
237
238   my $subcountry = eval { new Locale::SubCountry($country) };
239   my @states = $subcountry ? $subcountry->all_codes : undef;
240
241   if ( !scalar(@states) || ( scalar(@states) == 1 && !defined($states[0]) ) ) {
242
243     my $cust_main_county = new FS::cust_main_county({
244       'tax'   => 0,
245       'country' => $country,
246     });  
247     my $error = $cust_main_county->insert;
248     die $error if $error;
249
250   } else {
251
252     if ( $states[0] =~ /^(\d+|\w)$/ ) {
253       @states = map $subcountry->full_name($_), @states
254     }
255
256     foreach my $state ( @states ) {
257
258       my $cust_main_county = new FS::cust_main_county({
259         'state' => $state,
260         'tax'   => 0,
261         'country' => $country,
262       });  
263       my $error = $cust_main_county->insert;
264       die $error if $error;
265
266     }
267   
268   }
269 }
270
271 #billing events
272 foreach my $aref ( 
273   [ 'COMP', 'Comp invoice', '$cust_bill->comp();', 30, 'comp' ],
274   [ 'CARD', 'Batch card', '$cust_bill->batch_card();', 40, 'batch-card' ],
275   [ 'BILL', 'Send invoice', '$cust_bill->send();', 50, 'send' ],
276   [ 'DCRD', 'Send invoice', '$cust_bill->send();', 50, 'send' ],
277   [ 'DCHK', 'Send invoice', '$cust_bill->send();', 50, 'send' ],
278 ) {
279
280   my $part_bill_event = new FS::part_bill_event({
281     'payby' => $aref->[0],
282     'event' => $aref->[1],
283     'eventcode' => $aref->[2],
284     'seconds' => 0,
285     'weight' => $aref->[3],
286     'plan' => $aref->[4],
287   });
288   my($error);
289   $error=$part_bill_event->insert;
290   die $error if $error;
291
292 }
293
294 $dbh->commit or die $dbh->errstr;
295 $dbh->disconnect or die $dbh->errstr;
296
297 #print "Freeside database initialized sucessfully\n";
298
299 sub usage {
300   die "Usage:\n  freeside-setup [ -s ] user\n"; 
301 }
302
303 ###
304 # Now it becomes an object.  much better.
305 ###
306 sub tables_hash_hack {
307
308   #note that s/(date|change)/_$1/; to avoid keyword conflict.
309   #put a kludge in FS::Record to catch this or? (pry need some date-handling
310   #stuff anyway also)
311
312   my(%tables)=( #yech.}
313
314     'agent' => {
315       'columns' => [
316         'agentnum', 'serial',            '',     '',
317         'agent',    'varchar',           '',     $char_d,
318         'typenum',  'int',            '',     '',
319         'freq',     'int',       'NULL', '',
320         'prog',     @perl_type,
321         'disabled',     'char', 'NULL', 1,
322         'username', 'varchar',       'NULL',     $char_d,
323         '_password','varchar',       'NULL',     $char_d,
324       ],
325       'primary_key' => 'agentnum',
326       'unique' => [],
327       'index' => [ ['typenum'], ['disabled'] ],
328     },
329
330     'agent_type' => {
331       'columns' => [
332         'typenum',   'serial',  '', '',
333         'atype',     'varchar', '', $char_d,
334       ],
335       'primary_key' => 'typenum',
336       'unique' => [],
337       'index' => [],
338     },
339
340     'type_pkgs' => {
341       'columns' => [
342         'typenum',   'int',  '', '',
343         'pkgpart',   'int',  '', '',
344       ],
345       'primary_key' => '',
346       'unique' => [ ['typenum', 'pkgpart'] ],
347       'index' => [ ['typenum'] ],
348     },
349
350     'cust_bill' => {
351       'columns' => [
352         'invnum',    'serial',  '', '',
353         'custnum',   'int',  '', '',
354         '_date',     @date_type,
355         'charged',   @money_type,
356         'printed',   'int',  '', '',
357         'closed',    'char', 'NULL', 1,
358       ],
359       'primary_key' => 'invnum',
360       'unique' => [],
361       'index' => [ ['custnum'], ['_date'] ],
362     },
363
364     'cust_bill_event' => {
365       'columns' => [
366         'eventnum',    'serial',  '', '',
367         'invnum',   'int',  '', '',
368         'eventpart',   'int',  '', '',
369         '_date',     @date_type,
370         'status', 'varchar', '', $char_d,
371         'statustext', 'text', 'NULL', '',
372       ],
373       'primary_key' => 'eventnum',
374       #no... there are retries now #'unique' => [ [ 'eventpart', 'invnum' ] ],
375       'unique' => [],
376       'index' => [ ['invnum'], ['status'] ],
377     },
378
379     'part_bill_event' => {
380       'columns' => [
381         'eventpart',    'serial',  '', '',
382         'payby',       'char',  '', 4,
383         'event',       'varchar',           '',     $char_d,
384         'eventcode',    @perl_type,
385         'seconds',     'int', 'NULL', '',
386         'weight',      'int', '', '',
387         'plan',       'varchar', 'NULL', $char_d,
388         'plandata',   'text', 'NULL', '',
389         'disabled',     'char', 'NULL', 1,
390       ],
391       'primary_key' => 'eventpart',
392       'unique' => [],
393       'index' => [ ['payby'], ['disabled'], ],
394     },
395
396     'cust_bill_pkg' => {
397       'columns' => [
398         'pkgnum',  'int', '', '',
399         'invnum',  'int', '', '',
400         'setup',   @money_type,
401         'recur',   @money_type,
402         'sdate',   @date_type,
403         'edate',   @date_type,
404         'itemdesc', 'varchar', 'NULL', $char_d,
405       ],
406       'primary_key' => '',
407       'unique' => [],
408       'index' => [ ['invnum'] ],
409     },
410
411     'cust_bill_pkg_detail' => {
412       'columns' => [
413         'detailnum', 'serial', '', '',
414         'pkgnum',  'int', '', '',
415         'invnum',  'int', '', '',
416         'detail',  'varchar', '', $char_d,
417       ],
418       'primary_key' => 'detailnum',
419       'unique' => [],
420       'index' => [ [ 'pkgnum', 'invnum' ] ],
421     },
422
423     'cust_credit' => {
424       'columns' => [
425         'crednum',  'serial', '', '',
426         'custnum',  'int', '', '',
427         '_date',    @date_type,
428         'amount',   @money_type,
429         'otaker',   'varchar', '', 32,
430         'reason',   'text', 'NULL', '',
431         'closed',    'char', 'NULL', 1,
432       ],
433       'primary_key' => 'crednum',
434       'unique' => [],
435       'index' => [ ['custnum'] ],
436     },
437
438     'cust_credit_bill' => {
439       'columns' => [
440         'creditbillnum', 'serial', '', '',
441         'crednum',  'int', '', '',
442         'invnum',  'int', '', '',
443         '_date',    @date_type,
444         'amount',   @money_type,
445       ],
446       'primary_key' => 'creditbillnum',
447       'unique' => [],
448       'index' => [ ['crednum'], ['invnum'] ],
449     },
450
451     'cust_main' => {
452       'columns' => [
453         'custnum',  'serial',  '',     '',
454         'agentnum', 'int',  '',     '',
455 #        'titlenum', 'int',  'NULL',   '',
456         'last',     'varchar', '',     $char_d,
457 #        'middle',   'varchar', 'NULL', $char_d,
458         'first',    'varchar', '',     $char_d,
459         'ss',       'varchar', 'NULL', 11,
460         'company',  'varchar', 'NULL', $char_d,
461         'address1', 'varchar', '',     $char_d,
462         'address2', 'varchar', 'NULL', $char_d,
463         'city',     'varchar', '',     $char_d,
464         'county',   'varchar', 'NULL', $char_d,
465         'state',    'varchar', 'NULL', $char_d,
466         'zip',      'varchar', '',     10,
467         'country',  'char', '',     2,
468         'daytime',  'varchar', 'NULL', 20,
469         'night',    'varchar', 'NULL', 20,
470         'fax',      'varchar', 'NULL', 12,
471         'ship_last',     'varchar', 'NULL', $char_d,
472 #        'ship_middle',   'varchar', 'NULL', $char_d,
473         'ship_first',    'varchar', 'NULL', $char_d,
474         'ship_company',  'varchar', 'NULL', $char_d,
475         'ship_address1', 'varchar', 'NULL', $char_d,
476         'ship_address2', 'varchar', 'NULL', $char_d,
477         'ship_city',     'varchar', 'NULL', $char_d,
478         'ship_county',   'varchar', 'NULL', $char_d,
479         'ship_state',    'varchar', 'NULL', $char_d,
480         'ship_zip',      'varchar', 'NULL', 10,
481         'ship_country',  'char', 'NULL', 2,
482         'ship_daytime',  'varchar', 'NULL', 20,
483         'ship_night',    'varchar', 'NULL', 20,
484         'ship_fax',      'varchar', 'NULL', 12,
485         'payby',    'char', '',     4,
486         'payinfo',  'varchar', 'NULL', $char_d,
487         'paycvv',   'varchar', 'NULL', 4,
488         #'paydate',  @date_type,
489         'paydate',  'varchar', 'NULL', 10,
490         'payname',  'varchar', 'NULL', $char_d,
491         'tax',      'char', 'NULL', 1,
492         'otaker',   'varchar', '',    32,
493         'refnum',   'int',  '',     '',
494         'referral_custnum', 'int',  'NULL', '',
495         'comments', 'text', 'NULL', '',
496       ],
497       'primary_key' => 'custnum',
498       'unique' => [],
499       #'index' => [ ['last'], ['company'] ],
500       'index' => [ ['last'], [ 'company' ], [ 'referral_custnum' ],
501                    [ 'daytime' ], [ 'night' ], [ 'fax' ], [ 'refnum' ],
502                  ],
503     },
504
505     'cust_main_invoice' => {
506       'columns' => [
507         'destnum',  'serial',  '',     '',
508         'custnum',  'int',  '',     '',
509         'dest',     'varchar', '',  $char_d,
510       ],
511       'primary_key' => 'destnum',
512       'unique' => [],
513       'index' => [ ['custnum'], ],
514     },
515
516     'cust_main_county' => { #county+state+country are checked off the
517                             #cust_main_county for validation and to provide
518                             # a tax rate.
519       'columns' => [
520         'taxnum',   'serial',   '',    '',
521         'state',    'varchar',  'NULL',    $char_d,
522         'county',   'varchar',  'NULL',    $char_d,
523         'country',  'char',  '', 2, 
524         'taxclass',   'varchar', 'NULL', $char_d,
525         'exempt_amount', @money_type,
526         'tax',      'real',  '',    '', #tax %
527         'taxname',  'varchar',  'NULL',    $char_d,
528         'setuptax',  'char', 'NULL', 1, # Y = setup tax exempt
529         'recurtax',  'char', 'NULL', 1, # Y = recur tax exempt
530       ],
531       'primary_key' => 'taxnum',
532       'unique' => [],
533   #    'unique' => [ ['taxnum'], ['state', 'county'] ],
534       'index' => [],
535     },
536
537     'cust_pay' => {
538       'columns' => [
539         'paynum',   'serial',    '',   '',
540         #now cust_bill_pay #'invnum',   'int',    '',   '',
541         'custnum',  'int',    '',   '',
542         'paid',     @money_type,
543         '_date',    @date_type,
544         'payby',    'char',   '',     4, # CARD/BILL/COMP, should be index into
545                                          # payment type table.
546         'payinfo',  'varchar',   'NULL', $char_d,  #see cust_main above
547         'paybatch', 'varchar',   'NULL', $char_d, #for auditing purposes.
548         'closed',    'char', 'NULL', 1,
549       ],
550       'primary_key' => 'paynum',
551       'unique' => [],
552       'index' => [ [ 'custnum' ], [ 'paybatch' ], [ 'payby' ], [ '_date' ] ],
553     },
554
555     'cust_pay_void' => {
556       'columns' => [
557         'paynum',    'int',    '',   '',
558         'custnum',   'int',    '',   '',
559         'paid',      @money_type,
560         '_date',     @date_type,
561         'payby',     'char',   '',     4, # CARD/BILL/COMP, should be index into
562                                           # payment type table.
563         'payinfo',   'varchar',   'NULL', $char_d,  #see cust_main above
564         'paybatch',  'varchar',   'NULL', $char_d, #for auditing purposes.
565         'closed',    'char', 'NULL', 1,
566         'void_date', @date_type,
567         'reason',    'varchar',   'NULL', $char_d,
568         'otaker',   'varchar', '', 32,
569       ],
570       'primary_key' => 'paynum',
571       'unique' => [],
572       'index' => [ [ 'custnum' ] ],
573     },
574
575     'cust_bill_pay' => {
576       'columns' => [
577         'billpaynum', 'serial',     '',   '',
578         'invnum',  'int',     '',   '',
579         'paynum',  'int',     '',   '',
580         'amount',  @money_type,
581         '_date',   @date_type
582       ],
583       'primary_key' => 'billpaynum',
584       'unique' => [],
585       'index' => [ [ 'paynum' ], [ 'invnum' ] ],
586     },
587
588     'cust_pay_batch' => { #what's this used for again?  list of customers
589                           #in current CARD batch? (necessarily CARD?)
590       'columns' => [
591         'paybatchnum',   'serial',    '',   '',
592         'invnum',   'int',    '',   '',
593         'custnum',   'int',    '',   '',
594         'last',     'varchar', '',     $char_d,
595         'first',    'varchar', '',     $char_d,
596         'address1', 'varchar', '',     $char_d,
597         'address2', 'varchar', 'NULL', $char_d,
598         'city',     'varchar', '',     $char_d,
599         'state',    'varchar', 'NULL', $char_d,
600         'zip',      'varchar', '',     10,
601         'country',  'char', '',     2,
602 #        'trancode', 'int', '', '',
603         'cardnum',  'varchar', '',     16,
604         #'exp',      @date_type,
605         'exp',      'varchar', '',     11,
606         'payname',  'varchar', 'NULL', $char_d,
607         'amount',   @money_type,
608       ],
609       'primary_key' => 'paybatchnum',
610       'unique' => [],
611       'index' => [ ['invnum'], ['custnum'] ],
612     },
613
614     'cust_pkg' => {
615       'columns' => [
616         'pkgnum',    'serial',    '',   '',
617         'custnum',   'int',    '',   '',
618         'pkgpart',   'int',    '',   '',
619         'otaker',    'varchar', '', 32,
620         'setup',     @date_type,
621         'bill',      @date_type,
622         'last_bill', @date_type,
623         'susp',      @date_type,
624         'cancel',    @date_type,
625         'expire',    @date_type,
626         'manual_flag', 'char', 'NULL', 1,
627       ],
628       'primary_key' => 'pkgnum',
629       'unique' => [],
630       'index' => [ ['custnum'] ],
631     },
632
633     'cust_refund' => {
634       'columns' => [
635         'refundnum',    'serial',    '',   '',
636         #now cust_credit_refund #'crednum',      'int',    '',   '',
637         'custnum',  'int',    '',   '',
638         '_date',        @date_type,
639         'refund',       @money_type,
640         'otaker',       'varchar',   '',   32,
641         'reason',       'varchar',   '',   $char_d,
642         'payby',        'char',   '',     4, # CARD/BILL/COMP, should be index
643                                              # into payment type table.
644         'payinfo',      'varchar',   'NULL', $char_d,  #see cust_main above
645         'paybatch',     'varchar',   'NULL', $char_d,
646         'closed',    'char', 'NULL', 1,
647       ],
648       'primary_key' => 'refundnum',
649       'unique' => [],
650       'index' => [],
651     },
652
653     'cust_credit_refund' => {
654       'columns' => [
655         'creditrefundnum', 'serial',     '',   '',
656         'crednum',  'int',     '',   '',
657         'refundnum',  'int',     '',   '',
658         'amount',  @money_type,
659         '_date',   @date_type
660       ],
661       'primary_key' => 'creditrefundnum',
662       'unique' => [],
663       'index' => [ [ 'crednum', 'refundnum' ] ],
664     },
665
666
667     'cust_svc' => {
668       'columns' => [
669         'svcnum',    'serial',    '',   '',
670         'pkgnum',    'int',    'NULL',   '',
671         'svcpart',   'int',    '',   '',
672       ],
673       'primary_key' => 'svcnum',
674       'unique' => [],
675       'index' => [ ['svcnum'], ['pkgnum'], ['svcpart'] ],
676     },
677
678     'part_pkg' => {
679       'columns' => [
680         'pkgpart',    'serial',    '',   '',
681         'pkg',        'varchar',   '',   $char_d,
682         'comment',    'varchar',   '',   $char_d,
683         'setup',      @perl_type,
684         'freq',       'varchar',   '',   $char_d,  #billing frequency
685         'recur',      @perl_type,
686         'setuptax',  'char', 'NULL', 1,
687         'recurtax',  'char', 'NULL', 1,
688         'plan',       'varchar', 'NULL', $char_d,
689         'plandata',   'text', 'NULL', '',
690         'disabled',   'char', 'NULL', 1,
691         'taxclass',   'varchar', 'NULL', $char_d,
692       ],
693       'primary_key' => 'pkgpart',
694       'unique' => [],
695       'index' => [ [ 'disabled' ], ],
696     },
697
698 #    'part_title' => {
699 #      'columns' => [
700 #        'titlenum',   'int',    '',   '',
701 #        'title',      'varchar',   '',   $char_d,
702 #      ],
703 #      'primary_key' => 'titlenum',
704 #      'unique' => [ [] ],
705 #      'index' => [ [] ],
706 #    },
707
708     'pkg_svc' => {
709       'columns' => [
710         'pkgpart',    'int',    '',   '',
711         'svcpart',    'int',    '',   '',
712         'quantity',   'int',    '',   '',
713         'primary_svc','char', 'NULL',  1,
714       ],
715       'primary_key' => '',
716       'unique' => [ ['pkgpart', 'svcpart'] ],
717       'index' => [ ['pkgpart'] ],
718     },
719
720     'part_referral' => {
721       'columns' => [
722         'refnum',   'serial',    '',   '',
723         'referral', 'varchar',   '',   $char_d,
724         'disabled',     'char', 'NULL', 1,
725       ],
726       'primary_key' => 'refnum',
727       'unique' => [],
728       'index' => [ ['disabled'] ],
729     },
730
731     'part_svc' => {
732       'columns' => [
733         'svcpart',    'serial',    '',   '',
734         'svc',        'varchar',   '',   $char_d,
735         'svcdb',      'varchar',   '',   $char_d,
736         'disabled',   'char',  'NULL',   1,
737       ],
738       'primary_key' => 'svcpart',
739       'unique' => [],
740       'index' => [ [ 'disabled' ] ],
741     },
742
743     'part_svc_column' => {
744       'columns' => [
745         'columnnum',   'serial',         '', '',
746         'svcpart',     'int',         '', '',
747         'columnname',  'varchar',     '', 64,
748         'columnvalue', 'varchar', 'NULL', $char_d,
749         'columnflag',  'char',    'NULL', 1, 
750       ],
751       'primary_key' => 'columnnum',
752       'unique' => [ [ 'svcpart', 'columnname' ] ],
753       'index' => [ [ 'svcpart' ] ],
754     },
755
756     #(this should be renamed to part_pop)
757     'svc_acct_pop' => {
758       'columns' => [
759         'popnum',    'serial',    '',   '',
760         'city',      'varchar',   '',   $char_d,
761         'state',     'varchar',   '',   $char_d,
762         'ac',        'char',   '',   3,
763         'exch',      'char',   '',   3,
764         'loc',       'char',   'NULL',   4, #NULL for legacy purposes
765       ],
766       'primary_key' => 'popnum',
767       'unique' => [],
768       'index' => [ [ 'state' ] ],
769     },
770
771     'part_pop_local' => {
772       'columns' => [
773         'localnum',  'serial',     '',     '',
774         'popnum',    'int',     '',     '',
775         'city',      'varchar', 'NULL', $char_d,
776         'state',     'char',    'NULL', 2,
777         'npa',       'char',    '',     3,
778         'nxx',       'char',    '',     3,
779       ],
780       'primary_key' => 'localnum',
781       'unique' => [],
782       'index' => [ [ 'npa', 'nxx' ], [ 'popnum' ] ],
783     },
784
785     'svc_acct' => {
786       'columns' => [
787         'svcnum',    'int',    '',   '',
788         'username',  'varchar',   '',   $username_len, #unique (& remove dup code)
789         '_password', 'varchar',   '',   72, #13 for encryped pw's plus ' *SUSPENDED* (md5 passwords can be 34, blowfish 60)
790         'sec_phrase', 'varchar',  'NULL',   $char_d,
791         'popnum',    'int',    'NULL',   '',
792         'uid',       'int', 'NULL',   '',
793         'gid',       'int', 'NULL',   '',
794         'finger',    'varchar',   'NULL',   $char_d,
795         'dir',       'varchar',   'NULL',   $char_d,
796         'shell',     'varchar',   'NULL',   $char_d,
797         'quota',     'varchar',   'NULL',   $char_d,
798         'slipip',    'varchar',   'NULL',   15, #four TINYINTs, bah.
799         'seconds',   'int', 'NULL',   '', #uhhhh
800         'domsvc',    'int', '',   '',
801       ],
802       'primary_key' => 'svcnum',
803       #'unique' => [ [ 'username', 'domsvc' ] ],
804       'unique' => [],
805       'index' => [ ['username'], ['domsvc'] ],
806     },
807
808     #'svc_charge' => {
809     #  'columns' => [
810     #    'svcnum',    'int',    '',   '',
811     #    'amount',    @money_type,
812     #  ],
813     #  'primary_key' => 'svcnum',
814     #  'unique' => [ [] ],
815     #  'index' => [ [] ],
816     #},
817
818     'svc_domain' => {
819       'columns' => [
820         'svcnum',    'int',    '',   '',
821         'domain',    'varchar',    '',   $char_d,
822         'catchall',  'int', 'NULL',    '',
823       ],
824       'primary_key' => 'svcnum',
825       'unique' => [ ['domain'] ],
826       'index' => [],
827     },
828
829     'domain_record' => {
830       'columns' => [
831         'recnum',    'serial',     '',  '',
832         'svcnum',    'int',     '',  '',
833         #'reczone',   'varchar', '',  $char_d,
834         'reczone',   'varchar', '',  255,
835         'recaf',     'char',    '',  2,
836         'rectype',   'varchar',    '',  5,
837         #'recdata',   'varchar', '',  $char_d,
838         'recdata',   'varchar', '',  255,
839       ],
840       'primary_key' => 'recnum',
841       'unique'      => [],
842       'index'       => [ ['svcnum'] ],
843     },
844
845     'svc_forward' => {
846       'columns' => [
847         'svcnum',   'int',            '',   '',
848         'srcsvc',   'int',        'NULL',   '',
849         'src',      'varchar',    'NULL',  255,
850         'dstsvc',   'int',        'NULL',   '',
851         'dst',      'varchar',    'NULL',  255,
852       ],
853       'primary_key' => 'svcnum',
854       'unique'      => [],
855       'index'       => [ ['srcsvc'], ['dstsvc'] ],
856     },
857
858     'svc_www' => {
859       'columns' => [
860         'svcnum',   'int',    '',  '',
861         'recnum',   'int',    '',  '',
862         'usersvc',  'int',    '',  '',
863       ],
864       'primary_key' => 'svcnum',
865       'unique'      => [],
866       'index'       => [],
867     },
868
869     #'svc_wo' => {
870     #  'columns' => [
871     #    'svcnum',    'int',    '',   '',
872     #    'svcnum',    'int',    '',   '',
873     #    'svcnum',    'int',    '',   '',
874     #    'worker',    'varchar',   '',   $char_d,
875     #    '_date',     @date_type,
876     #  ],
877     #  'primary_key' => 'svcnum',
878     #  'unique' => [ [] ],
879     #  'index' => [ [] ],
880     #},
881
882     'prepay_credit' => {
883       'columns' => [
884         'prepaynum',   'serial',     '',   '',
885         'identifier',  'varchar', '', $char_d,
886         'amount',      @money_type,
887         'seconds',     'int',     'NULL', '',
888       ],
889       'primary_key' => 'prepaynum',
890       'unique'      => [ ['identifier'] ],
891       'index'       => [],
892     },
893
894     'port' => {
895       'columns' => [
896         'portnum',  'serial',     '',   '',
897         'ip',       'varchar', 'NULL', 15,
898         'nasport',  'int',     'NULL', '',
899         'nasnum',   'int',     '',   '',
900       ],
901       'primary_key' => 'portnum',
902       'unique'      => [],
903       'index'       => [],
904     },
905
906     'nas' => {
907       'columns' => [
908         'nasnum',   'serial',     '',    '',
909         'nas',      'varchar', '',    $char_d,
910         'nasip',    'varchar', '',    15,
911         'nasfqdn',  'varchar', '',    $char_d,
912         'last',     'int',     '',    '',
913       ],
914       'primary_key' => 'nasnum',
915       'unique'      => [ [ 'nas' ], [ 'nasip' ] ],
916       'index'       => [ [ 'last' ] ],
917     },
918
919     'session' => {
920       'columns' => [
921         'sessionnum', 'serial',       '',   '',
922         'portnum',    'int',       '',   '',
923         'svcnum',     'int',       '',   '',
924         'login',      @date_type,
925         'logout',     @date_type,
926       ],
927       'primary_key' => 'sessionnum',
928       'unique'      => [],
929       'index'       => [ [ 'portnum' ] ],
930     },
931
932     'queue' => {
933       'columns' => [
934         'jobnum', 'serial', '', '',
935         'job', 'text', '', '',
936         '_date', 'int', '', '',
937         'status', 'varchar', '', $char_d,
938         'statustext', 'text', 'NULL', '',
939         'svcnum', 'int', 'NULL', '',
940       ],
941       'primary_key' => 'jobnum',
942       'unique'      => [],
943       'index'       => [ [ 'svcnum' ], [ 'status' ] ],
944     },
945
946     'queue_arg' => {
947       'columns' => [
948         'argnum', 'serial', '', '',
949         'jobnum', 'int', '', '',
950         'arg', 'text', 'NULL', '',
951       ],
952       'primary_key' => 'argnum',
953       'unique'      => [],
954       'index'       => [ [ 'jobnum' ] ],
955     },
956
957     'queue_depend' => {
958       'columns' => [
959         'dependnum', 'serial', '', '',
960         'jobnum', 'int', '', '',
961         'depend_jobnum', 'int', '', '',
962       ],
963       'primary_key' => 'dependnum',
964       'unique'      => [],
965       'index'       => [ [ 'jobnum' ], [ 'depend_jobnum' ] ],
966     },
967
968     'export_svc' => {
969       'columns' => [
970         'exportsvcnum' => 'serial', '', '',
971         'exportnum'    => 'int', '', '',
972         'svcpart'      => 'int', '', '',
973       ],
974       'primary_key' => 'exportsvcnum',
975       'unique'      => [ [ 'exportnum', 'svcpart' ] ],
976       'index'       => [ [ 'exportnum' ], [ 'svcpart' ] ],
977     },
978
979     'part_export' => {
980       'columns' => [
981         'exportnum', 'serial', '', '',
982         #'svcpart',   'int', '', '',
983         'machine', 'varchar', '', $char_d,
984         'exporttype', 'varchar', '', $char_d,
985         'nodomain',     'char', 'NULL', 1,
986       ],
987       'primary_key' => 'exportnum',
988       'unique'      => [],
989       'index'       => [ [ 'machine' ], [ 'exporttype' ] ],
990     },
991
992     'part_export_option' => {
993       'columns' => [
994         'optionnum', 'serial', '', '',
995         'exportnum', 'int', '', '',
996         'optionname', 'varchar', '', $char_d,
997         'optionvalue', 'text', 'NULL', '',
998       ],
999       'primary_key' => 'optionnum',
1000       'unique'      => [],
1001       'index'       => [ [ 'exportnum' ], [ 'optionname' ] ],
1002     },
1003
1004     'radius_usergroup' => {
1005       'columns' => [
1006         'usergroupnum', 'serial', '', '',
1007         'svcnum',       'int', '', '',
1008         'groupname',    'varchar', '', $char_d,
1009       ],
1010       'primary_key' => 'usergroupnum',
1011       'unique'      => [],
1012       'index'       => [ [ 'svcnum' ], [ 'groupname' ] ],
1013     },
1014
1015     'msgcat' => {
1016       'columns' => [
1017         'msgnum', 'serial', '', '',
1018         'msgcode', 'varchar', '', $char_d,
1019         'locale', 'varchar', '', 16,
1020         'msg', 'text', '', '',
1021       ],
1022       'primary_key' => 'msgnum',
1023       'unique'      => [ [ 'msgcode', 'locale' ] ],
1024       'index'       => [],
1025     },
1026
1027     'cust_tax_exempt' => {
1028       'columns' => [
1029         'exemptnum', 'serial', '', '',
1030         'custnum',   'int', '', '',
1031         'taxnum',    'int', '', '',
1032         'year',      'int', '', '',
1033         'month',     'int', '', '',
1034         'amount',   @money_type,
1035       ],
1036       'primary_key' => 'exemptnum',
1037       'unique'      => [ [ 'custnum', 'taxnum', 'year', 'month' ] ],
1038       'index'       => [],
1039     },
1040
1041     'router' => {
1042       'columns' => [
1043         'routernum', 'serial', '', '',
1044         'routername', 'varchar', '', $char_d,
1045         'svcnum', 'int', 'NULL', '',
1046       ],
1047       'primary_key' => 'routernum',
1048       'unique'      => [],
1049       'index'       => [],
1050     },
1051
1052     'part_svc_router' => {
1053       'columns' => [
1054         'svcpart', 'int', '', '',
1055         'routernum', 'int', '', '',
1056       ],
1057       'primary_key' => '',
1058       'unique'      => [],
1059       'index'       => [],
1060     },
1061
1062     'addr_block' => {
1063       'columns' => [
1064         'blocknum', 'serial', '', '',
1065         'routernum', 'int', '', '',
1066         'ip_gateway', 'varchar', '', 15,
1067         'ip_netmask', 'int', '', '',
1068       ],
1069       'primary_key' => 'blocknum',
1070       'unique'      => [ [ 'blocknum', 'routernum' ] ],
1071       'index'       => [],
1072     },
1073
1074     'svc_broadband' => {
1075       'columns' => [
1076         'svcnum', 'int', '', '',
1077         'blocknum', 'int', '', '',
1078         'speed_up', 'int', '', '',
1079         'speed_down', 'int', '', '',
1080         'ip_addr', 'varchar', '', 15,
1081       ],
1082       'primary_key' => 'svcnum',
1083       'unique'      => [],
1084       'index'       => [],
1085     },
1086
1087     'part_virtual_field' => {
1088       'columns' => [
1089         'vfieldpart', 'int', '', '',
1090         'dbtable', 'varchar', '', 32,
1091         'name', 'varchar', '', 32,
1092         'check_block', 'text', 'NULL', '',
1093         'length', 'int', 'NULL', '',
1094         'list_source', 'text', 'NULL', '',
1095         'label', 'varchar', 'NULL', 80,
1096       ],
1097       'primary_key' => 'vfieldpart',
1098       'unique' => [],
1099       'index' => [],
1100     },
1101
1102     'virtual_field' => {
1103       'columns' => [
1104         'recnum', 'int', '', '',
1105         'vfieldpart', 'int', '', '',
1106         'value', 'varchar', '', 128,
1107       ],
1108       'primary_key' => '',
1109       'unique' => [ [ 'vfieldpart', 'recnum' ] ],
1110       'index' => [],
1111     },
1112
1113     'acct_snarf' => {
1114       'columns' => [
1115         'snarfnum',  'int', '', '',
1116         'svcnum',    'int', '', '',
1117         'machine',   'varchar', '', 255,
1118         'protocol',  'varchar', '', $char_d,
1119         'username',  'varchar', '', $char_d,
1120         '_password', 'varchar', '', $char_d,
1121       ],
1122       'primary_key' => 'snarfnum',
1123       'unique' => [],
1124       'index'  => [ [ 'svcnum' ] ],
1125     },
1126
1127     'svc_external' => {
1128       'columns' => [
1129         'svcnum', 'int', '', '',
1130         'id',     'int', '', '',
1131         'title',  'varchar', 'NULL', $char_d,
1132       ],
1133       'primary_key' => 'svcnum',
1134       'unique'      => [],
1135       'index'       => [],
1136     },
1137
1138     'cust_pay_refund' => {
1139       'columns' => [
1140         'payrefundnum', 'serial', '', '',
1141         'paynum',  'int', '', '',
1142         'refundnum',  'int', '', '',
1143         '_date',    @date_type,
1144         'amount',   @money_type,
1145       ],
1146       'primary_key' => 'payrefundnum',
1147       'unique' => [],
1148       'index' => [ ['paynum'], ['refundnum'] ],
1149     },
1150
1151
1152
1153   );
1154
1155   %tables;
1156
1157 }
1158