{ columns => [ 'eventnum' ],
table => 'cust_event',
},
- { columns => [ 'billpkgnum' ],
- table => 'cust_bill_pkg',
- },
+ #{ columns => [ 'billpkgnum' ],
+ # table => 'cust_bill_pkg',
+ #},
{ columns => [ 'feepart' ],
table => 'part_fee',
},
{ columns => [ 'billpkgnum' ],
table => 'cust_bill_pkg',
},
- { columns => [ 'base_billpkgnum' ],
- table => 'cust_bill_pkg',
- references => [ 'billpkgnum' ],
- },
- { columns => [ 'base_invnum' ],
- table => 'cust_bill',
- references => [ 'invnum' ],
+ ],
+ },
+
+ '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'],
+ ],
+ 'foreign_keys' => [
+ { columns => [ 'billpkgnum' ],
+ table => 'cust_bill_pkg_void',
},
],
},
+
'cust_bill_pkg_tax_location' => {
'columns' => [
'billpkgtaxlocationnum', 'serial', '', '', '', '',
{ columns => [ 'locationnum' ],
table => 'cust_location',
},
- { columns => [ 'taxable_billpkgnum' ],
- table => 'cust_bill_pkg',
- references => [ 'billpkgnum' ],
- },
+ #{ columns => [ 'taxable_billpkgnum' ],
+ # table => 'cust_bill_pkg',
+ # references => [ 'billpkgnum' ],
+ #},
],
},
{ columns => [ 'taxratelocationnum' ],
table => 'tax_rate_location',
},
- { columns => [ 'taxable_billpkgnum' ],
- table => 'cust_bill_pkg',
- references => [ 'billpkgnum' ],
- },
+ #{ columns => [ 'taxable_billpkgnum' ],
+ # table => 'cust_bill_pkg',
+ # references => [ 'billpkgnum' ],
+ #},
],
},
'unitsetup', @money_typen, '', '',
'unitrecur', @money_typen, '', '',
'hidden', 'char', 'NULL', 1, '', '',
+ 'feepart', 'int', 'NULL', '', '', '',
#void fields
'void_date', @date_type, '', '',
'reason', 'varchar', 'NULL', $char_d, '', '',
{ columns => [ 'locationnum' ],
table => 'cust_location',
},
- { columns => [ 'taxable_billpkgnum' ],
- table => 'cust_bill_pkg_void',
- references => [ 'billpkgnum' ],
- },
+ #{ columns => [ 'taxable_billpkgnum' ],
+ # table => 'cust_bill_pkg_void',
+ # references => [ 'billpkgnum' ],
+ #},
],
},
$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
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::Cursor;
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 }) ) {
cust_tax_exempt_pkg
cust_bill_pay_pkg
cust_credit_bill_pkg
+ cust_bill_pkg_fee
)) {
foreach my $linked ( qsearch($table, { billpkgnum=>$self->billpkgnum }) ) {
}
}
-=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;
- }
-}
-
=back
=head1 CLASS METHODS
--- /dev/null
+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;
+
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;
cust_bill_pkg_tax_location
cust_bill_pkg_tax_rate_location
cust_tax_exempt_pkg
+ cust_bill_pkg_fee
)) {
foreach my $voided (
|| $self->ut_moneyn('unitsetup')
|| $self->ut_moneyn('unitrecur')
|| $self->ut_enum('hidden', [ '', 'Y' ])
+ || $self->ut_numbern('feepart')
;
return $error if $error;
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
--- /dev/null
+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";
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
'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);