optimization for ginourmous numbers of packages for intergate, whew
[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 DBI;
10 use DBIx::DBSchema 0.21;
11 use DBIx::DBSchema::Table;
12 use DBIx::DBSchema::Column;
13 use DBIx::DBSchema::ColGroup::Unique;
14 use DBIx::DBSchema::ColGroup::Index;
15 use FS::UID qw(adminsuidsetup datasrc checkeuid getsecrets);
16 use FS::Record;
17 use FS::cust_main_county;
18 use FS::raddb;
19 use FS::part_bill_event;
20
21 die "Not running uid freeside!" unless checkeuid();
22
23 my %attrib2db =
24   map { lc($FS::raddb::attrib{$_}) => $_ } keys %FS::raddb::attrib;
25
26 getopts("s");
27 my $user = shift or die &usage;
28 getsecrets($user);
29
30 #needs to match FS::Record
31 my($dbdef_file) = "/usr/local/etc/freeside/dbdef.". datasrc;
32
33 ###
34
35 #print "\nEnter the maximum username length: ";
36 #my($username_len)=&getvalue;
37 my $username_len = 32; #usernamemax config file
38
39 #print "\n\n", <<END, ":";
40 #Freeside tracks the RADIUS User-Name, check attribute Password and
41 #reply attribute Framed-IP-Address for each user.  You can specify additional
42 #check and reply attributes (or you can add them later with the
43 #fs-radius-add-check and fs-radius-add-reply programs).
44 #
45 #First enter any additional RADIUS check attributes you need to track for each 
46 #user, separated by whitespace.
47 #END
48 #my @check_attributes = map { $attrib2db{lc($_)} or die "unknown attribute $_"; }
49 #                         split(" ",&getvalue);
50 #
51 #print "\n\n", <<END, ":";
52 #Now enter any additional reply attributes you need to track for each user,
53 #separated by whitespace.
54 #END
55 #my @attributes = map { $attrib2db{lc($_)} or die "unknown attribute $_"; }
56 #                   split(" ",&getvalue);
57 #
58 #print "\n\n", <<END, ":";
59 #Do you wish to enable the tracking of a second, separate shipping/service
60 #address?
61 #END
62 #my $ship = &_yesno;
63 #
64 #sub getvalue {
65 #  my($x)=scalar(<STDIN>);
66 #  chop $x;
67 #  $x;
68 #}
69 #
70 #sub _yesno {
71 #  print " [y/N]:";
72 #  my $x = scalar(<STDIN>);
73 #  $x =~ /^y/i;
74 #}
75
76 my @check_attributes = (); #add later
77 my @attributes = (); #add later
78 my $ship = $opt_s;
79
80 ###
81
82 my($char_d) = 80; #default maxlength for text fields
83
84 #my(@date_type)  = ( 'timestamp', '', ''     );
85 my(@date_type)  = ( 'int', 'NULL', ''     );
86 my(@perl_type) = ( 'text', 'NULL', ''  ); 
87 my @money_type = ( 'decimal',   '', '10,2' );
88
89 ###
90 # create a dbdef object from the old data structure
91 ###
92
93 my(%tables)=&tables_hash_hack;
94
95 #turn it into objects
96 my($dbdef) = new DBIx::DBSchema ( map {  
97   my(@columns);
98   while (@{$tables{$_}{'columns'}}) {
99     my($name,$type,$null,$length)=splice @{$tables{$_}{'columns'}}, 0, 4;
100     push @columns, new DBIx::DBSchema::Column ( $name,$type,$null,$length );
101   }
102   DBIx::DBSchema::Table->new(
103     $_,
104     $tables{$_}{'primary_key'},
105     DBIx::DBSchema::ColGroup::Unique->new($tables{$_}{'unique'}),
106     DBIx::DBSchema::ColGroup::Index->new($tables{$_}{'index'}),
107     @columns,
108   );
109 } (keys %tables) );
110
111 my $cust_main = $dbdef->table('cust_main');
112 unless ($ship) { #remove ship_ from cust_main
113   $cust_main->delcolumn($_) foreach ( grep /^ship_/, $cust_main->columns );
114 } else { #add indices
115   push @{$cust_main->index->lol_ref},
116     map { [ "ship_$_" ] } qw( last company daytime night fax );
117 }
118
119 #add radius attributes to svc_acct
120
121 my($svc_acct)=$dbdef->table('svc_acct');
122
123 my($attribute);
124 foreach $attribute (@attributes) {
125   $svc_acct->addcolumn ( new DBIx::DBSchema::Column (
126     'radius_'. $attribute,
127     'varchar',
128     'NULL',
129     $char_d,
130   ));
131 }
132
133 foreach $attribute (@check_attributes) {
134   $svc_acct->addcolumn( new DBIx::DBSchema::Column (
135     'rc_'. $attribute,
136     'varchar',
137     'NULL',
138     $char_d,
139   ));
140 }
141
142 #create history tables (false laziness w/create-history-tables)
143 foreach my $table ( grep { ! /^h_/ } $dbdef->tables ) {
144   my $tableobj = $dbdef->table($table)
145     or die "unknown table $table";
146
147   die "unique->lol_ref undefined for $table"
148     unless defined $tableobj->unique->lol_ref;
149   die "index->lol_ref undefined for $table"
150     unless defined $tableobj->index->lol_ref;
151
152   my $h_tableobj = DBIx::DBSchema::Table->new( {
153     name        => "h_$table",
154     primary_key => 'historynum',
155     unique      => DBIx::DBSchema::ColGroup::Unique->new( [] ),
156     'index'     => DBIx::DBSchema::ColGroup::Index->new( [
157                      @{$tableobj->unique->lol_ref},
158                      @{$tableobj->index->lol_ref}
159                    ] ),
160     columns     => [
161                      DBIx::DBSchema::Column->new( {
162                        'name'    => 'historynum',
163                        'type'    => 'serial',
164                        'null'    => 'NOT NULL',
165                        'length'  => '',
166                        'default' => '',
167                        'local'   => '',
168                      } ),
169                      DBIx::DBSchema::Column->new( {
170                        'name'    => 'history_date',
171                        'type'    => 'int',
172                        'null'    => 'NULL',
173                        'length'  => '',
174                        'default' => '',
175                        'local'   => '',
176                      } ),
177                      DBIx::DBSchema::Column->new( {
178                        'name'    => 'history_user',
179                        'type'    => 'varchar',
180                        'null'    => 'NOT NULL',
181                        'length'  => '80',
182                        'default' => '',
183                        'local'   => '',
184                      } ),
185                      DBIx::DBSchema::Column->new( {
186                        'name'    => 'history_action',
187                        'type'    => 'varchar',
188                        'null'    => 'NOT NULL',
189                        'length'  => '80',
190                        'default' => '',
191                        'local'   => '',
192                      } ),
193                      map {
194                        my $column = $tableobj->column($_);
195
196                        #clone so as to not disturb the original
197                        $column = DBIx::DBSchema::Column->new( {
198                          map { $_ => $column->$_() }
199                            qw( name type null length default local )
200                        } );
201
202                        $column->type('int')
203                          if $column->type eq 'serial';
204                        #$column->default('')
205                        #  if $column->default =~ /^nextval\(/i;
206                        #( my $local = $column->local ) =~ s/AUTO_INCREMENT//i;
207                        #$column->local($local);
208                        $column;
209                      } $tableobj->columns
210                    ],
211   } );
212   $dbdef->addtable($h_tableobj);
213 }
214
215 #important
216 $dbdef->save($dbdef_file);
217 &FS::Record::reload_dbdef($dbdef_file);
218
219 ###
220 # create 'em
221 ###
222
223 my($dbh)=adminsuidsetup $user;
224
225 #create tables
226 $|=1;
227
228 foreach my $statement ( $dbdef->sql($dbh) ) {
229   $dbh->do( $statement )
230     or die "CREATE error: ". $dbh->errstr. "\ndoing statement: $statement";
231 }
232
233 #not really sample data (and shouldn't default to US)
234
235 #cust_main_county
236
237 #USPS state codes
238 foreach ( qw(
239 AL AK AS AZ AR CA CO CT DC DE FM FL GA GU HI ID IL IN IA KS KY LA
240 ME MH MD MA MI MN MS MO MT NC ND NE NH NJ NM NV NY MP OH OK OR PA PW PR RI 
241 SC SD TN TX UT VT VI VA WA WV WI WY AE AA AP
242 ) ) {
243   my($cust_main_county)=new FS::cust_main_county({
244     'state' => $_,
245     'tax'   => 0,
246     'country' => 'US',
247   });  
248   my($error);
249   $error=$cust_main_county->insert;
250   die $error if $error;
251 }
252
253 #AU "offical" state codes ala mark.williamson@ebbs.com.au (Mark Williamson)
254 foreach ( qw(
255 VIC NSW NT QLD TAS ACT WA SA
256 ) ) {
257   my($cust_main_county)=new FS::cust_main_county({
258     'state' => $_,
259     'tax'   => 0,
260     'country' => 'AU',
261   });  
262   my($error);
263   $error=$cust_main_county->insert;
264   die $error if $error;
265 }
266
267 #ISO 2-letter country codes (same as country TLDs) except US and AU
268 foreach ( qw(
269 AF AL DZ AS AD AO AI AQ AG AR AM AW AT AZ BS BH BD BB BY BE BZ BJ BM BT BO
270 BA BW BV BR IO BN BG BF BI KH CM CA CV KY CF TD CL CN CX CC CO KM CG CK CR CI
271 HR CU CY CZ DK DJ DM DO TP EC EG SV GQ ER EE ET FK FO FJ FI FR FX GF PF TF GA
272 GM GE DE GH GI GR GL GD GP GU GT GN GW GY HT HM HN HK HU IS IN ID IR IQ IE IL
273 IT JM JP JO KZ KE KI KP KR KW KG LA LV LB LS LR LY LI LT LU MO MK MG MW MY MV
274 ML MT MH MQ MR MU YT MX FM MD MC MN MS MA MZ MM NA NR NP NL AN NC NZ NI NE NG
275 NU NF MP NO OM PK PW PA PG PY PE PH PN PL PT PR QA RE RO RU RW KN LC VC WS SM
276 ST SA SN SC SL SG SK SI SB SO ZA GS ES LK SH PM SD SR SJ SZ SE CH SY TW TJ TZ
277 TH TG TK TO TT TN TR TM TC TV UG UA AE GB UM UY UZ VU VA VE VN VG VI WF EH
278 YE YU ZR ZM ZW
279 ) ) {
280   my($cust_main_county)=new FS::cust_main_county({
281     'tax'   => 0,
282     'country' => $_,
283   });  
284   my($error);
285   $error=$cust_main_county->insert;
286   die $error if $error;
287 }
288
289 #billing events
290 foreach my $aref ( 
291   [ 'COMP', 'Comp invoice', '$cust_bill->comp();', 30, 'comp' ],
292   [ 'CARD', 'Batch card', '$cust_bill->batch_card();', 40, 'batch-card' ],
293   [ 'BILL', 'Send invoice', '$cust_bill->send();', 50, 'send' ],
294 ) {
295
296   my $part_bill_event = new FS::part_bill_event({
297     'payby' => $aref->[0],
298     'event' => $aref->[1],
299     'eventcode' => $aref->[2],
300     'seconds' => 0,
301     'weight' => $aref->[3],
302     'plan' => $aref->[4],
303   });
304   my($error);
305   $error=$part_bill_event->insert;
306   die $error if $error;
307
308 }
309
310 $dbh->commit or die $dbh->errstr;
311 $dbh->disconnect or die $dbh->errstr;
312
313 #print "Freeside database initialized sucessfully\n";
314
315 sub usage {
316   die "Usage:\n  freeside-setup [ -s ] user\n"; 
317 }
318
319 ###
320 # Now it becomes an object.  much better.
321 ###
322 sub tables_hash_hack {
323
324   #note that s/(date|change)/_$1/; to avoid keyword conflict.
325   #put a kludge in FS::Record to catch this or? (pry need some date-handling
326   #stuff anyway also)
327
328   my(%tables)=( #yech.}
329
330     'agent' => {
331       'columns' => [
332         'agentnum', 'serial',            '',     '',
333         'agent',    'varchar',           '',     $char_d,
334         'typenum',  'int',            '',     '',
335         'freq',     'int',       'NULL', '',
336         'prog',     @perl_type,
337       ],
338       'primary_key' => 'agentnum',
339       'unique' => [],
340       'index' => [ ['typenum'] ],
341     },
342
343     'agent_type' => {
344       'columns' => [
345         'typenum',   'serial',  '', '',
346         'atype',     'varchar', '', $char_d,
347       ],
348       'primary_key' => 'typenum',
349       'unique' => [],
350       'index' => [],
351     },
352
353     'type_pkgs' => {
354       'columns' => [
355         'typenum',   'int',  '', '',
356         'pkgpart',   'int',  '', '',
357       ],
358       'primary_key' => '',
359       'unique' => [ ['typenum', 'pkgpart'] ],
360       'index' => [ ['typenum'] ],
361     },
362
363     'cust_bill' => {
364       'columns' => [
365         'invnum',    'serial',  '', '',
366         'custnum',   'int',  '', '',
367         '_date',     @date_type,
368         'charged',   @money_type,
369         'printed',   'int',  '', '',
370         'closed',    'char', 'NULL', 1,
371       ],
372       'primary_key' => 'invnum',
373       'unique' => [],
374       'index' => [ ['custnum'] ],
375     },
376
377     'cust_bill_event' => {
378       'columns' => [
379         'eventnum',    'serial',  '', '',
380         'invnum',   'int',  '', '',
381         'eventpart',   'int',  '', '',
382         '_date',     @date_type,
383         'status', 'varchar', '', $char_d,
384         'statustext', 'text', 'NULL', '',
385       ],
386       'primary_key' => 'eventnum',
387       #no... there are retries now #'unique' => [ [ 'eventpart', 'invnum' ] ],
388       'unique' => [],
389       'index' => [ ['invnum'], ['status'] ],
390     },
391
392     'part_bill_event' => {
393       'columns' => [
394         'eventpart',    'serial',  '', '',
395         'payby',       'char',  '', 4,
396         'event',       'varchar',           '',     $char_d,
397         'eventcode',    @perl_type,
398         'seconds',     'int', 'NULL', '',
399         'weight',      'int', '', '',
400         'plan',       'varchar', 'NULL', $char_d,
401         'plandata',   'text', 'NULL', '',
402         'disabled',     'char', 'NULL', 1,
403       ],
404       'primary_key' => 'eventpart',
405       'unique' => [],
406       'index' => [ ['payby'] ],
407     },
408
409     'cust_bill_pkg' => {
410       'columns' => [
411         'pkgnum',  'int', '', '',
412         'invnum',  'int', '', '',
413         'setup',   @money_type,
414         'recur',   @money_type,
415         'sdate',   @date_type,
416         'edate',   @date_type,
417         'itemdesc', 'varchar', 'NULL', $char_d,
418       ],
419       'primary_key' => '',
420       'unique' => [],
421       'index' => [ ['invnum'] ],
422     },
423
424     'cust_credit' => {
425       'columns' => [
426         'crednum',  'serial', '', '',
427         'custnum',  'int', '', '',
428         '_date',    @date_type,
429         'amount',   @money_type,
430         'otaker',   'varchar', '', 32,
431         'reason',   'text', 'NULL', '',
432         'closed',    'char', 'NULL', 1,
433       ],
434       'primary_key' => 'crednum',
435       'unique' => [],
436       'index' => [ ['custnum'] ],
437     },
438
439     'cust_credit_bill' => {
440       'columns' => [
441         'creditbillnum', 'serial', '', '',
442         'crednum',  'int', '', '',
443         'invnum',  'int', '', '',
444         '_date',    @date_type,
445         'amount',   @money_type,
446       ],
447       'primary_key' => 'creditbillnum',
448       'unique' => [],
449       'index' => [ ['crednum'], ['invnum'] ],
450     },
451
452     'cust_main' => {
453       'columns' => [
454         'custnum',  'serial',  '',     '',
455         'agentnum', 'int',  '',     '',
456 #        'titlenum', 'int',  'NULL',   '',
457         'last',     'varchar', '',     $char_d,
458 #        'middle',   'varchar', 'NULL', $char_d,
459         'first',    'varchar', '',     $char_d,
460         'ss',       'char', 'NULL', 11,
461         'company',  'varchar', 'NULL', $char_d,
462         'address1', 'varchar', '',     $char_d,
463         'address2', 'varchar', 'NULL', $char_d,
464         'city',     'varchar', '',     $char_d,
465         'county',   'varchar', 'NULL', $char_d,
466         'state',    'varchar', 'NULL', $char_d,
467         'zip',      'varchar', '',     10,
468         'country',  'char', '',     2,
469         'daytime',  'varchar', 'NULL', 20,
470         'night',    'varchar', 'NULL', 20,
471         'fax',      'varchar', 'NULL', 12,
472         'ship_last',     'varchar', 'NULL', $char_d,
473 #        'ship_middle',   'varchar', 'NULL', $char_d,
474         'ship_first',    'varchar', 'NULL', $char_d,
475         'ship_company',  'varchar', 'NULL', $char_d,
476         'ship_address1', 'varchar', 'NULL', $char_d,
477         'ship_address2', 'varchar', 'NULL', $char_d,
478         'ship_city',     'varchar', 'NULL', $char_d,
479         'ship_county',   'varchar', 'NULL', $char_d,
480         'ship_state',    'varchar', 'NULL', $char_d,
481         'ship_zip',      'varchar', 'NULL', 10,
482         'ship_country',  'char', 'NULL', 2,
483         'ship_daytime',  'varchar', 'NULL', 20,
484         'ship_night',    'varchar', 'NULL', 20,
485         'ship_fax',      'varchar', 'NULL', 12,
486         'payby',    'char', '',     4,
487         'payinfo',  'varchar', 'NULL', $char_d,
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' ],
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       ],
529       'primary_key' => 'taxnum',
530       'unique' => [],
531   #    'unique' => [ ['taxnum'], ['state', 'county'] ],
532       'index' => [],
533     },
534
535     'cust_pay' => {
536       'columns' => [
537         'paynum',   'serial',    '',   '',
538         #now cust_bill_pay #'invnum',   'int',    '',   '',
539         'custnum',  'int',    '',   '',
540         'paid',     @money_type,
541         '_date',    @date_type,
542         'payby',    'char',   '',     4, # CARD/BILL/COMP, should be index into
543                                          # payment type table.
544         'payinfo',  'varchar',   'NULL', $char_d,  #see cust_main above
545         'paybatch', 'varchar',   'NULL', $char_d, #for auditing purposes.
546         'closed',    'char', 'NULL', 1,
547       ],
548       'primary_key' => 'paynum',
549       'unique' => [],
550       'index' => [ [ 'custnum' ], [ 'paybatch' ] ],
551     },
552
553     'cust_bill_pay' => {
554       'columns' => [
555         'billpaynum', 'serial',     '',   '',
556         'invnum',  'int',     '',   '',
557         'paynum',  'int',     '',   '',
558         'amount',  @money_type,
559         '_date',   @date_type
560       ],
561       'primary_key' => 'billpaynum',
562       'unique' => [],
563       'index' => [ [ 'paynum' ], [ 'invnum' ] ],
564     },
565
566     'cust_pay_batch' => { #what's this used for again?  list of customers
567                           #in current CARD batch? (necessarily CARD?)
568       'columns' => [
569         'paybatchnum',   'serial',    '',   '',
570         'invnum',   'int',    '',   '',
571         'custnum',   'int',    '',   '',
572         'last',     'varchar', '',     $char_d,
573         'first',    'varchar', '',     $char_d,
574         'address1', 'varchar', '',     $char_d,
575         'address2', 'varchar', 'NULL', $char_d,
576         'city',     'varchar', '',     $char_d,
577         'state',    'varchar', 'NULL', $char_d,
578         'zip',      'varchar', '',     10,
579         'country',  'char', '',     2,
580 #        'trancode', 'int', '', '',
581         'cardnum',  'varchar', '',     16,
582         #'exp',      @date_type,
583         'exp',      'varchar', '',     11,
584         'payname',  'varchar', 'NULL', $char_d,
585         'amount',   @money_type,
586       ],
587       'primary_key' => 'paybatchnum',
588       'unique' => [],
589       'index' => [ ['invnum'], ['custnum'] ],
590     },
591
592     'cust_pkg' => {
593       'columns' => [
594         'pkgnum',    'serial',    '',   '',
595         'custnum',   'int',    '',   '',
596         'pkgpart',   'int',    '',   '',
597         'otaker',    'varchar', '', 32,
598         'setup',     @date_type,
599         'bill',      @date_type,
600         'susp',      @date_type,
601         'cancel',    @date_type,
602         'expire',    @date_type,
603         'manual_flag', 'char', 'NULL', 1,
604       ],
605       'primary_key' => 'pkgnum',
606       'unique' => [],
607       'index' => [ ['custnum'] ],
608     },
609
610     'cust_refund' => {
611       'columns' => [
612         'refundnum',    'serial',    '',   '',
613         #now cust_credit_refund #'crednum',      'int',    '',   '',
614         'custnum',  'int',    '',   '',
615         '_date',        @date_type,
616         'refund',       @money_type,
617         'otaker',       'varchar',   '',   32,
618         'reason',       'varchar',   '',   $char_d,
619         'payby',        'char',   '',     4, # CARD/BILL/COMP, should be index
620                                              # into payment type table.
621         'payinfo',      'varchar',   'NULL', $char_d,  #see cust_main above
622         'paybatch',     'varchar',   'NULL', $char_d,
623         'closed',    'char', 'NULL', 1,
624       ],
625       'primary_key' => 'refundnum',
626       'unique' => [],
627       'index' => [],
628     },
629
630     'cust_credit_refund' => {
631       'columns' => [
632         'creditrefundnum', 'serial',     '',   '',
633         'crednum',  'int',     '',   '',
634         'refundnum',  'int',     '',   '',
635         'amount',  @money_type,
636         '_date',   @date_type
637       ],
638       'primary_key' => 'creditrefundnum',
639       'unique' => [],
640       'index' => [ [ 'crednum', 'refundnum' ] ],
641     },
642
643
644     'cust_svc' => {
645       'columns' => [
646         'svcnum',    'serial',    '',   '',
647         'pkgnum',    'int',    'NULL',   '',
648         'svcpart',   'int',    '',   '',
649       ],
650       'primary_key' => 'svcnum',
651       'unique' => [],
652       'index' => [ ['svcnum'], ['pkgnum'], ['svcpart'] ],
653     },
654
655     'part_pkg' => {
656       'columns' => [
657         'pkgpart',    'serial',    '',   '',
658         'pkg',        'varchar',   '',   $char_d,
659         'comment',    'varchar',   '',   $char_d,
660         'setup',      @perl_type,
661         'freq',       'int', '', '',  #billing frequency (months)
662         'recur',      @perl_type,
663         'setuptax',  'char', 'NULL', 1,
664         'recurtax',  'char', 'NULL', 1,
665         'plan',       'varchar', 'NULL', $char_d,
666         'plandata',   'text', 'NULL', '',
667         'disabled',   'char', 'NULL', 1,
668         'taxclass',   'varchar', 'NULL', $char_d,
669       ],
670       'primary_key' => 'pkgpart',
671       'unique' => [],
672       'index' => [ [ disabled ], ],
673     },
674
675 #    'part_title' => {
676 #      'columns' => [
677 #        'titlenum',   'int',    '',   '',
678 #        'title',      'varchar',   '',   $char_d,
679 #      ],
680 #      'primary_key' => 'titlenum',
681 #      'unique' => [ [] ],
682 #      'index' => [ [] ],
683 #    },
684
685     'pkg_svc' => {
686       'columns' => [
687         'pkgpart',    'int',    '',   '',
688         'svcpart',    'int',    '',   '',
689         'quantity',   'int',    '',   '',
690       ],
691       'primary_key' => '',
692       'unique' => [ ['pkgpart', 'svcpart'] ],
693       'index' => [ ['pkgpart'] ],
694     },
695
696     'part_referral' => {
697       'columns' => [
698         'refnum',   'serial',    '',   '',
699         'referral', 'varchar',   '',   $char_d,
700       ],
701       'primary_key' => 'refnum',
702       'unique' => [],
703       'index' => [],
704     },
705
706     'part_svc' => {
707       'columns' => [
708         'svcpart',    'serial',    '',   '',
709         'svc',        'varchar',   '',   $char_d,
710         'svcdb',      'varchar',   '',   $char_d,
711         'disabled',   'char',  'NULL',   1,
712       ],
713       'primary_key' => 'svcpart',
714       'unique' => [],
715       'index' => [ [ 'disabled' ] ],
716     },
717
718     'part_svc_column' => {
719       'columns' => [
720         'columnnum',   'serial',         '', '',
721         'svcpart',     'int',         '', '',
722         'columnname',  'varchar',     '', 64,
723         'columnvalue', 'varchar', 'NULL', $char_d,
724         'columnflag',  'char',    'NULL', 1, 
725       ],
726       'primary_key' => 'columnnum',
727       'unique' => [ [ 'svcpart', 'columnname' ] ],
728       'index' => [ [ 'svcpart' ] ],
729     },
730
731     #(this should be renamed to part_pop)
732     'svc_acct_pop' => {
733       'columns' => [
734         'popnum',    'serial',    '',   '',
735         'city',      'varchar',   '',   $char_d,
736         'state',     'varchar',   '',   $char_d,
737         'ac',        'char',   '',   3,
738         'exch',      'char',   '',   3,
739         'loc',       'char',   'NULL',   4, #NULL for legacy purposes
740       ],
741       'primary_key' => 'popnum',
742       'unique' => [],
743       'index' => [ [ 'state' ] ],
744     },
745
746     'part_pop_local' => {
747       'columns' => [
748         'localnum',  'serial',     '',     '',
749         'popnum',    'int',     '',     '',
750         'city',      'varchar', 'NULL', $char_d,
751         'state',     'char',    'NULL', 2,
752         'npa',       'char',    '',     3,
753         'nxx',       'char',    '',     3,
754       ],
755       'primary_key' => 'localnum',
756       'unique' => [],
757       'index' => [ [ 'npa', 'nxx' ], [ 'popnum' ] ],
758     },
759
760     'svc_acct' => {
761       'columns' => [
762         'svcnum',    'int',    '',   '',
763         'username',  'varchar',   '',   $username_len, #unique (& remove dup code)
764         '_password', 'varchar',   '',   50, #13 for encryped pw's plus ' *SUSPENDED* (mp5 passwords can be 34)
765         'sec_phrase', 'varchar',  'NULL',   $char_d,
766         'popnum',    'int',    'NULL',   '',
767         'uid',       'int', 'NULL',   '',
768         'gid',       'int', 'NULL',   '',
769         'finger',    'varchar',   'NULL',   $char_d,
770         'dir',       'varchar',   'NULL',   $char_d,
771         'shell',     'varchar',   'NULL',   $char_d,
772         'quota',     'varchar',   'NULL',   $char_d,
773         'slipip',    'varchar',   'NULL',   15, #four TINYINTs, bah.
774         'seconds',   'int', 'NULL',   '', #uhhhh
775         'domsvc',    'int', '',   '',
776       ],
777       'primary_key' => 'svcnum',
778       #'unique' => [ [ 'username', 'domsvc' ] ],
779       'unique' => [],
780       'index' => [ ['username'], ['domsvc'] ],
781     },
782
783     #'svc_charge' => {
784     #  'columns' => [
785     #    'svcnum',    'int',    '',   '',
786     #    'amount',    @money_type,
787     #  ],
788     #  'primary_key' => 'svcnum',
789     #  'unique' => [ [] ],
790     #  'index' => [ [] ],
791     #},
792
793     'svc_domain' => {
794       'columns' => [
795         'svcnum',    'int',    '',   '',
796         'domain',    'varchar',    '',   $char_d,
797         'catchall',  'int', 'NULL',    '',
798       ],
799       'primary_key' => 'svcnum',
800       'unique' => [ ['domain'] ],
801       'index' => [],
802     },
803
804     'domain_record' => {
805       'columns' => [
806         'recnum',    'serial',     '',  '',
807         'svcnum',    'int',     '',  '',
808         #'reczone',   'varchar', '',  $char_d,
809         'reczone',   'varchar', '',  255,
810         'recaf',     'char',    '',  2,
811         'rectype',   'char',    '',  5,
812         #'recdata',   'varchar', '',  $char_d,
813         'recdata',   'varchar', '',  255,
814       ],
815       'primary_key' => 'recnum',
816       'unique'      => [],
817       'index'       => [ ['svcnum'] ],
818     },
819
820     'svc_forward' => {
821       'columns' => [
822         'svcnum',   'int',    '',  '',
823         'srcsvc',   'int',    '',  '',
824         'dstsvc',   'int',    '',  '',
825         'dst',      'varchar',    'NULL',  $char_d,
826       ],
827       'primary_key' => 'svcnum',
828       'unique'      => [],
829       'index'       => [ ['srcsvc'], ['dstsvc'] ],
830     },
831
832     'svc_www' => {
833       'columns' => [
834         'svcnum',   'int',    '',  '',
835         'recnum',   'int',    '',  '',
836         'usersvc',  'int',    '',  '',
837       ],
838       'primary_key' => 'svcnum',
839       'unique'      => [],
840       'index'       => [],
841     },
842
843     #'svc_wo' => {
844     #  'columns' => [
845     #    'svcnum',    'int',    '',   '',
846     #    'svcnum',    'int',    '',   '',
847     #    'svcnum',    'int',    '',   '',
848     #    'worker',    'varchar',   '',   $char_d,
849     #    '_date',     @date_type,
850     #  ],
851     #  'primary_key' => 'svcnum',
852     #  'unique' => [ [] ],
853     #  'index' => [ [] ],
854     #},
855
856     'prepay_credit' => {
857       'columns' => [
858         'prepaynum',   'serial',     '',   '',
859         'identifier',  'varchar', '', $char_d,
860         'amount',      @money_type,
861         'seconds',     'int',     'NULL', '',
862       ],
863       'primary_key' => 'prepaynum',
864       'unique'      => [ ['identifier'] ],
865       'index'       => [],
866     },
867
868     'port' => {
869       'columns' => [
870         'portnum',  'serial',     '',   '',
871         'ip',       'varchar', 'NULL', 15,
872         'nasport',  'int',     'NULL', '',
873         'nasnum',   'int',     '',   '',
874       ],
875       'primary_key' => 'portnum',
876       'unique'      => [],
877       'index'       => [],
878     },
879
880     'nas' => {
881       'columns' => [
882         'nasnum',   'serial',     '',    '',
883         'nas',      'varchar', '',    $char_d,
884         'nasip',    'varchar', '',    15,
885         'nasfqdn',  'varchar', '',    $char_d,
886         'last',     'int',     '',    '',
887       ],
888       'primary_key' => 'nasnum',
889       'unique'      => [ [ 'nas' ], [ 'nasip' ] ],
890       'index'       => [ [ 'last' ] ],
891     },
892
893     'session' => {
894       'columns' => [
895         'sessionnum', 'serial',       '',   '',
896         'portnum',    'int',       '',   '',
897         'svcnum',     'int',       '',   '',
898         'login',      @date_type,
899         'logout',     @date_type,
900       ],
901       'primary_key' => 'sessionnum',
902       'unique'      => [],
903       'index'       => [ [ 'portnum' ] ],
904     },
905
906     'queue' => {
907       'columns' => [
908         'jobnum', 'serial', '', '',
909         'job', 'text', '', '',
910         '_date', 'int', '', '',
911         'status', 'varchar', '', $char_d,
912         'statustext', 'text', 'NULL', '',
913         'svcnum', 'int', 'NULL', '',
914       ],
915       'primary_key' => 'jobnum',
916       'unique'      => [],
917       'index'       => [ [ 'svcnum' ], [ 'status' ] ],
918     },
919
920     'queue_arg' => {
921       'columns' => [
922         'argnum', 'serial', '', '',
923         'jobnum', 'int', '', '',
924         'arg', 'text', 'NULL', '',
925       ],
926       'primary_key' => 'argnum',
927       'unique'      => [],
928       'index'       => [ [ 'jobnum' ] ],
929     },
930
931     'queue_depend' => {
932       'columns' => [
933         'dependnum', 'serial', '', '',
934         'jobnum', 'int', '', '',
935         'depend_jobnum', 'int', '', '',
936       ],
937       'primary_key' => 'dependnum',
938       'unique'      => [],
939       'index'       => [ [ 'jobnum' ], [ 'depend_jobnum' ] ],
940     },
941
942     'export_svc' => {
943       'columns' => [
944         'exportsvcnum' => 'serial', '', '',
945         'exportnum'    => 'int', '', '',
946         'svcpart'      => 'int', '', '',
947       ],
948       'primary_key' => 'exportsvcnum',
949       'unique'      => [ [ 'exportnum', 'svcpart' ] ],
950       'index'       => [ [ 'exportnum' ], [ 'svcpart' ] ],
951     },
952
953     'part_export' => {
954       'columns' => [
955         'exportnum', 'serial', '', '',
956         #'svcpart',   'int', '', '',
957         'machine', 'varchar', '', $char_d,
958         'exporttype', 'varchar', '', $char_d,
959         'nodomain',     'char', 'NULL', 1,
960       ],
961       'primary_key' => 'exportnum',
962       'unique'      => [],
963       'index'       => [ [ 'machine' ], [ 'exporttype' ] ],
964     },
965
966     'part_export_option' => {
967       'columns' => [
968         'optionnum', 'serial', '', '',
969         'exportnum', 'int', '', '',
970         'optionname', 'varchar', '', $char_d,
971         'optionvalue', 'text', 'NULL', '',
972       ],
973       'primary_key' => 'optionnum',
974       'unique'      => [],
975       'index'       => [ [ 'exportnum' ], [ 'optionname' ] ],
976     },
977
978     'radius_usergroup' => {
979       'columns' => [
980         'usergroupnum', 'serial', '', '',
981         'svcnum',       'int', '', '',
982         'groupname',    'varchar', '', $char_d,
983       ],
984       'primary_key' => 'usergroupnum',
985       'unique'      => [],
986       'index'       => [ [ 'svcnum' ], [ 'groupname' ] ],
987     },
988
989     'msgcat' => {
990       'columns' => [
991         'msgnum', 'serial', '', '',
992         'msgcode', 'varchar', '', $char_d,
993         'locale', 'varchar', '', 16,
994         'msg', 'text', '', '',
995       ],
996       'primary_key' => 'msgnum',
997       'unique'      => [ [ 'msgcode', 'locale' ] ],
998       'index'       => [],
999     },
1000
1001     'cust_tax_exempt' => {
1002       'columns' => [
1003         'exemptnum', 'serial', '', '',
1004         'custnum',   'int', '', '',
1005         'taxnum',    'int', '', '',
1006         'year',      'int', '', '',
1007         'month',     'int', '', '',
1008         'amount',   @money_type,
1009       ],
1010       'primary_key' => 'exemptnum',
1011       'unique'      => [ [ 'custnum', 'taxnum', 'year', 'month' ] ],
1012       'index'       => [],
1013     },
1014
1015     'ac_type' => {
1016       'columns' => [
1017         'actypenum', 'serial', '', '',
1018         'actypename', 'varchar', '', $char_d,
1019       ],
1020       'primary_key' => 'actypenum',
1021       'unique'      => [],
1022       'index'       => [],
1023     },
1024
1025     'ac' => {
1026       'columns' => [
1027         'acnum', 'serial', '', '',
1028         'actypenum', 'int', '', '',
1029         'acname', 'varchar', '', $char_d,
1030       ],
1031       'primary_key' => 'acnum',
1032       'unique'      => [],
1033       'index'       => [ [ 'actypenum' ] ],
1034     },
1035
1036     'part_ac_field' => {
1037       'columns' => [
1038         'acfieldpart', 'serial', '', '',
1039         'actypenum', 'int', '', '',
1040         'name', 'varchar', '', $char_d,
1041         'ut_type', 'varchar', '', $char_d,
1042       ],
1043       'primary_key' => 'acfieldpart',
1044       'unique'      => [],
1045       'index'       => [ [ 'actypenum' ] ],
1046     },
1047
1048     'ac_field' => {
1049       'columns' => [
1050         'acfieldpart', 'int', '', '',
1051         'acnum', 'int', '', '',
1052         'value', 'text', '', '',
1053       ],
1054       'primary_key' => '',
1055       'unique'      => [ [ 'acfieldpart', 'acnum' ] ],
1056       'index'       => [ [ 'acnum' ] ],
1057     },
1058
1059     'ac_block' => {
1060       'columns' => [
1061         'acnum', 'int', '', '',
1062         'ip_gateway', 'varchar', '', 15,
1063         'ip_netmask', 'int', '', '',
1064       ],
1065       'primary_key' => '',
1066       'unique'      => [],
1067       'index'       => [ [ 'acnum' ] ],
1068     },
1069
1070     'svc_broadband' => {
1071       'columns' => [
1072         'svcnum', 'int', '', '',
1073         'actypenum', 'int', '', '',
1074         'speed_up', 'int', '', '',
1075         'speed_down', 'int', '', '',
1076         'acnum', 'int', '', '',
1077         'ip_addr', 'varchar', '', 15,
1078         'ip_netmask', 'int', '', '',
1079         'mac_addr', 'char', '', 17,
1080         'location', 'varchar', '', $char_d,
1081       ],
1082       'primary_key' => 'svcnum',
1083       'unique'      => [],
1084       'index'       => [ [ 'actypenum' ] ],
1085     },
1086
1087   );
1088
1089   %tables;
1090
1091 }
1092