3 #to delay loading dbdef until we're ready
4 BEGIN { $FS::Record::setup_hack = 1; }
10 use Locale::SubCountry;
12 use DBIx::DBSchema 0.20;
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);
19 use FS::cust_main_county;
21 use FS::part_bill_event;
23 die "Not running uid freeside!" unless checkeuid();
26 map { lc($FS::raddb::attrib{$_}) => $_ } keys %FS::raddb::attrib;
29 my $user = shift or die &usage;
32 #needs to match FS::Record
33 my($dbdef_file) = "/usr/local/etc/freeside/dbdef.". datasrc;
37 #print "\nEnter the maximum username length: ";
38 #my($username_len)=&getvalue;
39 my $username_len = 32; #usernamemax config file
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).
47 #First enter any additional RADIUS check attributes you need to track for each
48 #user, separated by whitespace.
50 #my @check_attributes = map { $attrib2db{lc($_)} or die "unknown attribute $_"; }
51 # split(" ",&getvalue);
53 #print "\n\n", <<END, ":";
54 #Now enter any additional reply attributes you need to track for each user,
55 #separated by whitespace.
57 #my @attributes = map { $attrib2db{lc($_)} or die "unknown attribute $_"; }
58 # split(" ",&getvalue);
60 #print "\n\n", <<END, ":";
61 #Do you wish to enable the tracking of a second, separate shipping/service
67 # my($x)=scalar(<STDIN>);
74 # my $x = scalar(<STDIN>);
78 my @check_attributes = (); #add later
79 my @attributes = (); #add later
84 my($char_d) = 80; #default maxlength for text fields
86 #my(@date_type) = ( 'timestamp', '', '' );
87 my(@date_type) = ( 'int', 'NULL', '' );
88 my(@perl_type) = ( 'text', 'NULL', '' );
89 my @money_type = ( 'decimal', '', '10,2' );
92 # create a dbdef object from the old data structure
95 my(%tables)=&tables_hash_hack;
98 my($dbdef) = new DBIx::DBSchema ( map {
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 );
104 DBIx::DBSchema::Table->new(
106 $tables{$_}{'primary_key'},
107 DBIx::DBSchema::ColGroup::Unique->new($tables{$_}{'unique'}),
108 DBIx::DBSchema::ColGroup::Index->new($tables{$_}{'index'}),
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 on ship_last and ship_company
117 push @{$cust_main->index->lol_ref}, ( ['ship_last'], ['ship_company'] )
120 #add radius attributes to svc_acct
122 my($svc_acct)=$dbdef->table('svc_acct');
125 foreach $attribute (@attributes) {
126 $svc_acct->addcolumn ( new DBIx::DBSchema::Column (
127 'radius_'. $attribute,
134 foreach $attribute (@check_attributes) {
135 $svc_acct->addcolumn( new DBIx::DBSchema::Column (
143 ##make part_svc table (but now as object)
145 #my($part_svc)=$dbdef->table('part_svc');
147 ##because of svc_acct_pop
148 ##foreach (grep /^svc_/, $dbdef->tables) {
149 ##foreach (qw(svc_acct svc_acct_sm svc_charge svc_domain svc_wo)) {
150 #foreach (qw(svc_acct svc_domain svc_forward svc_www)) {
151 # my($table)=$dbdef->table($_);
153 # foreach $col ( $table->columns ) {
154 # next if $col =~ /^svcnum$/;
155 # $part_svc->addcolumn( new DBIx::DBSchema::Column (
156 # $table->name. '__' . $table->column($col)->name,
157 # 'varchar', #$table->column($col)->type,
159 # $char_d, #$table->column($col)->length,
161 # $part_svc->addcolumn ( new DBIx::DBSchema::Column (
162 # $table->name. '__'. $table->column($col)->name . "_flag",
170 #create history tables (false laziness w/create-history-tables)
171 foreach my $table ( grep { ! /^h_/ } $dbdef->tables ) {
172 my $tableobj = $dbdef->table($table)
173 or die "unknown table $table";
175 die "unique->lol_ref undefined for $table"
176 unless defined $tableobj->unique->lol_ref;
177 die "index->lol_ref undefined for $table"
178 unless defined $tableobj->index->lol_ref;
180 my $h_tableobj = DBIx::DBSchema::Table->new( {
182 primary_key => 'historynum',
183 unique => DBIx::DBSchema::ColGroup::Unique->new( [] ),
184 'index' => DBIx::DBSchema::ColGroup::Index->new( [
185 @{$tableobj->unique->lol_ref},
186 @{$tableobj->index->lol_ref}
189 DBIx::DBSchema::Column->new( {
190 'name' => 'historynum',
192 'null' => 'NOT NULL',
197 DBIx::DBSchema::Column->new( {
198 'name' => 'history_date',
205 DBIx::DBSchema::Column->new( {
206 'name' => 'history_user',
208 'null' => 'NOT NULL',
213 DBIx::DBSchema::Column->new( {
214 'name' => 'history_action',
216 'null' => 'NOT NULL',
221 map { $tableobj->column($_) } $tableobj->columns
224 $dbdef->addtable($h_tableobj);
228 $dbdef->save($dbdef_file);
229 &FS::Record::reload_dbdef($dbdef_file);
235 my($dbh)=adminsuidsetup $user;
240 foreach my $statement ( $dbdef->sql($dbh) ) {
241 $dbh->do( $statement )
242 or die "CREATE error: ". $dbh->errstr. "\ndoing statement: $statement";
246 foreach my $country ( sort map uc($_), all_country_codes ) {
248 my $subcountry = eval { new Locale::SubCountry($country) };
249 my @states = $subcountry ? $subcountry->all_codes : undef;
251 if ( !scalar(@states) || ( scalar(@states) == 1 && !defined($states[0]) ) ) {
253 my $cust_main_county = new FS::cust_main_county({
255 'country' => $country,
257 my $error = $cust_main_county->insert;
258 die $error if $error;
262 if ( $states[0] =~ /^(\d+|\w)$/ ) {
263 @states = map $subcountry->full_name($_), @states
266 foreach my $state ( @states ) {
268 my $cust_main_county = new FS::cust_main_county({
271 'country' => $country,
273 my $error = $cust_main_county->insert;
274 die $error if $error;
283 [ 'COMP', 'Comp invoice', '$cust_bill->comp();', 30, 'comp' ],
284 [ 'CARD', 'Batch card', '$cust_bill->batch_card();', 40, 'batch-card' ],
285 [ 'BILL', 'Send invoice', '$cust_bill->send();', 50, 'send' ],
288 my $part_bill_event = new FS::part_bill_event({
289 'payby' => $aref->[0],
290 'event' => $aref->[1],
291 'eventcode' => $aref->[2],
293 'weight' => $aref->[3],
294 'plan' => $aref->[4],
297 $error=$part_bill_event->insert;
298 die $error if $error;
302 $dbh->commit or die $dbh->errstr;
303 $dbh->disconnect or die $dbh->errstr;
305 #print "Freeside database initialized sucessfully\n";
308 die "Usage:\n freeside-setup [ -s ] user\n";
312 # Now it becomes an object. much better.
314 sub tables_hash_hack {
316 #note that s/(date|change)/_$1/; to avoid keyword conflict.
317 #put a kludge in FS::Record to catch this or? (pry need some date-handling
320 my(%tables)=( #yech.}
324 'agentnum', 'int', '', '',
325 'agent', 'varchar', '', $char_d,
326 'typenum', 'int', '', '',
327 'freq', 'int', 'NULL', '',
330 'primary_key' => 'agentnum',
332 'index' => [ ['typenum'] ],
337 'typenum', 'int', '', '',
338 'atype', 'varchar', '', $char_d,
340 'primary_key' => 'typenum',
347 'typenum', 'int', '', '',
348 'pkgpart', 'int', '', '',
351 'unique' => [ ['typenum', 'pkgpart'] ],
352 'index' => [ ['typenum'] ],
357 'invnum', 'int', '', '',
358 'custnum', 'int', '', '',
360 'charged', @money_type,
361 'printed', 'int', '', '',
362 'closed', 'char', 'NULL', 1,
364 'primary_key' => 'invnum',
366 'index' => [ ['custnum'], ['_date'] ],
369 'cust_bill_event' => {
371 'eventnum', 'int', '', '',
372 'invnum', 'int', '', '',
373 'eventpart', 'int', '', '',
375 'status', 'varchar', '', $char_d,
376 'statustext', 'text', 'NULL', '',
378 'primary_key' => 'eventnum',
379 #no... there are retries now #'unique' => [ [ 'eventpart', 'invnum' ] ],
381 'index' => [ ['invnum'], ['status'] ],
384 'part_bill_event' => {
386 'eventpart', 'int', '', '',
387 'payby', 'char', '', 4,
388 'event', 'varchar', '', $char_d,
389 'eventcode', @perl_type,
390 'seconds', 'int', 'NULL', '',
391 'weight', 'int', '', '',
392 'plan', 'varchar', 'NULL', $char_d,
393 'plandata', 'text', 'NULL', '',
394 'disabled', 'char', 'NULL', 1,
396 'primary_key' => 'eventpart',
398 'index' => [ ['payby'] ],
403 'pkgnum', 'int', '', '',
404 'invnum', 'int', '', '',
405 'setup', @money_type,
406 'recur', @money_type,
411 'unique' => [ ['pkgnum', 'invnum'] ],
412 'index' => [ ['invnum'] ],
417 'crednum', 'int', '', '',
418 'custnum', 'int', '', '',
420 'amount', @money_type,
421 'otaker', 'varchar', '', 32,
422 'reason', 'text', 'NULL', '',
423 'closed', 'char', 'NULL', 1,
425 'primary_key' => 'crednum',
427 'index' => [ ['custnum'] ],
430 'cust_credit_bill' => {
432 'creditbillnum', 'int', '', '',
433 'crednum', 'int', '', '',
434 'invnum', 'int', '', '',
436 'amount', @money_type,
438 'primary_key' => 'creditbillnum',
440 'index' => [ ['crednum'], ['invnum'] ],
445 'custnum', 'int', '', '',
446 'agentnum', 'int', '', '',
447 # 'titlenum', 'int', 'NULL', '',
448 'last', 'varchar', '', $char_d,
449 # 'middle', 'varchar', 'NULL', $char_d,
450 'first', 'varchar', '', $char_d,
451 'ss', 'varchar', 'NULL', 11,
452 'company', 'varchar', 'NULL', $char_d,
453 'address1', 'varchar', '', $char_d,
454 'address2', 'varchar', 'NULL', $char_d,
455 'city', 'varchar', '', $char_d,
456 'county', 'varchar', 'NULL', $char_d,
457 'state', 'varchar', 'NULL', $char_d,
458 'zip', 'varchar', '', 10,
459 'country', 'char', '', 2,
460 'daytime', 'varchar', 'NULL', 20,
461 'night', 'varchar', 'NULL', 20,
462 'fax', 'varchar', 'NULL', 12,
463 'ship_last', 'varchar', 'NULL', $char_d,
464 # 'ship_middle', 'varchar', 'NULL', $char_d,
465 'ship_first', 'varchar', 'NULL', $char_d,
466 'ship_company', 'varchar', 'NULL', $char_d,
467 'ship_address1', 'varchar', 'NULL', $char_d,
468 'ship_address2', 'varchar', 'NULL', $char_d,
469 'ship_city', 'varchar', 'NULL', $char_d,
470 'ship_county', 'varchar', 'NULL', $char_d,
471 'ship_state', 'varchar', 'NULL', $char_d,
472 'ship_zip', 'varchar', 'NULL', 10,
473 'ship_country', 'char', 'NULL', 2,
474 'ship_daytime', 'varchar', 'NULL', 20,
475 'ship_night', 'varchar', 'NULL', 20,
476 'ship_fax', 'varchar', 'NULL', 12,
477 'payby', 'char', '', 4,
478 'payinfo', 'varchar', 'NULL', $char_d,
479 #'paydate', @date_type,
480 'paydate', 'varchar', 'NULL', 10,
481 'payname', 'varchar', 'NULL', $char_d,
482 'tax', 'char', 'NULL', 1,
483 'otaker', 'varchar', '', 32,
484 'refnum', 'int', '', '',
485 'referral_custnum', 'int', 'NULL', '',
486 'comments', 'text', 'NULL', '',
488 'primary_key' => 'custnum',
490 #'index' => [ ['last'], ['company'] ],
491 'index' => [ ['last'], [ 'company' ], [ 'referral_custnum' ] ],
494 'cust_main_invoice' => {
496 'destnum', 'int', '', '',
497 'custnum', 'int', '', '',
498 'dest', 'varchar', '', $char_d,
500 'primary_key' => 'destnum',
502 'index' => [ ['custnum'], ],
505 'cust_main_county' => { #county+state+country are checked off the
506 #cust_main_county for validation and to provide
509 'taxnum', 'int', '', '',
510 'state', 'varchar', 'NULL', $char_d,
511 'county', 'varchar', 'NULL', $char_d,
512 'country', 'char', '', 2,
513 'taxclass', 'varchar', 'NULL', $char_d,
514 'exempt_amount', @money_type,
515 'tax', 'real', '', '', #tax %
517 'primary_key' => 'taxnum',
519 # 'unique' => [ ['taxnum'], ['state', 'county'] ],
525 'paynum', 'int', '', '',
526 #now cust_bill_pay #'invnum', 'int', '', '',
527 'custnum', 'int', '', '',
530 'payby', 'char', '', 4, # CARD/BILL/COMP, should be index into
531 # payment type table.
532 'payinfo', 'varchar', 'NULL', $char_d, #see cust_main above
533 'paybatch', 'varchar', 'NULL', $char_d, #for auditing purposes.
534 'closed', 'char', 'NULL', 1,
536 'primary_key' => 'paynum',
538 'index' => [ [ 'custnum' ], [ 'paybatch' ] ],
543 'billpaynum', 'int', '', '',
544 'invnum', 'int', '', '',
545 'paynum', 'int', '', '',
546 'amount', @money_type,
549 'primary_key' => 'billpaynum',
551 'index' => [ [ 'paynum' ], [ 'invnum' ] ],
554 'cust_pay_batch' => { #what's this used for again? list of customers
555 #in current CARD batch? (necessarily CARD?)
557 'paybatchnum', 'int', '', '',
558 'invnum', 'int', '', '',
559 'custnum', 'int', '', '',
560 'last', 'varchar', '', $char_d,
561 'first', 'varchar', '', $char_d,
562 'address1', 'varchar', '', $char_d,
563 'address2', 'varchar', 'NULL', $char_d,
564 'city', 'varchar', '', $char_d,
565 'state', 'varchar', 'NULL', $char_d,
566 'zip', 'varchar', '', 10,
567 'country', 'char', '', 2,
568 # 'trancode', 'int', '', '',
569 'cardnum', 'varchar', '', 16,
571 'exp', 'varchar', '', 11,
572 'payname', 'varchar', 'NULL', $char_d,
573 'amount', @money_type,
575 'primary_key' => 'paybatchnum',
577 'index' => [ ['invnum'], ['custnum'] ],
582 'pkgnum', 'int', '', '',
583 'custnum', 'int', '', '',
584 'pkgpart', 'int', '', '',
585 'otaker', 'varchar', '', 32,
589 'cancel', @date_type,
590 'expire', @date_type,
591 'manual_flag', 'char', 'NULL', 1,
593 'primary_key' => 'pkgnum',
595 'index' => [ ['custnum'] ],
600 'refundnum', 'int', '', '',
601 #now cust_credit_refund #'crednum', 'int', '', '',
602 'custnum', 'int', '', '',
604 'refund', @money_type,
605 'otaker', 'varchar', '', 32,
606 'reason', 'varchar', '', $char_d,
607 'payby', 'char', '', 4, # CARD/BILL/COMP, should be index
608 # into payment type table.
609 'payinfo', 'varchar', 'NULL', $char_d, #see cust_main above
610 'paybatch', 'varchar', 'NULL', $char_d,
611 'closed', 'char', 'NULL', 1,
613 'primary_key' => 'refundnum',
618 'cust_credit_refund' => {
620 'creditrefundnum', 'int', '', '',
621 'crednum', 'int', '', '',
622 'refundnum', 'int', '', '',
623 'amount', @money_type,
626 'primary_key' => 'creditrefundnum',
628 'index' => [ [ 'crednum', 'refundnum' ] ],
634 'svcnum', 'int', '', '',
635 'pkgnum', 'int', 'NULL', '',
636 'svcpart', 'int', '', '',
638 'primary_key' => 'svcnum',
640 'index' => [ ['svcnum'], ['pkgnum'], ['svcpart'] ],
645 'pkgpart', 'int', '', '',
646 'pkg', 'varchar', '', $char_d,
647 'comment', 'varchar', '', $char_d,
649 'freq', 'int', '', '', #billing frequency (months)
651 'setuptax', 'char', 'NULL', 1,
652 'recurtax', 'char', 'NULL', 1,
653 'plan', 'varchar', 'NULL', $char_d,
654 'plandata', 'text', 'NULL', '',
655 'disabled', 'char', 'NULL', 1,
656 'taxclass', 'varchar', 'NULL', $char_d,
658 'primary_key' => 'pkgpart',
660 'index' => [ [ 'disabled' ], ],
665 # 'titlenum', 'int', '', '',
666 # 'title', 'varchar', '', $char_d,
668 # 'primary_key' => 'titlenum',
669 # 'unique' => [ [] ],
675 'pkgpart', 'int', '', '',
676 'svcpart', 'int', '', '',
677 'quantity', 'int', '', '',
680 'unique' => [ ['pkgpart', 'svcpart'] ],
681 'index' => [ ['pkgpart'] ],
686 'refnum', 'int', '', '',
687 'referral', 'varchar', '', $char_d,
689 'primary_key' => 'refnum',
696 'svcpart', 'int', '', '',
697 'svc', 'varchar', '', $char_d,
698 'svcdb', 'varchar', '', $char_d,
699 'disabled', 'char', 'NULL', 1,
701 'primary_key' => 'svcpart',
703 'index' => [ [ 'disabled' ] ],
706 'part_svc_column' => {
708 'columnnum', 'int', '', '',
709 'svcpart', 'int', '', '',
710 'columnname', 'varchar', '', 64,
711 'columnvalue', 'varchar', 'NULL', $char_d,
712 'columnflag', 'char', 'NULL', 1,
714 'primary_key' => 'columnnum',
715 'unique' => [ [ 'svcpart', 'columnname' ] ],
716 'index' => [ [ 'svcpart' ] ],
719 #(this should be renamed to part_pop)
722 'popnum', 'int', '', '',
723 'city', 'varchar', '', $char_d,
724 'state', 'varchar', '', $char_d,
726 'exch', 'char', '', 3,
727 'loc', 'char', 'NULL', 4, #NULL for legacy purposes
729 'primary_key' => 'popnum',
731 'index' => [ [ 'state' ] ],
734 'part_pop_local' => {
736 'localnum', 'int', '', '',
737 'popnum', 'int', '', '',
738 'city', 'varchar', 'NULL', $char_d,
739 'state', 'char', 'NULL', 2,
740 'npa', 'char', '', 3,
741 'nxx', 'char', '', 3,
743 'primary_key' => 'localnum',
745 'index' => [ [ 'npa', 'nxx' ], [ 'popnum' ] ],
750 'svcnum', 'int', '', '',
751 'username', 'varchar', '', $username_len, #unique (& remove dup code)
752 '_password', 'varchar', '', 72, #13 for encryped pw's plus ' *SUSPENDED* (md5 passwords can be 34, blowfish 60)
753 'sec_phrase', 'varchar', 'NULL', $char_d,
754 'popnum', 'int', 'NULL', '',
755 'uid', 'int', 'NULL', '',
756 'gid', 'int', 'NULL', '',
757 'finger', 'varchar', 'NULL', $char_d,
758 'dir', 'varchar', 'NULL', $char_d,
759 'shell', 'varchar', 'NULL', $char_d,
760 'quota', 'varchar', 'NULL', $char_d,
761 'slipip', 'varchar', 'NULL', 15, #four TINYINTs, bah.
762 'seconds', 'int', 'NULL', '', #uhhhh
763 'domsvc', 'int', '', '',
765 'primary_key' => 'svcnum',
766 #'unique' => [ [ 'username', 'domsvc' ] ],
768 'index' => [ ['username'], ['domsvc'] ],
773 # 'svcnum', 'int', '', '',
774 # 'domsvc', 'int', '', '',
775 # 'domuid', 'int', '', '',
776 # 'domuser', 'varchar', '', $char_d,
778 # 'primary_key' => 'svcnum',
779 # 'unique' => [ [] ],
780 # 'index' => [ ['domsvc'], ['domuid'] ],
785 # 'svcnum', 'int', '', '',
786 # 'amount', @money_type,
788 # 'primary_key' => 'svcnum',
789 # 'unique' => [ [] ],
795 'svcnum', 'int', '', '',
796 'domain', 'varchar', '', $char_d,
797 'catchall', 'int', 'NULL', '',
799 'primary_key' => 'svcnum',
800 'unique' => [ ['domain'] ],
806 'recnum', 'int', '', '',
807 'svcnum', 'int', '', '',
808 'reczone', 'varchar', '', 255,
809 'recaf', 'char', '', 2,
810 'rectype', 'varchar', '', 5,
811 'recdata', 'varchar', '', 255,
813 'primary_key' => 'recnum',
815 'index' => [ ['svcnum'] ],
820 'svcnum', 'int', '', '',
821 'srcsvc', 'int', '', '',
822 'dstsvc', 'int', '', '',
823 'dst', 'varchar', 'NULL', $char_d,
825 'primary_key' => 'svcnum',
827 'index' => [ ['srcsvc'], ['dstsvc'] ],
832 'svcnum', 'int', '', '',
833 'recnum', 'int', '', '',
834 'usersvc', 'int', '', '',
836 'primary_key' => 'svcnum',
843 # 'svcnum', 'int', '', '',
844 # 'svcnum', 'int', '', '',
845 # 'svcnum', 'int', '', '',
846 # 'worker', 'varchar', '', $char_d,
847 # '_date', @date_type,
849 # 'primary_key' => 'svcnum',
850 # 'unique' => [ [] ],
856 'prepaynum', 'int', '', '',
857 'identifier', 'varchar', '', $char_d,
858 'amount', @money_type,
859 'seconds', 'int', 'NULL', '',
861 'primary_key' => 'prepaynum',
862 'unique' => [ ['identifier'] ],
868 'portnum', 'int', '', '',
869 'ip', 'varchar', 'NULL', 15,
870 'nasport', 'int', 'NULL', '',
871 'nasnum', 'int', '', '',
873 'primary_key' => 'portnum',
880 'nasnum', 'int', '', '',
881 'nas', 'varchar', '', $char_d,
882 'nasip', 'varchar', '', 15,
883 'nasfqdn', 'varchar', '', $char_d,
884 'last', 'int', '', '',
886 'primary_key' => 'nasnum',
887 'unique' => [ [ 'nas' ], [ 'nasip' ] ],
888 'index' => [ [ 'last' ] ],
893 'sessionnum', 'int', '', '',
894 'portnum', 'int', '', '',
895 'svcnum', 'int', '', '',
897 'logout', @date_type,
899 'primary_key' => 'sessionnum',
901 'index' => [ [ 'portnum' ] ],
906 'jobnum', 'int', '', '',
907 'job', 'text', '', '',
908 '_date', 'int', '', '',
909 'status', 'varchar', '', $char_d,
910 'statustext', 'text', 'NULL', '',
911 'svcnum', 'int', 'NULL', '',
913 'primary_key' => 'jobnum',
915 'index' => [ [ 'svcnum' ], [ 'status' ] ],
920 'argnum', 'int', '', '',
921 'jobnum', 'int', '', '',
922 'arg', 'text', 'NULL', '',
924 'primary_key' => 'argnum',
926 'index' => [ [ 'jobnum' ] ],
931 'dependnum', 'int', '', '',
932 'jobnum', 'int', '', '',
933 'depend_jobnum', 'int', '', '',
935 'primary_key' => 'dependnum',
937 'index' => [ [ 'jobnum' ], [ 'depend_jobnum' ] ],
942 'exportsvcnum' => 'int', '', '',
943 'exportnum' => 'int', '', '',
944 'svcpart' => 'int', '', '',
946 'primary_key' => 'exportsvcnum',
947 'unique' => [ [ 'exportnum', 'svcpart' ] ],
948 'index' => [ [ 'exportnum' ], [ 'svcpart' ] ],
953 'exportnum', 'int', '', '',
954 #'svcpart', 'int', '', '',
955 'machine', 'varchar', '', $char_d,
956 'exporttype', 'varchar', '', $char_d,
957 'nodomain', 'char', 'NULL', 1,
959 'primary_key' => 'exportnum',
961 'index' => [ [ 'machine' ], [ 'exporttype' ] ],
964 'part_export_option' => {
966 'optionnum', 'int', '', '',
967 'exportnum', 'int', '', '',
968 'optionname', 'varchar', '', $char_d,
969 'optionvalue', 'text', 'NULL', '',
971 'primary_key' => 'optionnum',
973 'index' => [ [ 'exportnum' ], [ 'optionname' ] ],
976 'radius_usergroup' => {
978 'usergroupnum', 'int', '', '',
979 'svcnum', 'int', '', '',
980 'groupname', 'varchar', '', $char_d,
982 'primary_key' => 'usergroupnum',
984 'index' => [ [ 'svcnum' ], [ 'groupname' ] ],
989 'msgnum', 'int', '', '',
990 'msgcode', 'varchar', '', $char_d,
991 'locale', 'varchar', '', 16,
992 'msg', 'text', '', '',
994 'primary_key' => 'msgnum',
995 'unique' => [ [ 'msgcode', 'locale' ] ],
999 'cust_tax_exempt' => {
1001 'exemptnum', 'int', '', '',
1002 'custnum', 'int', '', '',
1003 'taxnum', 'int', '', '',
1004 'year', 'int', '', '',
1005 'month', 'int', '', '',
1006 'amount', @money_type,
1008 'primary_key' => 'exemptnum',
1009 'unique' => [ [ 'custnum', 'taxnum', 'year', 'month' ] ],