@@ -, +, @@
by guarantor and other guarantees
---
C4/Circulation.pm | 15 ++
C4/SIP/ILS/Patron.pm | 10 +-
Koha/Patron.pm | 45 ++++
circ/circulation.pl | 6 +
.../data/mysql/atomicupdate/bug_19283.perl | 10 +
installer/data/mysql/sysprefs.sql | 1 +
.../admin/preferences/circulation.pref | 5 +
.../prog/en/modules/circ/circulation.tt | 8 +
opac/sco/sco-main.pl | 2 +-
t/db_dependent/Koha/Patron.t | 206 +++++++++++++++++-
10 files changed, 303 insertions(+), 5 deletions(-)
create mode 100644 installer/data/mysql/atomicupdate/bug_19283.perl
--- a/C4/Circulation.pm
+++ a/C4/Circulation.pm
@@ -796,6 +796,21 @@ sub CanBookBeIssued {
}
}
+ # Check the debt of this patrons guarantors *and* the guarantees of those guarantors
+ my $no_issues_charge_guarantors = C4::Context->preference("NoIssuesChargeGuarantorsWithGuarantees");
+ $no_issues_charge_guarantors = undef unless looks_like_number( $no_issues_charge_guarantors );
+ if ( defined $no_issues_charge_guarantors ) {
+ my $guarantors_non_issues_charges += $patron->relationships_debt({ include_guarantors => 1, only_this_guaranor => 0, include_this_patron => 1 });
+
+ if ( $guarantors_non_issues_charges > $no_issues_charge_guarantors && !$inprocess && !$allowfineoverride) {
+ $issuingimpossible{DEBT_GUARANTORS} = $guarantors_non_issues_charges;
+ } elsif ( $guarantors_non_issues_charges > $no_issues_charge_guarantors && !$inprocess && $allowfineoverride) {
+ $needsconfirmation{DEBT_GUARANTORS} = $guarantors_non_issues_charges;
+ } elsif ( $allfinesneedoverride && $guarantors_non_issues_charges > 0 && $guarantors_non_issues_charges <= $no_issues_charge_guarantors && !$inprocess ) {
+ $needsconfirmation{DEBT_GUARANTORS} = $guarantors_non_issues_charges;
+ }
+ }
+
if ( C4::Context->preference("IssuingInProcess") ) {
if ( $non_issues_charges > $amountlimit && !$inprocess && !$allowfineoverride) {
$issuingimpossible{DEBT} = $non_issues_charges;
--- a/C4/SIP/ILS/Patron.pm
+++ a/C4/SIP/ILS/Patron.pm
@@ -67,10 +67,14 @@ sub new {
$dexpiry and $dexpiry =~ s/-//g; # YYYYMMDD
# Get fines and add fines for guarantees (depends on preference NoIssuesChargeGuarantees)
- my $fines_amount = $flags->{CHARGES}->{amount};
+ my $fines_amount = $flags->{CHARGES}->{amount}; #TODO Replace with $patron->account->non_issues_charges
$fines_amount = ($fines_amount and $fines_amount > 0) ? $fines_amount : 0;
- my $guarantees_fines_amount = $flags->{CHARGES_GUARANTEES} ? $flags->{CHARGES_GUARANTEES}->{amount} : 0;
- $fines_amount += $guarantees_fines_amount;
+ if ( C4::Context->preference('NoIssuesChargeGuarantorsWithGuarantees') ) {
+ $fines_amount += $patron->relationships_debt({ include_guarantors => 1, only_this_guaranor => 0, include_this_patron => 1 });
+ } else {
+ my $guarantees_fines_amount = $flags->{CHARGES_GUARANTEES} ? $flags->{CHARGES_GUARANTEES}->{amount} : 0; #TODO: Replace with $patron->relationships_debt
+ $fines_amount += $guarantees_fines_amount;
+ }
my $fee_limit = _fee_limit();
my $fine_blocked = $fines_amount > $fee_limit;
--- a/Koha/Patron.pm
+++ a/Koha/Patron.pm
@@ -470,6 +470,51 @@ sub guarantee_relationships {
);
}
+=head3 relationships_debt
+
+Returns the amount owed by the patron's guarantors *and* the other guarantees of those guarantors
+
+=cut
+
+sub relationships_debt {
+ my ($self, $params) = @_;
+
+ my $include_guarantors = $params->{include_guarantors};
+ my $only_this_guarantor = $params->{only_this_guaranor};
+ my $include_this_patron = $params->{include_this_patron};
+
+ my @guarantors;
+ if ( $only_this_guarantor ) {
+ @guarantors = $self->guarantor_relationships ? ( $self ) : ();
+ } elsif ( $self->guarantor_relationships ) {
+ # I am a guarantee, just get all my guarantors
+ @guarantors = $self->guarantor_relationships->guarantors;
+ } else {
+ # I am a guarantor, I need to get all the guarantors of all my guarantees
+ @guarantors = map { $_->guarantor_relationships->guarantors } $self->guarantee_relationships->guarantees;
+ }
+
+ my $non_issues_charges = 0;
+ my $seen = $include_this_patron ? {} : { $self->id => 1 }; # For tracking members already added to the total
+ foreach my $g (@guarantors) {
+ $non_issues_charges += $g->account->non_issues_charges if $include_guarantors;
+
+ # We've added what the guarantor owes, not added in that guarantor's guarantees as well
+ my @guarantees = map { $_->guarantee } $g->guarantee_relationships();
+ my $guarantees_non_issues_charges;
+ foreach my $g (@guarantees) {
+ next if $seen->{ $g->id };
+ $guarantees_non_issues_charges += $g->account->non_issues_charges;
+ # Mark this guarantee as seen so we don't double count a guarantee linked to multiple guarantors
+ $seen->{ $g->id } = 1;
+ }
+
+ $non_issues_charges += $guarantees_non_issues_charges;
+ }
+
+ return $non_issues_charges;
+}
+
=head3 housebound_profile
Returns the HouseboundProfile associated with this patron.
--- a/circ/circulation.pl
+++ a/circ/circulation.pl
@@ -402,6 +402,12 @@ if (@$barcodes) {
}
}
+ if ( $error->{DEBT_GUARANTORS} ) {
+ $template_params->{DEBT_GUARANTORS} = $error->{DEBT_GUARANTORS};
+ $template_params->{IMPOSSIBLE} = 1;
+ $blocker = 1;
+ }
+
if ( $error->{UNKNOWN_BARCODE} or not $onsite_checkout or not C4::Context->preference("OnSiteCheckoutsForce") ) {
delete $question->{'DEBT'} if ($debt_confirmed);
foreach my $impossible ( keys %$error ) {
--- a/installer/data/mysql/atomicupdate/bug_19283.perl
+++ a/installer/data/mysql/atomicupdate/bug_19283.perl
@@ -0,0 +1,10 @@
+$DBversion = 'XXX'; # will be replaced by the RM
+if ( CheckVersion($DBversion) ) {
+ $dbh->do(q{
+ INSERT IGNORE INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `type` ) VALUES
+ ('NoIssuesChargeGuarantorsWithGuarantees','','','Define maximum amount withstanding before check outs are blocked including guarantors and their other guarantees','Integer');
+ });
+
+ print "Upgrade to $DBversion done (Bug 19382 - Add ability to block guarantees based on fees owed by guarantor and other guarantees)\n";
+ SetVersion($DBversion);
+}
--- a/installer/data/mysql/sysprefs.sql
+++ a/installer/data/mysql/sysprefs.sql
@@ -325,6 +325,7 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `
('NewsAuthorDisplay','none','none|opac|staff|both','Display the author name for news items.','Choice'),
('noissuescharge','5','','Define maximum amount withstanding before check outs are blocked','Integer'),
('NoIssuesChargeGuarantees','','','Define maximum amount withstanding before check outs are blocked','Integer'),
+('NoIssuesChargeGuarantorsWithGuarantees','','','Define maximum amount withstanding before check outs are blocked including guarantors and their other guarantees','Integer'),
('noItemTypeImages','0',NULL,'If ON, disables item-type images','YesNo'),
('NoRenewalBeforePrecision','exact_time','date|exact_time','Calculate "No renewal before" based on date only or exact time of due date','Choice'),
('NotesBlacklist','',NULL,'List of notes fields that should not appear in the title notes/description separator of details','free'),
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref
+++ a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref
@@ -344,6 +344,11 @@ Circulation:
- pref: NoIssuesChargeGuarantees
class: integer
- '[% local_currency %] in fines.'
+ -
+ - Prevent a patron from checking out if the patron has guarantors and those guarantor's guarantees owing in total more than
+ - pref: NoIssuesChargeGuarantorsWithGuarantees
+ class: integer
+ - '[% local_currency %] in fines.'
-
- pref: RentalsInNoissuesCharge
choices:
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt
+++ a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt
@@ -105,6 +105,10 @@
The patron's guarantees collectively have a debt of [% DEBT_GUARANTEES | $Price %].
[% END %]
+ [% IF ( DEBT_GUARANTORS ) %]
+ The patron's guarantors and their other guarantees collectively have a debt of [% DEBT_GUARANTORS | $Price %].
+ [% END %]
+
[% IF ( RENTALCHARGE && RENTALCHARGE > 0 ) %]
Rental charge for this item: [% RENTALCHARGE | $Price %]
[% END %]
@@ -309,6 +313,10 @@
+ [% IF ( DEBT_GUARANTORS ) %]
+ - The patron's guarantors and their other guarantees collectively have a debt of [% DEBT_GUARANTORS | $Price %].
+ [% END %]
+
[% IF ( STATS ) %]
- Local use recorded
[% END %]
--- a/opac/sco/sco-main.pl
+++ a/opac/sco/sco-main.pl
@@ -151,7 +151,7 @@ elsif ( $patron && ( $op eq 'checkout' || $op eq 'renew' ) ) {
);
my $issue_error;
if ( $confirm_required = scalar keys %$needconfirm ) {
- for my $error ( qw( UNKNOWN_BARCODE max_loans_allowed ISSUED_TO_ANOTHER NO_MORE_RENEWALS NOT_FOR_LOAN DEBT WTHDRAWN RESTRICTED RESERVED ITEMNOTSAMEBRANCH EXPIRED DEBARRED CARD_LOST GNA INVALID_DATE UNKNOWN_BARCODE TOO_MANY DEBT_GUARANTEES USERBLOCKEDOVERDUE PATRON_CANT PREVISSUE NOT_FOR_LOAN_FORCING ITEM_LOST) ) {
+ for my $error ( qw( UNKNOWN_BARCODE max_loans_allowed ISSUED_TO_ANOTHER NO_MORE_RENEWALS NOT_FOR_LOAN DEBT WTHDRAWN RESTRICTED RESERVED ITEMNOTSAMEBRANCH EXPIRED DEBARRED CARD_LOST GNA INVALID_DATE UNKNOWN_BARCODE TOO_MANY DEBT_GUARANTEES DEBT_GUARANTORS USERBLOCKEDOVERDUE PATRON_CANT PREVISSUE NOT_FOR_LOAN_FORCING ITEM_LOST) ) {
if ( $needconfirm->{$error} ) {
$issue_error = $error;
$confirmed = 0;
--- a/t/db_dependent/Koha/Patron.t
+++ a/t/db_dependent/Koha/Patron.t
@@ -19,7 +19,7 @@
use Modern::Perl;
-use Test::More tests => 2;
+use Test::More tests => 3;
use Test::Exception;
use Koha::Database;
@@ -73,6 +73,210 @@ subtest 'add_guarantor() tests' => sub {
$schema->storage->txn_rollback;
};
+subtest 'relationships_debt() tests' => sub {
+
+ plan tests => 168;
+
+ $schema->storage->txn_begin;
+
+ t::lib::Mocks::mock_preference( 'borrowerRelationship', 'parent' );
+
+ my $parent_1 = $builder->build_object({ class => 'Koha::Patrons' });
+ my $parent_2 = $builder->build_object({ class => 'Koha::Patrons' });
+ my $child_1 = $builder->build_object({ class => 'Koha::Patrons' });
+ my $child_2 = $builder->build_object({ class => 'Koha::Patrons' });
+
+ $child_1->add_guarantor({ guarantor_id => $parent_1->borrowernumber, relationship => 'parent' });
+ $child_1->add_guarantor({ guarantor_id => $parent_2->borrowernumber, relationship => 'parent' });
+ $child_2->add_guarantor({ guarantor_id => $parent_1->borrowernumber, relationship => 'parent' });
+ $child_2->add_guarantor({ guarantor_id => $parent_2->borrowernumber, relationship => 'parent' });
+
+ is( $child_1->guarantor_relationships->guarantors->count, 2, 'Child 1 has correct number of guarantors' );
+ is( $child_2->guarantor_relationships->guarantors->count, 2, 'Child 2 has correct number of guarantors' );
+ is( $parent_1->guarantee_relationships->guarantees->count, 2, 'Parent 1 has correct number of guarantors' );
+ is( $parent_2->guarantee_relationships->guarantees->count, 2, 'Parent 2 has correct number of guarantors' );
+
+ # 3 params, count from 0 to 6 in binary ( 3 places ) to get the set of switches, then do that 4 times, one for each parent and child
+ is( $parent_1->relationships_debt({ only_this_guarantor => 0, include_guarantors => 0, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $parent_1->relationships_debt({ only_this_guarantor => 0, include_guarantors => 0, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $parent_1->relationships_debt({ only_this_guarantor => 0, include_guarantors => 1, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $parent_1->relationships_debt({ only_this_guarantor => 0, include_guarantors => 1, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $parent_1->relationships_debt({ only_this_guarantor => 1, include_guarantors => 0, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $parent_1->relationships_debt({ only_this_guarantor => 1, include_guarantors => 0, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $parent_1->relationships_debt({ only_this_guarantor => 1, include_guarantors => 1, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $parent_1->relationships_debt({ only_this_guarantor => 1, include_guarantors => 1, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $parent_2->relationships_debt({ only_this_guarantor => 0, include_guarantors => 0, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $parent_2->relationships_debt({ only_this_guarantor => 0, include_guarantors => 0, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $parent_2->relationships_debt({ only_this_guarantor => 0, include_guarantors => 1, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $parent_2->relationships_debt({ only_this_guarantor => 0, include_guarantors => 1, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $parent_2->relationships_debt({ only_this_guarantor => 1, include_guarantors => 0, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $parent_2->relationships_debt({ only_this_guarantor => 1, include_guarantors => 0, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $parent_2->relationships_debt({ only_this_guarantor => 1, include_guarantors => 1, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $parent_2->relationships_debt({ only_this_guarantor => 1, include_guarantors => 1, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $child_1->relationships_debt({ only_this_guarantor => 0, include_guarantors => 0, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $child_1->relationships_debt({ only_this_guarantor => 0, include_guarantors => 0, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $child_1->relationships_debt({ only_this_guarantor => 0, include_guarantors => 1, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $child_1->relationships_debt({ only_this_guarantor => 0, include_guarantors => 1, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $child_1->relationships_debt({ only_this_guarantor => 1, include_guarantors => 0, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $child_1->relationships_debt({ only_this_guarantor => 1, include_guarantors => 0, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $child_1->relationships_debt({ only_this_guarantor => 1, include_guarantors => 1, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $child_1->relationships_debt({ only_this_guarantor => 1, include_guarantors => 1, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $child_2->relationships_debt({ only_this_guarantor => 0, include_guarantors => 0, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $child_2->relationships_debt({ only_this_guarantor => 0, include_guarantors => 0, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $child_2->relationships_debt({ only_this_guarantor => 0, include_guarantors => 1, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $child_2->relationships_debt({ only_this_guarantor => 0, include_guarantors => 1, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $child_2->relationships_debt({ only_this_guarantor => 1, include_guarantors => 0, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $child_2->relationships_debt({ only_this_guarantor => 1, include_guarantors => 0, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $child_2->relationships_debt({ only_this_guarantor => 1, include_guarantors => 1, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $child_2->relationships_debt({ only_this_guarantor => 1, include_guarantors => 1, include_this_patron => 1 }), 0, 'Family debt is correct' );
+
+ $child_2->account->add_debit({ type => 'ACCOUNT', amount => 10, interface => 'commandline' });
+ is( $child_2->account->non_issues_charges, 10, 'Child 2 owes correct amount' );
+
+ is( $parent_1->relationships_debt({ only_this_guarantor => 0, include_guarantors => 0, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $parent_1->relationships_debt({ only_this_guarantor => 0, include_guarantors => 0, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $parent_1->relationships_debt({ only_this_guarantor => 0, include_guarantors => 1, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $parent_1->relationships_debt({ only_this_guarantor => 0, include_guarantors => 1, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $parent_1->relationships_debt({ only_this_guarantor => 1, include_guarantors => 0, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $parent_1->relationships_debt({ only_this_guarantor => 1, include_guarantors => 0, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $parent_1->relationships_debt({ only_this_guarantor => 1, include_guarantors => 1, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $parent_1->relationships_debt({ only_this_guarantor => 1, include_guarantors => 1, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $parent_2->relationships_debt({ only_this_guarantor => 0, include_guarantors => 0, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $parent_2->relationships_debt({ only_this_guarantor => 0, include_guarantors => 0, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $parent_2->relationships_debt({ only_this_guarantor => 0, include_guarantors => 1, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $parent_2->relationships_debt({ only_this_guarantor => 0, include_guarantors => 1, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $parent_2->relationships_debt({ only_this_guarantor => 1, include_guarantors => 0, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $parent_2->relationships_debt({ only_this_guarantor => 1, include_guarantors => 0, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $parent_2->relationships_debt({ only_this_guarantor => 1, include_guarantors => 1, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $parent_2->relationships_debt({ only_this_guarantor => 1, include_guarantors => 1, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $child_1->relationships_debt({ only_this_guarantor => 0, include_guarantors => 0, include_this_patron => 0 }), 10, 'Family debt is correct' );
+ is( $child_1->relationships_debt({ only_this_guarantor => 0, include_guarantors => 0, include_this_patron => 1 }), 10, 'Family debt is correct' );
+ is( $child_1->relationships_debt({ only_this_guarantor => 0, include_guarantors => 1, include_this_patron => 0 }), 10, 'Family debt is correct' );
+ is( $child_1->relationships_debt({ only_this_guarantor => 0, include_guarantors => 1, include_this_patron => 1 }), 10, 'Family debt is correct' );
+ is( $child_1->relationships_debt({ only_this_guarantor => 1, include_guarantors => 0, include_this_patron => 0 }), 10, 'Family debt is correct' );
+ is( $child_1->relationships_debt({ only_this_guarantor => 1, include_guarantors => 0, include_this_patron => 1 }), 10, 'Family debt is correct' );
+ is( $child_1->relationships_debt({ only_this_guarantor => 1, include_guarantors => 1, include_this_patron => 0 }), 10, 'Family debt is correct' );
+ is( $child_1->relationships_debt({ only_this_guarantor => 1, include_guarantors => 1, include_this_patron => 1 }), 10, 'Family debt is correct' );
+ is( $child_2->relationships_debt({ only_this_guarantor => 0, include_guarantors => 0, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $child_2->relationships_debt({ only_this_guarantor => 0, include_guarantors => 0, include_this_patron => 1 }), 10, 'Family debt is correct' );
+ is( $child_2->relationships_debt({ only_this_guarantor => 0, include_guarantors => 1, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $child_2->relationships_debt({ only_this_guarantor => 0, include_guarantors => 1, include_this_patron => 1 }), 10, 'Family debt is correct' );
+ is( $child_2->relationships_debt({ only_this_guarantor => 1, include_guarantors => 0, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $child_2->relationships_debt({ only_this_guarantor => 1, include_guarantors => 0, include_this_patron => 1 }), 10, 'Family debt is correct' );
+ is( $child_2->relationships_debt({ only_this_guarantor => 1, include_guarantors => 1, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $child_2->relationships_debt({ only_this_guarantor => 1, include_guarantors => 1, include_this_patron => 1 }), 10, 'Family debt is correct' );
+
+ $parent_1->account->add_debit({ type => 'ACCOUNT', amount => 10, interface => 'commandline' });
+ is( $parent_1->account->non_issues_charges, 10, 'Parent 1 owes correct amount' );
+
+ is( $parent_1->relationships_debt({ only_this_guarantor => 0, include_guarantors => 0, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $parent_1->relationships_debt({ only_this_guarantor => 0, include_guarantors => 0, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $parent_1->relationships_debt({ only_this_guarantor => 0, include_guarantors => 1, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $parent_1->relationships_debt({ only_this_guarantor => 0, include_guarantors => 1, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $parent_1->relationships_debt({ only_this_guarantor => 1, include_guarantors => 0, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $parent_1->relationships_debt({ only_this_guarantor => 1, include_guarantors => 0, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $parent_1->relationships_debt({ only_this_guarantor => 1, include_guarantors => 1, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $parent_1->relationships_debt({ only_this_guarantor => 1, include_guarantors => 1, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $parent_2->relationships_debt({ only_this_guarantor => 0, include_guarantors => 0, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $parent_2->relationships_debt({ only_this_guarantor => 0, include_guarantors => 0, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $parent_2->relationships_debt({ only_this_guarantor => 0, include_guarantors => 1, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $parent_2->relationships_debt({ only_this_guarantor => 0, include_guarantors => 1, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $parent_2->relationships_debt({ only_this_guarantor => 1, include_guarantors => 0, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $parent_2->relationships_debt({ only_this_guarantor => 1, include_guarantors => 0, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $parent_2->relationships_debt({ only_this_guarantor => 1, include_guarantors => 1, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $parent_2->relationships_debt({ only_this_guarantor => 1, include_guarantors => 1, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $child_1->relationships_debt({ only_this_guarantor => 0, include_guarantors => 0, include_this_patron => 0 }), 10, 'Family debt is correct' );
+ is( $child_1->relationships_debt({ only_this_guarantor => 0, include_guarantors => 0, include_this_patron => 1 }), 10, 'Family debt is correct' );
+ is( $child_1->relationships_debt({ only_this_guarantor => 0, include_guarantors => 1, include_this_patron => 0 }), 20, 'Family debt is correct' );
+ is( $child_1->relationships_debt({ only_this_guarantor => 0, include_guarantors => 1, include_this_patron => 1 }), 20, 'Family debt is correct' );
+ is( $child_1->relationships_debt({ only_this_guarantor => 1, include_guarantors => 0, include_this_patron => 0 }), 10, 'Family debt is correct' );
+ is( $child_1->relationships_debt({ only_this_guarantor => 1, include_guarantors => 0, include_this_patron => 1 }), 10, 'Family debt is correct' );
+ is( $child_1->relationships_debt({ only_this_guarantor => 1, include_guarantors => 1, include_this_patron => 0 }), 20, 'Family debt is correct' );
+ is( $child_1->relationships_debt({ only_this_guarantor => 1, include_guarantors => 1, include_this_patron => 1 }), 20, 'Family debt is correct' );
+ is( $child_2->relationships_debt({ only_this_guarantor => 0, include_guarantors => 0, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $child_2->relationships_debt({ only_this_guarantor => 0, include_guarantors => 0, include_this_patron => 1 }), 10, 'Family debt is correct' );
+ is( $child_2->relationships_debt({ only_this_guarantor => 0, include_guarantors => 1, include_this_patron => 0 }), 10, 'Family debt is correct' );
+ is( $child_2->relationships_debt({ only_this_guarantor => 0, include_guarantors => 1, include_this_patron => 1 }), 20, 'Family debt is correct' );
+ is( $child_2->relationships_debt({ only_this_guarantor => 1, include_guarantors => 0, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $child_2->relationships_debt({ only_this_guarantor => 1, include_guarantors => 0, include_this_patron => 1 }), 10, 'Family debt is correct' );
+ is( $child_2->relationships_debt({ only_this_guarantor => 1, include_guarantors => 1, include_this_patron => 0 }), 10, 'Family debt is correct' );
+ is( $child_2->relationships_debt({ only_this_guarantor => 1, include_guarantors => 1, include_this_patron => 1 }), 20, 'Family debt is correct' );
+
+ $parent_2->account->add_debit({ type => 'ACCOUNT', amount => 10, interface => 'commandline' });
+ is( $parent_2->account->non_issues_charges, 10, 'Parent 2 owes correct amount' );
+
+ is( $parent_1->relationships_debt({ only_this_guarantor => 0, include_guarantors => 0, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $parent_1->relationships_debt({ only_this_guarantor => 0, include_guarantors => 0, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $parent_1->relationships_debt({ only_this_guarantor => 0, include_guarantors => 1, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $parent_1->relationships_debt({ only_this_guarantor => 0, include_guarantors => 1, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $parent_1->relationships_debt({ only_this_guarantor => 1, include_guarantors => 0, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $parent_1->relationships_debt({ only_this_guarantor => 1, include_guarantors => 0, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $parent_1->relationships_debt({ only_this_guarantor => 1, include_guarantors => 1, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $parent_1->relationships_debt({ only_this_guarantor => 1, include_guarantors => 1, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $parent_2->relationships_debt({ only_this_guarantor => 0, include_guarantors => 0, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $parent_2->relationships_debt({ only_this_guarantor => 0, include_guarantors => 0, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $parent_2->relationships_debt({ only_this_guarantor => 0, include_guarantors => 1, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $parent_2->relationships_debt({ only_this_guarantor => 0, include_guarantors => 1, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $parent_2->relationships_debt({ only_this_guarantor => 1, include_guarantors => 0, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $parent_2->relationships_debt({ only_this_guarantor => 1, include_guarantors => 0, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $parent_2->relationships_debt({ only_this_guarantor => 1, include_guarantors => 1, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $parent_2->relationships_debt({ only_this_guarantor => 1, include_guarantors => 1, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $child_1->relationships_debt({ only_this_guarantor => 0, include_guarantors => 0, include_this_patron => 0 }), 10, 'Family debt is correct' );
+ is( $child_1->relationships_debt({ only_this_guarantor => 0, include_guarantors => 0, include_this_patron => 1 }), 10, 'Family debt is correct' );
+ is( $child_1->relationships_debt({ only_this_guarantor => 0, include_guarantors => 1, include_this_patron => 0 }), 30, 'Family debt is correct' );
+ is( $child_1->relationships_debt({ only_this_guarantor => 0, include_guarantors => 1, include_this_patron => 1 }), 30, 'Family debt is correct' );
+ is( $child_1->relationships_debt({ only_this_guarantor => 1, include_guarantors => 0, include_this_patron => 0 }), 10, 'Family debt is correct' );
+ is( $child_1->relationships_debt({ only_this_guarantor => 1, include_guarantors => 0, include_this_patron => 1 }), 10, 'Family debt is correct' );
+ is( $child_1->relationships_debt({ only_this_guarantor => 1, include_guarantors => 1, include_this_patron => 0 }), 30, 'Family debt is correct' );
+ is( $child_1->relationships_debt({ only_this_guarantor => 1, include_guarantors => 1, include_this_patron => 1 }), 30, 'Family debt is correct' );
+ is( $child_2->relationships_debt({ only_this_guarantor => 0, include_guarantors => 0, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $child_2->relationships_debt({ only_this_guarantor => 0, include_guarantors => 0, include_this_patron => 1 }), 10, 'Family debt is correct' );
+ is( $child_2->relationships_debt({ only_this_guarantor => 0, include_guarantors => 1, include_this_patron => 0 }), 20, 'Family debt is correct' );
+ is( $child_2->relationships_debt({ only_this_guarantor => 0, include_guarantors => 1, include_this_patron => 1 }), 30, 'Family debt is correct' );
+ is( $child_2->relationships_debt({ only_this_guarantor => 1, include_guarantors => 0, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $child_2->relationships_debt({ only_this_guarantor => 1, include_guarantors => 0, include_this_patron => 1 }), 10, 'Family debt is correct' );
+ is( $child_2->relationships_debt({ only_this_guarantor => 1, include_guarantors => 1, include_this_patron => 0 }), 20, 'Family debt is correct' );
+ is( $child_2->relationships_debt({ only_this_guarantor => 1, include_guarantors => 1, include_this_patron => 1 }), 30, 'Family debt is correct' );
+
+ $child_1->account->add_debit({ type => 'ACCOUNT', amount => 10, interface => 'commandline' });
+ is( $child_1->account->non_issues_charges, 10, 'Child 1 owes correct amount' );
+
+ is( $parent_1->relationships_debt({ only_this_guarantor => 0, include_guarantors => 0, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $parent_1->relationships_debt({ only_this_guarantor => 0, include_guarantors => 0, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $parent_1->relationships_debt({ only_this_guarantor => 0, include_guarantors => 1, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $parent_1->relationships_debt({ only_this_guarantor => 0, include_guarantors => 1, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $parent_1->relationships_debt({ only_this_guarantor => 1, include_guarantors => 0, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $parent_1->relationships_debt({ only_this_guarantor => 1, include_guarantors => 0, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $parent_1->relationships_debt({ only_this_guarantor => 1, include_guarantors => 1, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $parent_1->relationships_debt({ only_this_guarantor => 1, include_guarantors => 1, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $parent_2->relationships_debt({ only_this_guarantor => 0, include_guarantors => 0, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $parent_2->relationships_debt({ only_this_guarantor => 0, include_guarantors => 0, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $parent_2->relationships_debt({ only_this_guarantor => 0, include_guarantors => 1, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $parent_2->relationships_debt({ only_this_guarantor => 0, include_guarantors => 1, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $parent_2->relationships_debt({ only_this_guarantor => 1, include_guarantors => 0, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $parent_2->relationships_debt({ only_this_guarantor => 1, include_guarantors => 0, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $parent_2->relationships_debt({ only_this_guarantor => 1, include_guarantors => 1, include_this_patron => 0 }), 0, 'Family debt is correct' );
+ is( $parent_2->relationships_debt({ only_this_guarantor => 1, include_guarantors => 1, include_this_patron => 1 }), 0, 'Family debt is correct' );
+ is( $child_1->relationships_debt({ only_this_guarantor => 0, include_guarantors => 0, include_this_patron => 0 }), 10, 'Family debt is correct' );
+ is( $child_1->relationships_debt({ only_this_guarantor => 0, include_guarantors => 0, include_this_patron => 1 }), 20, 'Family debt is correct' );
+ is( $child_1->relationships_debt({ only_this_guarantor => 0, include_guarantors => 1, include_this_patron => 0 }), 30, 'Family debt is correct' );
+ is( $child_1->relationships_debt({ only_this_guarantor => 0, include_guarantors => 1, include_this_patron => 1 }), 40, 'Family debt is correct' );
+ is( $child_1->relationships_debt({ only_this_guarantor => 1, include_guarantors => 0, include_this_patron => 0 }), 10, 'Family debt is correct' );
+ is( $child_1->relationships_debt({ only_this_guarantor => 1, include_guarantors => 0, include_this_patron => 1 }), 20, 'Family debt is correct' );
+ is( $child_1->relationships_debt({ only_this_guarantor => 1, include_guarantors => 1, include_this_patron => 0 }), 30, 'Family debt is correct' );
+ is( $child_1->relationships_debt({ only_this_guarantor => 1, include_guarantors => 1, include_this_patron => 1 }), 40, 'Family debt is correct' );
+ is( $child_2->relationships_debt({ only_this_guarantor => 0, include_guarantors => 0, include_this_patron => 0 }), 10, 'Family debt is correct' );
+ is( $child_2->relationships_debt({ only_this_guarantor => 0, include_guarantors => 0, include_this_patron => 1 }), 20, 'Family debt is correct' );
+ is( $child_2->relationships_debt({ only_this_guarantor => 0, include_guarantors => 1, include_this_patron => 0 }), 30, 'Family debt is correct' );
+ is( $child_2->relationships_debt({ only_this_guarantor => 0, include_guarantors => 1, include_this_patron => 1 }), 40, 'Family debt is correct' );
+ is( $child_2->relationships_debt({ only_this_guarantor => 1, include_guarantors => 0, include_this_patron => 0 }), 10, 'Family debt is correct' );
+ is( $child_2->relationships_debt({ only_this_guarantor => 1, include_guarantors => 0, include_this_patron => 1 }), 20, 'Family debt is correct' );
+ is( $child_2->relationships_debt({ only_this_guarantor => 1, include_guarantors => 1, include_this_patron => 0 }), 30, 'Family debt is correct' );
+ is( $child_2->relationships_debt({ only_this_guarantor => 1, include_guarantors => 1, include_this_patron => 1 }), 40, 'Family debt is correct' );
+
+ $schema->storage->txn_rollback;
+};
+
subtest 'add_enrolment_fee_if_needed() tests' => sub {
plan tests => 2;
--