time/data detail on invoices
authorivan <ivan>
Thu, 6 Feb 2003 05:26:50 +0000 (05:26 +0000)
committerivan <ivan>
Thu, 6 Feb 2003 05:26:50 +0000 (05:26 +0000)
FS/FS.pm
FS/FS/cust_bill.pm
FS/FS/cust_bill_pkg.pm
FS/FS/cust_bill_pkg_detail.pm [new file with mode: 0644]
FS/FS/cust_main.pm
FS/MANIFEST
FS/bin/freeside-setup
FS/t/cust_bill_pkg_detail.t [new file with mode: 0644]
httemplate/docs/schema.html
httemplate/docs/upgrade10.html [new file with mode: 0644]
httemplate/edit/part_pkg.cgi

index a2df6f1..e4a3208 100644 (file)
--- a/FS/FS.pm
+++ b/FS/FS.pm
@@ -102,6 +102,8 @@ L<FS::cust_bill> - Invoice class
 
 L<FS::cust_bill_pkg> - Invoice line item class
 
 
 L<FS::cust_bill_pkg> - Invoice line item class
 
+L<FS::cust_bill_pkg_detail> - Invoice line item detail class
+
 L<FS::part_bill_event> - Invoice event definition class
 
 L<FS::cust_bill_event> - Completed invoice event class
 L<FS::part_bill_event> - Invoice event definition class
 
 L<FS::cust_bill_event> - Completed invoice event class
index c661baa..aa82eb6 100644 (file)
@@ -953,38 +953,43 @@ sub print_text {
   }
 
   #new charges
   }
 
   #new charges
-  foreach ( ( grep {   $_->pkgnum } $self->cust_bill_pkg ),  #packages first
-            ( grep { ! $_->pkgnum } $self->cust_bill_pkg ),  #then taxes
+  foreach my $cust_bill_pkg (
+    ( grep {   $_->pkgnum } $self->cust_bill_pkg ),  #packages first
+    ( grep { ! $_->pkgnum } $self->cust_bill_pkg ),  #then taxes
   ) {
 
   ) {
 
-    if ( $_->pkgnum ) {
+    if ( $cust_bill_pkg->pkgnum ) {
 
 
-      my($cust_pkg)=qsearchs('cust_pkg', { 'pkgnum', $_->pkgnum } );
-      my($part_pkg)=qsearchs('part_pkg',{'pkgpart'=>$cust_pkg->pkgpart});
-      my($pkg)=$part_pkg->pkg;
+      my $cust_pkg = qsearchs('cust_pkg', { pkgnum =>$cust_bill_pkg->pkgnum } );
+      my $part_pkg = qsearchs('part_pkg', { pkgpart=>$cust_pkg->pkgpart } );
+      my $pkg = $part_pkg->pkg;
 
 
-      if ( $_->setup != 0 ) {
-        push @buf, [ "$pkg Setup", $money_char. sprintf("%10.2f",$_->setup) ];
+      if ( $cust_bill_pkg->setup != 0 ) {
+        push @buf, [ "$pkg Setup",
+                     $money_char. sprintf("%10.2f", $cust_bill_pkg->setup) ];
         push @buf,
           map { [ "  ". $_->[0]. ": ". $_->[1], '' ] } $cust_pkg->labels;
       }
 
         push @buf,
           map { [ "  ". $_->[0]. ": ". $_->[1], '' ] } $cust_pkg->labels;
       }
 
-      if ( $_->recur != 0 ) {
+      if ( $cust_bill_pkg->recur != 0 ) {
         push @buf, [
         push @buf, [
-          "$pkg (" . time2str("%x",$_->sdate) . " - " .
-                                time2str("%x",$_->edate) . ")",
-          $money_char. sprintf("%10.2f",$_->recur)
+          "$pkg (" . time2str("%x", $cust_bill_pkg->sdate) . " - " .
+                                time2str("%x", $cust_bill_pkg->edate) . ")",
+          $money_char. sprintf("%10.2f", $cust_bill_pkg->recur)
         ];
         push @buf,
           map { [ "  ". $_->[0]. ": ". $_->[1], '' ] } $cust_pkg->labels;
       }
 
         ];
         push @buf,
           map { [ "  ". $_->[0]. ": ". $_->[1], '' ] } $cust_pkg->labels;
       }
 
+      push @buf, map { [ "  $_", '' ] } $cust_bill_pkg->details;
+
     } else { #pkgnum tax
     } else { #pkgnum tax
-      my $itemdesc = defined $_->dbdef_table->column('itemdesc')
-                     ? ( $_->itemdesc || 'Tax' )
+      my $itemdesc = defined $cust_bill_pkg->dbdef_table->column('itemdesc')
+                     ? ( $cust_bill_pkg->itemdesc || 'Tax' )
                      : 'Tax';
                      : 'Tax';
-      push @buf,[$itemdesc, $money_char. sprintf("%10.2f",$_->setup) ] 
-        if $_->setup != 0;
+      push @buf, [ $itemdesc,
+                   $money_char. sprintf("%10.2f", $cust_bill_pkg->setup) ] 
+        if $cust_bill_pkg->setup != 0;
     }
   }
 
     }
   }
 
