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.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);
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
117 push @{$cust_main->index->lol_ref},
118 map { [ "ship_$_" ] } qw( last company daytime night fax );
121 #add radius attributes to svc_acct
123 my($svc_acct)=$dbdef->table('svc_acct');
126 foreach $attribute (@attributes) {
127 $svc_acct->addcolumn ( new DBIx::DBSchema::Column (
128 'radius_'. $attribute,
135 foreach $attribute (@check_attributes) {
136 $svc_acct->addcolumn( new DBIx::DBSchema::Column (
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";
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;
154 my $h_tableobj = DBIx::DBSchema::Table->new( {
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}
163 DBIx::DBSchema::Column->new( {
164 'name' => 'historynum',
166 'null' => 'NOT NULL',
171 DBIx::DBSchema::Column->new( {
172 'name' => 'history_date',
179 DBIx::DBSchema::Column->new( {
180 'name' => 'history_user',
182 'null' => 'NOT NULL',
187 DBIx::DBSchema::Column->new( {
188 'name' => 'history_action',
190 'null' => 'NOT NULL',
196 my $column = $tableobj->column($_);
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 )
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);
214 $dbdef->addtable($h_tableobj);
218 $dbdef->save($dbdef_file);
219 &FS::Record::reload_dbdef($dbdef_file);
225 my($dbh)=adminsuidsetup $user;
230 foreach my $statement ( $dbdef->sql($dbh) ) {
231 $dbh->do( $statement )
232 or die "CREATE error: ". $dbh->errstr. "\ndoing statement: $statement";
236 foreach my $country ( sort map uc($_), all_country_codes ) {
238 my $subcountry = eval { new Locale::SubCountry($country) };
239 my @states = $subcountry ? $subcountry->all_codes : undef;
241 if ( !scalar(@states) || ( scalar(@states) == 1 && !defined($states[0]) ) ) {
243 my $cust_main_county = new FS::cust_main_county({
245 'country' => $country,
247 my $error = $cust_main_county->insert;
248 die $error if $error;
252 if ( $states[0] =~ /^(\d+|\w)$/ ) {
253 @states = map $subcountry->full_name($_), @states
256 foreach my $state ( @states ) {
258 my $cust_main_county = new FS::cust_main_county({
261 'country' => $country,
263 my $error = $cust_main_county->insert;
264 die $error if $error;
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' ],
280 my $part_bill_event = new FS::part_bill_event({
281 'payby' => $aref->[0],
282 'event' => $aref->[1],
283 'eventcode' => $aref->[2],
285 'weight' => $aref->[3],
286 'plan' => $aref->[4],
289 $error=$part_bill_event->insert;
290 die $error if $error;
294 $dbh->commit or die $dbh->errstr;
295 $dbh->disconnect or die $dbh->errstr;
297 #print "Freeside database initialized sucessfully\n";
300 die "Usage:\n freeside-setup [ -s ] user\n";
304 # Now it becomes an object. much better.
306 sub tables_hash_hack {
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
312 my(%tables)=( #yech.}
316 'agentnum', 'serial', '', '',
317 'agent', 'varchar', '', $char_d,
318 'typenum', 'int', '', '',
319 'freq', 'int', 'NULL', '',
321 'disabled', 'char', 'NULL', 1,
322 'username', 'varchar', 'NULL', $char_d,
323 '_password','varchar', 'NULL', $char_d,
325 'primary_key' => 'agentnum',
327 'index' => [ ['typenum'], ['disabled'] ],
332 'typenum', 'serial', '', '',
333 'atype', 'varchar', '', $char_d,
335 'primary_key' => 'typenum',
342 'typenum', 'int', '', '',
343 'pkgpart', 'int', '', '',
346 'unique' => [ ['typenum', 'pkgpart'] ],
347 'index' => [ ['typenum'] ],
352 'invnum', 'serial', '', '',
353 'custnum', 'int', '', '',
355 'charged', @money_type,
356 'printed', 'int', '', '',
357 'closed', 'char', 'NULL', 1,
359 'primary_key' => 'invnum',
361 'index' => [ ['custnum'], ['_date'] ],
364 'cust_bill_event' => {
366 'eventnum', 'serial', '', '',
367 'invnum', 'int', '', '',
368 'eventpart', 'int', '', '',
370 'status', 'varchar', '', $char_d,
371 'statustext', 'text', 'NULL', '',
373 'primary_key' => 'eventnum',
374 #no... there are retries now #'unique' => [ [ 'eventpart', 'invnum' ] ],
376 'index' => [ ['invnum'], ['status'] ],
379 'part_bill_event' => {
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,
391 'primary_key' => 'eventpart',
393 'index' => [ ['payby'], ['disabled'], ],
398 'pkgnum', 'int', '', '',
399 'invnum', 'int', '', '',
400 'setup', @money_type,
401 'recur', @money_type,
404 'itemdesc', 'varchar', 'NULL', $char_d,
408 'index' => [ ['invnum'] ],
411 'cust_bill_pkg_detail' => {
413 'detailnum', 'serial', '', '',
414 'pkgnum', 'int', '', '',
415 'invnum', 'int', '', '',
416 'detail', 'varchar', '', $char_d,
418 'primary_key' => 'detailnum',
420 'index' => [ [ 'pkgnum', 'invnum' ] ],
425 'crednum', 'serial', '', '',
426 'custnum', 'int', '', '',
428 'amount', @money_type,
429 'otaker', 'varchar', '', 32,
430 'reason', 'text', 'NULL', '',
431 'closed', 'char', 'NULL', 1,
433 'primary_key' => 'crednum',
435 'index' => [ ['custnum'] ],
438 'cust_credit_bill' => {
440 'creditbillnum', 'serial', '', '',
441 'crednum', 'int', '', '',
442 'invnum', 'int', '', '',
444 'amount', @money_type,
446 'primary_key' => 'creditbillnum',
448 'index' => [ ['crednum'], ['invnum'] ],
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', '',
497 'primary_key' => 'custnum',
499 #'index' => [ ['last'], ['company'] ],
500 'index' => [ ['last'], [ 'company' ], [ 'referral_custnum' ],
501 [ 'daytime' ], [ 'night' ], [ 'fax' ],
505 'cust_main_invoice' => {
507 'destnum', 'serial', '', '',
508 'custnum', 'int', '', '',
509 'dest', 'varchar', '', $char_d,
511 'primary_key' => 'destnum',
513 'index' => [ ['custnum'], ],
516 'cust_main_county' => { #county+state+country are checked off the
517 #cust_main_county for validation and to provide
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
531 'primary_key' => 'taxnum',
533 # 'unique' => [ ['taxnum'], ['state', 'county'] ],
539 'paynum', 'serial', '', '',
540 #now cust_bill_pay #'invnum', 'int', '', '',
541 'custnum', 'int', '', '',
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,
550 'primary_key' => 'paynum',
552 'index' => [ [ 'custnum' ], [ 'paybatch' ], [ 'payby' ], [ '_date' ] ],
557 'billpaynum', 'serial', '', '',
558 'invnum', 'int', '', '',
559 'paynum', 'int', '', '',
560 'amount', @money_type,
563 'primary_key' => 'billpaynum',
565 'index' => [ [ 'paynum' ], [ 'invnum' ] ],
568 'cust_pay_batch' => { #what's this used for again? list of customers
569 #in current CARD batch? (necessarily CARD?)
571 'paybatchnum', 'serial', '', '',
572 'invnum', 'int', '', '',
573 'custnum', 'int', '', '',
574 'last', 'varchar', '', $char_d,
575 'first', 'varchar', '', $char_d,
576 'address1', 'varchar', '', $char_d,
577 'address2', 'varchar', 'NULL', $char_d,
578 'city', 'varchar', '', $char_d,
579 'state', 'varchar', 'NULL', $char_d,
580 'zip', 'varchar', '', 10,
581 'country', 'char', '', 2,
582 # 'trancode', 'int', '', '',
583 'cardnum', 'varchar', '', 16,
585 'exp', 'varchar', '', 11,
586 'payname', 'varchar', 'NULL', $char_d,
587 'amount', @money_type,
589 'primary_key' => 'paybatchnum',
591 'index' => [ ['invnum'], ['custnum'] ],
596 'pkgnum', 'serial', '', '',
597 'custnum', 'int', '', '',
598 'pkgpart', 'int', '', '',
599 'otaker', 'varchar', '', 32,
602 'last_bill', @date_type,
604 'cancel', @date_type,
605 'expire', @date_type,
606 'manual_flag', 'char', 'NULL', 1,
608 'primary_key' => 'pkgnum',
610 'index' => [ ['custnum'] ],
615 'refundnum', 'serial', '', '',
616 #now cust_credit_refund #'crednum', 'int', '', '',
617 'custnum', 'int', '', '',
619 'refund', @money_type,
620 'otaker', 'varchar', '', 32,
621 'reason', 'varchar', '', $char_d,
622 'payby', 'char', '', 4, # CARD/BILL/COMP, should be index
623 # into payment type table.
624 'payinfo', 'varchar', 'NULL', $char_d, #see cust_main above
625 'paybatch', 'varchar', 'NULL', $char_d,
626 'closed', 'char', 'NULL', 1,
628 'primary_key' => 'refundnum',
633 'cust_credit_refund' => {
635 'creditrefundnum', 'serial', '', '',
636 'crednum', 'int', '', '',
637 'refundnum', 'int', '', '',
638 'amount', @money_type,
641 'primary_key' => 'creditrefundnum',
643 'index' => [ [ 'crednum', 'refundnum' ] ],
649 'svcnum', 'serial', '', '',
650 'pkgnum', 'int', 'NULL', '',
651 'svcpart', 'int', '', '',
653 'primary_key' => 'svcnum',
655 'index' => [ ['svcnum'], ['pkgnum'], ['svcpart'] ],
660 'pkgpart', 'serial', '', '',
661 'pkg', 'varchar', '', $char_d,
662 'comment', 'varchar', '', $char_d,
664 'freq', 'varchar', '', $char_d, #billing frequency
666 'setuptax', 'char', 'NULL', 1,
667 'recurtax', 'char', 'NULL', 1,
668 'plan', 'varchar', 'NULL', $char_d,
669 'plandata', 'text', 'NULL', '',
670 'disabled', 'char', 'NULL', 1,
671 'taxclass', 'varchar', 'NULL', $char_d,
673 'primary_key' => 'pkgpart',
675 'index' => [ [ 'disabled' ], ],
680 # 'titlenum', 'int', '', '',
681 # 'title', 'varchar', '', $char_d,
683 # 'primary_key' => 'titlenum',
684 # 'unique' => [ [] ],
690 'pkgpart', 'int', '', '',
691 'svcpart', 'int', '', '',
692 'quantity', 'int', '', '',
693 'primary_svc','char', 'NULL', 1,
696 'unique' => [ ['pkgpart', 'svcpart'] ],
697 'index' => [ ['pkgpart'] ],
702 'refnum', 'serial', '', '',
703 'referral', 'varchar', '', $char_d,
704 'disabled', 'char', 'NULL', 1,
706 'primary_key' => 'refnum',
708 'index' => [ ['disabled'] ],
713 'svcpart', 'serial', '', '',
714 'svc', 'varchar', '', $char_d,
715 'svcdb', 'varchar', '', $char_d,
716 'disabled', 'char', 'NULL', 1,
718 'primary_key' => 'svcpart',
720 'index' => [ [ 'disabled' ] ],
723 'part_svc_column' => {
725 'columnnum', 'serial', '', '',
726 'svcpart', 'int', '', '',
727 'columnname', 'varchar', '', 64,
728 'columnvalue', 'varchar', 'NULL', $char_d,
729 'columnflag', 'char', 'NULL', 1,
731 'primary_key' => 'columnnum',
732 'unique' => [ [ 'svcpart', 'columnname' ] ],
733 'index' => [ [ 'svcpart' ] ],
736 #(this should be renamed to part_pop)
739 'popnum', 'serial', '', '',
740 'city', 'varchar', '', $char_d,
741 'state', 'varchar', '', $char_d,
743 'exch', 'char', '', 3,
744 'loc', 'char', 'NULL', 4, #NULL for legacy purposes
746 'primary_key' => 'popnum',
748 'index' => [ [ 'state' ] ],
751 'part_pop_local' => {
753 'localnum', 'serial', '', '',
754 'popnum', 'int', '', '',
755 'city', 'varchar', 'NULL', $char_d,
756 'state', 'char', 'NULL', 2,
757 'npa', 'char', '', 3,
758 'nxx', 'char', '', 3,
760 'primary_key' => 'localnum',
762 'index' => [ [ 'npa', 'nxx' ], [ 'popnum' ] ],
767 'svcnum', 'int', '', '',
768 'username', 'varchar', '', $username_len, #unique (& remove dup code)
769 '_password', 'varchar', '', 72, #13 for encryped pw's plus ' *SUSPENDED* (md5 passwords can be 34, blowfish 60)
770 'sec_phrase', 'varchar', 'NULL', $char_d,
771 'popnum', 'int', 'NULL', '',
772 'uid', 'int', 'NULL', '',
773 'gid', 'int', 'NULL', '',
774 'finger', 'varchar', 'NULL', $char_d,
775 'dir', 'varchar', 'NULL', $char_d,
776 'shell', 'varchar', 'NULL', $char_d,
777 'quota', 'varchar', 'NULL', $char_d,
778 'slipip', 'varchar', 'NULL', 15, #four TINYINTs, bah.
779 'seconds', 'int', 'NULL', '', #uhhhh
780 'domsvc', 'int', '', '',
782 'primary_key' => 'svcnum',
783 #'unique' => [ [ 'username', 'domsvc' ] ],
785 'index' => [ ['username'], ['domsvc'] ],
790 # 'svcnum', 'int', '', '',
791 # 'amount', @money_type,
793 # 'primary_key' => 'svcnum',
794 # 'unique' => [ [] ],
800 'svcnum', 'int', '', '',
801 'domain', 'varchar', '', $char_d,
802 'catchall', 'int', 'NULL', '',
804 'primary_key' => 'svcnum',
805 'unique' => [ ['domain'] ],
811 'recnum', 'serial', '', '',
812 'svcnum', 'int', '', '',
813 #'reczone', 'varchar', '', $char_d,
814 'reczone', 'varchar', '', 255,
815 'recaf', 'char', '', 2,
816 'rectype', 'varchar', '', 5,
817 #'recdata', 'varchar', '', $char_d,
818 'recdata', 'varchar', '', 255,
820 'primary_key' => 'recnum',
822 'index' => [ ['svcnum'] ],
827 'svcnum', 'int', '', '',
828 'srcsvc', 'int', 'NULL', '',
829 'src', 'varchar', 'NULL', 255,
830 'dstsvc', 'int', 'NULL', '',
831 'dst', 'varchar', 'NULL', 255,
833 'primary_key' => 'svcnum',
835 'index' => [ ['srcsvc'], ['dstsvc'] ],
840 'svcnum', 'int', '', '',
841 'recnum', 'int', '', '',
842 'usersvc', 'int', '', '',
844 'primary_key' => 'svcnum',
851 # 'svcnum', 'int', '', '',
852 # 'svcnum', 'int', '', '',
853 # 'svcnum', 'int', '', '',
854 # 'worker', 'varchar', '', $char_d,
855 # '_date', @date_type,
857 # 'primary_key' => 'svcnum',
858 # 'unique' => [ [] ],
864 'prepaynum', 'serial', '', '',
865 'identifier', 'varchar', '', $char_d,
866 'amount', @money_type,
867 'seconds', 'int', 'NULL', '',
869 'primary_key' => 'prepaynum',
870 'unique' => [ ['identifier'] ],
876 'portnum', 'serial', '', '',
877 'ip', 'varchar', 'NULL', 15,
878 'nasport', 'int', 'NULL', '',
879 'nasnum', 'int', '', '',
881 'primary_key' => 'portnum',
888 'nasnum', 'serial', '', '',
889 'nas', 'varchar', '', $char_d,
890 'nasip', 'varchar', '', 15,
891 'nasfqdn', 'varchar', '', $char_d,
892 'last', 'int', '', '',
894 'primary_key' => 'nasnum',
895 'unique' => [ [ 'nas' ], [ 'nasip' ] ],
896 'index' => [ [ 'last' ] ],
901 'sessionnum', 'serial', '', '',
902 'portnum', 'int', '', '',
903 'svcnum', 'int', '', '',
905 'logout', @date_type,
907 'primary_key' => 'sessionnum',
909 'index' => [ [ 'portnum' ] ],
914 'jobnum', 'serial', '', '',
915 'job', 'text', '', '',
916 '_date', 'int', '', '',
917 'status', 'varchar', '', $char_d,
918 'statustext', 'text', 'NULL', '',
919 'svcnum', 'int', 'NULL', '',
921 'primary_key' => 'jobnum',
923 'index' => [ [ 'svcnum' ], [ 'status' ] ],
928 'argnum', 'serial', '', '',
929 'jobnum', 'int', '', '',
930 'arg', 'text', 'NULL', '',
932 'primary_key' => 'argnum',
934 'index' => [ [ 'jobnum' ] ],
939 'dependnum', 'serial', '', '',
940 'jobnum', 'int', '', '',
941 'depend_jobnum', 'int', '', '',
943 'primary_key' => 'dependnum',
945 'index' => [ [ 'jobnum' ], [ 'depend_jobnum' ] ],
950 'exportsvcnum' => 'serial', '', '',
951 'exportnum' => 'int', '', '',
952 'svcpart' => 'int', '', '',
954 'primary_key' => 'exportsvcnum',
955 'unique' => [ [ 'exportnum', 'svcpart' ] ],
956 'index' => [ [ 'exportnum' ], [ 'svcpart' ] ],
961 'exportnum', 'serial', '', '',
962 #'svcpart', 'int', '', '',
963 'machine', 'varchar', '', $char_d,
964 'exporttype', 'varchar', '', $char_d,
965 'nodomain', 'char', 'NULL', 1,
967 'primary_key' => 'exportnum',
969 'index' => [ [ 'machine' ], [ 'exporttype' ] ],
972 'part_export_option' => {
974 'optionnum', 'serial', '', '',
975 'exportnum', 'int', '', '',
976 'optionname', 'varchar', '', $char_d,
977 'optionvalue', 'text', 'NULL', '',
979 'primary_key' => 'optionnum',
981 'index' => [ [ 'exportnum' ], [ 'optionname' ] ],
984 'radius_usergroup' => {
986 'usergroupnum', 'serial', '', '',
987 'svcnum', 'int', '', '',
988 'groupname', 'varchar', '', $char_d,
990 'primary_key' => 'usergroupnum',
992 'index' => [ [ 'svcnum' ], [ 'groupname' ] ],
997 'msgnum', 'serial', '', '',
998 'msgcode', 'varchar', '', $char_d,
999 'locale', 'varchar', '', 16,
1000 'msg', 'text', '', '',
1002 'primary_key' => 'msgnum',
1003 'unique' => [ [ 'msgcode', 'locale' ] ],
1007 'cust_tax_exempt' => {
1009 'exemptnum', 'serial', '', '',
1010 'custnum', 'int', '', '',
1011 'taxnum', 'int', '', '',
1012 'year', 'int', '', '',
1013 'month', 'int', '', '',
1014 'amount', @money_type,
1016 'primary_key' => 'exemptnum',
1017 'unique' => [ [ 'custnum', 'taxnum', 'year', 'month' ] ],
1023 'routernum', 'serial', '', '',
1024 'routername', 'varchar', '', $char_d,
1025 'svcnum', 'int', 'NULL', '',
1027 'primary_key' => 'routernum',
1032 'part_svc_router' => {
1034 'svcpart', 'int', '', '',
1035 'routernum', 'int', '', '',
1037 'primary_key' => '',
1044 'blocknum', 'serial', '', '',
1045 'routernum', 'int', '', '',
1046 'ip_gateway', 'varchar', '', 15,
1047 'ip_netmask', 'int', '', '',
1049 'primary_key' => 'blocknum',
1050 'unique' => [ [ 'blocknum', 'routernum' ] ],
1054 'svc_broadband' => {
1056 'svcnum', 'int', '', '',
1057 'blocknum', 'int', '', '',
1058 'speed_up', 'int', '', '',
1059 'speed_down', 'int', '', '',
1060 'ip_addr', 'varchar', '', 15,
1062 'primary_key' => 'svcnum',
1067 'part_virtual_field' => {
1069 'vfieldpart', 'int', '', '',
1070 'dbtable', 'varchar', '', 32,
1071 'name', 'varchar', '', 32,
1072 'check_block', 'text', 'NULL', '',
1073 'length', 'int', 'NULL', '',
1074 'list_source', 'text', 'NULL', '',
1075 'label', 'varchar', 'NULL', 80,
1077 'primary_key' => 'vfieldpart',
1082 'virtual_field' => {
1084 'recnum', 'int', '', '',
1085 'vfieldpart', 'int', '', '',
1086 'value', 'varchar', '', 128,
1088 'primary_key' => '',
1089 'unique' => [ [ 'vfieldpart', 'recnum' ] ],
1095 'snarfnum', 'int', '', '',
1096 'svcnum', 'int', '', '',
1097 'machine', 'varchar', '', 255,
1098 'protocol', 'varchar', '', $char_d,
1099 'username', 'varchar', '', $char_d,
1100 '_password', 'varchar', '', $char_d,
1102 'primary_key' => 'snarfnum',
1104 'index' => [ [ 'svcnum' ] ],
1109 'svcnum', 'int', '', '',
1110 'id', 'int', '', '',
1111 'title', 'varchar', 'NULL', $char_d,
1113 'primary_key' => 'svcnum',