[freeside-commits] branch FREESIDE_3_BRANCH updated. ac659c649a8a59398e4dc76c0e25a71a055dc29c

Mark Wells mark at 420.am
Thu Mar 19 13:53:17 PDT 2015


The branch, FREESIDE_3_BRANCH has been updated
       via  ac659c649a8a59398e4dc76c0e25a71a055dc29c (commit)
      from  1afc4addeb73d8b87d6d840a450a396551cf614b (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit ac659c649a8a59398e4dc76c0e25a71a055dc29c
Author: Mark Wells <mark at freeside.biz>
Date:   Tue Mar 17 16:09:20 2015 -0700

    correctly void invoices with fees, #32862

diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm
index e512d2d..0294e9e 100644
--- a/FS/FS/Schema.pm
+++ b/FS/FS/Schema.pm
@@ -871,6 +871,23 @@ sub tables_hashref {
                        ],
     },
 
+    'cust_bill_pkg_fee_void' => {
+      'columns' => [
+        'billpkgfeenum',    'serial', '', '', '', '',
+        'billpkgnum',          'int', '', '', '', '',
+        'base_invnum',       'int', '', '', '', '',
+        'base_billpkgnum',   'int', 'NULL', '', '', '',
+        'amount',        @money_type,         '', '',
+      ],
+      'primary_key' => 'billpkgfeenum',
+      'unique'      => [],
+      'index'       => [ ['billpkgnum'],
+                         ['base_invnum'],
+                         ['base_billpkgnum'],
+                       ],
+    },
+
+
     'cust_bill_pkg_tax_location' => {
       'columns' => [
         'billpkgtaxlocationnum', 'serial',      '', '', '', '',
@@ -928,6 +945,7 @@ sub tables_hashref {
         'unitsetup',           @money_typen,            '', '', 
         'unitrecur',           @money_typen,            '', '', 
         'hidden',              'char', 'NULL',       1, '', '',
+        'feepart',              'int', 'NULL',      '', '', '',
         #void fields
         'void_date', @date_type, '', '', 
         'reason',    'varchar',   'NULL', $char_d, '', '', 
diff --git a/FS/FS/TemplateItem_Mixin.pm b/FS/FS/TemplateItem_Mixin.pm
index 27b8f1b..dcd7ab3 100644
--- a/FS/FS/TemplateItem_Mixin.pm
+++ b/FS/FS/TemplateItem_Mixin.pm
@@ -45,7 +45,31 @@ sub part_pkg {
     $part_pkg = $cust_pkg->part_pkg if $cust_pkg;
     $part_pkg;
   }
+}
+
+=item part_fee
 
+Returns the fee definition for this line item, if there is one.
+
+=cut
+
+sub part_fee {
+  my $self = shift;
+  $self->feepart
+    ? FS::part_fee->by_key($self->feepart)
+    : '';
+}
+
+=item part_X
+
+Returns L</part_pkg> or L</part_fee>, whichever is applicable (or nothing,
+if called on a tax line item).
+
+=cut
+
+sub part_X {
+  my $self = shift;
+  $self->part_pkg || $self->part_fee;
 }
 
 =item desc LOCALE
diff --git a/FS/FS/Template_Mixin.pm b/FS/FS/Template_Mixin.pm
index a547420..08875b3 100644
--- a/FS/FS/Template_Mixin.pm
+++ b/FS/FS/Template_Mixin.pm
@@ -2860,6 +2860,7 @@ sub _items_fee {
     my %base_invnums; # invnum => invoice date
     foreach ($cust_bill_pkg->cust_bill_pkg_fee) {
       if ($_->base_invnum) {
+        # XXX what if base_bill has been voided?
         my $base_bill = FS::cust_bill->by_key($_->base_invnum);
         my $base_date = $self->time2str_local('short', $base_bill->_date)
           if $base_bill;
diff --git a/FS/FS/cust_bill_pkg.pm b/FS/FS/cust_bill_pkg.pm
index 298e234..0e333ae 100644
--- a/FS/FS/cust_bill_pkg.pm
+++ b/FS/FS/cust_bill_pkg.pm
@@ -26,6 +26,7 @@ use FS::cust_bill_pkg_discount_void;
 use FS::cust_bill_pkg_tax_location_void;
 use FS::cust_bill_pkg_tax_rate_location_void;
 use FS::cust_tax_exempt_pkg_void;
+use FS::cust_bill_pkg_fee_void;
 use FS::part_fee;
 
 use FS::Cursor;
@@ -363,6 +364,7 @@ sub void {
     cust_bill_pkg_tax_location
     cust_bill_pkg_tax_rate_location
     cust_tax_exempt_pkg
+    cust_bill_pkg_fee
   )) {
 
     foreach my $linked ( qsearch($table, { billpkgnum=>$self->billpkgnum }) ) {
@@ -422,6 +424,7 @@ sub delete {
     cust_tax_exempt_pkg
     cust_bill_pay_pkg
     cust_credit_bill_pkg
+    cust_bill_pkg_fee
   )) {
 
     foreach my $linked ( qsearch($table, { billpkgnum=>$self->billpkgnum }) ) {
@@ -1153,35 +1156,6 @@ sub tax_location {
   }
 }
 
-=item part_X
-
-Returns the L<FS::part_pkg> or L<FS::part_fee> object that defines this
-charge.  If called on a tax line, returns nothing.
-
-=cut
-
-sub part_X {
-  my $self = shift;
-  if ( $self->pkgpart_override ) {
-    return FS::part_pkg->by_key($self->pkgpart_override);
-  } elsif ( $self->pkgnum ) {
-    return $self->cust_pkg->part_pkg;
-  } elsif ( $self->feepart ) {
-    return $self->part_fee;
-  } else {
-    return;
-  }
-}
-
-# stubs
-
-sub part_fee {
-  my $self = shift;
-  $self->feepart
-    ? FS::part_fee->by_key($self->feepart)
-    : undef;
-}
-
 =back
 
 =head1 CLASS METHODS
diff --git a/FS/FS/cust_bill_pkg_fee_void.pm b/FS/FS/cust_bill_pkg_fee_void.pm
new file mode 100644
index 0000000..51f5a3f
--- /dev/null
+++ b/FS/FS/cust_bill_pkg_fee_void.pm
@@ -0,0 +1,85 @@
+package FS::cust_bill_pkg_fee_void;
+
+use strict;
+use base qw( FS::Record );
+use FS::Record qw( qsearch qsearchs );
+
+=head1 NAME
+
+FS::cust_bill_pkg_fee - Object methods for cust_bill_pkg_fee_void records
+
+=head1 SYNOPSIS
+
+  use FS::cust_bill_pkg_fee;
+
+  $record = new FS::cust_bill_pkg_fee \%hash;
+  $record = new FS::cust_bill_pkg_fee { 'column' => 'value' };
+
+  $error = $record->insert;
+
+  $error = $new_record->replace($old_record);
+
+  $error = $record->delete;
+
+  $error = $record->check;
+
+=head1 DESCRIPTION
+
+An FS::cust_bill_pkg_fee_void object records the origin of a fee that 
+appears on a voided invoice.  FS::cust_bill_pkg_fee_void inherits from
+FS::Record.  The following fields are currently supported:
+
+=over 4
+
+=item billpkgfeenum - primary key
+
+=item billpkgnum - the billpkgnum of the fee line item
+
+=item base_invnum - the invoice number (L<FS::cust_bill>) that caused (this
+portion of) the fee to be charged.
+
+=item base_billpkgnum - the invoice line item (L<FS::cust_bill_pkg>) that
+caused (this portion of) the fee to be charged.  May be null.
+
+=item amount - the fee amount
+
+=back
+
+=head1 METHODS
+
+=over 4
+
+=cut
+
+sub table { 'cust_bill_pkg_fee_void'; }
+
+=item check
+
+Checks all fields to make sure this is a valid record.  If there is an error,
+returns the error, otherwise returns false.  Called by the insert and replace
+methods.
+
+=cut
+
+sub check { my $self = shift;
+
+  my $error = $self->ut_numbern('billpkgfeenum')
+           || $self->ut_number('billpkgnum')
+           || $self->ut_foreign_key('base_invnum', 'cust_bill', 'invnum')
+           || $self->ut_foreign_keyn('base_billpkgnum', 'cust_bill_pkg', 'billpkgnum')
+           || $self->ut_money('amount')
+  ;
+  return $error if $error;
+
+  $self->SUPER::check; }
+
+=back
+
+=head1 SEE ALSO
+
+L<FS::Record>
+
+=cut
+
+1;
+
diff --git a/FS/FS/cust_bill_pkg_void.pm b/FS/FS/cust_bill_pkg_void.pm
index 8949ba7..080452e 100644
--- a/FS/FS/cust_bill_pkg_void.pm
+++ b/FS/FS/cust_bill_pkg_void.pm
@@ -8,6 +8,7 @@ use FS::cust_bill_pkg_detail;
 use FS::cust_bill_pkg_display;
 use FS::cust_bill_pkg_discount;
 use FS::cust_bill_pkg;
+use FS::cust_bill_pkg_fee;
 use FS::cust_bill_pkg_tax_location;
 use FS::cust_bill_pkg_tax_rate_location;
 use FS::cust_tax_exempt_pkg;
@@ -170,6 +171,7 @@ sub unvoid {
     cust_bill_pkg_tax_location
     cust_bill_pkg_tax_rate_location
     cust_tax_exempt_pkg
+    cust_bill_pkg_fee
   )) {
 
     foreach my $voided (
@@ -239,6 +241,7 @@ sub check {
     || $self->ut_moneyn('unitsetup')
     || $self->ut_moneyn('unitrecur')
     || $self->ut_enum('hidden', [ '', 'Y' ])
+    || $self->ut_numbern('feepart')
   ;
   return $error if $error;
 
@@ -258,6 +261,11 @@ sub cust_bill {
   qsearchs( 'cust_bill_void', { 'invnum' => $self->invnum } );
 }
 
+sub cust_bill_pkg_fee {
+  my $self = shift;
+  qsearch( 'cust_bill_pkg_fee_void', { 'billpkgnum' => $self->billpkgnum } );
+}
+
 =back
 
 =head1 BUGS
diff --git a/FS/t/cust_bill_pkg_fee_void.t b/FS/t/cust_bill_pkg_fee_void.t
new file mode 100644
index 0000000..a2a51dc
--- /dev/null
+++ b/FS/t/cust_bill_pkg_fee_void.t
@@ -0,0 +1,5 @@
+BEGIN { $| = 1; print "1..1\n" }
+END {print "not ok 1\n" unless $loaded;}
+use FS::cust_bill_pkg_fee_void;
+$loaded=1;
+print "ok 1\n";
diff --git a/httemplate/view/cust_bill.cgi b/httemplate/view/cust_bill.cgi
index 27376d5..e6191be 100755
--- a/httemplate/view/cust_bill.cgi
+++ b/httemplate/view/cust_bill.cgi
@@ -2,26 +2,37 @@
   emt("View this customer (#[_1])",$display_custnum) => "${p}view/cust_main.cgi?$custnum",
 ) &>
 
-% if ( $conf->exists('deleteinvoices')
-%      && $curuser->access_right('Delete invoices' )
-%    )
-% {
-
-    <SCRIPT TYPE="text/javascript">
-    function areyousure(href, message) {
-      if (confirm(message) == true)
-        window.location.href = href;
-    }
-    </SCRIPT>
-
-    <A HREF  = "javascript:areyousure(
-                  '<%$p%>misc/delete-cust_bill.html?<% $invnum %>',
-                  '<% mt('Are you sure you want to delete this invoice?') |h %>'
-               )"
-       TITLE = "<% mt('Delete this invoice from the database completely') |h %>"
-    ><% mt('Delete this invoice') |h %></A>
-    <BR><BR>
+<SCRIPT TYPE="text/javascript">
+function areyousure(href, message) {
+  if (confirm(message) == true)
+    window.location.href = href;
+}
+</SCRIPT>
 
+% if ( !$cust_bill->closed ) { # otherwise allow no changes
+%   my $can_delete = $conf->exists('deleteinvoices')
+%                    && $curuser->access_right('Delete invoices');
+%   my $can_void = $curuser->access_right('Void invoices');
+%   if ( $can_void ) {
+    <& /elements/popup_link.html,
+      'label'       => emt('Void this invoice'),
+      'actionlabel' => emt('Void this invoice'),
+      'action'      => $p.'misc/void-cust_bill.html?invnum='.$invnum,
+    &>
+%   }
+%   if ( $can_void and $can_delete ) {
+   | 
+%   }
+%   if ( $can_delete ) {
+    <A href="" onclick="areyousure(\
+      '<%$p%>misc/delete-cust_bill.html?<% $invnum %>',\
+      <% mt('Are you sure you want to delete this invoice?') |js_string %>)"\
+    TITLE = "<% mt('Delete this invoice from the database completely') |h %>">\
+    <% emt('Delete this invoice') |h %></A>
+%   }
+%   if ( $can_void or $can_delete ) {
+  <BR><BR>
+%   }
 % }
 
 % if ( $cust_bill->owed > 0
@@ -190,6 +201,13 @@ my $cust_bill = qsearchs({
   'hashref'   => { 'invnum' => $invnum },
   'extra_sql' => ' AND '. $curuser->agentnums_sql,
 });
+# if we're asked for a voided invnum, redirect appropriately
+if (!$cust_bill and FS::cust_bill_void->row_exists("invnum = $invnum") ) {
+  $m->clear_buffer;
+  my $url = $p.'view/cust_bill_void.html?'.$cgi->query_string;
+  $m->print( $cgi->redirect($url) );
+  $m->abort;
+}
 die "Invoice #$invnum not found!" unless $cust_bill;
 
 $cust_bill->set('mode' => $mode);

-----------------------------------------------------------------------

Summary of changes:
 FS/FS/Schema.pm                                  |   18 +++++
 FS/FS/TemplateItem_Mixin.pm                      |   24 ++++++
 FS/FS/Template_Mixin.pm                          |    1 +
 FS/FS/cust_bill_pkg.pm                           |   32 +-------
 FS/FS/cust_bill_pkg_fee_void.pm                  |   85 ++++++++++++++++++++++
 FS/FS/cust_bill_pkg_void.pm                      |    8 ++
 FS/t/{AccessRight.t => cust_bill_pkg_fee_void.t} |    2 +-
 httemplate/view/cust_bill.cgi                    |   56 +++++++++-----
 8 files changed, 177 insertions(+), 49 deletions(-)
 create mode 100644 FS/FS/cust_bill_pkg_fee_void.pm
 copy FS/t/{AccessRight.t => cust_bill_pkg_fee_void.t} (75%)




More information about the freeside-commits mailing list