View | Details | Raw Unified | Return to bug 39014
Collapse All | Expand All

(-)a/Koha/Exceptions/Patron/Relationship.pm (-1 / +1 lines)
Lines 32-38 use Exception::Class ( Link Here
32
    'Koha::Exceptions::Patron::Relationship::InvalidRelationship' => {
32
    'Koha::Exceptions::Patron::Relationship::InvalidRelationship' => {
33
        isa         => 'Koha::Exceptions::Patron::Relationship',
33
        isa         => 'Koha::Exceptions::Patron::Relationship',
34
        description => 'The specified relationship is invalid',
34
        description => 'The specified relationship is invalid',
35
        fields      => [ 'relationship', 'no_relationship', 'invalid_guarantor', 'child_guarantor' ]
35
        fields => [ 'relationship', 'no_relationship', 'invalid_guarantor', 'child_guarantor', 'guarantor_cant_have_guarantors', 'guarantor' ],
36
    },
36
    },
37
    'Koha::Exceptions::Patron::Relationship::NoGuarantor' => {
37
    'Koha::Exceptions::Patron::Relationship::NoGuarantor' => {
38
        isa         => 'Koha::Exceptions::Patron::Relationship',
38
        isa         => 'Koha::Exceptions::Patron::Relationship',
(-)a/Koha/Patron.pm (-8 / +33 lines)
Lines 2708-2741 sub _anonymize_column { Link Here
2708
    $self->$col($val);
2708
    $self->$col($val);
2709
}
2709
}
2710
2710
2711
=head3 validate_guarantor
2711
=head3 can_be_guaranteed_by
2712
2712
2713
    Koha::Patron->validate_guarantor(\@guarantors, $contactname, $category );
2713
    $patron->can_be_guaranteed_by( [
2714
        $guarantor1,
2715
        $guarantor2,
2716
        ...
2717
    ] );
2714
2718
2715
    Validates guarantor patron.
2719
    Given an array of guarantors, checks if they can be guarantors for this patron.
2720
2721
    Throws Koha::Exceptions::Patron::Relationship::InvalidRelationship if a proposed
2722
        guarantor cannot be a guarantor for this patron.
2723
2724
    $patron->can_be_guaranteed_by();
2725
2726
    Given no guarantors, checks if this patron must be guaranteed by someone. Read
2727
    "can be guaranteed by nobody".
2728
    
2729
    Throws Koha::Exceptions::Patron::Relationship::NoGuarantor if this patron must
2730
        have a guarantor.
2716
2731
2717
=cut
2732
=cut
2718
2733
2719
sub validate_guarantor {
2734
sub can_be_guaranteed_by {
2720
    my ( $self, $guarantors, $contactname, $category ) = @_;
2735
    my ( $self, $guarantors ) = @_;
2721
2736
2722
    my $valid_guarantor = @$guarantors ? @$guarantors : $contactname;
2737
    my $category = $self->category;
2723
2738
2724
    if (    C4::Context->preference('ChildNeedsGuarantor')
2739
    if (    C4::Context->preference('ChildNeedsGuarantor')
2725
        and ( $category->category_type eq 'C' or $category->can_be_guarantee )
2740
        and ( $category->category_type eq 'C' or $category->can_be_guarantee )
2726
        and !$valid_guarantor )
2741
        and scalar @$guarantors == 0 )
2727
    {
2742
    {
2728
        Koha::Exceptions::Patron::Relationship::NoGuarantor->throw();
2743
        Koha::Exceptions::Patron::Relationship::NoGuarantor->throw();
2729
    }
2744
    }
2730
2745
2746
    if ( $self->is_guarantor && scalar @$guarantors > 0 ) {
2747
        Koha::Exceptions::Patron::Relationship::InvalidRelationship->throw( guarantor_cant_have_guarantors => 1 );
2748
    }
2749
2731
    foreach my $guarantor (@$guarantors) {
2750
    foreach my $guarantor (@$guarantors) {
2751
        next if ref($guarantor) ne 'Koha::Patron';
2752
2732
        if ( $guarantor->is_guarantee ) {
2753
        if ( $guarantor->is_guarantee ) {
2733
            Koha::Exceptions::Patron::Relationship::InvalidRelationship->throw( invalid_guarantor => 1 );
2754
            Koha::Exceptions::Patron::Relationship::InvalidRelationship->throw(
2755
                invalid_guarantor => 1,
2756
                guarantor         => $guarantor,
2757
            );
2734
        } elsif ( $guarantor->is_child ) {
2758
        } elsif ( $guarantor->is_child ) {
2735
            Koha::Exceptions::Patron::Relationship::InvalidRelationship->throw( child_guarantor => 1 );
2759
            Koha::Exceptions::Patron::Relationship::InvalidRelationship->throw( child_guarantor => 1 );
2736
        }
2760
        }
2737
    }
2761
    }
2738
2762
2763
    return 1;
2739
}
2764
}
2740
2765
2741
=head3 add_guarantor
2766
=head3 add_guarantor
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt (-3 / +6 lines)
Lines 195-204 Link Here
195
                                    <li id="ERROR_child_is_guarantor">Child patron cannot be a guarantor.</li>
195
                                    <li id="ERROR_child_is_guarantor">Child patron cannot be a guarantor.</li>
196
                                [% END %]
196
                                [% END %]
197
                                [% IF ( ERROR_guarantor_is_guarantee ) %]
197
                                [% IF ( ERROR_guarantor_is_guarantee ) %]
198
                                    <li id="ERROR_guarantor_is_guarantee">A guarantee cannot be a guarantor.</li>
198
                                    <li id="ERROR_guarantor_is_guarantee">
199
                                        Cannot add a guarantor. The proposed guarantor <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% guarantor_is_guarantee.borrowernumber | uri %]" target="blank">
200
                                        [% guarantor_is_guarantee.firstname | html %] [% guarantor_is_guarantee.surname | html %] ([% guarantor_is_guarantee.cardnumber | html %])
201
                                        </a> is a guarantee of someone else, and guarantees cannot be guarantors.</li>
199
                                [% END %]
202
                                [% END %]
200
                                [% IF ( ERROR_guarantee_is_guarantor ) %]
203
                                [% IF ( ERROR_guarantor_cant_have_guarantors ) %]
201
                                    <li id="ERROR_guarantee_is_guarantor">A guarantor cannot be a guarantee.</li>
204
                                    <li id="ERROR_guarantor_cant_have_guarantors">Cannot add a guarantor. This patron is already a guarantor, and guarantors cannot have guarantors.</li>
202
                                [% END %]
205
                                [% END %]
203
                                [% IF ( ERROR_cannot_delete_guarantor ) %]
206
                                [% IF ( ERROR_cannot_delete_guarantor ) %]
204
                                    <li id="ERROR_cannot_delete_guarantor">Cannot delete guarantor(s). A child patron needs a guarantor.</li>
207
                                    <li id="ERROR_cannot_delete_guarantor">Cannot delete guarantor(s). A child patron needs a guarantor.</li>
(-)a/members/memberentry.pl (-15 / +44 lines)
Lines 24-29 use Try::Tiny; Link Here
24
24
25
# external modules
25
# external modules
26
use CGI qw ( -utf8 );
26
use CGI qw ( -utf8 );
27
use Scalar::Util qw( blessed );
27
28
28
# internal modules
29
# internal modules
29
use C4::Auth qw( get_template_and_user haspermission );
30
use C4::Auth qw( get_template_and_user haspermission );
Lines 53-58 my $input = CGI->new; Link Here
53
my %data;
54
my %data;
54
55
55
my $dbh = C4::Context->dbh;
56
my $dbh = C4::Context->dbh;
57
my $logger = Koha::Logger->get({ interface => 'intranet '});
56
58
57
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
59
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
58
    {
60
    {
Lines 278-310 if (@delete_guarantor) { Link Here
278
    if ( C4::Context->preference('ChildNeedsGuarantor') && $will_remove_last ) {
280
    if ( C4::Context->preference('ChildNeedsGuarantor') && $will_remove_last ) {
279
        push @errors, 'ERROR_cannot_delete_guarantor';
281
        push @errors, 'ERROR_cannot_delete_guarantor';
280
    } else {
282
    } else {
283
        my @deleted_guarantors;
281
        foreach my $id (@delete_guarantor) {
284
        foreach my $id (@delete_guarantor) {
282
            my $r = Koha::Patron::Relationships->find($id);
285
            my $r = Koha::Patron::Relationships->find($id);
283
            $r->delete() if $r;
286
            if ($r) {
287
                $r->delete();
288
                push @deleted_guarantors, $id;
289
            }
290
        }
291
        foreach my $deleted_guarantor_id (@deleted_guarantors) {
292
            @guarantors = grep { ref($_) eq 'Koha::Patron' && $_->id ne $deleted_guarantor_id } @guarantors;
284
        }
293
        }
285
    }
294
    }
286
}
295
}
287
296
288
#Check if guarantor requirements are met
297
#Check if guarantor requirements are met
289
if ( ( $op eq 'cud-save' || $op eq 'cud-insert' ) ) {
298
my $guarantors_to_be_validated =
290
    unless ( $patron && $patron->is_guarantor ) {
299
    @guarantors ? \@guarantors : $newdata{'contactname'} ? [ $newdata{'contactname'} ] : [];
291
        try {
300
if ( ( $op eq 'cud-save' || $op eq 'cud-insert' ) && $guarantors_to_be_validated ) {
292
            Koha::Patron->validate_guarantor( \@guarantors, $newdata{'contactname'}, $category );
301
    try {
293
        } catch {
302
        if ($patron) {
294
            if ( ref($_) eq "Koha::Exceptions::Patron::Relationship::NoGuarantor" ) {
303
            if ( $patron->categorycode eq $categorycode ) {
304
                $patron->can_be_guaranteed_by($guarantors_to_be_validated);
305
            } else {
306
                # If $patron's categorycode is about to change, check guarantor requirements against
307
                # the new category but keep the original $patron object intact
308
                # (this clone()s the $patron)
309
                ( bless {%$patron}, ref $patron )->categorycode($categorycode)
310
                    ->can_be_guaranteed_by($guarantors_to_be_validated);
311
            }
312
        } else {
313
            Koha::Patron->new( { categorycode => $categorycode } )->can_be_guaranteed_by($guarantors_to_be_validated);
314
        }
315
    } catch {
316
        unless ( blessed($_) ) {
317
            $logger->error($_);
318
        } else {
319
            if ( $_->isa("Koha::Exceptions::Patron::Relationship::NoGuarantor") ) {
295
                push @errors, "ERROR_child_no_guarantor";
320
                push @errors, "ERROR_child_no_guarantor";
296
            } elsif ( ref($_) eq "Koha::Exceptions::Patron::Relationship::InvalidRelationship" ) {
321
            } elsif ( $_->isa("Koha::Exceptions::Patron::Relationship::InvalidRelationship") ) {
297
                if ( $_->full_message eq "Guarantee patron cannot be a guarantor." ) {
322
                if ( $_->invalid_guarantor ) {
298
                    push @errors, "ERROR_guarantor_is_guarantee";
323
                    push @errors, "ERROR_guarantor_is_guarantee";
299
                } elsif ( $_->full_message eq "Child patron cannot be a guarantor." ) {
324
                    $template->param( guarantor_is_guarantee => $_->guarantor );
325
                } elsif ( $_->child_guarantor ) {
300
                    push @errors, "ERROR_child_is_guarantor";
326
                    push @errors, "ERROR_child_is_guarantor";
327
                } elsif ( $_->guarantor_cant_have_guarantors ) {
328
                    push @errors, "ERROR_guarantor_cant_have_guarantors";
301
                }
329
                }
330
            } else {
331
                $logger->error( $_->error );
332
                $_->rethrow;
302
            }
333
            }
303
            return;
334
        }
304
        };
335
        return;
305
    } else {
336
    };
306
        push @errors, "ERROR_guarantee_is_guarantor";
307
    }
308
}
337
}
309
338
310
my @valid_relationships = split( /\|/, C4::Context->preference('borrowerRelationship'), -1 );
339
my @valid_relationships = split( /\|/, C4::Context->preference('borrowerRelationship'), -1 );
(-)a/t/db_dependent/Koha/Patron.t (-11 / +18 lines)
Lines 2624-2630 subtest 'get_lists_with_patron() tests' => sub { Link Here
2624
    $schema->storage->txn_rollback;
2624
    $schema->storage->txn_rollback;
2625
};
2625
};
2626
2626
2627
subtest 'validate_guarantor() tests' => sub {
2627
subtest 'can_be_guaranteed_by() tests' => sub {
2628
2628
2629
    plan tests => 5;
2629
    plan tests => 5;
2630
2630
Lines 2659-2664 subtest 'validate_guarantor() tests' => sub { Link Here
2659
            value => { categorycode => $guarantor_category->{categorycode} }
2659
            value => { categorycode => $guarantor_category->{categorycode} }
2660
        }
2660
        }
2661
    );
2661
    );