@@ -1128,10 +1133,6 @@ sub print_text {
 
 =back
 
 
 =back
 
-=head1 VERSION
-
-$Id: cust_bill.pm,v 1.61 2003-01-10 07:41:05 ivan Exp $
-
 =head1 BUGS
 
 The delete method.
 =head1 BUGS
 
 The delete method.
index 5a1dcd2..a6615d0 100644 (file)
@@ -2,11 +2,12 @@ package FS::cust_bill_pkg;
 
 use strict;
 use vars qw( @ISA );
 
 use strict;
 use vars qw( @ISA );
-use FS::Record qw( qsearchs );
+use FS::Record qw( qsearch qsearchs dbdef dbh );
 use FS::cust_pkg;
 use FS::cust_bill;
 use FS::cust_pkg;
 use FS::cust_bill;
+use FS::cust_bill_pkg_detail;
 
 
-@ISA = qw(FS::Record );
+@ISA = qw( FS::Record );
 
 =head1 NAME
 
 
 =head1 NAME
 
@@ -73,6 +74,51 @@ sub table { 'cust_bill_pkg'; }
 Adds this line item to the database.  If there is an error, returns the error,
 otherwise returns false.
 
 Adds this line item to the database.  If there is an error, returns the error,
 otherwise returns false.
 
+=cut
+
+sub insert {
+  my $self = shift;
+
+  local $SIG{HUP} = 'IGNORE';
+  local $SIG{INT} = 'IGNORE';
+  local $SIG{QUIT} = 'IGNORE';
+  local $SIG{TERM} = 'IGNORE';
+  local $SIG{TSTP} = 'IGNORE';
+  local $SIG{PIPE} = 'IGNORE';
+
+  my $oldAutoCommit = $FS::UID::AutoCommit;
+  local $FS::UID::AutoCommit = 0;
+  my $dbh = dbh;
+
+  my $error = $self->SUPER::insert;
+  if ( $error ) {
+    $dbh->rollback if $oldAutoCommit;
+    return $error;
+  }
+
+  unless ( defined dbdef->table('cust_bill_pkg_detail') && $self->get('details') ) {
+    $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+    return '';
+  }
+
+  foreach my $detail ( @{$self->get('details')} ) {
+    my $cust_bill_pkg_detail = new FS::cust_bill_pkg_detail {
+      'pkgnum' => $self->pkgnum,
+      'invnum' => $self->invnum,
+      'detail' => $detail,
+    };
+    $error = $cust_bill_pkg_detail->insert;
+    if ( $error ) {
+      $dbh->rollback if $oldAutoCommit;
+      return $error;
+    }
+  }
+
+  $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+  '';
+
+}
+
 =item delete
 
 Currently unimplemented.  I don't remove line items because there would then be
 =item delete
 
 Currently unimplemented.  I don't remove line items because there would then be
@@ -139,11 +185,22 @@ sub cust_pkg {
   qsearchs( 'cust_pkg', { 'pkgnum' => $self->pkgnum } );
 }
 
   qsearchs( 'cust_pkg', { 'pkgnum' => $self->pkgnum } );
 }
 
-=back
+=item details
+
+Returns an array of detail information for the invoice line item.
 
 
-=head1 VERSION
+=cut
 
 
-$Id: cust_bill_pkg.pm,v 1.4 2002-09-21 11:17:39 ivan Exp $
+sub details {
+  my $self = shift;
+  return () unless defined dbdef->table('cust_bill_pkg_detail');
+  map { $_->detail }
+    qsearch ( 'cust_bill_pkg_detail', { 'pkgnum' => $self->pkgnum,
+                                        'invnum' => $self->invnum, } );
+    #qsearch ( 'cust_bill_pkg_detail', { 'lineitemnum' => $self->lineitemnum });
+}
+
+=back
 
 =head1 BUGS
 
 
 =head1 BUGS
 
