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 2802-2835 sub _anonymize_column { Link Here
2802
    $self->$col($val);
2802
    $self->$col($val);
2803
}
2803
}
2804
2804
2805
=head3 validate_guarantor
2805
=head3 can_be_guaranteed_by
2806
2806
2807
    Koha::Patron->validate_guarantor(\@guarantors, $contactname, $category );
2807
    $patron->can_be_guaranteed_by( [
2808
        $guarantor1,
2809
        $guarantor2,
2810
        ...
2811
    ] );
2808
2812
2809
    Validates guarantor patron.
2813
    Given an array of guarantors, checks if they can be guarantors for this patron.
2814
2815
    Throws Koha::Exceptions::Patron::Relationship::InvalidRelationship if a proposed
2816
        guarantor cannot be a guarantor for this patron.
2817
2818
    $patron->can_be_guaranteed_by();
2819
2820
    Given no guarantors, checks if this patron must be guaranteed by someone. Read
2821
    "can be guaranteed by nobody".
2822
2823
    Throws Koha::Exceptions::Patron::Relationship::NoGuarantor if this patron must
2824
        have a guarantor.
2810
2825
2811
=cut
2826
=cut
2812
2827
2813
sub validate_guarantor {
2828
sub can_be_guaranteed_by {
2814
    my ( $self, $guarantors, $contactname, $category ) = @_;
2829
    my ( $self, $guarantors ) = @_;
2815
2830
2816
    my $valid_guarantor = @$guarantors ? @$guarantors : $contactname;
2831
    my $category = $self->category;
2817
2832
2818
    if (    C4::Context->preference('ChildNeedsGuarantor')
2833
    if (    C4::Context->preference('ChildNeedsGuarantor')
2819
        and ( $category->category_type eq 'C' or $category->can_be_guarantee )
2834
        and ( $category->category_type eq 'C' or $category->can_be_guarantee )
2820
        and !$valid_guarantor )
2835
        and scalar @$guarantors == 0 )
2821
    {
2836
    {
2822
        Koha::Exceptions::Patron::Relationship::NoGuarantor->throw();
2837
        Koha::Exceptions::Patron::Relationship::NoGuarantor->throw();
2823
    }
2838
    }
2824
2839
2840
    if ( $self->is_guarantor && scalar @$guarantors > 0 ) {
2841
        Koha::Exceptions::Patron::Relationship::InvalidRelationship->throw( guarantor_cant_have_guarantors => 1 );
2842
    }
2843
2825
    foreach my $guarantor (@$guarantors) {
2844
    foreach my $guarantor (@$guarantors) {
2845
        next if ref($guarantor) ne 'Koha::Patron';
2846
2826
        if ( $guarantor->is_guarantee ) {
2847
        if ( $guarantor->is_guarantee ) {
2827
            Koha::Exceptions::Patron::Relationship::InvalidRelationship->throw( invalid_guarantor => 1 );
2848
            Koha::Exceptions::Patron::Relationship::InvalidRelationship->throw(
2849
                invalid_guarantor => 1,
2850
                guarantor         => $guarantor,
2851
            );
2828
        } elsif ( $guarantor->is_child ) {
2852
        } elsif ( $guarantor->is_child ) {
2829
            Koha::Exceptions::Patron::Relationship::InvalidRelationship->throw( child_guarantor => 1 );
2853
            Koha::Exceptions::Patron::Relationship::InvalidRelationship->throw( child_guarantor => 1 );
2830
        }
2854
        }
2831
    }
2855
    }
2832
2856
2857
    return 1;
2833
}
2858
}
2834
2859
2835
=head3 add_guarantor
2860
=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 273-305 if (@delete_guarantor) { Link Here
273
    if ( C4::Context->preference('ChildNeedsGuarantor') && $will_remove_last ) {
275
    if ( C4::Context->preference('ChildNeedsGuarantor') && $will_remove_last ) {
274
        push @errors, 'ERROR_cannot_delete_guarantor';
276
        push @errors, 'ERROR_cannot_delete_guarantor';
275
    } else {
277
    } else {
278
        my @deleted_guarantors;
276
        foreach my $id (@delete_guarantor) {
279
        foreach my $id (@delete_guarantor) {
277
            my $r = Koha::Patron::Relationships->find($id);
280
            my $r = Koha::Patron::Relationships->find($id);
278
            $r->delete() if $r;
281
            if ($r) {
282
                $r->delete();
283
                push @deleted_guarantors, $id;
284
            }
285
        }
286
        foreach my $deleted_guarantor_id (@deleted_guarantors) {
287
            @guarantors = grep { ref($_) eq 'Koha::Patron' && $_->id ne $deleted_guarantor_id } @guarantors;
279
        }
288
        }
280
    }
289
    }
281
}
290
}
282
291
283
#Check if guarantor requirements are met
292
#Check if guarantor requirements are met
284
if ( ( $op eq 'cud-save' || $op eq 'cud-insert' ) ) {
293
my $guarantors_to_be_validated =
285
    unless ( $patron && $patron->is_guarantor ) {
294
    @guarantors ? \@guarantors : $newdata{'contactname'} ? [ $newdata{'contactname'} ] : [];
286
        try {
295
if ( ( $op eq 'cud-save' || $op eq 'cud-insert' ) && $guarantors_to_be_validated ) {
287
            Koha::Patron->validate_guarantor( \@guarantors, $newdata{'contactname'}, $category );
296
    try {
288
        } catch {
297
        if ($patron) {
289
            if ( ref($_) eq "Koha::Exceptions::Patron::Relationship::NoGuarantor" ) {
298
            if ( $patron->categorycode eq $categorycode ) {
299
                $patron->can_be_guaranteed_by($guarantors_to_be_validated);
300
            } else {
301
                # If $patron's categorycode is about to change, check guarantor requirements against
302
                # the new category but keep the original $patron object intact
303
                # (this clone()s the $patron)
304
                ( bless {%$patron}, ref $patron )->categorycode($categorycode)
305
                    ->can_be_guaranteed_by($guarantors_to_be_validated);
306
            }
307
        } else {
308
            Koha::Patron->new( { categorycode => $categorycode } )->can_be_guaranteed_by($guarantors_to_be_validated);
309
        }
310
    } catch {
311
        unless ( blessed($_) ) {
312
            $logger->error($_);
313
        } else {
314
            if ( $_->isa("Koha::Exceptions::Patron::Relationship::NoGuarantor") ) {
290
                push @errors, "ERROR_child_no_guarantor";
315
                push @errors, "ERROR_child_no_guarantor";
291
            } elsif ( ref($_) eq "Koha::Exceptions::Patron::Relationship::InvalidRelationship" ) {
316
            } elsif ( $_->isa("Koha::Exceptions::Patron::Relationship::InvalidRelationship") ) {
292
                if ( $_->full_message eq "Guarantee patron cannot be a guarantor." ) {
317
                if ( $_->invalid_guarantor ) {
293
                    push @errors, "ERROR_guarantor_is_guarantee";
318
                    push @errors, "ERROR_guarantor_is_guarantee";
294
                } elsif ( $_->full_message eq "Child patron cannot be a guarantor." ) {
319
                    $template->param( guarantor_is_guarantee => $_->guarantor );
320
                } elsif ( $_->child_guarantor ) {
295
                    push @errors, "ERROR_child_is_guarantor";
321
                    push @errors, "ERROR_child_is_guarantor";
322
                } elsif ( $_->guarantor_cant_have_guarantors ) {
323
                    push @errors, "ERROR_guarantor_cant_have_guarantors";
296
                }
324
                }
325
            } else {
326
                $logger->error( $_->error );
327
                $_->rethrow;
297
            }
328
            }
298
            return;
329
        }
299
        };
330
        return;
300
    } else {
331
    };
301
        push @errors, "ERROR_guarantee_is_guarantor";
302
    }
303
}
332
}
304
333
305
my @valid_relationships = split( /\|/, C4::Context->preference('borrowerRelationship'), -1 );
334
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