2662
    my $patron2 = $builder->build_object(
2663
        {
2664
            class => 'Koha::Patrons',
2665
            value => { categorycode => $guarantor_category->{categorycode} }
2666
        }
2667
    );
2662
2668
2663
    my @guarantors;
2669
    my @guarantors;
2664
    my $contactname = "";
2670
    my $contactname = "";
Lines 2666-2694 subtest 'validate_guarantor() tests' => sub { Link Here
2666
2672
2667
    t::lib::Mocks::mock_preference( 'ChildNeedsGuarantor', 0 );
2673
    t::lib::Mocks::mock_preference( 'ChildNeedsGuarantor', 0 );
2668
2674
2669
    lives_ok { $child->validate_guarantor( \@guarantors, $contactname, $category ); }
2675
    lives_ok { $child->can_be_guaranteed_by( \@guarantors ); }
2670
    'Validation passes when ChildNeedsGuarantor syspref is disabled';
2676
    'Validation passes when ChildNeedsGuarantor syspref is disabled';
2671
2677
2672
    t::lib::Mocks::mock_preference( 'ChildNeedsGuarantor', 1 );
2678
    t::lib::Mocks::mock_preference( 'ChildNeedsGuarantor', 1 );
2673
2679
2674
    throws_ok { $child->validate_guarantor( \@guarantors, $contactname, $category ); }
2680
    throws_ok { $child->can_be_guaranteed_by( \@guarantors ); }
2675
    'Koha::Exceptions::Patron::Relationship::NoGuarantor',
2681
    'Koha::Exceptions::Patron::Relationship::NoGuarantor',
2676
        'Exception thrown when guarantor is required but not provided.';
2682
        'Exception thrown when guarantor is required but not provided.';
2677
2683
2678
    @guarantors = ( $patron, $child2 );
2684
    @guarantors = ( $patron, $child2 );
2679
    throws_ok { $child->validate_guarantor( \@guarantors, $contactname, $category ); }
2685
    throws_ok { $child->can_be_guaranteed_by( \@guarantors ); }
2680
    'Koha::Exceptions::Patron::Relationship::InvalidRelationship',
2686
    'Koha::Exceptions::Patron::Relationship::InvalidRelationship',
2681
        'Exception thrown when child patron is added as guarantor.';
2687
        'Exception thrown when child patron is added as guarantor.';
2682
2688
2689
    t::lib::Mocks::mock_preference( 'borrowerRelationship', 'parent' );
2690
    $child2->add_guarantor({ guarantor_id => $patron->id, relationship => 'parent' });
2691
    @guarantors = ( $patron2 );
2692
    throws_ok { $patron->can_be_guaranteed_by( \@guarantors ); }
2693
    'Koha::Exceptions::Patron::Relationship::InvalidRelationship',
2694
        'Exception thrown when trying to add a guarantor to a guarantor.';
2695
2683
    @guarantors = ($patron);
2696
    @guarantors = ($patron);
2684
    lives_ok { $child->validate_guarantor( \@guarantors, undef, $category ); }
2697
    lives_ok { $child->can_be_guaranteed_by( \@guarantors ); }
2685
    'Validation passes when valid guarantors are passed in array';
2698
    'Validation passes when valid guarantors are passed in array';
2686
2699
2687
    @guarantors  = ();
2688
    $contactname = "Guarantor";
2689
    lives_ok { $child->validate_guarantor( \@guarantors, $contactname, $category ); }
2690
    'Validation passes when guarantor contanct name is passed';
2691
2692
    $schema->storage->txn_rollback;
2700
    $schema->storage->txn_rollback;
2693
};
2701
};
2694
2702
2695
- 

Return to bug 39014