1 package FS::usage_class;
5 use FS::Record qw( qsearch qsearchs );
8 my $conf = new FS::Conf;
10 @ISA = qw(FS::Record);
14 FS::usage_class - Object methods for usage_class records
20 $record = new FS::usage_class \%hash;
21 $record = new FS::usage_class { 'column' => 'value' };
23 $error = $record->insert;
25 $error = $new_record->replace($old_record);
27 $error = $record->delete;
29 $error = $record->check;
33 An FS::usage_class object represents a usage class. Every rate detail
34 (see L<FS::rate_detail>) has, optionally, a usage class. FS::usage_class
35 inherits from FS::Record. The following fields are currently supported:
41 Primary key (assigned automatically for new usage classes)
45 Text name of this usage class
49 Disabled flag, empty or 'Y'
60 Creates a new usage class. To add the usage class to the database,
63 Note that this stores the hash reference, not a distinct copy of the hash it
64 points to. You can ask the object for a copy with the I<hash> method.
68 sub table { 'usage_class'; }
72 Adds this record to the database. If there is an error, returns the error,
73 otherwise returns false.
79 Delete this record from the database.
83 =item replace OLD_RECORD
85 Replaces the OLD_RECORD with this one in the database. If there is an error,
86 returns the error, otherwise returns false.
92 Checks all fields to make sure this is a valid usage class. If there is
93 an error, returns the error, otherwise returns false. Called by the insert
102 $self->ut_numbern('classnum')
103 || $self->ut_numbern('weight')
104 || $self->ut_text('classname')
105 || $self->ut_textn('format')
106 || $self->ut_enum('disabled', [ '', 'Y' ])
108 return $error if $error;
113 =item summary_formats_labelhash
115 Returns a list of line item format descriptions suitable for assigning to
120 # transform hashes of arrays to arrays of hashes for false laziness removal?
121 my %summary_formats = (
123 'label' => [ qw( Description Calls Minutes Amount ) ],
125 sub { shift->{description} },
126 sub { shift->{calls} },
127 sub { sprintf( '%.1f', shift->{duration}/60 ) },
128 sub { my($href, %opt) = @_;
129 ($opt{dollar} || ''). $href->{amount};
132 'align' => [ qw( l r r r ) ],
133 'span' => [ qw( 4 1 1 1 ) ], # unitprices?
134 'width' => [ qw( 8.2cm 2.5cm 1.4cm 1.6cm ) ], # don't like this
138 'label' => [ qw( Description Calls Amount ) ],
140 sub { shift->{description} },
141 sub { shift->{calls} },
142 sub { my($href, %opt) = @_;
143 ($opt{dollar} || ''). $href->{amount};
146 'align' => [ qw( l r r ) ],
147 'span' => [ qw( 5 1 1 ) ],
148 'width' => [ qw( 10.7cm 1.4cm 1.6cm ) ], # don't like this
152 'label' => [ qw( Date Time Number Destination Duration Amount ) ],
159 sub { my $href = shift; #ugh! making bunk of 'normalization'
160 $href->{subtotal} ? $href->{subtotal} : ' '
163 'align' => [ qw( l l l l r r ) ],
164 'span' => [ qw( 1 1 1 1 1 2 ) ], # unitprices?
165 'width' => [ qw( 4.3cm 1.4cm 2.5cm 2.5cm 1.4cm 1.6cm ) ],# don't like this
169 'label' => [ qw( col1 col2 col3 col4 col5 col6 ) ],
176 sub { my $href = shift; #ugh! making bunk of 'normalization'
177 $href->{subtotal} ? $href->{subtotal} : ' '
180 'align' => [ qw( l l l l r r ) ],
181 'span' => [ qw( 1 1 1 1 1 2 ) ], # unitprices?
182 'width' => [ qw( 4.3cm 1.4cm 2.5cm 2.5cm 1.4cm 1.6cm ) ],# don't like this
186 'label' => [ qw( col1 col2 col3 col4 ) ],
193 'align' => [ qw( l l l l r r ) ],
194 'span' => [ qw( 1 1 1 1 1 2 ) ],
195 'width' => [ qw( 4.3cm 1.4cm 2.5cm 2.5cm ) ],
199 'label' => [ qw( col1 col2 col3 col4 col5 col6 col7 ) ],
207 sub { my $href = shift; #ugh! making bunk of 'normalization'
208 $href->{subtotal} ? $href->{subtotal} : ' '
211 'align' => [ qw( l l l l l r r ) ],
212 'span' => [ qw( 1 1 1 1 1 1 1 ) ], # unitprices?
213 'width' => [ qw( 2.9cm 1.4cm 1.4cm 2.5cm 2.5cm 1.4cm 1.6cm ) ],# don't like this
218 sub summary_formats_labelhash {
219 map { $_ => join(',', @{$summary_formats{$_}{label}}) }
220 grep { $summary_formats{$_}{show} }
221 keys %summary_formats;
224 =item header_generator FORMAT
226 Returns a coderef used for generation of an invoice line item header for this
227 usage_class. FORMAT is either html or latex
237 sub _generator_defaults {
238 my ( $self, $format, %opt ) = @_;
239 my %format = ( %{ $summary_formats{$self->format} }, %opt );
240 return ( \%format, ' ', ' ', ' ', sub { shift } );
243 sub header_generator {
244 my ( $self, $format, %opt ) = @_;
246 my ( $f, $prefix, $suffix, $separator, $column ) =
247 $self->_generator_defaults($format, %opt);
249 if ($format eq 'latex') {
250 $prefix = "\\hline\n\\rule{0pt}{2.5ex}\n\\makebox[1.4cm]{}&\n";
251 $suffix = "\\\\\n\\hline";
254 sub { my ($d,$a,$s,$w) = @_;
255 return "\\multicolumn{$s}{$a}{\\makebox[$w][$a]{\\textbf{$d}}}";
257 } elsif ( $format eq 'html' ) {
258 $prefix = '<th></th>';
262 sub { my ($d,$a,$s,$w) = @_;
263 return qq!<th align="$html_align{$a}">$d</th>!;
271 foreach (my $i = 0; exists($f->{label}->[$i]); $i++) {
273 &{$column}( map { $f->{$_}->[$i] } qw(label align span width) );
276 $prefix. join($separator, @result). $suffix;
281 =item description_generator FORMAT
283 Returns a coderef used for generation of invoice line items for this
284 usage_class. FORMAT is either html or latex
288 sub description_generator {
289 my ( $self, $format, %opt ) = @_;
291 my ( $f, $prefix, $suffix, $separator, $column ) =
292 $self->_generator_defaults($format, %opt);
294 my $money_char = '$';
295 if ($format eq 'latex') {
296 $prefix = "\\hline\n\\multicolumn{1}{c}{\\rule{0pt}{2.5ex}~} &\n";
298 $separator = " & \n";
300 sub { my ($d,$a,$s,$w) = @_;
301 return "\\multicolumn{$s}{$a}{\\makebox[$w][$a]{\\textbf{$d}}}";
303 $money_char = '\\dollar';
304 }elsif ( $format eq 'html' ) {
305 $prefix = '"><td align="center"></td>';
309 sub { my ($d,$a,$s,$w) = @_;
310 return qq!<td align="$html_align{$a}">$d</td>!;
312 $money_char = $conf->config('money_char') || '$';
320 foreach (my $i = 0; $f->{label}->[$i]; $i++) {
322 $dollar = $money_char if $i == scalar(@{$f->{label}})-1;
324 &{$column}( &{$f->{fields}->[$i]}($href, 'dollar' => $dollar),
325 map { $f->{$_}->[$i] } qw(align span width)
329 $prefix. join( $separator, @result ). $suffix;
334 =item total_generator FORMAT
336 Returns a coderef used for generation of invoice total lines for this
337 usage_class. FORMAT is either html or latex
341 sub total_generator {
342 my ( $self, $format, %opt ) = @_;
344 # $OUT .= '\FStotaldesc{' . $section->{'description'} . ' Total}' .
345 # '{' . $section->{'subtotal'} . '}' . "\n";
347 my ( $f, $prefix, $suffix, $separator, $column ) =
348 $self->_generator_defaults($format, %opt);
351 if ($format eq 'latex') {
354 $separator = " & \n";
356 sub { my ($d,$a,$s,$w) = @_;
357 return "\\multicolumn{$s}{$a}{\\makebox[$w][$a]{$d}}";
359 }elsif ( $format eq 'html' ) {
363 $style = 'border-top: 3px solid #000000;border-bottom: 3px solid #000000;';
365 sub { my ($d,$a,$s,$w) = @_;
366 return qq!<td align="$html_align{$a}" style="$style">$d</td>!;
375 # my $r = &{$f->{fields}->[$i]}(@args);
376 # $r .= ' Total' unless $i;
378 foreach (my $i = 0; $f->{label}->[$i]; $i++) {
380 &{$column}( &{$f->{fields}->[$i]}(@args). ($i ? '' : ' Total'),
381 map { $f->{$_}->[$i] } qw(align span width)
385 $prefix. join( $separator, @result ). $suffix;
390 =item total_line_generator FORMAT
392 Returns a coderef used for generation of invoice total line items for this
393 usage_class. FORMAT is either html or latex
397 # not used: will have issues with hash element names (description vs
398 # total_item and amount vs total_amount -- another array of functions?
400 sub total_line_generator {
401 my ( $self, $format, %opt ) = @_;
403 # $OUT .= '\FStotaldesc{' . $line->{'total_item'} . '}' .
404 # '{' . $line->{'total_amount'} . '}' . "\n";
406 my ( $f, $prefix, $suffix, $separator, $column ) =
407 $self->_generator_defaults($format, %opt);
410 if ($format eq 'latex') {
413 $separator = " & \n";
415 sub { my ($d,$a,$s,$w) = @_;
416 return "\\multicolumn{$s}{$a}{\\makebox[$w][$a]{$d}}";
418 }elsif ( $format eq 'html' ) {
422 $style = 'border-top: 3px solid #000000;border-bottom: 3px solid #000000;';
424 sub { my ($d,$a,$s,$w) = @_;
425 return qq!<td align="$html_align{$a}" style="$style">$d</td>!;
434 foreach (my $i = 0; $f->{label}->[$i]; $i++) {
436 &{$column}( &{$f->{fields}->[$i]}(@args),
437 map { $f->{$_}->[$i] } qw(align span width)
441 $prefix. join( $separator, @result ). $suffix;
448 sub _populate_initial_data {
449 my ($class, %opts) = @_;
451 foreach ("Intrastate", "Interstate", "International") {
452 my $object = $class->new( { 'classname' => $_ } );
453 my $error = $object->insert;
454 die "error inserting $class into database: $error\n"
465 return $class->_populate_initial_data(@_)
466 unless scalar( qsearch( 'usage_class', {} ) );
478 L<FS::Record>, schema.html from the base documentation.