change texas-style tax exemptions to be against a specific line item rather than...
[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       ],
629       'primary_key' => 'pkgpart',
630       'unique' => [],
631       'index' => [ [ 'promo_code' ], [ 'disabled' ] ],
632     },
633
634 #    'part_title' => {
635 #      'columns' => [
636 #        'titlenum',   'int',    '',   '',
637 #        'title',      'varchar',   '',   $char_d,
638 #      ],
639 #      'primary_key' => 'titlenum',
640 #      'unique' => [ [] ],
641 #      'index' => [ [] ],
642 #    },
643
644     'pkg_svc' => {
645       'columns' => [
646         'pkgsvcnum',  'serial', '',  '',
647         'pkgpart',    'int',    '',   '',
648         'svcpart',    'int',    '',   '',
649         'quantity',   'int',    '',   '',
650         'primary_svc','char', 'NULL',  1,
651       ],
652       'primary_key' => 'pkgsvcnum',
653       'unique' => [ ['pkgpart', 'svcpart'] ],
654       'index' => [ ['pkgpart'] ],
655     },
656
657     'part_referral' => {
658       'columns' => [
659         'refnum',   'serial',    '',   '',
660         'referral', 'varchar',   '',   $char_d,
661         'disabled',     'char', 'NULL', 1,
662       ],
663       'primary_key' => 'refnum',
664       'unique' => [],
665       'index' => [ ['disabled'] ],
666     },
667
668     'part_svc' => {
669       'columns' => [
670         'svcpart',    'serial',    '',   '',
671         'svc',        'varchar',   '',   $char_d,
672         'svcdb',      'varchar',   '',   $char_d,
673         'disabled',   'char',  'NULL',   1,
674       ],
675       'primary_key' => 'svcpart',
676       'unique' => [],
677       'index' => [ [ 'disabled' ] ],
678     },
679
680     'part_svc_column' => {
681       'columns' => [
682         'columnnum',   'serial',         '', '',
683         'svcpart',     'int',         '', '',
684         'columnname',  'varchar',     '', 64,
685         'columnvalue', 'varchar', 'NULL', $char_d,
686         'columnflag',  'char',    'NULL', 1, 
687       ],
688       'primary_key' => 'columnnum',
689       'unique' => [ [ 'svcpart', 'columnname' ] ],
690       'index' => [ [ 'svcpart' ] ],
691     },
692
693     #(this should be renamed to part_pop)
694     'svc_acct_pop' => {
695       'columns' => [
696         'popnum',    'serial',    '',   '',
697         'city',      'varchar',   '',   $char_d,
698         'state',     'varchar',   '',   $char_d,
699         'ac',        'char',   '',   3,
700         'exch',      'char',   '',   3,
701         'loc',       'char',   'NULL',   4, #NULL for legacy purposes
702       ],
703       'primary_key' => 'popnum',
704       'unique' => [],
705       'index' => [ [ 'state' ] ],
706     },
707
708     'part_pop_local' => {
709       'columns' => [
710         'localnum',  'serial',     '',     '',
711         'popnum',    'int',     '',     '',
712         'city',      'varchar', 'NULL', $char_d,
713         'state',     'char',    'NULL', 2,
714         'npa',       'char',    '',     3,
715         'nxx',       'char',    '',     3,
716       ],
717       'primary_key' => 'localnum',
718       'unique' => [],
719       'index' => [ [ 'npa', 'nxx' ], [ 'popnum' ] ],
720     },
721
722     'svc_acct' => {
723       'columns' => [
724         'svcnum',    'int',    '',   '',
725         'username',  'varchar',   '',   $username_len, #unique (& remove dup code)
726         '_password', 'varchar',   '',   72, #13 for encryped pw's plus ' *SUSPENDED* (md5 passwords can be 34, blowfish 60)
727         'sec_phrase', 'varchar',  'NULL',   $char_d,
728         'popnum',    'int',    'NULL',   '',
729         'uid',       'int', 'NULL',   '',
730         'gid',       'int', 'NULL',   '',
731         'finger',    'varchar',   'NULL',   $char_d,
732         'dir',       'varchar',   'NULL',   $char_d,
733         'shell',     'varchar',   'NULL',   $char_d,
734         'quota',     'varchar',   'NULL',   $char_d,
735         'slipip',    'varchar',   'NULL',   15, #four TINYINTs, bah.
736         'seconds',   'int', 'NULL',   '', #uhhhh
737         'domsvc',    'int', '',   '',
738       ],
739       'primary_key' => 'svcnum',
740       #'unique' => [ [ 'username', 'domsvc' ] ],
741       'unique' => [],
742       'index' => [ ['username'], ['domsvc'] ],
743     },
744
745     #'svc_charge' => {
746     #  'columns' => [
747     #    'svcnum',    'int',    '',   '',
748     #    'amount',    @money_type,
749     #  ],
750     #  'primary_key' => 'svcnum',
751     #  'unique' => [ [] ],
752     #  'index' => [ [] ],
753     #},
754
755     'svc_domain' => {
756       'columns' => [
757         'svcnum',    'int',    '',   '',
758         'domain',    'varchar',    '',   $char_d,
759         'catchall',  'int', 'NULL',    '',
760       ],
761       'primary_key' => 'svcnum',
762       'unique' => [ ['domain'] ],
763       'index' => [],
764     },
765
766     'domain_record' => {
767       'columns' => [
768         'recnum',    'serial',     '',  '',
769         'svcnum',    'int',     '',  '',
770         #'reczone',   'varchar', '',  $char_d,
771         'reczone',   'varchar', '',  255,
772         'recaf',     'char',    '',  2,
773         'rectype',   'varchar',    '',  5,
774         #'recdata',   'varchar', '',  $char_d,
775         'recdata',   'varchar', '',  255,
776       ],
777       'primary_key' => 'recnum',
778       'unique'      => [],
779       'index'       => [ ['svcnum'] ],
780     },
781
782     'svc_forward' => {
783       'columns' => [
784         'svcnum',   'int',            '',   '',
785         'srcsvc',   'int',        'NULL',   '',
786         'src',      'varchar',    'NULL',  255,
787         'dstsvc',   'int',        'NULL',   '',
788         'dst',      'varchar',    'NULL',  255,
789       ],
790       'primary_key' => 'svcnum',
791       'unique'      => [],
792       'index'       => [ ['srcsvc'], ['dstsvc'] ],
793     },
794
795     'svc_www' => {
796       'columns' => [
797         'svcnum',   'int',    '',  '',
798         'recnum',   'int',    '',  '',
799         'usersvc',  'int',    '',  '',
800       ],
801       'primary_key' => 'svcnum',
802       'unique'      => [],
803       'index'       => [],
804     },
805
806     #'svc_wo' => {
807     #  'columns' => [
808     #    'svcnum',    'int',    '',   '',
809     #    'svcnum',    'int',    '',   '',
810     #    'svcnum',    'int',    '',   '',
811     #    'worker',    'varchar',   '',   $char_d,
812     #    '_date',     @date_type,
813     #  ],
814     #  'primary_key' => 'svcnum',
815     #  'unique' => [ [] ],
816     #  'index' => [ [] ],
817     #},
818
819     'prepay_credit' => {
820       'columns' => [
821         'prepaynum',   'serial',     '',   '',
822         'identifier',  'varchar', '', $char_d,
823         'amount',      @money_type,
824         'seconds',     'int',     'NULL', '',
825         'agentnum',    'int',     'NULL', '',
826       ],
827       'primary_key' => 'prepaynum',
828       'unique'      => [ ['identifier'] ],
829       'index'       => [],
830     },
831
832     'port' => {
833       'columns' => [
834         'portnum',  'serial',     '',   '',
835         'ip',       'varchar', 'NULL', 15,
836         'nasport',  'int',     'NULL', '',
837         'nasnum',   'int',     '',   '',
838       ],
839       'primary_key' => 'portnum',
840       'unique'      => [],
841       'index'       => [],
842     },
843
844     'nas' => {
845       'columns' => [
846         'nasnum',   'serial',     '',    '',
847         'nas',      'varchar', '',    $char_d,
848         'nasip',    'varchar', '',    15,
849         'nasfqdn',  'varchar', '',    $char_d,
850         'last',     'int',     '',    '',
851       ],
852       'primary_key' => 'nasnum',
853       'unique'      => [ [ 'nas' ], [ 'nasip' ] ],
854       'index'       => [ [ 'last' ] ],
855     },
856
857     'session' => {
858       'columns' => [
859         'sessionnum', 'serial',       '',   '',
860         'portnum',    'int',       '',   '',
861         'svcnum',     'int',       '',   '',
862         'login',      @date_type,
863         'logout',     @date_type,
864       ],
865       'primary_key' => 'sessionnum',
866       'unique'      => [],
867       'index'       => [ [ 'portnum' ] ],
868     },
869
870     'queue' => {
871       'columns' => [
872         'jobnum', 'serial', '', '',
873         'job', 'text', '', '',
874         '_date', 'int', '', '',
875         'status', 'varchar', '', $char_d,
876         'statustext', 'text', 'NULL', '',
877         'svcnum', 'int', 'NULL', '',
878       ],
879       'primary_key' => 'jobnum',
880       'unique'      => [],
881       'index'       => [ [ 'svcnum' ], [ 'status' ] ],
882     },
883
884     'queue_arg' => {
885       'columns' => [
886         'argnum', 'serial', '', '',
887         'jobnum', 'int', '', '',
888         'arg', 'text', 'NULL', '',
889       ],
890       'primary_key' => 'argnum',
891       'unique'      => [],
892       'index'       => [ [ 'jobnum' ] ],
893     },
894
895     'queue_depend' => {
896       'columns' => [
897         'dependnum', 'serial', '', '',
898         'jobnum', 'int', '', '',
899         'depend_jobnum', 'int', '', '',
900       ],
901       'primary_key' => 'dependnum',
902       'unique'      => [],
903       'index'       => [ [ 'jobnum' ], [ 'depend_jobnum' ] ],
904     },
905
906     'export_svc' => {
907       'columns' => [
908         'exportsvcnum' => 'serial', '', '',
909         'exportnum'    => 'int', '', '',
910         'svcpart'      => 'int', '', '',
911       ],
912       'primary_key' => 'exportsvcnum',
913       'unique'      => [ [ 'exportnum', 'svcpart' ] ],
914       'index'       => [ [ 'exportnum' ], [ 'svcpart' ] ],
915     },
916
917     'part_export' => {
918       'columns' => [
919         'exportnum', 'serial', '', '',
920         #'svcpart',   'int', '', '',
921         'machine', 'varchar', '', $char_d,
922         'exporttype', 'varchar', '', $char_d,
923         'nodomain',     'char', 'NULL', 1,
924       ],
925       'primary_key' => 'exportnum',
926       'unique'      => [],
927       'index'       => [ [ 'machine' ], [ 'exporttype' ] ],
928     },
929
930     'part_export_option' => {
931       'columns' => [
932         'optionnum', 'serial', '', '',
933         'exportnum', 'int', '', '',
934         'optionname', 'varchar', '', $char_d,
935         'optionvalue', 'text', 'NULL', '',
936       ],
937       'primary_key' => 'optionnum',
938       'unique'      => [],
939       'index'       => [ [ 'exportnum' ], [ 'optionname' ] ],
940     },
941
942     'radius_usergroup' => {
943       'columns' => [
944         'usergroupnum', 'serial', '', '',
945         'svcnum',       'int', '', '',
946         'groupname',    'varchar', '', $char_d,
947       ],
948       'primary_key' => 'usergroupnum',
949       'unique'      => [],
950       'index'       => [ [ 'svcnum' ], [ 'groupname' ] ],
951     },
952
953     'msgcat' => {
954       'columns' => [
955         'msgnum', 'serial', '', '',
956         'msgcode', 'varchar', '', $char_d,
957         'locale', 'varchar', '', 16,
958         'msg', 'text', '', '',
959       ],
960       'primary_key' => 'msgnum',
961       'unique'      => [ [ 'msgcode', 'locale' ] ],
962       'index'       => [],
963     },
964
965     'cust_tax_exempt' => {
966       'columns' => [
967         'exemptnum', 'serial', '', '',
968         'custnum',   'int', '', '',
969         'taxnum',    'int', '', '',
970         'year',      'int', '', '',
971         'month',     'int', '', '',
972         'amount',   @money_type,
973       ],
974       'primary_key' => 'exemptnum',
975       'unique'      => [ [ 'custnum', 'taxnum', 'year', 'month' ] ],
976       'index'       => [],
977     },
978
979     'cust_tax_exempt_pkg' => {
980       'columns' => [
981         'exemptpkgnum',  'serial', '', '',
982         #'custnum',      'int', '', '',
983         'billpkgnum',   'int', '', '',
984         'taxnum',       'int', '', '',
985         'year',         'int', '', '',
986         'month',        'int', '', '',
987         'amount',       @money_type,
988       ],
989       'primary_key' => 'exemptpkgnum',
990       'unique' => [],
991       'index'  => [ [ 'taxnum', 'year', 'month' ],
992                     [ 'billpkgnum' ],
993                     [ 'taxnum' ]
994                   ],
995     },
996
997     'router' => {
998       'columns' => [
999         'routernum', 'serial', '', '',
1000         'routername', 'varchar', '', $char_d,
1001         'svcnum', 'int', 'NULL', '',
1002       ],
1003       'primary_key' => 'routernum',
1004       'unique'      => [],
1005       'index'       => [],
1006     },
1007
1008     'part_svc_router' => {
1009       'columns' => [
1010         'svcrouternum', 'serial', '', '',
1011         'svcpart', 'int', '', '',
1012         'routernum', 'int', '', '',
1013       ],
1014       'primary_key' => 'svcrouternum',
1015       'unique'      => [],
1016       'index'       => [],
1017     },
1018
1019     'addr_block' => {
1020       'columns' => [
1021         'blocknum', 'serial', '', '',
1022         'routernum', 'int', '', '',
1023         'ip_gateway', 'varchar', '', 15,
1024         'ip_netmask', 'int', '', '',
1025       ],
1026       'primary_key' => 'blocknum',
1027       'unique'      => [ [ 'blocknum', 'routernum' ] ],
1028       'index'       => [],
1029     },
1030
1031     'svc_broadband' => {
1032       'columns' => [
1033         'svcnum', 'int', '', '',
1034         'blocknum', 'int', '', '',
1035         'speed_up', 'int', '', '',
1036         'speed_down', 'int', '', '',
1037         'ip_addr', 'varchar', '', 15,
1038       ],
1039       'primary_key' => 'svcnum',
1040       'unique'      => [],
1041       'index'       => [],
1042     },
1043
1044     'part_virtual_field' => {
1045       'columns' => [
1046         'vfieldpart', 'int', '', '',
1047         'dbtable', 'varchar', '', 32,
1048         'name', 'varchar', '', 32,
1049         'check_block', 'text', 'NULL', '',
1050         'length', 'int', 'NULL', '',
1051         'list_source', 'text', 'NULL', '',
1052         'label', 'varchar', 'NULL', 80,
1053       ],
1054       'primary_key' => 'vfieldpart',
1055       'unique' => [],
1056       'index' => [],
1057     },
1058
1059     'virtual_field' => {
1060       'columns' => [
1061         'vfieldnum', 'serial', '', '',
1062         'recnum', 'int', '', '',
1063         'vfieldpart', 'int', '', '',
1064         'value', 'varchar', '', 128,
1065       ],
1066       'primary_key' => 'vfieldnum',
1067       'unique' => [ [ 'vfieldpart', 'recnum' ] ],
1068       'index' => [],
1069     },
1070
1071     'acct_snarf' => {
1072       'columns' => [
1073         'snarfnum',  'int', '', '',
1074         'svcnum',    'int', '', '',
1075         'machine',   'varchar', '', 255,
1076         'protocol',  'varchar', '', $char_d,
1077         'username',  'varchar', '', $char_d,
1078         '_password', 'varchar', '', $char_d,
1079       ],
1080       'primary_key' => 'snarfnum',
1081       'unique' => [],
1082       'index'  => [ [ 'svcnum' ] ],
1083     },
1084
1085     'svc_external' => {
1086       'columns' => [
1087         'svcnum', 'int', '', '',
1088         'id',     'int', 'NULL', '',
1089         'title',  'varchar', 'NULL', $char_d,
1090       ],
1091       'primary_key' => 'svcnum',
1092       'unique'      => [],
1093       'index'       => [],
1094     },
1095
1096     'cust_pay_refund' => {
1097       'columns' => [
1098         'payrefundnum', 'serial', '', '',
1099         'paynum',  'int', '', '',
1100         'refundnum',  'int', '', '',
1101         '_date',    @date_type,
1102         'amount',   @money_type,
1103       ],
1104       'primary_key' => 'payrefundnum',
1105       'unique' => [],
1106       'index' => [ ['paynum'], ['refundnum'] ],
1107     },
1108
1109     'part_pkg_option' => {
1110       'columns' => [
1111         'optionnum', 'serial', '', '',
1112         'pkgpart', 'int', '', '',
1113         'optionname', 'varchar', '', $char_d,
1114         'optionvalue', 'text', 'NULL', '',
1115       ],
1116       'primary_key' => 'optionnum',
1117       'unique'      => [],
1118       'index'       => [ [ 'pkgpart' ], [ 'optionname' ] ],
1119     },
1120
1121     'rate' => {
1122       'columns' => [
1123         'ratenum',  'serial', '', '',
1124         'ratename', 'varchar', '', $char_d,
1125       ],
1126       'primary_key' => 'ratenum',
1127       'unique'      => [],
1128       'index'       => [],
1129     },
1130
1131     'rate_detail' => {
1132       'columns' => [
1133         'ratedetailnum',   'serial', '', '',
1134         'ratenum',         'int',     '', '',
1135         'orig_regionnum',  'int', 'NULL', '',
1136         'dest_regionnum',  'int',     '', '',
1137         'min_included',    'int',     '', '',
1138         'min_charge',      @money_type,
1139         'sec_granularity', 'int',     '', '',
1140         #time period (link to table of periods)?
1141       ],
1142       'primary_key' => 'ratedetailnum',
1143       'unique'      => [ [ 'ratenum', 'orig_regionnum', 'dest_regionnum' ] ],
1144       'index'       => [ [ 'ratenum', 'dest_regionnum' ] ],
1145     },
1146
1147     'rate_region' => {
1148       'columns' => [
1149         'regionnum',   'serial',      '', '',
1150         'regionname',  'varchar',     '', $char_d,
1151       ],
1152       'primary_key' => 'regionnum',
1153       'unique'      => [],
1154       'index'       => [],
1155     },
1156
1157     'rate_prefix' => {
1158       'columns' => [
1159         'prefixnum',   'serial',    '', '',
1160         'regionnum',   'int',       '', '',,
1161         'countrycode', 'varchar',     '', 3,
1162         'npa',         'varchar', 'NULL', 6,
1163         'nxx',         'varchar', 'NULL', 3,
1164       ],
1165       'primary_key' => 'prefixnum',
1166       'unique'      => [],
1167       'index'       => [ [ 'countrycode' ], [ 'regionnum' ] ],
1168     },
1169
1170     'reg_code' => {
1171       'columns' => [
1172         'codenum',   'serial',    '', '',
1173         'code',      'varchar',   '', $char_d,
1174         'agentnum',  'int',       '', '',
1175       ],
1176       'primary_key' => 'codenum',
1177       'unique'      => [ [ 'agentnum', 'code' ] ],
1178       'index'       => [ [ 'agentnum' ] ],
1179     },
1180
1181     'reg_code_pkg' => {
1182       'columns' => [
1183         'codepkgnum', 'serial', '', '',
1184         'codenum',   'int',    '', '',
1185         'pkgpart',   'int',    '', '',
1186       ],
1187       'primary_key' => 'codepkgnum',
1188       'unique'      => [ [ 'codenum', 'pkgpart' ] ],
1189       'index'       => [ [ 'codenum' ] ],
1190     },
1191
1192     'clientapi_session' => {
1193       'columns' => [
1194         'sessionnum',  'serial',  '', '',
1195         'sessionid',  'varchar',  '', $char_d,
1196         'namespace',  'varchar',  '', $char_d,
1197       ],
1198       'primary_key' => 'sessionnum',
1199       'unique'      => [ [ 'sessionid', 'namespace' ] ],
1200       'index'       => [],
1201     },
1202
1203     'clientapi_session_field' => {
1204       'columns' => [
1205         'fieldnum',    'serial',     '', '',
1206         'sessionnum',     'int',     '', '',
1207         'fieldname',  'varchar',     '', $char_d,
1208         'fieldvalue',    'text', 'NULL', '',
1209       ],
1210       'primary_key' => 'fieldnum',
1211       'unique'      => [ [ 'sessionnum', 'fieldname' ] ],
1212       'index'       => [],
1213     },
1214
1215     'payment_gateway' => {
1216       'columns' => [
1217         'gatewaynum',       'serial',   '',     '',
1218         'gateway_module',   'varchar',  '',     $char_d,
1219         'gateway_username', 'varchar',  'NULL', $char_d,
1220         'gateway_password', 'varchar',  'NULL', $char_d,
1221         'gateway_action',   'varchar',  'NULL', $char_d,
1222         'disabled',   'char',  'NULL',   1,
1223       ],
1224       'primary_key' => 'gatewaynum',
1225       'unique' => [],
1226       'index'  => [ [ 'disabled' ] ],
1227     },
1228
1229     'payment_gateway_option' => {
1230       'columns' => [
1231         'optionnum',   'serial',  '',     '',
1232         'gatewaynum',  'int',     '',     '',
1233         'optionname',  'varchar', '',     $char_d,
1234         'optionvalue', 'text',    'NULL', '',
1235       ],
1236       'primary_key' => 'optionnum',
1237       'unique'      => [],
1238       'index'       => [ [ 'gatewaynum' ], [ 'optionname' ] ],
1239     },
1240
1241     'agent_payment_gateway' => {
1242       'columns' => [
1243         'agentgatewaynum', 'serial', '', '',
1244         'agentnum',        'int', '', '',
1245         'gatewaynum',      'int', '', '',
1246         'cardtype',        'varchar', 'NULL', $char_d,
1247         'taxclass',        'varchar', 'NULL', $char_d,
1248       ],
1249       'primary_key' => 'agentgatewaynum',
1250       'unique'      => [],
1251       'index'       => [ [ 'agentnum', 'cardtype' ], ],
1252     },
1253
1254     'banned_pay' => {
1255       'columns' => [
1256         'bannum',  'serial',   '',     '',
1257         'payby',   'char',     '',       4,
1258         'payinfo', 'varchar',  '',     128, #say, a 512-big digest _hex encoded
1259         #'paymask', 'varchar',  'NULL', $char_d,
1260         '_date',   @date_type,
1261         'otaker',  'varchar',  '',     32,
1262         'reason',  'varchar',  'NULL', $char_d,
1263       ],
1264       'primary_key' => 'bannum',
1265       'unique'      => [ [ 'payby', 'payinfo' ] ],
1266       'index'       => [],
1267     },
1268
1269     'cancel_reason' => {
1270       'columns' => [
1271         'reasonnum', 'serial',  '',     '',
1272         'reason',    'varchar', '',     $char_d,
1273         'disabled',  'char',    'NULL', 1,
1274       ],
1275       'primary_key' => 'reasonnum',
1276       'unique' => [],
1277       'index'  => [ [ 'disabled' ] ],
1278     },
1279
1280   };
1281
1282 }
1283
1284 =back
1285
1286 =head1 BUGS
1287
1288 =head1 SEE ALSO
1289
1290 L<DBIx::DBSchema>
1291
1292 =cut
1293
1294 1;
1295