diff --git a/FS/FS/cust_bill_pkg_detail.pm b/FS/FS/cust_bill_pkg_detail.pm
new file mode 100644 (file)
index 0000000..199de43
--- /dev/null
@@ -0,0 +1,123 @@
+package FS::cust_bill_pkg_detail;
+
+use strict;
+use vars qw( @ISA );
+use FS::Record qw( qsearch qsearchs );
+
+@ISA = qw(FS::Record);
+
+=head1 NAME
+
+FS::cust_bill_pkg_detail - Object methods for cust_bill_pkg_detail records
+
+=head1 SYNOPSIS
+
+  use FS::cust_bill_pkg_detail;
+
+  $record = new FS::cust_bill_pkg_detail \%hash;
+  $record = new FS::cust_bill_pkg_detail { 'column' => 'value' };
+
+  $error = $record->insert;
+
+  $error = $new_record->replace($old_record);
+
+  $error = $record->delete;
+
+  $error = $record->check;
+
+=head1 DESCRIPTION
+
+An FS::cust_bill_pkg_detail object represents additional detail information for
+an invoice line item (see L<FS::cust_bill_pkg>).  FS::cust_bill_pkg_detail
+inherits from FS::Record.  The following fields are currently supported:
+
+=over 4
+
+=item detailnum - primary key
+
+=item pkgnum -
+
+=item invnum -
+
+=item detail - detail description
+
+=back
+
+=head1 METHODS
+
+=over 4
+
+=item new HASHREF
+
+Creates a new line item detail.  To add the line item detail to the database,
+see L<"insert">.
+
+Note that this stores the hash reference, not a distinct copy of the hash it
+points to.  You can ask the object for a copy with the I<hash> method.
+
+=cut
+
+# the new method can be inherited from FS::Record, if a table method is defined
+
+sub table { 'cust_bill_pkg_detail'; }
+
+=item insert
+
+Adds this record to the database.  If there is an error, returns the error,
+otherwise returns false.
+
+=cut
+
+# the insert method can be inherited from FS::Record
+
+=item delete
+
+Delete this record from the database.
+
+=cut
+
+# the delete method can be inherited from FS::Record
+
+=item replace OLD_RECORD
+
+Replaces the OLD_RECORD with this one in the database.  If there is an error,
+returns the error, otherwise returns false.
+
+=cut
+
+# the replace method can be inherited from FS::Record
+
+=item check
+
+Checks all fields to make sure this is a valid line item detail.  If there is
+an error, returns the error, otherwise returns false.  Called by the insert
+and replace methods.
+
+=cut
+
+# the check method should currently be supplied - FS::Record contains some
+# data checking routines
+
+sub check {
+  my $self = shift;
+
+  $self->ut_numbern('detailnum')
+    || $self->ut_foreign_key('pkgnum', 'cust_pkg', 'pkgnum')
+    || $self->ut_foreign_key('invnum', 'cust_pkg', 'invnum')
+    || $self->ut_text('detail')
+  ;
+
+}
+
+=back
+
+=head1 BUGS
+
+=head1 SEE ALSO
+
+L<FS::cust_bill_pkg>, L<FS::Record>, schema.html from the base documentation.
+
+=cut
+
+1;
+
index 91ffa45..807fadb 100644 (file)
@@ -947,6 +947,8 @@ sub bill {
     my %hash = $cust_pkg->hash;
     my $old_cust_pkg = new FS::cust_pkg \%hash;
 
     my %hash = $cust_pkg->hash;
     my $old_cust_pkg = new FS::cust_pkg \%hash;
 
+    my @details = ();
+
     # bill setup
     my $setup = 0;
     unless ( $cust_pkg->setup ) {
     # bill setup
     my $setup = 0;
     unless ( $cust_pkg->setup ) {
@@ -1040,11 +1042,12 @@ sub bill {
       }
       if ( $setup > 0 || $recur > 0 ) {
         my $cust_bill_pkg = new FS::cust_bill_pkg ({
       }
       if ( $setup > 0 || $recur > 0 ) {
         my $cust_bill_pkg = new FS::cust_bill_pkg ({
-          'pkgnum' => $cust_pkg->pkgnum,
-          'setup'  => $setup,
-          'recur'  => $recur,
-          'sdate'  => $sdate,
-          'edate'  => $cust_pkg->bill,
+          'pkgnum'  => $cust_pkg->pkgnum,
+          'setup'   => $setup,
+          'recur'   => $recur,
+          'sdate'   => $sdate,
+          'edate'   => $cust_pkg->bill,
+          'details' => \@details,
         });
         push @cust_bill_pkg, $cust_bill_pkg;
         $total_setup += $setup;
         });
         push @cust_bill_pkg, $cust_bill_pkg;
         $total_setup += $setup;
index b3de623..e8b1da7 100644 (file)
@@ -51,6 +51,7 @@ FS/agent.pm
 FS/agent_type.pm
 FS/cust_bill.pm
 FS/cust_bill_pkg.pm
 FS/agent_type.pm
 FS/cust_bill.pm
 FS/cust_bill_pkg.pm
+FS/cust_bill_pkg_detail.pm
 FS/cust_credit.pm
 FS/cust_credit_bill.pm
 FS/cust_main.pm
 FS/cust_credit.pm
 FS/cust_credit_bill.pm
 FS/cust_main.pm
@@ -127,6 +128,7 @@ t/cust_bill.t
 t/cust_bill_event.t
 t/cust_bill_pay.t
 t/cust_bill_pkg.t
 t/cust_bill_event.t
 t/cust_bill_pay.t
 t/cust_bill_pkg.t
+t/cust_bill_pkg_detail.t
 t/cust_credit.t
 t/cust_credit_bill.t
 t/cust_credit_refund.t
 t/cust_credit.t
 t/cust_credit_bill.t
 t/cust_credit_refund.t
index 1948376..cf009c2 100755 (executable)
@@ -421,6 +421,18 @@ sub tables_hash_hack {
       'index' => [ ['invnum'] ],
     },
 
       'index' => [ ['invnum'] ],
     },
 
+    'cust_bill_pkg_detail' => {
+      'columns' => [
+        'detailnum', 'serial', '', '',
+        'pkgnum',  'int', '', '',
+        'invnum',  'int', '', '',
+        'detail',  'varchar', '', $char_d,
+      ],
+      'primary_key' => 'detailnum',
+      'unique' => [],
+      'index' => [ [ 'pkgnum', 'invnum' ] ],
+    },
+
     'cust_credit' => {
       'columns' => [
         'crednum',  'serial', '', '',
     'cust_credit' => {
       'columns' => [
         'crednum',  'serial', '', '',
diff --git a/FS/t/cust_bill_pkg_detail.t b/FS/t/cust_bill_pkg_detail.t
new file mode 100644 (file)
index 0000000..ea6e3d1
--- /dev/null
@@ -0,0 +1,5 @@
+BEGIN { $| = 1; print "1..1\n" }
+END {print "not ok 1\n" unless $loaded;}
+use FS::cust_bill_pkg_detail;
+$loaded=1;
+print "ok 1\n";
index b4d21f3..6522b04 100644 (file)
         <li>edate - ending date
         <li>itemdesc - Line item description (currently used only when pkgnum is 0)
       </ul>
         <li>edate - ending date
         <li>itemdesc - Line item description (currently used only when pkgnum is 0)
       </ul>
+    <li><a name="cust_bill_pkg_detail" href="man/FS/cust_bill_pkg_detail.html">cust_bill_pkg_detail</a> - Invoice line items detail
+      <ul>
+        <li>detailnum - primary key
+        <li>pkgnum -
+        <li>invnum - 
+        <li>detail - Detail description
+      </ul>
     <li><a name="cust_credit" href="man/FS/cust_credit.html">cust_credit</a> - Credits.  The equivalent of a negative <a href="#cust_bill">cust_bill</a> record.
       <ul>
         <li>crednum - primary key
     <li><a name="cust_credit" href="man/FS/cust_credit.html">cust_credit</a> - Credits.  The equivalent of a negative <a href="#cust_bill">cust_bill</a> record.
       <ul>
         <li>crednum - primary key
diff --git a/httemplate/docs/upgrade10.html b/httemplate/docs/upgrade10.html
new file mode 100644 (file)
index 0000000..7aa26f6
--- /dev/null
@@ -0,0 +1,11 @@
+this is very incomplete
+
+CREATE TABLE cust_bill_pkg_detail (
+  detailnum serial,
+  pkgnum int NOT NULL,
+  invnum int NOT NULL,
+  detail varchar(80),
+  PRIMARY KEY (detailnum)
+);
+CREATE INDEX cust_bill_pkg_detail1 ON cust_bill_pkg_detail ( pkgnum, invnum );
+
index 1fd6349..851d3aa 100755 (executable)
@@ -395,7 +395,7 @@ tie my %plans, 'Tie::IxHash',
     },
     'fieldorder' => [qw( setup_fee recur_flat recur_included_hours recur_hourly_charge recur_included_input recur_input_charge recur_included_output recur_output_charge recur_included_total recur_total_charge )],
     'setup' => 'what.setup_fee.value',
     },
     'fieldorder' => [qw( setup_fee recur_flat recur_included_hours recur_hourly_charge recur_included_input recur_input_charge recur_included_output recur_output_charge recur_included_total recur_total_charge )],
     'setup' => 'what.setup_fee.value',
-    'recur' => '\'my $last_bill = $cust_pkg->last_bill; my $hours = $cust_pkg->seconds_since_sqlradacct($last_bill, $sdate ) / 3600 - \' + what.recur_included_hours.value + \'; $hours = 0 if $hours < 0; my $input = $cust_pkg->attribute_since_sqlradacct($last_bill, $sdate, \"AcctInputOctets\" ) / 1048576; my $output = $cust_pkg->attribute_since_sqlradacct($last_bill, $sdate, \"AcctOutputOctets\" ) / 1048576; my $total = $input + $output - \' + what.recur_included_total.value + \'; $total = 0 if $total < 0; my $input = $input - \' + what.recur_included_input.value + \'; $input = 0 if $input < 0; my $output = $output - \' + what.recur_included_output.value + \'; $output = 0 if $output < 0; \' + what.recur_flat.value + \' + \' + what.recur_hourly_charge.value + \' * $hours + \' + what.recur_input_charge.value + \' * $input + \' + what.recur_output_charge.value + \' * $output + \' + what.recur_total_charge.value + \' * $total ;\'',
+    'recur' => '\'my $last_bill = $cust_pkg->last_bill; my $hours = $cust_pkg->seconds_since_sqlradacct($last_bill, $sdate ) / 3600 - \' + what.recur_included_hours.value + \'; $hours = 0 if $hours < 0; my $input = $cust_pkg->attribute_since_sqlradacct($last_bill, $sdate, \"AcctInputOctets\" ) / 1048576; my $output = $cust_pkg->attribute_since_sqlradacct($last_bill, $sdate, \"AcctOutputOctets\" ) / 1048576; my $total = $input + $output - \' + what.recur_included_total.value + \'; $total = 0 if $total < 0; my $input = $input - \' + what.recur_included_input.value + \'; $input = 0 if $input < 0; my $output = $output - \' + what.recur_included_output.value + \'; $output = 0 if $output < 0; my $totalcharge = sprintf(\"%.2f\", \' + what.recur_total_charge.value + \' * $total); my $hourscharge = sprintf(\"%.2f\", \' + what.recur_hourly_charge.value + \' * $hours); push @details, \"Last month\\\'s excess data \". sprintf(\"%.1f\", $total). \" megs: \\\$$totalcharge\", \"Last month\\\'s excess time \". sprintf(\"%.1f\", $hours). \" hours: \\\$$hourscharge\"; \' + what.recur_flat.value + \' + $hourscharge + \' + what.recur_input_charge.value + \' * $input + \' + what.recur_output_charge.value + \' * $output + $totalcharge ;\'',
   },
 
 ;
   },
 
 ;
@@ -485,11 +485,11 @@ my $widget = new HTML::Widgets::SelectLayers(
              '<TR><TD>'.
              '<FONT SIZE="1">Setup expression<BR>'.
              '<INPUT TYPE="text" NAME="setup" SIZE="160" VALUE="'.
              '<TR><TD>'.
              '<FONT SIZE="1">Setup expression<BR>'.
              '<INPUT TYPE="text" NAME="setup" SIZE="160" VALUE="'.
-               $hashref->{setup}. '" onLoad="fchanged(this)">'.
+               encode_entities($hashref->{setup}). '" onLoad="fchanged(this)">'.
              '</FONT><BR>'.
              '<FONT SIZE="1">Recurring espression<BR>'.
              '<INPUT TYPE="text" NAME="recur" SIZE="160" VALUE="'.
              '</FONT><BR>'.
              '<FONT SIZE="1">Recurring espression<BR>'.
              '<INPUT TYPE="text" NAME="recur" SIZE="160" VALUE="'.
-               $hashref->{recur}. '" onLoad="fchanged(this)">'.
+               encode_entities($hashref->{recur}). '" onLoad="fchanged(this)">'.
              '</FONT>'.
              '</TR></TD>'.
              '</TABLE>';
              '</FONT>'.
              '</TR></TD>'.
              '</TABLE>';