whew, FINALLY can fix monthly exemption columns to work correctly. also make them...
[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         'payby',       'char',  '', 4,
311         'event',       'varchar',           '',     $char_d,
312         'eventcode',    @perl_type,
313         'seconds',     'int', 'NULL', '',
314         'weight',      'int', '', '',
315         'plan',       'varchar', 'NULL', $char_d,
316         'plandata',   'text', 'NULL', '',
317         'disabled',     'char', 'NULL', 1,
318       ],
319       'primary_key' => 'eventpart',
320       'unique' => [],
321       'index' => [ ['payby'], ['disabled'], ],
322     },
323
324     'cust_bill_pkg' => {
325       'columns' => [
326         'billpkgnum', 'serial', '', '',
327         'pkgnum',  'int', '', '',
328         'invnum',  'int', '', '',
329         'setup',   @money_type,
330         'recur',   @money_type,
331         'sdate',   @date_type,
332         'edate',   @date_type,
333         'itemdesc', 'varchar', 'NULL', $char_d,
334       ],
335       'primary_key' => 'billpkgnum',
336       'unique' => [],
337       'index' => [ ['invnum'], [ 'pkgnum' ] ],
338     },
339
340     'cust_bill_pkg_detail' => {
341       'columns' => [
342         'detailnum', 'serial', '', '',
343         'pkgnum',  'int', '', '',
344         'invnum',  'int', '', '',
345         'detail',  'varchar', '', $char_d,
346       ],
347       'primary_key' => 'detailnum',
348       'unique' => [],
349       'index' => [ [ 'pkgnum', 'invnum' ] ],
350     },
351
352     'cust_credit' => {
353       'columns' => [
354         'crednum',  'serial', '', '',
355         'custnum',  'int', '', '',
356         '_date',    @date_type,
357         'amount',   @money_type,
358         'otaker',   'varchar', '', 32,
359         'reason',   'text', 'NULL', '',
360         'closed',    'char', 'NULL', 1,
361       ],
362       'primary_key' => 'crednum',
363       'unique' => [],
364       'index' => [ ['custnum'] ],
365     },
366
367     'cust_credit_bill' => {
368       'columns' => [
369         'creditbillnum', 'serial', '', '',
370         'crednum',  'int', '', '',
371         'invnum',  'int', '', '',
372         '_date',    @date_type,
373         'amount',   @money_type,
374       ],
375       'primary_key' => 'creditbillnum',
376       'unique' => [],
377       'index' => [ ['crednum'], ['invnum'] ],
378     },
379
380     'cust_main' => {
381       'columns' => [
382         'custnum',  'serial',  '',     '',
383         'agentnum', 'int',  '',     '',
384 #        'titlenum', 'int',  'NULL',   '',
385         'last',     'varchar', '',     $char_d,
386 #        'middle',   'varchar', 'NULL', $char_d,
387         'first',    'varchar', '',     $char_d,
388         'ss',       'varchar', 'NULL', 11,
389         'company',  'varchar', 'NULL', $char_d,
390         'address1', 'varchar', '',     $char_d,
391         'address2', 'varchar', 'NULL', $char_d,
392         'city',     'varchar', '',     $char_d,
393         'county',   'varchar', 'NULL', $char_d,
394         'state',    'varchar', 'NULL', $char_d,
395         'zip',      'varchar', 'NULL', 10,
396         'country',  'char', '',     2,
397         'daytime',  'varchar', 'NULL', 20,
398         'night',    'varchar', 'NULL', 20,
399         'fax',      'varchar', 'NULL', 12,
400         'ship_last',     'varchar', 'NULL', $char_d,
401 #        'ship_middle',   'varchar', 'NULL', $char_d,
402         'ship_first',    'varchar', 'NULL', $char_d,
403         'ship_company',  'varchar', 'NULL', $char_d,
404         'ship_address1', 'varchar', 'NULL', $char_d,
405         'ship_address2', 'varchar', 'NULL', $char_d,
406         'ship_city',     'varchar', 'NULL', $char_d,
407         'ship_county',   'varchar', 'NULL', $char_d,
408         'ship_state',    'varchar', 'NULL', $char_d,
409         'ship_zip',      'varchar', 'NULL', 10,
410         'ship_country',  'char', 'NULL', 2,
411         'ship_daytime',  'varchar', 'NULL', 20,
412         'ship_night',    'varchar', 'NULL', 20,
413         'ship_fax',      'varchar', 'NULL', 12,
414         'payby',    'char', '',     4,
415         'payinfo',  'varchar', 'NULL', 512,
416         'paycvv',   'varchar', 'NULL', 512,
417         'paymask', 'varchar', 'NULL', $char_d,
418         #'paydate',  @date_type,
419         'paydate',  'varchar', 'NULL', 10,
420         'paystart_month', 'int', 'NULL', '',
421         'paystart_year',  'int', 'NULL', '',
422         'payissue', 'varchar', 'NULL', 2,
423         'payname',  'varchar', 'NULL', $char_d,
424         'payip',    'varchar', 'NULL', 15,
425         'tax',      'char', 'NULL', 1,
426         'otaker',   'varchar', '',    32,
427         'refnum',   'int',  '',     '',
428         'referral_custnum', 'int',  'NULL', '',
429         'comments', 'text', 'NULL', '',
430       ],
431       'primary_key' => 'custnum',
432       'unique' => [],
433       #'index' => [ ['last'], ['company'] ],
434       'index' => [ ['last'], [ 'company' ], [ 'referral_custnum' ],
435                    [ 'daytime' ], [ 'night' ], [ 'fax' ], [ 'refnum' ],
436                    [ 'county' ], [ 'state' ], [ 'country' ]
437                  ],
438     },
439
440     'cust_main_invoice' => {
441       'columns' => [
442         'destnum',  'serial',  '',     '',
443         'custnum',  'int',  '',     '',
444         'dest',     'varchar', '',  $char_d,
445       ],
446       'primary_key' => 'destnum',
447       'unique' => [],
448       'index' => [ ['custnum'], ],
449     },
450
451     'cust_main_county' => { #county+state+country are checked off the
452                             #cust_main_county for validation and to provide
453                             # a tax rate.
454       'columns' => [
455         'taxnum',   'serial',   '',    '',
456         'state',    'varchar',  'NULL',    $char_d,
457         'county',   'varchar',  'NULL',    $char_d,
458         'country',  'char',  '', 2, 
459         'taxclass',   'varchar', 'NULL', $char_d,
460         'exempt_amount', @money_type,
461         'tax',      'real',  '',    '', #tax %
462         'taxname',  'varchar',  'NULL',    $char_d,
463         'setuptax',  'char', 'NULL', 1, # Y = setup tax exempt
464         'recurtax',  'char', 'NULL', 1, # Y = recur tax exempt
465       ],
466       'primary_key' => 'taxnum',
467       'unique' => [],
468   #    'unique' => [ ['taxnum'], ['state', 'county'] ],
469       'index' => [ [ 'county' ], [ 'state' ], [ 'country' ] ],
470     },
471
472     'cust_pay' => {
473       'columns' => [
474         'paynum',   'serial',    '',   '',
475         #now cust_bill_pay #'invnum',   'int',    '',   '',
476         'custnum',  'int',    '',   '',
477         'paid',     @money_type,
478         '_date',    @date_type,
479         'payby',    'char',   '',     4, # CARD/BILL/COMP, should be index into
480                                          # payment type table.
481         'payinfo',  'varchar',   'NULL', $char_d,  #see cust_main above
482         'paybatch', 'varchar',   'NULL', $char_d, #for auditing purposes.
483         'closed',    'char', 'NULL', 1,
484       ],
485       'primary_key' => 'paynum',
486       'unique' => [],
487       'index' => [ [ 'custnum' ], [ 'paybatch' ], [ 'payby' ], [ '_date' ] ],
488     },
489
490     'cust_pay_void' => {
491       'columns' => [
492         'paynum',    'int',    '',   '',
493         'custnum',   'int',    '',   '',
494         'paid',      @money_type,
495         '_date',     @date_type,
496         'payby',     'char',   '',     4, # CARD/BILL/COMP, should be index into
497                                           # payment type table.
498         'payinfo',   'varchar',   'NULL', $char_d,  #see cust_main above
499         'paybatch',  'varchar',   'NULL', $char_d, #for auditing purposes.
500         'closed',    'char', 'NULL', 1,
501         'void_date', @date_type,
502         'reason',    'varchar',   'NULL', $char_d,
503         'otaker',   'varchar', '', 32,
504       ],
505       'primary_key' => 'paynum',
506       'unique' => [],
507       'index' => [ [ 'custnum' ] ],
508     },
509
510     'cust_bill_pay' => {
511       'columns' => [
512         'billpaynum', 'serial',     '',   '',
513         'invnum',  'int',     '',   '',
514         'paynum',  'int',     '',   '',
515         'amount',  @money_type,
516         '_date',   @date_type
517       ],
518       'primary_key' => 'billpaynum',
519       'unique' => [],
520       'index' => [ [ 'paynum' ], [ 'invnum' ] ],
521     },
522
523     'cust_pay_batch' => { #what's this used for again?  list of customers
524                           #in current CARD batch? (necessarily CARD?)
525       'columns' => [
526         'paybatchnum',   'serial',    '',   '',
527         'invnum',   'int',    '',   '',
528         'custnum',   'int',    '',   '',
529         'last',     'varchar', '',     $char_d,
530         'first',    'varchar', '',     $char_d,
531         'address1', 'varchar', '',     $char_d,
532         'address2', 'varchar', 'NULL', $char_d,
533         'city',     'varchar', '',     $char_d,
534         'state',    'varchar', 'NULL', $char_d,
535         'zip',      'varchar', 'NULL', 10,
536         'country',  'char', '',     2,
537 #        'trancode', 'int', '', '',
538         'cardnum',  'varchar', '',     16,
539         #'exp',      @date_type,
540         'exp',      'varchar', '',     11,
541         'payname',  'varchar', 'NULL', $char_d,
542         'amount',   @money_type,
543       ],
544       'primary_key' => 'paybatchnum',
545       'unique' => [],
546       'index' => [ ['invnum'], ['custnum'] ],
547     },
548
549     'cust_pkg' => {
550       'columns' => [
551         'pkgnum',    'serial',    '',   '',
552         'custnum',   'int',    '',   '',
553         'pkgpart',   'int',    '',   '',
554         'otaker',    'varchar', '', 32,
555         'setup',     @date_type,
556         'bill',      @date_type,
557         'last_bill', @date_type,
558         'susp',      @date_type,
559         'cancel',    @date_type,
560         'expire',    @date_type,
561         'manual_flag', 'char', 'NULL', 1,
562       ],
563       'primary_key' => 'pkgnum',
564       'unique' => [],
565       'index' => [ ['custnum'], ['pkgpart'] ],
566     },
567
568     'cust_refund' => {
569       'columns' => [
570         'refundnum',    'serial',    '',   '',
571         #now cust_credit_refund #'crednum',      'int',    '',   '',
572         'custnum',  'int',    '',   '',
573         '_date',        @date_type,
574         'refund',       @money_type,
575         'otaker',       'varchar',   '',   32,
576         'reason',       'varchar',   '',   $char_d,
577         'payby',        'char',   '',     4, # CARD/BILL/COMP, should be index
578                                              # into payment type table.
579         'payinfo',      'varchar',   'NULL', $char_d,  #see cust_main above
580         'paybatch',     'varchar',   'NULL', $char_d,
581         'closed',    'char', 'NULL', 1,
582       ],
583       'primary_key' => 'refundnum',
584       'unique' => [],
585       'index' => [],
586     },
587
588     'cust_credit_refund' => {
589       'columns' => [
590         'creditrefundnum', 'serial',     '',   '',
591         'crednum',  'int',     '',   '',
592         'refundnum',  'int',     '',   '',
593         'amount',  @money_type,
594         '_date',   @date_type
595       ],
596       'primary_key' => 'creditrefundnum',
597       'unique' => [],
598       'index' => [ [ 'crednum', 'refundnum' ] ],
599     },
600
601
602     'cust_svc' => {
603       'columns' => [
604         'svcnum',    'serial',    '',   '',
605         'pkgnum',    'int',    'NULL',   '',
606         'svcpart',   'int',    '',   '',
607       ],
608       'primary_key' => 'svcnum',
609       'unique' => [],
610       'index' => [ ['svcnum'], ['pkgnum'], ['svcpart'] ],
611     },
612
613     'part_pkg' => {
614       'columns' => [
615         'pkgpart',    'serial',    '',   '',
616         'pkg',        'varchar',   '',   $char_d,
617         'comment',    'varchar',   '',   $char_d,
618         'promo_code', 'varchar', 'NULL', $char_d,
619         'setup',      @perl_type,
620         'freq',       'varchar',   '',   $char_d,  #billing frequency
621         'recur',      @perl_type,
622         'setuptax',  'char', 'NULL', 1,
623         'recurtax',  'char', 'NULL', 1,
624         'plan',       'varchar', 'NULL', $char_d,
625         'plandata',   'text', 'NULL', '',
626         'disabled',   'char', 'NULL', 1,
627         'taxclass',   'varchar', 'NULL', $char_d,
628         'classnum',   'int',     'NULL', '',
629       ],
630       'primary_key' => 'pkgpart',
631       'unique' => [],
632       'index' => [ [ 'promo_code' ], [ 'disabled' ] ],
633     },
634
635 #    'part_title' => {
636 #      'columns' => [
637 #        'titlenum',   'int',    '',   '',
638 #        'title',      'varchar',   '',   $char_d,
639 #      ],
640 #      'primary_key' => 'titlenum',
641 #      'unique' => [ [] ],
642 #      'index' => [ [] ],
643 #    },
644
645     'pkg_svc' => {
646       'columns' => [
647         'pkgsvcnum',  'serial', '',  '',
648         'pkgpart',    'int',    '',   '',
649         'svcpart',    'int',    '',   '',
650         'quantity',   'int',    '',   '',
651         'primary_svc','char', 'NULL',  1,
652       ],
653       'primary_key' => 'pkgsvcnum',
654       'unique' => [ ['pkgpart', 'svcpart'] ],
655       'index' => [ ['pkgpart'] ],
656     },
657
658     'part_referral' => {
659       'columns' => [
660         'refnum',   'serial',    '',   '',
661         'referral', 'varchar',   '',   $char_d,
662         'disabled',     'char', 'NULL', 1,
663       ],
664       'primary_key' => 'refnum',
665       'unique' => [],
666       'index' => [ ['disabled'] ],
667     },
668
669     'part_svc' => {
670       'columns' => [
671         'svcpart',    'serial',    '',   '',
672         'svc',        'varchar',   '',   $char_d,
673         'svcdb',      'varchar',   '',   $char_d,
674         'disabled',   'char',  'NULL',   1,
675       ],
676       'primary_key' => 'svcpart',
677       'unique' => [],
678       'index' => [ [ 'disabled' ] ],
679     },
680
681     'part_svc_column' => {
682       'columns' => [
683         'columnnum',   'serial',         '', '',
684         'svcpart',     'int',         '', '',
685         'columnname',  'varchar',     '', 64,
686         'columnvalue', 'varchar', 'NULL', $char_d,
687         'columnflag',  'char',    'NULL', 1, 
688       ],
689       'primary_key' => 'columnnum',
690       'unique' => [ [ 'svcpart', 'columnname' ] ],
691       'index' => [ [ 'svcpart' ] ],
692     },
693
694     #(this should be renamed to part_pop)
695     'svc_acct_pop' => {
696       'columns' => [
697         'popnum',    'serial',    '',   '',
698         'city',      'varchar',   '',   $char_d,
699         'state',     'varchar',   '',   $char_d,
700         'ac',        'char',   '',   3,
701         'exch',      'char',   '',   3,
702         'loc',       'char',   'NULL',   4, #NULL for legacy purposes
703       ],
704       'primary_key' => 'popnum',
705       'unique' => [],
706       'index' => [ [ 'state' ] ],
707     },
708
709     'part_pop_local' => {
710       'columns' => [
711         'localnum',  'serial',     '',     '',
712         'popnum',    'int',     '',     '',
713         'city',      'varchar', 'NULL', $char_d,
714         'state',     'char',    'NULL', 2,
715         'npa',       'char',    '',     3,
716         'nxx',       'char',    '',     3,
717       ],
718       'primary_key' => 'localnum',
719       'unique' => [],
720       'index' => [ [ 'npa', 'nxx' ], [ 'popnum' ] ],
721     },
722
723     'svc_acct' => {
724       'columns' => [
725         'svcnum',    'int',    '',   '',
726         'username',  'varchar',   '',   $username_len, #unique (& remove dup code)
727         '_password', 'varchar',   '',   72, #13 for encryped pw's plus ' *SUSPENDED* (md5 passwords can be 34, blowfish 60)
728         'sec_phrase', 'varchar',  'NULL',   $char_d,
729         'popnum',    'int',    'NULL',   '',
730         'uid',       'int', 'NULL',   '',
731         'gid',       'int', 'NULL',   '',
732         'finger',    'varchar',   'NULL',   $char_d,
733         'dir',       'varchar',   'NULL',   $char_d,
734         'shell',     'varchar',   'NULL',   $char_d,
735         'quota',     'varchar',   'NULL',   $char_d,
736         'slipip',    'varchar',   'NULL',   15, #four TINYINTs, bah.
737         'seconds',   'int', 'NULL',   '', #uhhhh
738         'domsvc',    'int', '',   '',
739       ],
740       'primary_key' => 'svcnum',
741       #'unique' => [ [ 'username', 'domsvc' ] ],
742       'unique' => [],
743       'index' => [ ['username'], ['domsvc'] ],
744     },
745
746     #'svc_charge' => {
747     #  'columns' => [
748     #    'svcnum',    'int',    '',   '',
749     #    'amount',    @money_type,
750     #  ],
751     #  'primary_key' => 'svcnum',
752     #  'unique' => [ [] ],
753     #  'index' => [ [] ],
754     #},
755
756     'svc_domain' => {
757       'columns' => [
758         'svcnum',    'int',    '',   '',
759         'domain',    'varchar',    '',   $char_d,
760         'catchall',  'int', 'NULL',    '',
761       ],
762       'primary_key' => 'svcnum',
763       'unique' => [ ['domain'] ],
764       'index' => [],
765     },
766
767     'domain_record' => {
768       'columns' => [
769         'recnum',    'serial',     '',  '',
770         'svcnum',    'int',     '',  '',
771         #'reczone',   'varchar', '',  $char_d,
772         'reczone',   'varchar', '',  255,
773         'recaf',     'char',    '',  2,
774         'rectype',   'varchar',    '',  5,
775         #'recdata',   'varchar', '',  $char_d,
776         'recdata',   'varchar', '',  255,
777       ],
778       'primary_key' => 'recnum',
779       'unique'      => [],
780       'index'       => [ ['svcnum'] ],
781     },
782
783     'svc_forward' => {
784       'columns' => [
785         'svcnum',   'int',            '',   '',
786         'srcsvc',   'int',        'NULL',   '',
787         'src',      'varchar',    'NULL',  255,
788         'dstsvc',   'int',        'NULL',   '',
789         'dst',      'varchar',    'NULL',  255,
790       ],
791       'primary_key' => 'svcnum',
792       'unique'      => [],
793       'index'       => [ ['srcsvc'], ['dstsvc'] ],
794     },
795
796     'svc_www' => {
797       'columns' => [
798         'svcnum',   'int',    '',  '',
799         'recnum',   'int',    '',  '',
800         'usersvc',  'int',    '',  '',
801       ],
802       'primary_key' => 'svcnum',
803       'unique'      => [],
804       'index'       => [],
805     },
806
807     #'svc_wo' => {
808     #  'columns' => [
809     #    'svcnum',    'int',    '',   '',
810     #    'svcnum',    'int',    '',   '',
811     #    'svcnum',    'int',    '',   '',
812     #    'worker',    'varchar',   '',   $char_d,
813     #    '_date',     @date_type,
814     #  ],
815     #  'primary_key' => 'svcnum',
816     #  'unique' => [ [] ],
817     #  'index' => [ [] ],
818     #},
819
820     'prepay_credit' => {
821       'columns' => [
822         'prepaynum',   'serial',     '',   '',
823         'identifier',  'varchar', '', $char_d,
824         'amount',      @money_type,
825         'seconds',     'int',     'NULL', '',
826         'agentnum',    'int',     'NULL', '',
827       ],
828       'primary_key' => 'prepaynum',
829       'unique'      => [ ['identifier'] ],
830       'index'       => [],
831     },
832
833     'port' => {
834       'columns' => [
835         'portnum',  'serial',     '',   '',
836         'ip',       'varchar', 'NULL', 15,
837         'nasport',  'int',     'NULL', '',
838         'nasnum',   'int',     '',   '',
839       ],
840       'primary_key' => 'portnum',
841       'unique'      => [],
842       'index'       => [],
843     },
844
845     'nas' => {
846       'columns' => [
847         'nasnum',   'serial',     '',    '',
848         'nas',      'varchar', '',    $char_d,
849         'nasip',    'varchar', '',    15,
850         'nasfqdn',  'varchar', '',    $char_d,
851         'last',     'int',     '',    '',
852       ],
853       'primary_key' => 'nasnum',
854       'unique'      => [ [ 'nas' ], [ 'nasip' ] ],
855       'index'       => [ [ 'last' ] ],
856     },
857
858     'session' => {
859       'columns' => [
860         'sessionnum', 'serial',       '',   '',
861         'portnum',    'int',       '',   '',
862         'svcnum',     'int',       '',   '',
863         'login',      @date_type,
864         'logout',     @date_type,
865       ],
866       'primary_key' => 'sessionnum',
867       'unique'      => [],
868       'index'       => [ [ 'portnum' ] ],
869     },
870
871     'queue' => {
872       'columns' => [
873         'jobnum', 'serial', '', '',
874         'job', 'text', '', '',
875         '_date', 'int', '', '',
876         'status', 'varchar', '', $char_d,
877         'statustext', 'text', 'NULL', '',
878         'svcnum', 'int', 'NULL', '',
879       ],
880       'primary_key' => 'jobnum',
881       'unique'      => [],
882       'index'       => [ [ 'svcnum' ], [ 'status' ] ],
883     },
884
885     'queue_arg' => {
886       'columns' => [
887         'argnum', 'serial', '', '',
888         'jobnum', 'int', '', '',
889         'arg', 'text', 'NULL', '',
890       ],
891       'primary_key' => 'argnum',
892       'unique'      => [],
893       'index'       => [ [ 'jobnum' ] ],
894     },
895
896     'queue_depend' => {
897       'columns' => [
898         'dependnum', 'serial', '', '',
899         'jobnum', 'int', '', '',
900         'depend_jobnum', 'int', '', '',
901       ],
902       'primary_key' => 'dependnum',
903       'unique'      => [],
904       'index'       => [ [ 'jobnum' ], [ 'depend_jobnum' ] ],
905     },
906
907     'export_svc' => {
908       'columns' => [
909         'exportsvcnum' => 'serial', '', '',
910         'exportnum'    => 'int', '', '',
911         'svcpart'      => 'int', '', '',
912       ],
913       'primary_key' => 'exportsvcnum',
914       'unique'      => [ [ 'exportnum', 'svcpart' ] ],
915       'index'       => [ [ 'exportnum' ], [ 'svcpart' ] ],
916     },
917
918     'part_export' => {
919       'columns' => [
920         'exportnum', 'serial', '', '',
921         #'svcpart',   'int', '', '',
922         'machine', 'varchar', '', $char_d,
923         'exporttype', 'varchar', '', $char_d,
924         'nodomain',     'char', 'NULL', 1,
925       ],
926       'primary_key' => 'exportnum',
927       'unique'      => [],
928       'index'       => [ [ 'machine' ], [ 'exporttype' ] ],
929     },
930
931     'part_export_option' => {
932       'columns' => [
933         'optionnum', 'serial', '', '',
934         'exportnum', 'int', '', '',
935         'optionname', 'varchar', '', $char_d,
936         'optionvalue', 'text', 'NULL', '',
937       ],
938       'primary_key' => 'optionnum',
939       'unique'      => [],
940       'index'       => [ [ 'exportnum' ], [ 'optionname' ] ],
941     },
942
943     'radius_usergroup' => {
944       'columns' => [
945         'usergroupnum', 'serial', '', '',
946         'svcnum',       'int', '', '',
947         'groupname',    'varchar', '', $char_d,
948       ],
949       'primary_key' => 'usergroupnum',
950       'unique'      => [],
951       'index'       => [ [ 'svcnum' ], [ 'groupname' ] ],
952     },
953
954     'msgcat' => {
955       'columns' => [
956         'msgnum', 'serial', '', '',
957         'msgcode', 'varchar', '', $char_d,
958         'locale', 'varchar', '', 16,
959         'msg', 'text', '', '',
960       ],
961       'primary_key' => 'msgnum',
962       'unique'      => [ [ 'msgcode', 'locale' ] ],
963       'index'       => [],
964     },
965
966     'cust_tax_exempt' => {
967       'columns' => [
968         'exemptnum', 'serial', '', '',
969         'custnum',   'int', '', '',
970         'taxnum',    'int', '', '',
971         'year',      'int', '', '',
972         'month',     'int', '', '',
973         'amount',   @money_type,
974       ],
975       'primary_key' => 'exemptnum',
976       'unique'      => [ [ 'custnum', 'taxnum', 'year', 'month' ] ],
977       'index'       => [],
978     },
979
980     'cust_tax_exempt_pkg' => {
981       'columns' => [
982         'exemptpkgnum',  'serial', '', '',
983         #'custnum',      'int', '', '',
984         'billpkgnum',   'int', '', '',
985         'taxnum',       'int', '', '',
986         'year',         'int', '', '',
987         'month',        'int', '', '',
988         'amount',       @money_type,
989       ],
990       'primary_key' => 'exemptpkgnum',
991       'unique' => [],
992       'index'  => [ [ 'taxnum', 'year', 'month' ],
993                     [ 'billpkgnum' ],
994                     [ 'taxnum' ]
995                   ],
996     },
997
998     'router' => {
999       'columns' => [
1000         'routernum', 'serial', '', '',
1001         'routername', 'varchar', '', $char_d,
1002         'svcnum', 'int', 'NULL', '',
1003       ],
1004       'primary_key' => 'routernum',
1005       'unique'      => [],
1006       'index'       => [],
1007     },
1008
1009     'part_svc_router' => {
1010       'columns' => [
1011         'svcrouternum', 'serial', '', '',
1012         'svcpart', 'int', '', '',
1013         'routernum', 'int', '', '',
1014       ],
1015       'primary_key' => 'svcrouternum',
1016       'unique'      => [],
1017       'index'       => [],
1018     },
1019
1020     'addr_block' => {
1021       'columns' => [
1022         'blocknum', 'serial', '', '',
1023         'routernum', 'int', '', '',
1024         'ip_gateway', 'varchar', '', 15,
1025         'ip_netmask', 'int', '', '',
1026       ],
1027       'primary_key' => 'blocknum',
1028       'unique'      => [ [ 'blocknum', 'routernum' ] ],
1029       'index'       => [],
1030     },
1031
1032     'svc_broadband' => {
1033       'columns' => [
1034         'svcnum', 'int', '', '',
1035         'blocknum', 'int', '', '',
1036         'speed_up', 'int', '', '',
1037         'speed_down', 'int', '', '',
1038         'ip_addr', 'varchar', '', 15,
1039       ],
1040       'primary_key' => 'svcnum',
1041       'unique'      => [],
1042       'index'       => [],
1043     },
1044
1045     'part_virtual_field' => {
1046       'columns' => [
1047         'vfieldpart', 'int', '', '',
1048         'dbtable', 'varchar', '', 32,
1049         'name', 'varchar', '', 32,
1050         'check_block', 'text', 'NULL', '',
1051         'length', 'int', 'NULL', '',
1052         'list_source', 'text', 'NULL', '',
1053         'label', 'varchar', 'NULL', 80,
1054       ],
1055       'primary_key' => 'vfieldpart',
1056       'unique' => [],
1057       'index' => [],
1058     },
1059
1060     'virtual_field' => {
1061       'columns' => [
1062         'vfieldnum', 'serial', '', '',
1063         'recnum', 'int', '', '',
1064         'vfieldpart', 'int', '', '',
1065         'value', 'varchar', '', 128,
1066       ],
1067       'primary_key' => 'vfieldnum',
1068       'unique' => [ [ 'vfieldpart', 'recnum' ] ],
1069       'index' => [],
1070     },
1071
1072     'acct_snarf' => {
1073       'columns' => [
1074         'snarfnum',  'int', '', '',
1075         'svcnum',    'int', '', '',
1076         'machine',   'varchar', '', 255,
1077         'protocol',  'varchar', '', $char_d,
1078         'username',  'varchar', '', $char_d,
1079         '_password', 'varchar', '', $char_d,
1080       ],
1081       'primary_key' => 'snarfnum',
1082       'unique' => [],
1083       'index'  => [ [ 'svcnum' ] ],
1084     },
1085
1086     'svc_external' => {
1087       'columns' => [
1088         'svcnum', 'int', '', '',
1089         'id',     'int', 'NULL', '',
1090         'title',  'varchar', 'NULL', $char_d,
1091       ],
1092       'primary_key' => 'svcnum',
1093       'unique'      => [],
1094       'index'       => [],
1095     },
1096
1097     'cust_pay_refund' => {
1098       'columns' => [
1099         'payrefundnum', 'serial', '', '',
1100         'paynum',  'int', '', '',
1101         'refundnum',  'int', '', '',
1102         '_date',    @date_type,
1103         'amount',   @money_type,
1104       ],
1105       'primary_key' => 'payrefundnum',
1106       'unique' => [],
1107       'index' => [ ['paynum'], ['refundnum'] ],
1108     },
1109
1110     'part_pkg_option' => {
1111       'columns' => [
1112         'optionnum', 'serial', '', '',
1113         'pkgpart', 'int', '', '',
1114         'optionname', 'varchar', '', $char_d,
1115         'optionvalue', 'text', 'NULL', '',
1116       ],
1117       'primary_key' => 'optionnum',
1118       'unique'      => [],
1119       'index'       => [ [ 'pkgpart' ], [ 'optionname' ] ],
1120     },
1121
1122     'rate' => {
1123       'columns' => [
1124         'ratenum',  'serial', '', '',
1125         'ratename', 'varchar', '', $char_d,
1126       ],
1127       'primary_key' => 'ratenum',
1128       'unique'      => [],
1129       'index'       => [],
1130     },
1131
1132     'rate_detail' => {
1133       'columns' => [
1134         'ratedetailnum',   'serial', '', '',
1135         'ratenum',         'int',     '', '',
1136         'orig_regionnum',  'int', 'NULL', '',
1137         'dest_regionnum',  'int',     '', '',
1138         'min_included',    'int',     '', '',
1139         'min_charge',      @money_type,
1140         'sec_granularity', 'int',     '', '',
1141         #time period (link to table of periods)?
1142       ],
1143       'primary_key' => 'ratedetailnum',
1144       'unique'      => [ [ 'ratenum', 'orig_regionnum', 'dest_regionnum' ] ],
1145       'index'       => [ [ 'ratenum', 'dest_regionnum' ] ],
1146     },
1147
1148     'rate_region' => {
1149       'columns' => [
1150         'regionnum',   'serial',      '', '',
1151         'regionname',  'varchar',     '', $char_d,
1152       ],
1153       'primary_key' => 'regionnum',
1154       'unique'      => [],
1155       'index'       => [],
1156     },
1157
1158     'rate_prefix' => {
1159       'columns' => [
1160         'prefixnum',   'serial',    '', '',
1161         'regionnum',   'int',       '', '',,
1162         'countrycode', 'varchar',     '', 3,
1163         'npa',         'varchar', 'NULL', 6,
1164         'nxx',         'varchar', 'NULL', 3,
1165       ],
1166       'primary_key' => 'prefixnum',
1167       'unique'      => [],
1168       'index'       => [ [ 'countrycode' ], [ 'regionnum' ] ],
1169     },
1170
1171     'reg_code' => {
1172       'columns' => [
1173         'codenum',   'serial',    '', '',
1174         'code',      'varchar',   '', $char_d,
1175         'agentnum',  'int',       '', '',
1176       ],
1177       'primary_key' => 'codenum',
1178       'unique'      => [ [ 'agentnum', 'code' ] ],
1179       'index'       => [ [ 'agentnum' ] ],
1180     },
1181
1182     'reg_code_pkg' => {
1183       'columns' => [
1184         'codepkgnum', 'serial', '', '',
1185         'codenum',   'int',    '', '',
1186         'pkgpart',   'int',    '', '',
1187       ],
1188       'primary_key' => 'codepkgnum',
1189       'unique'      => [ [ 'codenum', 'pkgpart' ] ],
1190       'index'       => [ [ 'codenum' ] ],
1191     },
1192
1193     'clientapi_session' => {
1194       'columns' => [
1195         'sessionnum',  'serial',  '', '',
1196         'sessionid',  'varchar',  '', $char_d,
1197         'namespace',  'varchar',  '', $char_d,
1198       ],
1199       'primary_key' => 'sessionnum',
1200       'unique'      => [ [ 'sessionid', 'namespace' ] ],
1201       'index'       => [],
1202     },
1203
1204     'clientapi_session_field' => {
1205       'columns' => [
1206         'fieldnum',    'serial',     '', '',
1207         'sessionnum',     'int',     '', '',
1208         'fieldname',  'varchar',     '', $char_d,
1209         'fieldvalue',    'text', 'NULL', '',
1210       ],
1211       'primary_key' => 'fieldnum',
1212       'unique'      => [ [ 'sessionnum', 'fieldname' ] ],
1213       'index'       => [],
1214     },
1215
1216     'payment_gateway' => {
1217       'columns' => [
1218         'gatewaynum',       'serial',   '',     '',
1219         'gateway_module',   'varchar',  '',     $char_d,
1220         'gateway_username', 'varchar',  'NULL', $char_d,
1221         'gateway_password', 'varchar',  'NULL', $char_d,
1222         'gateway_action',   'varchar',  'NULL', $char_d,
1223         'disabled',   'char',  'NULL',   1,
1224       ],
1225       'primary_key' => 'gatewaynum',
1226       'unique' => [],
1227       'index'  => [ [ 'disabled' ] ],
1228     },
1229
1230     'payment_gateway_option' => {
1231       'columns' => [
1232         'optionnum',   'serial',  '',     '',
1233         'gatewaynum',  'int',     '',     '',
1234         'optionname',  'varchar', '',     $char_d,
1235         'optionvalue', 'text',    'NULL', '',
1236       ],
1237       'primary_key' => 'optionnum',
1238       'unique'      => [],
1239       'index'       => [ [ 'gatewaynum' ], [ 'optionname' ] ],
1240     },
1241
1242     'agent_payment_gateway' => {
1243       'columns' => [
1244         'agentgatewaynum', 'serial', '', '',
1245         'agentnum',        'int', '', '',
1246         'gatewaynum',      'int', '', '',
1247         'cardtype',        'varchar', 'NULL', $char_d,
1248         'taxclass',        'varchar', 'NULL', $char_d,
1249       ],
1250       'primary_key' => 'agentgatewaynum',
1251       'unique'      => [],
1252       'index'       => [ [ 'agentnum', 'cardtype' ], ],
1253     },
1254
1255     'banned_pay' => {
1256       'columns' => [
1257         'bannum',  'serial',   '',     '',
1258         'payby',   'char',     '',       4,
1259         'payinfo', 'varchar',  '',     128, #say, a 512-big digest _hex encoded
1260         #'paymask', 'varchar',  'NULL', $char_d,
1261         '_date',   @date_type,
1262         'otaker',  'varchar',  '',     32,
1263         'reason',  'varchar',  'NULL', $char_d,
1264       ],
1265       'primary_key' => 'bannum',
1266       'unique'      => [ [ 'payby', 'payinfo' ] ],
1267       'index'       => [],
1268     },
1269
1270     'cancel_reason' => {
1271       'columns' => [
1272         'reasonnum', 'serial',  '',     '',
1273         'reason',    'varchar', '',     $char_d,
1274         'disabled',  'char',    'NULL', 1,
1275       ],
1276       'primary_key' => 'reasonnum',
1277       'unique' => [],
1278       'index'  => [ [ 'disabled' ] ],
1279     },
1280
1281     'pkg_class' => {
1282       'columns' => [
1283         'classnum',   'serial',  '', '',
1284         'classname',  'varchar', '', $char_d,
1285       ],
1286       'primary_key' => 'classnum',
1287       'unique' => [],
1288       'index' => [],
1289     },
1290
1291   };
1292
1293 }
1294
1295 =back
1296
1297 =head1 BUGS
1298
1299 =head1 SEE ALSO
1300
1301 L<DBIx::DBSchema>
1302
1303 =cut
1304
1305 1;
1306