33d0fd6d85d22473a01cf04a973a370b765ece8a
[freeside.git] / FS / FS / Schema.pm
1 package FS::Schema;
2
3 use vars qw(@ISA @EXPORT_OK $DEBUG $setup_hack %dbdef_cache);
4 use subs qw(reload_dbdef);
5 use Exporter;
6 use DBIx::DBSchema 0.25;
7 use DBIx::DBSchema::Table;
8 use DBIx::DBSchema::Column;
9 use DBIx::DBSchema::ColGroup::Unique;
10 use DBIx::DBSchema::ColGroup::Index;
11 use FS::UID qw(datasrc);
12
13 @ISA = qw(Exporter);
14 @EXPORT_OK = qw( dbdef dbdef_dist reload_dbdef );
15
16 $DEBUG = 0;
17 $me = '[FS::Schema]';
18
19 #ask FS::UID to run this stuff for us later
20 FS::UID->install_callback( sub {
21   #$conf = new FS::Conf; 
22   &reload_dbdef("/usr/local/etc/freeside/dbdef.". datasrc)
23     unless $setup_hack; #$setup_hack needed now?
24 } );
25
26 =head1 NAME
27
28 FS::Schema - Freeside database schema
29
30 =head1 SYNOPSYS
31
32     use FS::Schema qw(dbdef dbdef_dist reload_dbdef);
33
34     $dbdef = reload_dbdef;
35     $dbdef = reload_dbdef "/non/standard/filename";
36     $dbdef = dbdef;
37     $dbdef_dist = dbdef_dist;
38
39 =head1 DESCRIPTION
40
41 This class represents the database schema.
42
43 =head1 METHODS
44
45 =over 4
46
47 =item reload_dbdef([FILENAME])
48
49 Load a database definition (see L<DBIx::DBSchema>), optionally from a
50 non-default filename.  This command is executed at startup unless
51 I<$FS::Schema::setup_hack> is true.  Returns a DBIx::DBSchema object.
52
53 =cut
54
55 sub reload_dbdef {
56   my $file = shift;
57
58   unless ( exists $dbdef_cache{$file} ) {
59     warn "[debug]$me loading dbdef for $file\n" if $DEBUG;
60     $dbdef_cache{$file} = DBIx::DBSchema->load( $file )
61                             or die "can't load database schema from $file";
62   } else {
63     warn "[debug]$me re-using cached dbdef for $file\n" if $DEBUG;
64   }
65   $dbdef = $dbdef_cache{$file};
66 }
67
68 =item dbdef
69
70 Returns the current database definition (represents the current database,
71 assuming it is up-to-date).  See L<DBIx::DBSchema>.
72
73 =cut
74
75 sub dbdef { $dbdef; }
76
77 =item dbdef_dist [ OPTION => VALUE ... ]
78
79 Returns the current canoical database definition as defined in this file.
80
81 =cut
82
83 sub dbdef_dist {
84
85   ###
86   # create a dbdef object from the old data structure
87   ###
88
89   my $tables_hashref = tables_hashref();
90
91   #turn it into objects
92   my $dbdef = new DBIx::DBSchema map {  
93     my @columns;
94     while (@{$tables_hashref->{$_}{'columns'}}) {
95       my($name, $type, $null, $length) =
96         splice @{$tables_hashref->{$_}{'columns'}}, 0, 4;
97       push @columns, new DBIx::DBSchema::Column ( $name,$type,$null,$length );
98     }
99     DBIx::DBSchema::Table->new(
100       $_,
101       $tables_hashref->{$_}{'primary_key'},
102       DBIx::DBSchema::ColGroup::Unique->new($tables_hashref->{$_}{'unique'}),
103       DBIx::DBSchema::ColGroup::Index->new($tables_hashref->{$_}{'index'}),
104       @columns,
105     );
106   } keys %$tables_hashref;
107
108   if ( $DEBUG ) {
109     warn "[debug]$me initial dbdef_dist created ($dbdef) with tables:\n";
110     warn "[debug]$me   $_\n" foreach $dbdef->tables;
111   }
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 (
146     grep { ! /^clientapi_session/ }
147     grep { ! /^h_/ }
148     $dbdef->tables
149   ) {
150     my $tableobj = $dbdef->table($table)
151       or die "unknown table $table";
152   
153     die "unique->lol_ref undefined for $table"
154       unless defined $tableobj->unique->lol_ref;
155     die "index->lol_ref undefined for $table"
156       unless defined $tableobj->index->lol_ref;
157   
158     my $h_tableobj = DBIx::DBSchema::Table->new( {
159       name        => "h_$table",
160       primary_key => 'historynum',
161       unique      => DBIx::DBSchema::ColGroup::Unique->new( [] ),
162       'index'     => DBIx::DBSchema::ColGroup::Index->new( [
163                        @{$tableobj->unique->lol_ref},
164                        @{$tableobj->index->lol_ref}
165                      ] ),
166       columns     => [
167                        DBIx::DBSchema::Column->new( {
168                          'name'    => 'historynum',
169                          'type'    => 'serial',
170                          'null'    => 'NOT NULL',
171                          'length'  => '',
172                          'default' => '',
173                          'local'   => '',
174                        } ),
175                        DBIx::DBSchema::Column->new( {
176                          'name'    => 'history_date',
177                          'type'    => 'int',
178                          'null'    => 'NULL',
179                          'length'  => '',
180                          'default' => '',
181                          'local'   => '',
182                        } ),
183                        DBIx::DBSchema::Column->new( {
184                          'name'    => 'history_user',
185                          'type'    => 'varchar',
186                          'null'    => 'NOT NULL',
187                          'length'  => '80',
188                          'default' => '',
189                          'local'   => '',
190                        } ),
191                        DBIx::DBSchema::Column->new( {
192                          'name'    => 'history_action',
193                          'type'    => 'varchar',
194                          'null'    => 'NOT NULL',
195                          'length'  => '80',
196                          'default' => '',
197                          'local'   => '',
198                        } ),
199                        map {
200                          my $column = $tableobj->column($_);
201   
202                          #clone so as to not disturb the original
203                          $column = DBIx::DBSchema::Column->new( {
204                            map { $_ => $column->$_() }
205                              qw( name type null length default local )
206                          } );
207   
208                          if ( $column->type eq 'serial' ) {
209                            $column->type('int');
210                            $column->null('NULL');
211                          }
212                          #$column->default('')
213                          #  if $column->default =~ /^nextval\(/i;
214                          #( my $local = $column->local ) =~ s/AUTO_INCREMENT//i;
215                          #$column->local($local);
216                          $column;
217                        } $tableobj->columns
218                      ],
219     } );
220     $dbdef->addtable($h_tableobj);
221   }
222
223   $dbdef;
224
225 }
226
227 sub tables_hashref {
228
229   my $char_d = 80; #default maxlength for text fields
230
231   #my(@date_type)  = ( 'timestamp', '', ''     );
232   my @date_type  = ( 'int', 'NULL', ''     );
233   my @perl_type = ( 'text', 'NULL', ''  ); 
234   my @money_type = ( 'decimal',   '', '10,2' );
235
236   my $username_len = 32; #usernamemax config file
237
238   return {
239
240     'agent' => {
241       'columns' => [
242         'agentnum', 'serial',            '',     '',
243         'agent',    'varchar',           '',     $char_d,
244         'typenum',  'int',            '',     '',
245         'freq',     'int',       'NULL', '',
246         'prog',     @perl_type,
247         'disabled',     'char', 'NULL', 1,
248         'username', 'varchar',       'NULL',     $char_d,
249         '_password','varchar',       'NULL',     $char_d,
250         'ticketing_queueid', 'int', 'NULL', '',
251       ],
252       'primary_key' => 'agentnum',
253       'unique' => [],
254       'index' => [ ['typenum'], ['disabled'] ],
255     },
256
257     'agent_type' => {
258       'columns' => [
259         'typenum',   'serial',  '', '',
260         'atype',     'varchar', '', $char_d,
261       ],
262       'primary_key' => 'typenum',
263       'unique' => [],
264       'index' => [],
265     },
266
267     'type_pkgs' => {
268       'columns' => [
269         'typepkgnum', 'serial', '', '',
270         'typenum',   'int',  '', '',
271         'pkgpart',   'int',  '', '',
272       ],
273       'primary_key' => 'typepkgnum',
274       'unique' => [ ['typenum', 'pkgpart'] ],
275       'index' => [ ['typenum'] ],
276     },
277
278     'cust_bill' => {
279       'columns' => [
280         'invnum',    'serial',  '', '',
281         'custnum',   'int',  '', '',
282         '_date',     @date_type,
283         'charged',   @money_type,
284         'printed',   'int',  '', '',
285         'closed',    'char', 'NULL', 1,
286       ],
287       'primary_key' => 'invnum',
288       'unique' => [],
289       'index' => [ ['custnum'], ['_date'] ],
290     },
291
292     'cust_bill_event' => {
293       'columns' => [
294         'eventnum',    'serial',  '', '',
295         'invnum',   'int',  '', '',
296         'eventpart',   'int',  '', '',
297         '_date',     @date_type,
298         'status', 'varchar', '', $char_d,
299         'statustext', 'text', 'NULL', '',
300       ],
301       'primary_key' => 'eventnum',
302       #no... there are retries now #'unique' => [ [ 'eventpart', 'invnum' ] ],
303       'unique' => [],
304       'index' => [ ['invnum'], ['status'] ],
305     },
306
307     'part_bill_event' => {
308       'columns' => [
309         'eventpart',    'serial',  '', '',
310         'freq',        'varchar',       'NULL',     $char_d,
311         'payby',       'char',  '', 4,
312         'event',       'varchar',           '',     $char_d,
313         'eventcode',    @perl_type,
314         'seconds',     'int', 'NULL', '',
315         'weight',      'int', '', '',
316         'plan',       'varchar', 'NULL', $char_d,
317         'plandata',   'text', 'NULL', '',
318         'disabled',     'char', 'NULL', 1,
319       ],
320       'primary_key' => 'eventpart',
321       'unique' => [],
322       'index' => [ ['payby'], ['disabled'], ],
323     },
324
325     'cust_bill_pkg' => {
326       'columns' => [
327         'billpkgnum', 'serial', '', '',
328         'pkgnum',  'int', '', '',
329         'invnum',  'int', '', '',
330         'setup',   @money_type,
331         'recur',   @money_type,
332         'sdate',   @date_type,
333         'edate',   @date_type,
334         'itemdesc', 'varchar', 'NULL', $char_d,
335       ],
336       'primary_key' => 'billpkgnum',
337       'unique' => [],
338       'index' => [ ['invnum'], [ 'pkgnum' ] ],
339     },
340
341     'cust_bill_pkg_detail' => {
342       'columns' => [
343         'detailnum', 'serial', '', '',
344         'pkgnum',  'int', '', '',
345         'invnum',  'int', '', '',
346         'detail',  'varchar', '', $char_d,
347       ],
348       'primary_key' => 'detailnum',
349       'unique' => [],
350       'index' => [ [ 'pkgnum', 'invnum' ] ],
351     },
352
353     'cust_credit' => {
354       'columns' => [
355         'crednum',  'serial', '', '',
356         'custnum',  'int', '', '',
357         '_date',    @date_type,
358         'amount',   @money_type,
359         'otaker',   'varchar', '', 32,
360         'reason',   'text', 'NULL', '',
361         'closed',    'char', 'NULL', 1,
362       ],
363       'primary_key' => 'crednum',
364       'unique' => [],
365       'index' => [ ['custnum'] ],
366     },
367
368     'cust_credit_bill' => {
369       'columns' => [
370         'creditbillnum', 'serial', '', '',
371         'crednum',  'int', '', '',
372         'invnum',  'int', '', '',
373         '_date',    @date_type,
374         'amount',   @money_type,
375       ],
376       'primary_key' => 'creditbillnum',
377       'unique' => [],
378       'index' => [ ['crednum'], ['invnum'] ],
379     },
380
381     'cust_main' => {
382       'columns' => [
383         'custnum',  'serial',  '',     '',
384         'agentnum', 'int',  '',     '',
385 #        'titlenum', 'int',  'NULL',   '',
386         'last',     'varchar', '',     $char_d,
387 #        'middle',   'varchar', 'NULL', $char_d,
388         'first',    'varchar', '',     $char_d,
389         'ss',       'varchar', 'NULL', 11,
390         'company',  'varchar', 'NULL', $char_d,
391         'address1', 'varchar', '',     $char_d,
392         'address2', 'varchar', 'NULL', $char_d,
393         'city',     'varchar', '',     $char_d,
394         'county',   'varchar', 'NULL', $char_d,
395         'state',    'varchar', 'NULL', $char_d,
396         'zip',      'varchar', 'NULL', 10,
397         'country',  'char', '',     2,
398         'daytime',  'varchar', 'NULL', 20,
399         'night',    'varchar', 'NULL', 20,
400         'fax',      'varchar', 'NULL', 12,
401         'ship_last',     'varchar', 'NULL', $char_d,
402 #        'ship_middle',   'varchar', 'NULL', $char_d,
403         'ship_first',    'varchar', 'NULL', $char_d,
404         'ship_company',  'varchar', 'NULL', $char_d,
405         'ship_address1', 'varchar', 'NULL', $char_d,
406         'ship_address2', 'varchar', 'NULL', $char_d,
407         'ship_city',     'varchar', 'NULL', $char_d,
408         'ship_county',   'varchar', 'NULL', $char_d,
409         'ship_state',    'varchar', 'NULL', $char_d,
410         'ship_zip',      'varchar', 'NULL', 10,
411         'ship_country',  'char', 'NULL', 2,
412         'ship_daytime',  'varchar', 'NULL', 20,
413         'ship_night',    'varchar', 'NULL', 20,
414         'ship_fax',      'varchar', 'NULL', 12,
415         'payby',    'char', '',     4,
416         'payinfo',  'varchar', 'NULL', 512,
417         'paycvv',   'varchar', 'NULL', 512,
418         'paymask', 'varchar', 'NULL', $char_d,
419         #'paydate',  @date_type,
420         'paydate',  'varchar', 'NULL', 10,
421         'paystart_month', 'int', 'NULL', '',
422         'paystart_year',  'int', 'NULL', '',
423         'payissue', 'varchar', 'NULL', 2,
424         'payname',  'varchar', 'NULL', $char_d,
425         'payip',    'varchar', 'NULL', 15,
426         'tax',      'char', 'NULL', 1,
427         'otaker',   'varchar', '',    32,
428         'refnum',   'int',  '',     '',
429         'referral_custnum', 'int',  'NULL', '',
430         'comments', 'text', 'NULL', '',
431       ],
432       'primary_key' => 'custnum',
433       'unique' => [],
434       #'index' => [ ['last'], ['company'] ],
435       'index' => [ ['last'], [ 'company' ], [ 'referral_custnum' ],
436                    [ 'daytime' ], [ 'night' ], [ 'fax' ], [ 'refnum' ],
437                    [ 'county' ], [ 'state' ], [ 'country' ]
438                  ],
439     },
440
441     'cust_main_invoice' => {
442       'columns' => [
443         'destnum',  'serial',  '',     '',
444         'custnum',  'int',  '',     '',
445         'dest',     'varchar', '',  $char_d,
446       ],
447       'primary_key' => 'destnum',
448       'unique' => [],
449       'index' => [ ['custnum'], ],
450     },
451
452     'cust_main_county' => { #county+state+country are checked off the
453                             #cust_main_county for validation and to provide
454                             # a tax rate.
455       'columns' => [
456         'taxnum',   'serial',   '',    '',
457         'state',    'varchar',  'NULL',    $char_d,
458         'county',   'varchar',  'NULL',    $char_d,
459         'country',  'char',  '', 2, 
460         'taxclass',   'varchar', 'NULL', $char_d,
461         'exempt_amount', @money_type,
462         'tax',      'real',  '',    '', #tax %
463         'taxname',  'varchar',  'NULL',    $char_d,
464         'setuptax',  'char', 'NULL', 1, # Y = setup tax exempt
465         'recurtax',  'char', 'NULL', 1, # Y = recur tax exempt
466       ],
467       'primary_key' => 'taxnum',
468       'unique' => [],
469   #    'unique' => [ ['taxnum'], ['state', 'county'] ],
470       'index' => [ [ 'county' ], [ 'state' ], [ 'country' ] ],
471     },
472
473     'cust_pay' => {
474       'columns' => [
475         'paynum',   'serial',    '',   '',
476         #now cust_bill_pay #'invnum',   'int',    '',   '',
477         'custnum',  'int',    '',   '',
478         'paid',     @money_type,
479         '_date',    @date_type,
480         'payby',    'char',   '',     4, # CARD/BILL/COMP, should be index into
481                                          # payment type table.
482         'payinfo',  'varchar',   'NULL', $char_d,  #see cust_main above
483         'paybatch', 'varchar',   'NULL', $char_d, #for auditing purposes.
484         'closed',    'char', 'NULL', 1,
485       ],
486       'primary_key' => 'paynum',
487       'unique' => [],
488       'index' => [ [ 'custnum' ], [ 'paybatch' ], [ 'payby' ], [ '_date' ] ],
489     },
490
491     'cust_pay_void' => {
492       'columns' => [
493         'paynum',    'int',    '',   '',
494         'custnum',   'int',    '',   '',
495         'paid',      @money_type,
496         '_date',     @date_type,
497         'payby',     'char',   '',     4, # CARD/BILL/COMP, should be index into
498                                           # payment type table.
499         'payinfo',   'varchar',   'NULL', $char_d,  #see cust_main above
500         'paybatch',  'varchar',   'NULL', $char_d, #for auditing purposes.
501         'closed',    'char', 'NULL', 1,
502         'void_date', @date_type,
503         'reason',    'varchar',   'NULL', $char_d,
504         'otaker',   'varchar', '', 32,
505       ],
506       'primary_key' => 'paynum',
507       'unique' => [],
508       'index' => [ [ 'custnum' ] ],
509     },
510
511     'cust_bill_pay' => {
512       'columns' => [
513         'billpaynum', 'serial',     '',   '',
514         'invnum',  'int',     '',   '',
515         'paynum',  'int',     '',   '',
516         'amount',  @money_type,
517         '_date',   @date_type
518       ],
519       'primary_key' => 'billpaynum',
520       'unique' => [],
521       'index' => [ [ 'paynum' ], [ 'invnum' ] ],
522     },
523
524     'cust_pay_batch' => { #what's this used for again?  list of customers
525                           #in current CARD batch? (necessarily CARD?)
526       'columns' => [
527         'paybatchnum',   'serial',    '',   '',
528         'invnum',   'int',    '',   '',
529         'custnum',   'int',    '',   '',
530         'last',     'varchar', '',     $char_d,
531         'first',    'varchar', '',     $char_d,
532         'address1', 'varchar', '',     $char_d,
533         'address2', 'varchar', 'NULL', $char_d,
534         'city',     'varchar', '',     $char_d,
535         'state',    'varchar', 'NULL', $char_d,
536         'zip',      'varchar', 'NULL', 10,
537         'country',  'char', '',     2,
538 #        'trancode', 'int', '', '',
539         'cardnum',  'varchar', '',     16,
540         #'exp',      @date_type,
541         'exp',      'varchar', '',     11,
542         'payname',  'varchar', 'NULL', $char_d,
543         'amount',   @money_type,
544       ],
545       'primary_key' => 'paybatchnum',
546       'unique' => [],
547       'index' => [ ['invnum'], ['custnum'] ],
548     },
549
550     'cust_pkg' => {
551       'columns' => [
552         'pkgnum',    'serial',    '',   '',
553         'custnum',   'int',    '',   '',
554         'pkgpart',   'int',    '',   '',
555         'otaker',    'varchar', '', 32,
556         'setup',     @date_type,
557         'bill',      @date_type,
558         'last_bill', @date_type,
559         'susp',      @date_type,
560         'cancel',    @date_type,
561         'expire',    @date_type,
562         'manual_flag', 'char', 'NULL', 1,
563       ],
564       'primary_key' => 'pkgnum',
565       'unique' => [],
566       'index' => [ ['custnum'], ['pkgpart'] ],
567     },
568
569     'cust_refund' => {
570       'columns' => [
571         'refundnum',    'serial',    '',   '',
572         #now cust_credit_refund #'crednum',      'int',    '',   '',
573         'custnum',  'int',    '',   '',
574         '_date',        @date_type,
575         'refund',       @money_type,
576         'otaker',       'varchar',   '',   32,
577         'reason',       'varchar',   '',   $char_d,
578         'payby',        'char',   '',     4, # CARD/BILL/COMP, should be index
579                                              # into payment type table.
580         'payinfo',      'varchar',   'NULL', $char_d,  #see cust_main above
581         'paybatch',     'varchar',   'NULL', $char_d,
582         'closed',    'char', 'NULL', 1,
583       ],
584       'primary_key' => 'refundnum',
585       'unique' => [],
586       'index' => [],
587     },
588
589     'cust_credit_refund' => {
590       'columns' => [
591         'creditrefundnum', 'serial',     '',   '',
592         'crednum',  'int',     '',   '',
593         'refundnum',  'int',     '',   '',
594         'amount',  @money_type,
595         '_date',   @date_type
596       ],
597       'primary_key' => 'creditrefundnum',
598       'unique' => [],
599       'index' => [ [ 'crednum', 'refundnum' ] ],
600     },
601
602
603     'cust_svc' => {
604       'columns' => [
605         'svcnum',    'serial',    '',   '',
606         'pkgnum',    'int',    'NULL',   '',
607         'svcpart',   'int',    '',   '',
608       ],
609       'primary_key' => 'svcnum',
610       'unique' => [],
611       'index' => [ ['svcnum'], ['pkgnum'], ['svcpart'] ],
612     },
613
614     'part_pkg' => {
615       'columns' => [
616         'pkgpart',    'serial',    '',   '',
617         'pkg',        'varchar',   '',   $char_d,
618         'comment',    'varchar',   '',   $char_d,
619         'promo_code', 'varchar', 'NULL', $char_d,
620         'setup',      @perl_type,
621         'freq',       'varchar',   '',   $char_d,  #billing frequency
622         'recur',      @perl_type,
623         'setuptax',  'char', 'NULL', 1,
624         'recurtax',  'char', 'NULL', 1,
625         'plan',       'varchar', 'NULL', $char_d,
626         'plandata',   'text', 'NULL', '',
627         'disabled',   'char', 'NULL', 1,
628         'taxclass',   'varchar', 'NULL', $char_d,
629         'classnum',   'int',     'NULL', '',
630       ],
631       'primary_key' => 'pkgpart',
632       'unique' => [],
633       'index' => [ [ 'promo_code' ], [ 'disabled' ] ],
634     },
635
636 #    'part_title' => {
637 #      'columns' => [
638 #        'titlenum',   'int',    '',   '',
639 #        'title',      'varchar',   '',   $char_d,
640 #      ],
641 #      'primary_key' => 'titlenum',
642 #      'unique' => [ [] ],
643 #      'index' => [ [] ],
644 #    },
645
646     'pkg_svc' => {
647       'columns' => [
648         'pkgsvcnum',  'serial', '',  '',
649         'pkgpart',    'int',    '',   '',
650         'svcpart',    'int',    '',   '',
651         'quantity',   'int',    '',   '',
652         'primary_svc','char', 'NULL',  1,
653       ],
654       'primary_key' => 'pkgsvcnum',
655       'unique' => [ ['pkgpart', 'svcpart'] ],
656       'index' => [ ['pkgpart'] ],
657     },
658
659     'part_referral' => {
660       'columns' => [
661         'refnum',   'serial',    '',   '',
662         'referral', 'varchar',   '',   $char_d,
663         'disabled',     'char', 'NULL', 1,
664       ],
665       'primary_key' => 'refnum',
666       'unique' => [],
667       'index' => [ ['disabled'] ],
668     },
669
670     'part_svc' => {
671       'columns' => [
672         'svcpart',    'serial',    '',   '',
673         'svc',        'varchar',   '',   $char_d,
674         'svcdb',      'varchar',   '',   $char_d,
675         'disabled',   'char',  'NULL',   1,
676       ],
677       'primary_key' => 'svcpart',
678       'unique' => [],
679       'index' => [ [ 'disabled' ] ],
680     },
681
682     'part_svc_column' => {
683       'columns' => [
684         'columnnum',   'serial',         '', '',
685         'svcpart',     'int',         '', '',
686         'columnname',  'varchar',     '', 64,
687         'columnvalue', 'varchar', 'NULL', $char_d,
688         'columnflag',  'char',    'NULL', 1, 
689       ],
690       'primary_key' => 'columnnum',
691       'unique' => [ [ 'svcpart', 'columnname' ] ],
692       'index' => [ [ 'svcpart' ] ],
693     },
694
695     #(this should be renamed to part_pop)
696     'svc_acct_pop' => {
697       'columns' => [
698         'popnum',    'serial',    '',   '',
699         'city',      'varchar',   '',   $char_d,
700         'state',     'varchar',   '',   $char_d,
701         'ac',        'char',   '',   3,
702         'exch',      'char',   '',   3,
703         'loc',       'char',   'NULL',   4, #NULL for legacy purposes
704       ],
705       'primary_key' => 'popnum',
706       'unique' => [],
707       'index' => [ [ 'state' ] ],
708     },
709
710     'part_pop_local' => {
711       'columns' => [
712         'localnum',  'serial',     '',     '',
713         'popnum',    'int',     '',     '',
714         'city',      'varchar', 'NULL', $char_d,
715         'state',     'char',    'NULL', 2,
716         'npa',       'char',    '',     3,
717         'nxx',       'char',    '',     3,
718       ],
719       'primary_key' => 'localnum',
720       'unique' => [],
721       'index' => [ [ 'npa', 'nxx' ], [ 'popnum' ] ],
722     },
723
724     'svc_acct' => {
725       'columns' => [
726         'svcnum',    'int',    '',   '',
727         'username',  'varchar',   '',   $username_len, #unique (& remove dup code)
728         '_password', 'varchar',   '',   72, #13 for encryped pw's plus ' *SUSPENDED* (md5 passwords can be 34, blowfish 60)
729         'sec_phrase', 'varchar',  'NULL',   $char_d,
730         'popnum',    'int',    'NULL',   '',
731         'uid',       'int', 'NULL',   '',
732         'gid',       'int', 'NULL',   '',
733         'finger',    'varchar',   'NULL',   $char_d,
734         'dir',       'varchar',   'NULL',   $char_d,
735         'shell',     'varchar',   'NULL',   $char_d,
736         'quota',     'varchar',   'NULL',   $char_d,
737         'slipip',    'varchar',   'NULL',   15, #four TINYINTs, bah.
738         'seconds',   'int', 'NULL',   '', #uhhhh
739         'domsvc',    'int', '',   '',
740       ],
741       'primary_key' => 'svcnum',
742       #'unique' => [ [ 'username', 'domsvc' ] ],
743       'unique' => [],
744       'index' => [ ['username'], ['domsvc'] ],
745     },
746
747     #'svc_charge' => {
748     #  'columns' => [
749     #    'svcnum',    'int',    '',   '',
750     #    'amount',    @money_type,
751     #  ],
752     #  'primary_key' => 'svcnum',
753     #  'unique' => [ [] ],
754     #  'index' => [ [] ],
755     #},
756
757     'svc_domain' => {
758       'columns' => [
759         'svcnum',    'int',    '',   '',
760         'domain',    'varchar',    '',   $char_d,
761         'catchall',  'int', 'NULL',    '',
762       ],
763       'primary_key' => 'svcnum',
764       'unique' => [ ['domain'] ],
765       'index' => [],
766     },
767
768     'domain_record' => {
769       'columns' => [
770         'recnum',    'serial',     '',  '',
771         'svcnum',    'int',     '',  '',
772         #'reczone',   'varchar', '',  $char_d,
773         'reczone',   'varchar', '',  255,
774         'recaf',     'char',    '',  2,
775         'rectype',   'varchar',    '',  5,
776         #'recdata',   'varchar', '',  $char_d,
777         'recdata',   'varchar', '',  255,
778       ],
779       'primary_key' => 'recnum',
780       'unique'      => [],
781       'index'       => [ ['svcnum'] ],
782     },
783
784     'svc_forward' => {
785       'columns' => [
786         'svcnum',   'int',            '',   '',
787         'srcsvc',   'int',        'NULL',   '',
788         'src',      'varchar',    'NULL',  255,
789         'dstsvc',   'int',        'NULL',   '',
790         'dst',      'varchar',    'NULL',  255,
791       ],
792       'primary_key' => 'svcnum',
793       'unique'      => [],
794       'index'       => [ ['srcsvc'], ['dstsvc'] ],
795     },
796
797     'svc_www' => {
798       'columns' => [
799         'svcnum',   'int',    '',  '',
800         'recnum',   'int',    '',  '',
801         'usersvc',  'int',    '',  '',
802       ],
803       'primary_key' => 'svcnum',
804       'unique'      => [],
805       'index'       => [],
806     },
807
808     #'svc_wo' => {
809     #  'columns' => [
810     #    'svcnum',    'int',    '',   '',
811     #    'svcnum',    'int',    '',   '',
812     #    'svcnum',    'int',    '',   '',
813     #    'worker',    'varchar',   '',   $char_d,
814     #    '_date',     @date_type,
815     #  ],
816     #  'primary_key' => 'svcnum',
817     #  'unique' => [ [] ],
818     #  'index' => [ [] ],
819     #},
820
821     'prepay_credit' => {
822       'columns' => [
823         'prepaynum',   'serial',     '',   '',
824         'identifier',  'varchar', '', $char_d,
825         'amount',      @money_type,
826         'seconds',     'int',     'NULL', '',
827         'agentnum',    'int',     'NULL', '',
828       ],
829       'primary_key' => 'prepaynum',
830       'unique'      => [ ['identifier'] ],
831       'index'       => [],
832     },
833
834     'port' => {
835       'columns' => [
836         'portnum',  'serial',     '',   '',
837         'ip',       'varchar', 'NULL', 15,
838         'nasport',  'int',     'NULL', '',
839         'nasnum',   'int',     '',   '',
840       ],
841       'primary_key' => 'portnum',
842       'unique'      => [],
843       'index'       => [],
844     },
845
846     'nas' => {
847       'columns' => [
848         'nasnum',   'serial',     '',    '',
849         'nas',      'varchar', '',    $char_d,
850         'nasip',    'varchar', '',    15,
851         'nasfqdn',  'varchar', '',    $char_d,
852         'last',     'int',     '',    '',
853       ],
854       'primary_key' => 'nasnum',
855       'unique'      => [ [ 'nas' ], [ 'nasip' ] ],
856       'index'       => [ [ 'last' ] ],
857     },
858
859     'session' => {
860       'columns' => [
861         'sessionnum', 'serial',       '',   '',
862         'portnum',    'int',       '',   '',
863         'svcnum',     'int',       '',   '',
864         'login',      @date_type,
865         'logout',     @date_type,
866       ],
867       'primary_key' => 'sessionnum',
868       'unique'      => [],
869       'index'       => [ [ 'portnum' ] ],
870     },
871
872     'queue' => {
873       'columns' => [
874         'jobnum', 'serial', '', '',
875         'job', 'text', '', '',
876         '_date', 'int', '', '',
877         'status', 'varchar', '', $char_d,
878         'statustext', 'text', 'NULL', '',
879         'svcnum', 'int', 'NULL', '',
880       ],
881       'primary_key' => 'jobnum',
882       'unique'      => [],
883       'index'       => [ [ 'svcnum' ], [ 'status' ] ],
884     },
885
886     'queue_arg' => {
887       'columns' => [
888         'argnum', 'serial', '', '',
889         'jobnum', 'int', '', '',
890         'arg', 'text', 'NULL', '',
891       ],
892       'primary_key' => 'argnum',
893       'unique'      => [],
894       'index'       => [ [ 'jobnum' ] ],
895     },
896
897     'queue_depend' => {
898       'columns' => [
899         'dependnum', 'serial', '', '',
900         'jobnum', 'int', '', '',
901         'depend_jobnum', 'int', '', '',
902       ],
903       'primary_key' => 'dependnum',
904       'unique'      => [],
905       'index'       => [ [ 'jobnum' ], [ 'depend_jobnum' ] ],
906     },
907
908     'export_svc' => {
909       'columns' => [
910         'exportsvcnum' => 'serial', '', '',
911         'exportnum'    => 'int', '', '',
912         'svcpart'      => 'int', '', '',
913       ],
914       'primary_key' => 'exportsvcnum',
915       'unique'      => [ [ 'exportnum', 'svcpart' ] ],
916       'index'       => [ [ 'exportnum' ], [ 'svcpart' ] ],
917     },
918
919     'part_export' => {
920       'columns' => [
921         'exportnum', 'serial', '', '',
922         #'svcpart',   'int', '', '',
923         'machine', 'varchar', '', $char_d,
924         'exporttype', 'varchar', '', $char_d,
925         'nodomain',     'char', 'NULL', 1,
926       ],
927       'primary_key' => 'exportnum',
928       'unique'      => [],
929       'index'       => [ [ 'machine' ], [ 'exporttype' ] ],
930     },
931
932     'part_export_option' => {
933       'columns' => [
934         'optionnum', 'serial', '', '',
935         'exportnum', 'int', '', '',
936         'optionname', 'varchar', '', $char_d,
937         'optionvalue', 'text', 'NULL', '',
938       ],
939       'primary_key' => 'optionnum',
940       'unique'      => [],
941       'index'       => [ [ 'exportnum' ], [ 'optionname' ] ],
942     },
943
944     'radius_usergroup' => {
945       'columns' => [
946         'usergroupnum', 'serial', '', '',
947         'svcnum',       'int', '', '',
948         'groupname',    'varchar', '', $char_d,
949       ],
950       'primary_key' => 'usergroupnum',
951       'unique'      => [],
952       'index'       => [ [ 'svcnum' ], [ 'groupname' ] ],
953     },
954
955     'msgcat' => {
956       'columns' => [
957         'msgnum', 'serial', '', '',
958         'msgcode', 'varchar', '', $char_d,
959         'locale', 'varchar', '', 16,
960         'msg', 'text', '', '',
961       ],
962       'primary_key' => 'msgnum',
963       'unique'      => [ [ 'msgcode', 'locale' ] ],
964       'index'       => [],
965     },
966
967     'cust_tax_exempt' => {
968       'columns' => [
969         'exemptnum', 'serial', '', '',
970         'custnum',   'int', '', '',
971         'taxnum',    'int', '', '',
972         'year',      'int', '', '',
973         'month',     'int', '', '',
974         'amount',   @money_type,
975       ],
976       'primary_key' => 'exemptnum',
977       'unique'      => [ [ 'custnum', 'taxnum', 'year', 'month' ] ],
978       'index'       => [],
979     },
980
981     'cust_tax_exempt_pkg' => {
982       'columns' => [
983         'exemptpkgnum',  'serial', '', '',
984         #'custnum',      'int', '', '',
985         'billpkgnum',   'int', '', '',
986         'taxnum',       'int', '', '',
987         'year',         'int', '', '',
988         'month',        'int', '', '',
989         'amount',       @money_type,
990       ],
991       'primary_key' => 'exemptpkgnum',
992       'unique' => [],
993       'index'  => [ [ 'taxnum', 'year', 'month' ],
994                     [ 'billpkgnum' ],
995                     [ 'taxnum' ]
996                   ],
997     },
998
999     'router' => {
1000       'columns' => [
1001         'routernum', 'serial', '', '',
1002         'routername', 'varchar', '', $char_d,
1003         'svcnum', 'int', 'NULL', '',
1004       ],
1005       'primary_key' => 'routernum',
1006       'unique'      => [],
1007       'index'       => [],
1008     },
1009
1010     'part_svc_router' => {
1011       'columns' => [
1012         'svcrouternum', 'serial', '', '',
1013         'svcpart', 'int', '', '',
1014         'routernum', 'int', '', '',
1015       ],
1016       'primary_key' => 'svcrouternum',
1017       'unique'      => [],
1018       'index'       => [],
1019     },
1020
1021     'addr_block' => {
1022       'columns' => [
1023         'blocknum', 'serial', '', '',
1024         'routernum', 'int', '', '',
1025         'ip_gateway', 'varchar', '', 15,
1026         'ip_netmask', 'int', '', '',
1027       ],
1028       'primary_key' => 'blocknum',
1029       'unique'      => [ [ 'blocknum', 'routernum' ] ],
1030       'index'       => [],
1031     },
1032
1033     'svc_broadband' => {
1034       'columns' => [
1035         'svcnum', 'int', '', '',
1036         'blocknum', 'int', '', '',
1037         'speed_up', 'int', '', '',
1038         'speed_down', 'int', '', '',
1039         'ip_addr', 'varchar', '', 15,
1040       ],
1041       'primary_key' => 'svcnum',
1042       'unique'      => [],
1043       'index'       => [],
1044     },
1045
1046     'part_virtual_field' => {
1047       'columns' => [
1048         'vfieldpart', 'int', '', '',
1049         'dbtable', 'varchar', '', 32,
1050         'name', 'varchar', '', 32,
1051         'check_block', 'text', 'NULL', '',
1052         'length', 'int', 'NULL', '',
1053         'list_source', 'text', 'NULL', '',
1054         'label', 'varchar', 'NULL', 80,
1055       ],
1056       'primary_key' => 'vfieldpart',
1057       'unique' => [],
1058       'index' => [],
1059     },
1060
1061     'virtual_field' => {
1062       'columns' => [
1063         'vfieldnum', 'serial', '', '',
1064         'recnum', 'int', '', '',
1065         'vfieldpart', 'int', '', '',
1066         'value', 'varchar', '', 128,
1067       ],
1068       'primary_key' => 'vfieldnum',
1069       'unique' => [ [ 'vfieldpart', 'recnum' ] ],
1070       'index' => [],
1071     },
1072
1073     'acct_snarf' => {
1074       'columns' => [
1075         'snarfnum',  'int', '', '',
1076         'svcnum',    'int', '', '',
1077         'machine',   'varchar', '', 255,
1078         'protocol',  'varchar', '', $char_d,
1079         'username',  'varchar', '', $char_d,
1080         '_password', 'varchar', '', $char_d,
1081       ],
1082       'primary_key' => 'snarfnum',
1083       'unique' => [],
1084       'index'  => [ [ 'svcnum' ] ],
1085     },
1086
1087     'svc_external' => {
1088       'columns' => [
1089         'svcnum', 'int', '', '',
1090         'id',     'int', 'NULL', '',
1091         'title',  'varchar', 'NULL', $char_d,
1092       ],
1093       'primary_key' => 'svcnum',
1094       'unique'      => [],
1095       'index'       => [],
1096     },
1097
1098     'cust_pay_refund' => {
1099       'columns' => [
1100         'payrefundnum', 'serial', '', '',
1101         'paynum',  'int', '', '',
1102         'refundnum',  'int', '', '',
1103         '_date',    @date_type,
1104         'amount',   @money_type,
1105       ],
1106       'primary_key' => 'payrefundnum',
1107       'unique' => [],
1108       'index' => [ ['paynum'], ['refundnum'] ],
1109     },
1110
1111     'part_pkg_option' => {
1112       'columns' => [
1113         'optionnum', 'serial', '', '',
1114         'pkgpart', 'int', '', '',
1115         'optionname', 'varchar', '', $char_d,
1116         'optionvalue', 'text', 'NULL', '',
1117       ],
1118       'primary_key' => 'optionnum',
1119       'unique'      => [],
1120       'index'       => [ [ 'pkgpart' ], [ 'optionname' ] ],
1121     },
1122
1123     'rate' => {
1124       'columns' => [
1125         'ratenum',  'serial', '', '',
1126         'ratename', 'varchar', '', $char_d,
1127       ],
1128       'primary_key' => 'ratenum',
1129       'unique'      => [],
1130       'index'       => [],
1131     },
1132
1133     'rate_detail' => {
1134       'columns' => [
1135         'ratedetailnum',   'serial', '', '',
1136         'ratenum',         'int',     '', '',
1137         'orig_regionnum',  'int', 'NULL', '',
1138         'dest_regionnum',  'int',     '', '',
1139         'min_included',    'int',     '', '',
1140         'min_charge',      @money_type,
1141         'sec_granularity', 'int',     '', '',
1142         #time period (link to table of periods)?
1143       ],
1144       'primary_key' => 'ratedetailnum',
1145       'unique'      => [ [ 'ratenum', 'orig_regionnum', 'dest_regionnum' ] ],
1146       'index'       => [ [ 'ratenum', 'dest_regionnum' ] ],
1147     },
1148
1149     'rate_region' => {
1150       'columns' => [
1151         'regionnum',   'serial',      '', '',
1152         'regionname',  'varchar',     '', $char_d,
1153       ],
1154       'primary_key' => 'regionnum',
1155       'unique'      => [],
1156       'index'       => [],
1157     },
1158
1159     'rate_prefix' => {
1160       'columns' => [
1161         'prefixnum',   'serial',    '', '',
1162         'regionnum',   'int',       '', '',,
1163         'countrycode', 'varchar',     '', 3,
1164         'npa',         'varchar', 'NULL', 6,
1165         'nxx',         'varchar', 'NULL', 3,
1166       ],
1167       'primary_key' => 'prefixnum',
1168       'unique'      => [],
1169       'index'       => [ [ 'countrycode' ], [ 'regionnum' ] ],
1170     },
1171
1172     'reg_code' => {
1173       'columns' => [
1174         'codenum',   'serial',    '', '',
1175         'code',      'varchar',   '', $char_d,
1176         'agentnum',  'int',       '', '',
1177       ],
1178       'primary_key' => 'codenum',
1179       'unique'      => [ [ 'agentnum', 'code' ] ],
1180       'index'       => [ [ 'agentnum' ] ],
1181     },
1182
1183     'reg_code_pkg' => {
1184       'columns' => [
1185         'codepkgnum', 'serial', '', '',
1186         'codenum',   'int',    '', '',
1187         'pkgpart',   'int',    '', '',
1188       ],
1189       'primary_key' => 'codepkgnum',
1190       'unique'      => [ [ 'codenum', 'pkgpart' ] ],
1191       'index'       => [ [ 'codenum' ] ],
1192     },
1193
1194     'clientapi_session' => {
1195       'columns' => [
1196         'sessionnum',  'serial',  '', '',
1197         'sessionid',  'varchar',  '', $char_d,
1198         'namespace',  'varchar',  '', $char_d,
1199       ],
1200       'primary_key' => 'sessionnum',
1201       'unique'      => [ [ 'sessionid', 'namespace' ] ],
1202       'index'       => [],
1203     },
1204
1205     'clientapi_session_field' => {
1206       'columns' => [
1207         'fieldnum',    'serial',     '', '',
1208         'sessionnum',     'int',     '', '',
1209         'fieldname',  'varchar',     '', $char_d,
1210         'fieldvalue',    'text', 'NULL', '',
1211       ],
1212       'primary_key' => 'fieldnum',
1213       'unique'      => [ [ 'sessionnum', 'fieldname' ] ],
1214       'index'       => [],
1215     },
1216
1217     'payment_gateway' => {
1218       'columns' => [
1219         'gatewaynum',       'serial',   '',     '',
1220         'gateway_module',   'varchar',  '',     $char_d,
1221         'gateway_username', 'varchar',  'NULL', $char_d,
1222         'gateway_password', 'varchar',  'NULL', $char_d,
1223         'gateway_action',   'varchar',  'NULL', $char_d,
1224         'disabled',   'char',  'NULL',   1,
1225       ],
1226       'primary_key' => 'gatewaynum',
1227       'unique' => [],
1228       'index'  => [ [ 'disabled' ] ],
1229     },
1230
1231     'payment_gateway_option' => {
1232       'columns' => [
1233         'optionnum',   'serial',  '',     '',
1234         'gatewaynum',  'int',     '',     '',
1235         'optionname',  'varchar', '',     $char_d,
1236         'optionvalue', 'text',    'NULL', '',
1237       ],
1238       'primary_key' => 'optionnum',
1239       'unique'      => [],
1240       'index'       => [ [ 'gatewaynum' ], [ 'optionname' ] ],
1241     },
1242
1243     'agent_payment_gateway' => {
1244       'columns' => [
1245         'agentgatewaynum', 'serial', '', '',
1246         'agentnum',        'int', '', '',
1247         'gatewaynum',      'int', '', '',
1248         'cardtype',        'varchar', 'NULL', $char_d,
1249         'taxclass',        'varchar', 'NULL', $char_d,
1250       ],
1251       'primary_key' => 'agentgatewaynum',
1252       'unique'      => [],
1253       'index'       => [ [ 'agentnum', 'cardtype' ], ],
1254     },
1255
1256     'banned_pay' => {
1257       'columns' => [
1258         'bannum',  'serial',   '',     '',
1259         'payby',   'char',     '',       4,
1260         'payinfo', 'varchar',  '',     128, #say, a 512-big digest _hex encoded
1261         #'paymask', 'varchar',  'NULL', $char_d,
1262         '_date',   @date_type,
1263         'otaker',  'varchar',  '',     32,
1264         'reason',  'varchar',  'NULL', $char_d,
1265       ],
1266       'primary_key' => 'bannum',
1267       'unique'      => [ [ 'payby', 'payinfo' ] ],
1268       'index'       => [],
1269     },
1270
1271     'cancel_reason' => {
1272       'columns' => [
1273         'reasonnum', 'serial',  '',     '',
1274         'reason',    'varchar', '',     $char_d,
1275         'disabled',  'char',    'NULL', 1,
1276       ],
1277       'primary_key' => 'reasonnum',
1278       'unique' => [],
1279       'index'  => [ [ 'disabled' ] ],
1280     },
1281
1282     'pkg_class' => {
1283       'columns' => [
1284         'classnum',   'serial',  '', '',
1285         'classname',  'varchar', '', $char_d,
1286       ],
1287       'primary_key' => 'classnum',
1288       'unique' => [],
1289       'index' => [],
1290     },
1291
1292   };
1293
1294 }
1295
1296 =back
1297
1298 =head1 BUGS
1299
1300 =head1 SEE ALSO
1301
1302 L<DBIx::DBSchema>
1303
1304 =cut
1305
1306 1;
1307