eliminate some false laziness in FS::Misc::send_email vs. msg_template/email.pm send_...
[freeside.git] / FS / FS / class_Common.pm
1 package FS::class_Common;
2
3 use strict;
4 use base qw( FS::Record );
5 use FS::Record qw( qsearch qsearchs );
6
7 =head1 NAME
8
9 FS::class_Common - Base class for classification classes
10
11 =head1 SYNOPSIS
12
13 use base qw( FS::class_Common );
14 use FS::category_table; #should use this
15
16 #required
17 sub _target_table { 'table_name'; }
18
19 #optional for non-standard names
20 sub _target_column { 'classnum'; } #default is classnum
21 sub _category_table { 'table_name'; } #default is to replace s/class/category/
22
23 =head1 DESCRIPTION
24
25 FS::class_Common is a base class for classes which provide a classification for
26 other classes, such as pkg_class or cust_class.
27
28 =head1 METHODS
29
30 =over 4
31
32 =item new HASHREF
33
34 Creates a new classification.  To add the classfication to the database, see
35 L<"insert">.
36
37 =cut
38
39 =item insert
40
41 Adds this classification to the database.  If there is an error, returns the
42 error, otherwise returns false.
43
44 =item delete
45
46 Deletes this classification from the database.  Only classifications with no
47 associated target objects can be deleted.  If there is an error, returns
48 the error, otherwise returns false.
49
50 =cut
51
52 sub delete {
53   my $self = shift;
54
55   return "Can't delete a ". $self->table.
56          " with ". $self->_target_table. " records!"
57     if qsearch( $self->_target_table,
58                 { $self->_target_column => $self->classnum }
59               );
60
61   $self->SUPER::delete;
62 }
63
64 =item replace OLD_RECORD
65
66 Replaces OLD_RECORD with this one in the database.  If there is an error,
67 returns the error, otherwise returns false.
68
69 =item check
70
71 Checks all fields to make sure this is a valid classification.  If
72 there is an error, returns the error, otherwise returns false.  Called by the
73 insert and replace methods.
74
75 =cut
76
77 sub check {
78   my $self = shift;
79
80   $self->ut_numbern('classnum')
81     or $self->ut_text('classname')
82     or $self->ut_foreign_keyn( 'categorynum',
83                                $self->_category_table,
84                                'categorynum',
85                              )
86     or $self->ut_enum('disabled', [ '', 'Y' ] )
87     or $self->SUPER::check;
88
89 }
90
91 =item category
92
93 Returns the category record associated with this class, or false if there is
94 none.
95
96 =cut
97
98 sub category {
99   my $self = shift;
100   qsearchs($self->_category_table, { 'categorynum' => $self->categorynum } );
101 }
102
103 =item categoryname
104
105 Returns the category name associated with this class, or false if there
106 is none.
107
108 =cut
109
110 sub categoryname {
111   my $category = shift->category;
112   $category ? $category->categoryname : '';
113 }
114
115 #required
116 sub _target_table {
117   my $self = shift;
118   die "_target_table unspecified for $self";
119 }
120
121 #defaults
122
123 sub _target_column { 'classnum'; }
124
125 use vars qw( %_category_table );
126 sub _category_table {
127   my $self = shift;
128   return $_category_table{ ref $self } ||= do {
129     my $category_table = $self->table;
130     $category_table =~ s/class/category/ # s/_class$/_category/
131       or die "can't determine an automatic category table for $category_table";
132     $category_table;
133   }
134 }
135
136 =head1 BUGS
137
138 =head1 SEE ALSO
139
140 L<FS::category_Common>, L<FS::pkg_class>, L<FS::cust_class>
141
142 =cut
143
144 1;