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

(-)a/C4/Circulation.pm (-1 / +1 lines)
Lines 770-776 sub CanBookBeIssued { Link Here
770
    $no_issues_charge_guarantees = undef unless looks_like_number( $no_issues_charge_guarantees );
770
    $no_issues_charge_guarantees = undef unless looks_like_number( $no_issues_charge_guarantees );
771
    if ( defined $no_issues_charge_guarantees ) {
771
    if ( defined $no_issues_charge_guarantees ) {
772
        my $p = Koha::Patrons->find( $borrower->{borrowernumber} );
772
        my $p = Koha::Patrons->find( $borrower->{borrowernumber} );
773
        my @guarantees = $p->guarantees();
773
        my @guarantees = map { $_->guarantee } $p->guarantee_relationships();
774
        my $guarantees_non_issues_charges;
774
        my $guarantees_non_issues_charges;
775
        foreach my $g ( @guarantees ) {
775
        foreach my $g ( @guarantees ) {
776
            my ( $b, $n, $o ) = C4::Members::GetMemberAccountBalance( $g->id );
776
            my ( $b, $n, $o ) = C4::Members::GetMemberAccountBalance( $g->id );
(-)a/C4/Members.pm (-7 / +7 lines)
Lines 207-213 sub patronflags { Link Here
207
    $no_issues_charge_guarantees = undef unless looks_like_number( $no_issues_charge_guarantees );
207
    $no_issues_charge_guarantees = undef unless looks_like_number( $no_issues_charge_guarantees );
208
    if ( defined $no_issues_charge_guarantees ) {
208
    if ( defined $no_issues_charge_guarantees ) {
209
        my $p = Koha::Patrons->find( $patroninformation->{borrowernumber} );
209
        my $p = Koha::Patrons->find( $patroninformation->{borrowernumber} );
210
        my @guarantees = $p->guarantees();
210
        my @guarantees = map { $_->guarantee } $p->guarantee_relationships;
211
        my $guarantees_non_issues_charges;
211
        my $guarantees_non_issues_charges;
212
        foreach my $g ( @guarantees ) {
212
        foreach my $g ( @guarantees ) {
213
            my ( $b, $n, $o ) = C4::Members::GetMemberAccountBalance( $g->id );
213
            my ( $b, $n, $o ) = C4::Members::GetMemberAccountBalance( $g->id );
Lines 1063-1080 sub GetBorrowersToExpunge { Link Here
1063
        FROM   borrowers
1063
        FROM   borrowers
1064
        JOIN   categories USING (categorycode)
1064
        JOIN   categories USING (categorycode)
1065
        LEFT JOIN (
1065
        LEFT JOIN (
1066
            SELECT guarantorid
1066
            SELECT guarantor_id
1067
            FROM borrowers
1067
            FROM relationships
1068
            WHERE guarantorid IS NOT NULL
1068
            WHERE guarantor_id IS NOT NULL
1069
                AND guarantorid <> 0
1069
                AND guarantor_id <> 0
1070
        ) as tmp ON borrowers.borrowernumber=tmp.guarantorid
1070
        ) as tmp ON borrowers.borrowernumber=tmp.guarantor_id
1071
        LEFT JOIN old_issues USING (borrowernumber)
1071
        LEFT JOIN old_issues USING (borrowernumber)
1072
        LEFT JOIN issues USING (borrowernumber)|;
1072
        LEFT JOIN issues USING (borrowernumber)|;
1073
    if ( $filterpatronlist  ){
1073
    if ( $filterpatronlist  ){
1074
        $query .= q| LEFT JOIN patron_list_patrons USING (borrowernumber)|;
1074
        $query .= q| LEFT JOIN patron_list_patrons USING (borrowernumber)|;
1075
    }
1075
    }
1076
    $query .= q| WHERE  category_type <> 'S'
1076
    $query .= q| WHERE  category_type <> 'S'
1077
        AND tmp.guarantorid IS NULL
1077
        AND tmp.guarantor_id IS NULL
1078
   |;
1078
   |;
1079
    my @query_params;
1079
    my @query_params;
1080
    if ( $filterbranch && $filterbranch ne "" ) {
1080
    if ( $filterbranch && $filterbranch ne "" ) {
(-)a/Koha/Item.pm (+1 lines)
Lines 28-33 use C4::Context; Link Here
28
use Koha::Checkouts;
28
use Koha::Checkouts;
29
use Koha::IssuingRules;
29
use Koha::IssuingRules;
30
use Koha::Item::Transfer;
30
use Koha::Item::Transfer;
31
use Koha::Biblios;
31
use Koha::Patrons;
32
use Koha::Patrons;
32
use Koha::Libraries;
33
use Koha::Libraries;
33
34
(-)a/Koha/Object.pm (-2 / +6 lines)
Lines 69-76 sub new { Link Here
69
            next if not exists $attributes->{$column_name} or defined $attributes->{$column_name};
69
            next if not exists $attributes->{$column_name} or defined $attributes->{$column_name};
70
            delete $attributes->{$column_name};
70
            delete $attributes->{$column_name};
71
        }
71
        }
72
        $self->{_result} = $schema->resultset( $class->_type() )
72
73
          ->new($attributes);
73
        eval {
74
            $self->{_result} =
75
              $schema->resultset( $class->_type() )->new($attributes);
76
        };
77
        Carp::cluck("ERROR: $@") if $@;
74
    }
78
    }
75
79
76
    croak("No _type found! Koha::Object must be subclassed!")
80
    croak("No _type found! Koha::Object must be subclassed!")
(-)a/Koha/Patron.pm (-32 / +50 lines)
Lines 25-39 use Carp; Link Here
25
use C4::Context;
25
use C4::Context;
26
use C4::Log;
26
use C4::Log;
27
use Koha::Checkouts;
27
use Koha::Checkouts;
28
use Koha::Old::Checkouts;
28
use Koha::Database;
29
use Koha::Database;
29
use Koha::DateUtils;
30
use Koha::DateUtils;
30
use Koha::Holds;
31
use Koha::Holds;
31
use Koha::Old::Checkouts;
32
use Koha::Patrons;
32
use Koha::Patron::Categories;
33
use Koha::Patron::Categories;
34
use Koha::Patron::Relationships;
33
use Koha::Patron::HouseboundProfile;
35
use Koha::Patron::HouseboundProfile;
34
use Koha::Patron::HouseboundRole;
36
use Koha::Patron::HouseboundRole;
35
use Koha::Patron::Images;
37
use Koha::Patron::Images;
36
use Koha::Patrons;
37
use Koha::Virtualshelves;
38
use Koha::Virtualshelves;
38
use Koha::Club::Enrollments;
39
use Koha::Club::Enrollments;
39
40
Lines 107-147 sub category { Link Here
107
    return Koha::Patron::Category->_new_from_dbic( $self->_result->categorycode );
108
    return Koha::Patron::Category->_new_from_dbic( $self->_result->categorycode );
108
}
109
}
109
110
110
=head3 guarantor
111
=head3 image
111
112
Returns a Koha::Patron object for this patron's guarantor
113
112
114
=cut
113
=cut
115
114
116
sub guarantor {
115
sub image {
117
    my ( $self ) = @_;
116
    my ( $self ) = @_;
118
117
119
    return unless $self->guarantorid();
118
    return Koha::Patron::Images->find( $self->borrowernumber )
120
121
    return Koha::Patrons->find( $self->guarantorid() );
122
}
119
}
123
120
124
sub image {
121
=head3 library
125
    my ( $self ) = @_;
126
122
127
    return Koha::Patron::Images->find( $self->borrowernumber );
123
=cut
128
}
129
124
130
sub library {
125
sub library {
131
    my ( $self ) = @_;
126
    my ( $self ) = @_;
132
    return Koha::Library->_new_from_dbic($self->_result->branchcode);
127
    return Koha::Library->_new_from_dbic($self->_result->branchcode);
133
}
128
}
134
129
135
=head3 guarantees
130
=head3 guarantor_relationships
131
132
Returns Koha::Patron::Relationships object for this patron's guarantors
133
134
Returns the set of relationships for the patrons that are guarantors for this patron.
136
135
137
Returns the guarantees (list of Koha::Patron) of this patron
136
This is returned instead of a Koha::Patron object because the guarantor
137
may not exist as a patron in Koha. If this is true, the guarantors name
138
exists in the Koha::Patron::Relationship object and will have no guarantor_id.
138
139
139
=cut
140
=cut
140
141
141
sub guarantees {
142
sub guarantor_relationships {
142
    my ( $self ) = @_;
143
    my ($self) = @_;
143
144
144
    return Koha::Patrons->search( { guarantorid => $self->borrowernumber } );
145
    return Koha::Patron::Relationships->search( { guarantee_id => $self->id } );
146
}
147
148
=head3 guarantee_relationships
149
150
Returns Koha::Patron::Relationships object for this patron's guarantors
151
152
Returns the set of relationships for the patrons that are guarantees for this patron.
153
154
The method returns Koha::Patron::Relationship objects for the sake
155
of consistency with the guantors method.
156
A guarantee by definition must exist as a patron in Koha.
157
158
=cut
159
160
sub guarantee_relationships {
161
    my ($self) = @_;
162
163
    return Koha::Patron::Relationships->search( { guarantor_id => $self->id } );
145
}
164
}
146
165
147
=head3 housebound_profile
166
=head3 housebound_profile
Lines 179-201 Returns the siblings of this patron. Link Here
179
=cut
198
=cut
180
199
181
sub siblings {
200
sub siblings {
182
    my ( $self ) = @_;
201
    my ($self) = @_;
183
202
184
    my $guarantor = $self->guarantor;
203
    my @guarantors = $self->guarantor_relationships()->guarantors();
185
204
186
    return unless $guarantor;
205
    return unless @guarantors;
187
206
188
    return Koha::Patrons->search(
207
    my @siblings =
189
        {
208
      map { $_->guarantee_relationships()->guarantees() } @guarantors;
190
            guarantorid => {
209
191
                '!=' => undef,
210
    return unless @siblings;
192
                '=' => $guarantor->id,
211
193
            },
212
    my %seen;
194
            borrowernumber => {
213
    @siblings =
195
                '!=' => $self->borrowernumber,
214
      grep { !$seen{ $_->id }++ && ( $_->id != $self->id ) } @siblings;
196
            }
215
197
        }
216
    return wantarray ? @siblings : Koha::Patrons->search( { borrowernumber => { -in => [ map { $_->id } @siblings ] } } );
198
    );
199
}
217
}
200
218
201
=head3 wants_check_for_previous_checkout
219
=head3 wants_check_for_previous_checkout
(-)a/Koha/Patron/Relationship.pm (+73 lines)
Line 0 Link Here
1
package Koha::Patron::Relationship;
2
3
# This file is part of Koha.
4
#
5
# Koha is free software; you can redistribute it and/or modify it under the
6
# terms of the GNU General Public License as published by the Free Software
7
# Foundation; either version 3 of the License, or (at your option) any later
8
# version.
9
#
10
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
11
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License along
15
# with Koha; if not, write to the Free Software Foundation, Inc.,
16
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
18
use Modern::Perl;
19
20
use Carp;
21
22
use Koha::Database;
23
24
use base qw(Koha::Object);
25
26
=head1 NAME
27
28
Koha::Patron::Relationship - A class to represent relationships between patrons
29
30
Patrons in Koha may be guarantors or guarantees. This class models that relationship
31
and provides a way to access those relationships.
32
33
=head1 API
34
35
=head2 Class Methods
36
37
=cut
38
39
=head3 guarantor
40
41
Returns the Koha::Patron object for the guarantor, if there is one
42
43
=cut
44
45
sub guarantor {
46
    my ( $self ) = @_;
47
48
    return unless $self->guarantor_id;
49
50
    return Koha::Patrons->find( $self->guarantor_id );
51
}
52
53
=head3 guarantee
54
55
Returns the Koha::Patron object for the guarantee
56
57
=cut
58
59
sub guarantee {
60
    my ( $self ) = @_;
61
62
    return Koha::Patrons->find( $self->guarantee_id );
63
}
64
65
=head3 type
66
67
=cut
68
69
sub _type {
70
    return 'Relationship';
71
}
72
73
1;
(-)a/Koha/Patron/Relationships.pm (+94 lines)
Line 0 Link Here
1
package Koha::Patron::Relationships;
2
3
# This file is part of Koha.
4
#
5
# Koha is free software; you can redistribute it and/or modify it under the
6
# terms of the GNU General Public License as published by the Free Software
7
# Foundation; either version 3 of the License, or (at your option) any later
8
# version.
9
#
10
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
11
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License along
15
# with Koha; if not, write to the Free Software Foundation, Inc.,
16
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
18
use Modern::Perl;
19
20
use Carp;
21
use List::MoreUtils qw( uniq );
22
23
use Koha::Database;
24
use Koha::Patrons;
25
use Koha::Patron::Relationship;
26
27
use base qw(Koha::Objects);
28
29
=head1 NAME
30
31
Koha::Patron::Relationships - Koha Patron Relationship Object set class
32
33
=head1 API
34
35
=head2 Class Methods
36
37
=cut
38
39
=head3 guarantors
40
41
Returns all the guarantors in this set of relationships as a list of Koha::Patron objects
42
or as a Koha::Patrons object depending on the calling context
43
44
=cut
45
46
sub guarantors {
47
    my ($self) = @_;
48
49
    my $rs = $self->_resultset();
50
51
    my @guarantor_ids = $rs->get_column('guarantor_id')->all();
52
    # Guarantors may not have a guarantor_id, strip out undefs
53
    @guarantor_ids = grep { defined $_ } @guarantor_ids;
54
    @guarantor_ids = uniq( @guarantor_ids );
55
56
    my $guarantors = Koha::Patrons->search( { borrowernumber => \@guarantor_ids } );
57
58
    return wantarray ? $guarantors->as_list : $guarantors;
59
}
60
61
=head3 guarantees
62
63
Returns all the guarantees in this set of relationships as a list of Koha::Patron objects
64
or as a Koha::Patrons object depending on the calling context
65
66
=cut
67
68
sub guarantees {
69
    my ($self) = @_;
70
71
    my $rs = $self->_resultset();
72
73
    my @guarantee_ids = uniq( $rs->get_column('guarantee_id')->all() );
74
75
    my $guarantees = Koha::Patrons->search( { borrowernumber => \@guarantee_ids } );
76
77
    return wantarray ? $guarantees->as_list : $guarantees;
78
}
79
80
=cut
81
82
=head3 type
83
84
=cut
85
86
sub _type {
87
    return 'Relationship';
88
}
89
90
sub object_class {
91
    return 'Koha::Patron::Relationship';
92
}
93
94
1;
(-)a/Koha/Schema/Result/Relationship.pm (+132 lines)
Line 0 Link Here
1
use utf8;
2
package Koha::Schema::Result::Relationship;
3
4
# Created by DBIx::Class::Schema::Loader
5
# DO NOT MODIFY THE FIRST PART OF THIS FILE
6
7
=head1 NAME
8
9
Koha::Schema::Result::Relationship
10
11
=cut
12
13
use strict;
14
use warnings;
15
16
use base 'DBIx::Class::Core';
17
18
=head1 TABLE: C<relationships>
19
20
=cut
21
22
__PACKAGE__->table("relationships");
23
24
=head1 ACCESSORS
25
26
=head2 id
27
28
  data_type: 'integer'
29
  is_auto_increment: 1
30
  is_nullable: 0
31
32
=head2 guarantor_id
33
34
  data_type: 'integer'
35
  is_foreign_key: 1
36
  is_nullable: 1
37
38
=head2 guarantee_id
39
40
  data_type: 'integer'
41
  is_foreign_key: 1
42
  is_nullable: 0
43
44
=head2 relationship
45
46
  data_type: 'varchar'
47
  is_nullable: 0
48
  size: 100
49
50
=head2 surname
51
52
  data_type: 'mediumtext'
53
  is_nullable: 1
54
55
=head2 firstname
56
57
  data_type: 'mediumtext'
58
  is_nullable: 1
59
60
=cut
61
62
__PACKAGE__->add_columns(
63
  "id",
64
  { data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
65
  "guarantor_id",
66
  { data_type => "integer", is_foreign_key => 1, is_nullable => 1 },
67
  "guarantee_id",
68
  { data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
69
  "relationship",
70
  { data_type => "varchar", is_nullable => 0, size => 100 },
71
  "surname",
72
  { data_type => "mediumtext", is_nullable => 1 },
73
  "firstname",
74
  { data_type => "mediumtext", is_nullable => 1 },
75
);
76
77
=head1 PRIMARY KEY
78
79
=over 4
80
81
=item * L</id>
82
83
=back
84
85
=cut
86
87
__PACKAGE__->set_primary_key("id");
88
89
=head1 RELATIONS
90
91
=head2 guarantee
92
93
Type: belongs_to
94
95
Related object: L<Koha::Schema::Result::Borrower>
96
97
=cut
98
99
__PACKAGE__->belongs_to(
100
  "guarantee",
101
  "Koha::Schema::Result::Borrower",
102
  { borrowernumber => "guarantee_id" },
103
  { is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
104
);
105
106
=head2 guarantor
107
108
Type: belongs_to
109
110
Related object: L<Koha::Schema::Result::Borrower>
111
112
=cut
113
114
__PACKAGE__->belongs_to(
115
  "guarantor",
116
  "Koha::Schema::Result::Borrower",
117
  { borrowernumber => "guarantor_id" },
118
  {
119
    is_deferrable => 1,
120
    join_type     => "LEFT",
121
    on_delete     => "CASCADE",
122
    on_update     => "CASCADE",
123
  },
124
);
125
126
127
# Created by DBIx::Class::Schema::Loader v0.07042 @ 2016-05-03 13:19:34
128
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:2Nv437KMrKHvpQleXLOjYw
129
130
131
# You can replace this text with custom code or comments, and it will be preserved on regeneration
132
1;
(-)a/circ/circulation.pl (-5 / +5 lines)
Lines 582-593 my $view = $batch Link Here
582
582
583
my @relatives;
583
my @relatives;
584
if ( $borrowernumber ) {
584
if ( $borrowernumber ) {
585
    if ( $patron ) {
585
    if ( my $patron = Koha::Patrons->find( $borrower->{borrowernumber} ) ) {
586
        if ( my $guarantor = $patron->guarantor ) {
586
        if ( my @guarantors = $patron->guarantor_relationships()->guarantors() ) {
587
            push @relatives, $guarantor->borrowernumber;
587
            push( @relatives, $_->id ) for @guarantors;
588
            push @relatives, $_->borrowernumber for $patron->siblings;
588
            push( @relatives, $_->id ) for $patron->siblings();
589
        } else {
589
        } else {
590
            push @relatives, $_->borrowernumber for $patron->guarantees;
590
            push( @relatives, $_->id ) for $patron->guarantee_relationships()->guarantees();
591
        }
591
        }
592
    }
592
    }
593
}
593
}
(-)a/installer/data/mysql/atomicupdate/bug_14570.sql (+17 lines)
Line 0 Link Here
1
CREATE TABLE `relationships` (
2
      id INT(11) NOT NULL AUTO_INCREMENT,
3
      guarantor_id INT(11) NULL DEFAULT NULL,
4
      guarantee_id INT(11) NOT NULL,
5
      relationship VARCHAR(100) COLLATE utf8_unicode_ci NOT NULL,
6
      surname MEDIUMTEXT COLLATE utf8_unicode_ci NULL DEFAULT NULL,
7
      firstname MEDIUMTEXT COLLATE utf8_unicode_ci NULL DEFAULT NULL,
8
      PRIMARY KEY (id),
9
      CONSTRAINT r_guarantor FOREIGN KEY ( guarantor_id ) REFERENCES borrowers ( borrowernumber ) ON UPDATE CASCADE ON DELETE CASCADE,
10
      CONSTRAINT r_guarantee FOREIGN KEY ( guarantee_id ) REFERENCES borrowers ( borrowernumber ) ON UPDATE CASCADE ON DELETE CASCADE
11
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
12
13
UPDATE borrowers LEFT JOIN borrowers guarantor ON ( borrowers.guarantorid = guarantor.borrowernumber ) SET borrowers.guarantorid = NULL WHERE guarantor.borrowernumber IS NULL;
14
15
INSERT INTO relationships ( guarantor_id, guarantee_id, relationship, surname, firstname ) SELECT guarantorid, borrowernumber, relationship, contactname, contactfirstname FROM borrowers WHERE guarantorid IS NOT NULL OR contactname != "";
16
17
ALTER TABLE borrowers DROP guarantorid, DROP relationship, DROP contactname, DROP contactfirstname, DROP contacttitle;
(-)a/installer/data/mysql/kohastructure.sql (-16 / +15 lines)
Lines 604-615 CREATE TABLE `deletedborrowers` ( -- stores data related to the patrons/borrower Link Here
604
  `lost` tinyint(1) default NULL, -- set to 1 for yes and 0 for no, flag to note that library marked this patron/borrower as having lost their card
604
  `lost` tinyint(1) default NULL, -- set to 1 for yes and 0 for no, flag to note that library marked this patron/borrower as having lost their card
605
  `debarred` date default NULL, -- until this date the patron can only check-in (no loans, no holds, etc.), is a fine based on days instead of money (YYYY-MM-DD)
605
  `debarred` date default NULL, -- until this date the patron can only check-in (no loans, no holds, etc.), is a fine based on days instead of money (YYYY-MM-DD)
606
  `debarredcomment` VARCHAR(255) DEFAULT NULL, -- comment on the stop of patron
606
  `debarredcomment` VARCHAR(255) DEFAULT NULL, -- comment on the stop of patron
607
  `contactname` mediumtext, -- used for children and profesionals to include surname or last name of guarantor or organization name
608
  `contactfirstname` text, -- used for children to include first name of guarantor
609
  `contacttitle` text, -- used for children to include title (Mr., Mrs., etc) of guarantor
610
  `guarantorid` int(11) default NULL, -- borrowernumber used for children or professionals to link them to guarantors or organizations
611
  `borrowernotes` mediumtext, -- a note on the patron/borrower's account that is only visible in the staff client
607
  `borrowernotes` mediumtext, -- a note on the patron/borrower's account that is only visible in the staff client
612
  `relationship` varchar(100) default NULL, -- used for children to include the relationship to their guarantor
613
  `sex` varchar(1) default NULL, -- patron/borrower's gender
608
  `sex` varchar(1) default NULL, -- patron/borrower's gender
614
  `password` varchar(60) default NULL, -- patron/borrower's encrypted password
609
  `password` varchar(60) default NULL, -- patron/borrower's encrypted password
615
  `flags` int(11) default NULL, -- will include a number associated with the staff member's permissions
610
  `flags` int(11) default NULL, -- will include a number associated with the staff member's permissions
Lines 1641-1652 CREATE TABLE `borrowers` ( -- this table includes information about your patrons Link Here
1641
  `lost` tinyint(1) default NULL, -- set to 1 for yes and 0 for no, flag to note that library marked this patron/borrower as having lost their card
1636
  `lost` tinyint(1) default NULL, -- set to 1 for yes and 0 for no, flag to note that library marked this patron/borrower as having lost their card
1642
  `debarred` date default NULL, -- until this date the patron can only check-in (no loans, no holds, etc.), is a fine based on days instead of money (YYYY-MM-DD)
1637
  `debarred` date default NULL, -- until this date the patron can only check-in (no loans, no holds, etc.), is a fine based on days instead of money (YYYY-MM-DD)
1643
  `debarredcomment` VARCHAR(255) DEFAULT NULL, -- comment on the stop of the patron
1638
  `debarredcomment` VARCHAR(255) DEFAULT NULL, -- comment on the stop of the patron
1644
  `contactname` mediumtext, -- used for children and profesionals to include surname or last name of guarantor or organization name
1645
  `contactfirstname` text, -- used for children to include first name of guarantor
1646
  `contacttitle` text, -- used for children to include title (Mr., Mrs., etc) of guarantor
1647
  `guarantorid` int(11) default NULL, -- borrowernumber used for children or professionals to link them to guarantors or organizations
1648
  `borrowernotes` mediumtext, -- a note on the patron/borrower's account that is only visible in the staff client
1639
  `borrowernotes` mediumtext, -- a note on the patron/borrower's account that is only visible in the staff client
1649
  `relationship` varchar(100) default NULL, -- used for children to include the relationship to their guarantor
1650
  `sex` varchar(1) default NULL, -- patron/borrower's gender
1640
  `sex` varchar(1) default NULL, -- patron/borrower's gender
1651
  `password` varchar(60) default NULL, -- patron/borrower's Bcrypt encrypted password
1641
  `password` varchar(60) default NULL, -- patron/borrower's Bcrypt encrypted password
1652
  `flags` int(11) default NULL, -- will include a number associated with the staff member's permissions
1642
  `flags` int(11) default NULL, -- will include a number associated with the staff member's permissions
Lines 1679-1685 CREATE TABLE `borrowers` ( -- this table includes information about your patrons Link Here
1679
  KEY `categorycode` (`categorycode`),
1669
  KEY `categorycode` (`categorycode`),
1680
  KEY `branchcode` (`branchcode`),
1670
  KEY `branchcode` (`branchcode`),
1681
  UNIQUE KEY `userid` (`userid`),
1671
  UNIQUE KEY `userid` (`userid`),
1682
  KEY `guarantorid` (`guarantorid`),
1683
  KEY `surname_idx` (`surname`(255)),
1672
  KEY `surname_idx` (`surname`(255)),
1684
  KEY `firstname_idx` (`firstname`(255)),
1673
  KEY `firstname_idx` (`firstname`(255)),
1685
  KEY `othernames_idx` (`othernames`(255)),
1674
  KEY `othernames_idx` (`othernames`(255)),
Lines 3423-3434 CREATE TABLE IF NOT EXISTS `borrower_modifications` ( Link Here
3423
  `lost` tinyint(1) DEFAULT NULL,
3412
  `lost` tinyint(1) DEFAULT NULL,
3424
  `debarred` date DEFAULT NULL,
3413
  `debarred` date DEFAULT NULL,
3425
  `debarredcomment` varchar(255) DEFAULT NULL,
3414
  `debarredcomment` varchar(255) DEFAULT NULL,
3426
  `contactname` mediumtext,
3427
  `contactfirstname` text,
3428
  `contacttitle` text,
3429
  `guarantorid` int(11) DEFAULT NULL,
3430
  `borrowernotes` mediumtext,
3415
  `borrowernotes` mediumtext,
3431
  `relationship` varchar(100) DEFAULT NULL,
3432
  `sex` varchar(1) DEFAULT NULL,
3416
  `sex` varchar(1) DEFAULT NULL,
3433
  `password` varchar(30) DEFAULT NULL,
3417
  `password` varchar(30) DEFAULT NULL,
3434
  `flags` int(11) DEFAULT NULL,
3418
  `flags` int(11) DEFAULT NULL,
Lines 4099-4104 CREATE TABLE IF NOT EXISTS club_fields ( Link Here
4099
  CONSTRAINT club_fields_ibfk_3 FOREIGN KEY (club_template_field_id) REFERENCES club_template_fields (id) ON DELETE CASCADE ON UPDATE CASCADE,
4083
  CONSTRAINT club_fields_ibfk_3 FOREIGN KEY (club_template_field_id) REFERENCES club_template_fields (id) ON DELETE CASCADE ON UPDATE CASCADE,
4100
  CONSTRAINT club_fields_ibfk_4 FOREIGN KEY (club_id) REFERENCES clubs (id) ON DELETE CASCADE ON UPDATE CASCADE
4084
  CONSTRAINT club_fields_ibfk_4 FOREIGN KEY (club_id) REFERENCES clubs (id) ON DELETE CASCADE ON UPDATE CASCADE
4101
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
4085
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
4086
-- Table structure for table 'guarantors_guarantees'
4087
--
4088
4089
DROP TABLE IF EXISTS relationships;
4090
CREATE TABLE `relationships` (
4091
      id INT(11) NOT NULL AUTO_INCREMENT,
4092
      guarantor_id INT(11) NULL DEFAULT NULL,
4093
      guarantee_id INT(11) NOT NULL,
4094
      relationship VARCHAR(100) COLLATE utf8_unicode_ci NOT NULL,
4095
      surname MEDIUMTEXT COLLATE utf8_unicode_ci NULL DEFAULT NULL,
4096
      firstname MEDIUMTEXT COLLATE utf8_unicode_ci NULL DEFAULT NULL,
4097
      PRIMARY KEY (id),
4098
      CONSTRAINT r_guarantor FOREIGN KEY ( guarantor_id ) REFERENCES borrowers ( borrowernumber ) ON UPDATE CASCADE ON DELETE CASCADE,
4099
      CONSTRAINT r_guarantee FOREIGN KEY ( guarantee_id ) REFERENCES borrowers ( borrowernumber ) ON UPDATE CASCADE ON DELETE CASCADE
4100
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
4102
4101
4103
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
4102
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
4104
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
4103
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
(-)a/koha-tmpl/intranet-tmpl/prog/en/columns.def (-1 lines)
Lines 7-13 Link Here
7
<field name="borrowers.othernames">Other name</field>
7
<field name="borrowers.othernames">Other name</field>
8
<field name="borrowers.sex">Gender</field>
8
<field name="borrowers.sex">Gender</field>
9
<field name="borrowers.relationship">Relationship</field>
9
<field name="borrowers.relationship">Relationship</field>
10
<field name="borrowers.guarantorid">Guarantor borrower number</field>
11
<field name="borrowers.streetnumber">Street number</field>
10
<field name="borrowers.streetnumber">Street number</field>
12
<field name="borrowers.streettype">Street type</field>
11
<field name="borrowers.streettype">Street type</field>
13
<field name="borrowers.address">Address</field>
12
<field name="borrowers.address">Address</field>
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/members-toolbar.inc (-6 / +3 lines)
Lines 133-149 function searchToHold(){ Link Here
133
133
134
<div id="toolbar" class="btn-toolbar">
134
<div id="toolbar" class="btn-toolbar">
135
    [% IF ( CAN_user_borrowers ) %]
135
    [% IF ( CAN_user_borrowers ) %]
136
        [% IF ( guarantor ) %]
137
            <a id="editpatron" class="btn btn-default btn-sm" href="/cgi-bin/koha/members/memberentry.pl?op=modify&amp;destination=circ&amp;borrowernumber=[% borrowernumber %]&amp;guarantorid=[% guarantor.borrowernumber %]&amp;categorycode=[% categorycode %]">
138
        [% ELSE %]
139
            <a id="editpatron" class="btn btn-default btn-sm" href="/cgi-bin/koha/members/memberentry.pl?op=modify&amp;destination=circ&amp;borrowernumber=[% borrowernumber %]&amp;categorycode=[% categorycode %]">
136
            <a id="editpatron" class="btn btn-default btn-sm" href="/cgi-bin/koha/members/memberentry.pl?op=modify&amp;destination=circ&amp;borrowernumber=[% borrowernumber %]&amp;categorycode=[% categorycode %]">
140
        [% END %]
137
                <i class="fa fa-pencil"></i> Edit
141
        <i class="fa fa-pencil"></i> Edit</a>
138
            </a>
142
    [% END %]
139
    [% END %]
143
140
144
    [% IF ( CAN_user_borrowers ) %]
141
    [% IF ( CAN_user_borrowers ) %]
145
        [% IF adultborrower AND Koha.Preference("borrowerRelationship") %]
142
        [% IF adultborrower AND Koha.Preference("borrowerRelationship") %]
146
            <a id="addchild" class="btn btn-default btn-sm" href="/cgi-bin/koha/members/memberentry.pl?op=add&amp;guarantorid=[% borrowernumber %]"><i class="fa fa-plus"></i> Add child</a>
143
            <a id="addchild" class="btn btn-default btn-sm" href="/cgi-bin/koha/members/memberentry.pl?op=add&amp;guarantor_id=[% borrowernumber %]"><i class="fa fa-plus"></i> Add child</a>
147
        [% END %]
144
        [% END %]
148
        [% IF ( CAN_user_borrowers ) %]
145
        [% IF ( CAN_user_borrowers ) %]
149
            <a id="changepassword" class="btn btn-default btn-sm" href="/cgi-bin/koha/members/member-password.pl?member=[% borrowernumber %]"><i class="fa fa-lock"></i> Change password</a>
146
            <a id="changepassword" class="btn btn-default btn-sm" href="/cgi-bin/koha/members/member-password.pl?member=[% borrowernumber %]"><i class="fa fa-lock"></i> Change password</a>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt (-1 / +1 lines)
Lines 894-900 No patron matched <span class="ex">[% message | html %]</span> Link Here
894
    </li>
894
    </li>
895
895
896
    [% IF relatives_issues_count %]
896
    [% IF relatives_issues_count %]
897
        <li><a id="relatives-issues-tab" href="#relatives-issues">Relatives' checkouts</a></li>
897
        <li><a id="relatives-issues-tab" href="#relatives-issues">[% relatives_issues_count %] Relatives' checkouts</a></li>
898
    [% END %]
898
    [% END %]
899
899
900
    <li>
900
    <li>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt (-104 / +179 lines)
Lines 1-3 Link Here
1
[% USE To %]
1
[% USE Koha %]
2
[% USE Koha %]
2
[% USE KohaDates %]
3
[% USE KohaDates %]
3
[% USE Branches %]
4
[% USE Branches %]
Lines 25-38 $(document).ready(function() { Link Here
25
            $('#toolbar').fixFloat({ 'originalOffset': original_offset - additional_height });
26
            $('#toolbar').fixFloat({ 'originalOffset': original_offset - additional_height });
26
        })
27
        })
27
28
28
	[% IF categorycode %]
29
    [% IF categorycode %]
29
		update_category_code( "[% categorycode %]" );
30
        update_category_code( "[% categorycode %]" );
30
	[% ELSE %]
31
    [% ELSE %]
31
		if ( $("#categorycode_entry").length > 0 ){
32
        if ( $("#categorycode_entry").length > 0 ) {
32
			var category_code = $("#categorycode_entry").find("option:selected").val();
33
            var category_code = $("#categorycode_entry").find("option:selected").val();
33
			update_category_code( category_code );
34
            update_category_code( category_code );
34
		}
35
        }
35
	[% END %]
36
    [% END %]
37
38
    [% IF guarantor %]
39
        select_user( '[% guarantor.borrowernumber %]', [% To.json( guarantor.unblessed ) %] );
40
        $('#guarantor_add').ready(function() {
41
            $('#guarantor_add').click();
42
        });
43
    [% END %]
44
36
});
45
});
37
46
38
$(document).ready(function() {
47
$(document).ready(function() {
Lines 381-486 $(document).ready(function() { Link Here
381
	</fieldset>
390
	</fieldset>
382
[% END # hide fieldset %]
391
[% END # hide fieldset %]
383
392
384
[% IF ( showguarantor ) %]
393
[% IF show_guarantor || guarantor %]
385
    <input type="hidden" id="guarantorid" name="guarantorid"   value="[% guarantorid %]" />
394
    [% SET possible_relationships = Koha.Preference('borrowerRelationship') %]
386
    [% UNLESS step_6 %]
395
    <fieldset class="rows">
387
        <input type="hidden" name="branchcode" value="[% branchcode %]" />
396
        <legend>Guarantor information</legend>
388
    [% END %]
397
389
    <fieldset id="memberentry_guarantor" class="rows">
398
        <span id="guarantor_relationships">
390
        <legend id="guarantor_lgd">Guarantor information</legend>
399
            [% FOREACH r IN relationships %]
391
        <ol>
400
                <fieldset class="rows">
392
[% IF ( P ) %]
401
                    <ol>
393
	        [% IF ( guarantorid ) %]
402
                        [% IF catetory_type == 'P' %]
394
	        <li id="contact-details">
403
                            [% IF ( r.guarantor_id ) %]
395
	        [% ELSE %]
404
                                <li id="contact-details">
396
	        <li id="contact-details" style="display: none">
405
                            [% ELSE %]
397
	        [% END %]
406
                                <li id="contact-details" style="display: none">
398
	            <span class="label">Organization #:</span> [% IF ( guarantorid ) %] <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% guarantorid %]" target="blank">[% guarantorid %]</a>[% END %]
407
                            [% END %]
399
	        </li>
408
                                <span class="label">Organization #:</span> [% IF ( r.guarantor_id ) %] <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% r.guarantor_id %]" target="blank">[% r.guarantor_id %]</a>[% END %]
400
	        <li>
409
                            </li>
401
	            <label for="contactname">Organization name: </label>
410
402
	            [% IF ( guarantorid ) %]
411
                            <li>
403
	            <span>[% contactname %]</span>
412
                                <label for="guarantor_surname">Organization name: </label>
404
	            <input name="contactname" id="contactname" type="hidden" size="20" value="[% contactname | html %]" />
413
                                [% IF ( r.guarantor_id ) %]
405
	            [% ELSE %]
414
                                    <span>[% r.guarantor.surname %]</span>
406
                    <input name="contactname" id="contactname" type="text" size="20" value="[% contactname | html %]" />
415
                                [% END %]
407
	            [% END %]
416
                            </li>
408
	        </li>
417
                        [% ELSE %]
409
[% ELSE %]
418
                            [% IF category_type == 'C'  %]
410
 [% IF ( C ) %]
419
                                [% IF ( r.guarantor_id ) %]
411
 [% IF ( guarantorid ) %]
420
                                    <li id="contact-details">
412
 <li id="contact-details">
421
                                [% ELSE %]
413
 [% ELSE %]
422
                                    <li id="contact-details" style="display: none">
414
 <li id="contact-details" style="display: none">
423
                                [% END %]
415
 [% END %]
424
416
     <span class="label">Patron #:</span> [% IF ( guarantorid ) %] <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% guarantorid %]" target="blank">[% guarantorid %]</a>[% END %]
425
                                    <span class="label">Patron #:</span>
417
 </li>
426
                                    [% IF ( r.guarantor_id ) %]
418
        [% UNLESS nocontactname %]
427
                                        <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% r.guarantor_id %]" target="blank">[% r.guarantor_id %]</a>
419
 <li>
428
                                    [% END %]
420
     <label for="contactname">Surname: </label>
429
421
     [% IF ( guarantorid ) %]
430
                                </li>
422
     <span>[% contactname %]</span>
431
423
     <input name="contactname" id="contactname" type="hidden" size="20" value="[% contactname | html %]" />
432
                                [% IF r.surname || r.guarantor.surname %]
424
     [% ELSE %]
433
                                    <li>
425
        <input name="contactname" id="contactname" type="text" size="20" value="[% contactname | html %]" />
434
                                        <label for="guarantor_surname">Surname: </label>
426
     [% END %]
435
                                        <span>[% r.surname || r.guarantor.surname %]</span>
427
 </li>
436
                                    </li>
428
        [% END %]
437
                                [% END %]
429
        [% UNLESS nocontactfirstname %]
438
430
 <li>
439
                                [% IF r.firstname || r.guarantor.firstname  %]
431
     <label for="contactfirstname">First name: </label>
440
                                    <li>
432
     [% IF ( guarantorid ) %]
441
                                        <label for="guarantor_firstname">First name: </label>
433
     <span>[% contactfirstname %]</span>
442
                                        <span>[% r.firstname || r.guarantor.firstname %]</span>
434
     <input name="contactfirstname" id="contactfirstname" type="hidden" size="20" value="[% contactfirstname | html %]" />
443
                                    </li>
435
     [% ELSE %]
444
                                [% END %]
436
        <input name="contactfirstname" id="contactfirstname" type="text" size="20" value="[% contactfirstname | html %]" />
445
437
     [% END %]
446
                                <li>
438
 </li>
447
                                    <label for="relationship">Relationship: </label>
439
        [% END %]
448
                                    <span>[% r.relationship %]</span>
440
 [% IF ( relshiploop ) %]
449
                                </li>
441
 <li>
450
442
     <label for="relationship">Relationship: </label>
451
                                <li>
443
     <select name="relationship" id="relationship" >
452
                                    <label for="delete_guarantor">Delete: </label>
444
         [% FOREACH relshiploo IN relshiploop %]
453
                                    <input type="checkbox" name="delete_guarantor" value="[% r.id %]" />
445
         [% IF ( relshiploo.selected ) %]
454
                                </li>
446
         <option value="[% relshiploo.relationship %]" selected="selected" >[% relshiploo.relationship %]</option>
455
                            [% END %]
447
         [% ELSE %]
456
                        [% END %]
448
         <option value="[% relshiploo.relationship %]">[% relshiploo.relationship %]</option>
457
                    </ol>
449
         [% END %]
458
                </fieldset>
450
         [% END %]
459
            [% END # END relationships foreach %]
451
     </select>
460
        </span>
452
 </li>
461
453
 [% END %]
462
        <fieldset class="rows guarantor" id="guarantor_template">
454
 [% END %]
463
            <ol>
455
[% END %]
464
                <li class="guarantor_id">
456
        <li>
465
                    <span class="label">Patron #:</span>
457
            <span class="label">&nbsp;</span>
466
                    <span class="new_guarantor_id_text"></span>
458
            [% IF ( guarantorid ) %]
467
                    <input type="hidden" class="new_guarantor_id" name="new_guarantor_id" value=""/>
459
            <input id="guarantorsearch" type="button" value="Change" onclick="Dopopguarantor('guarantor_search.pl');" />
468
                </li>
460
            [% ELSE %]
469
461
            <input id="guarantorsearch" type="button" value="Set to patron" onclick="Dopopguarantor('guarantor_search.pl');" />
470
                <li>
462
            [% END %]
471
                    <label for="guarantor_surname">Surname: </label>
463
            <input id="guarantordelete" type="button" value="Delete" />
472
                    <span class="new_guarantor_surname_text"></span>
464
        </li>
473
                    <input type="hidden" class="new_guarantor_surname" name="new_guarantor_surname" value=""/>
465
    [% IF guarantorid && Koha.Preference('AllowStaffToSetCheckoutsVisibilityForGuarantor') %]
474
                </li>
466
        <li>
475
467
            <label for="privacy_guarantor_checkouts">Show checkouts to guarantor</label>
476
                <li>
468
            <select name="privacy_guarantor_checkouts" id="privacy_guarantor_checkouts">
477
                    <label for="guarantor_firstname">First name: </label>
469
                [% IF privacy_guarantor_checkouts %]
478
                    <span class="new_guarantor_firstname_text"></span>
470
                    <option value="0">No</option>
479
                    <input type="hidden" class="new_guarantor_firstname" name="new_guarantor_firstname" value=""/>
471
                    <option value="1" selected>Yes</option>
480
                </li>
481
482
                <li>
483
                    <label for="guarantor_relationship">Relationship: </label>
484
                    <select class="new_guarantor_relationship" name="new_guarantor_relationship">
485
                        [% FOREACH pr IN possible_relationships.split('\|') %]
486
                            <option value="[% pr %]">[% pr %]</option>
487
                        [% END %]
488
                    </select>
489
                </li>
490
491
                <li>
492
                    <label for="guarantor_cancel">&nbsp;</label>
493
                    <span><a href="#" class="guarantor_cancel">Cancel</a></span>
494
                </li>
495
            </ol>
496
        </fieldset>
497
498
        <fieldset class="rows">
499
            <legend>Add new guarantor</legend>
500
            <ol>
501
                <input type="hidden" id="guarantor_id" value=""/>
502
503
                [% IF catetory_type == 'P' %]
504
                    <li>
505
                        <label for="guarantor_surname">Organization name: </label>
506
                        <input name="guarantor_surname" id="guarantor_surname" type="hidden" size="20"/>
507
                    </li>
472
                [% ELSE %]
508
                [% ELSE %]
473
                    <option value="0" selected>No</option>
509
                    <li>
474
                    <option value="1">Yes</option>
510
                        <label for="guarantor_surname">Surname: </label>
511
                        <input name="guarantor_surname" id="guarantor_surname" type="text" size="20" />
512
                    </li>
513
514
                    <li>
515
                        <label for="guarantor_firstname">First name: </label>
516
                        <input name="guarantor_firstname" id="guarantor_firstname" type="text" size="20" />
517
                    </li>
518
519
                    [% IF ( possible_relationships ) %]
520
                        <li>
521
                            <label for="relationship">Relationship: </label>
522
                            <select name="relationship" id="relationship" >
523
                                [% FOREACH pr IN possible_relationships.split('\|') %]
524
                                    <option value="[% pr %]">[% pr %]</option>
525
                                [% END %]
526
                            </select>
527
                        </li>
528
                    [% END %]
475
                [% END %]
529
                [% END %]
476
            </select>
477
            <div class="hint">Allow guarantor of this patron to view this patron's checkouts from the OPAC</div>
478
        </li>
479
    [% END %]
480
        </ol>
481
    </fieldset>
482
530
531
                <li>
532
                    <span class="label">&nbsp;</span>
533
                    <a href="#" id="guarantor_add" class="btn btn-small"><i class="fa fa-plus"></i> Add guarantor</a>
534
                    <a href="#" id="guarantor_search" class="btn btn-small"><i class="fa fa-search"></i> Set to patron</a>
535
                    <a href="#" id="guarantor_clear">Clear</a>
536
                </li>
537
538
                [% IF relationships && Koha.Preference('AllowStaffToSetCheckoutsVisibilityForGuarantor') %]
539
                    <li>
540
                        <label for="privacy_guarantor_checkouts">Show checkouts to guarantors</label>
541
                        <select name="privacy_guarantor_checkouts" id="privacy_guarantor_checkouts">
542
                            [% IF privacy_guarantor_checkouts %]
543
                                <option value="0">No</option>
544
                                <option value="1" selected>Yes</option>
545
                            [% ELSE %]
546
                                <option value="0" selected>No</option>
547
                                <option value="1">Yes</option>
548
                            [% END %]
549
                        </select>
550
                        <div class="hint">Allow guarantors of this patron to view this patron's checkouts from the OPAC</div>
551
                    </li>
552
                [% END %]
553
            </ol>
554
        </fieldset>
555
    </fieldset>
483
[% END %]
556
[% END %]
557
558
484
[% UNLESS noaddress && noaddress2 && nocity && nostate && nozipcode && nocountry %]
559
[% UNLESS noaddress && noaddress2 && nocity && nostate && nozipcode && nocountry %]
485
    [% IF Koha.Preference( 'AddressFormat' ) %]
560
    [% IF Koha.Preference( 'AddressFormat' ) %]
486
        [% INCLUDE "member-main-address-style-${ Koha.Preference( 'AddressFormat' ) }.inc" %]
561
        [% INCLUDE "member-main-address-style-${ Koha.Preference( 'AddressFormat' ) }.inc" %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember-brief.tt (-7 / +20 lines)
Lines 47-59 Link Here
47
    <li><span class="label">Initials: </span>[% initials %]</li>
47
    <li><span class="label">Initials: </span>[% initials %]</li>
48
    <li><span class="label">Date of birth:</span>[% dateofbirth | $KohaDates %]</li>
48
    <li><span class="label">Date of birth:</span>[% dateofbirth | $KohaDates %]</li>
49
    <li><span class="label">Gender:</span>[% IF ( sex == 'F' ) %]Female[% ELSIF ( sex == 'M' ) %]Male[% ELSE %][% sex %][% END %]</li>[% END %]
49
    <li><span class="label">Gender:</span>[% IF ( sex == 'F' ) %]Female[% ELSIF ( sex == 'M' ) %]Male[% ELSE %][% sex %][% END %]</li>[% END %]
50
    [% IF ( isguarantee ) %]
50
    [% IF guarantees %]
51
        [% IF ( guaranteeloop ) %]
51
        <li>
52
            <li><span class="label">Guarantees:</span><ul>[% FOREACH guaranteeloo IN guaranteeloop %]<li><a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% guaranteeloo.borrowernumber %]">[% guaranteeloo.name %]  </a></li>[% END %]</ul></li>
52
            <span class="label">Guarantees:</span>
53
        [% END %]
53
            <ul>
54
    [% ELSE %]
54
                [% FOREACH guarantee IN guarantees %]
55
        [% IF ( guarantor.borrowernumber ) %]
55
                    <li><a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% guarantee.borrowernumber %]">[% guarantee.firstname %] [% guarantee.surname %]</a></li>
56
            <li><span class="label">Guarantor:</span><a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% guarantor.borrowernumber %]">[% guarantor.surname %], [% guarantor.firstname %]</a></li>
56
                [% END %]
57
            </ul>
58
        </li>
59
    [% ELSIF guarantor_relationships %]
60
        [% FOREACH gr IN guarantor_relationships %]
61
            <li>
62
                <span class="label">Guarantor:</span>
63
                [% IF gr.guarantor_id %]
64
                    [% SET guarantor = gr.guarantor %]
65
                    <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% guarantor.id %]">[% guarantor.firstname %] [% guarantor.surname %]</a>
66
                [% ELSE %]
67
                    [% gr.firstname %] [% gr.surname %]
68
                [% END %]
69
            </li>
57
        [% END %]
70
        [% END %]
58
    [% END %]
71
    [% END %]
59
	</ol>
72
	</ol>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt (-17 / +13 lines)
Lines 263-287 function validate1(date) { Link Here
263
                [% END %]
263
                [% END %]
264
            </ul>
264
            </ul>
265
        </li>
265
        </li>
266
    [% ELSIF guarantor %]
266
    [% ELSIF guarantor_relationships %]
267
        <li>
267
        [% FOREACH gr IN guarantor_relationships %]
268
            <span class="label">Guarantor:</span>
268
            <li>
269
            [% IF guarantor.borrowernumber %]
269
                <span class="label">Guarantor:</span>
270
                <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% guarantor.borrowernumber %]">[% guarantor.firstname | html %] [% guarantor.surname | html %]</a>
270
                [% IF gr.guarantor_id %]
271
            [% ELSE %]
271
                    [% SET guarantor = gr.guarantor %]
272
                [% guarantor.firstname | html %] [% guarantor.surname | html %]
272
                    <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% guarantor.id %]">[% guarantor.firstname %] [% guarantor.surname %]</a>
273
            [% END %]
273
                [% ELSE %]
274
        </li>
274
                    [% gr.firstname %] [% gr.surname %]
275
                [% END %]
276
            </li>
277
        [% END %]
275
    [% END %]
278
    [% END %]
276
</ol>
279
</ol>
277
</div>
280
</div>
278
      <div class="action">
279
        [% IF ( guarantor.borrowernumber ) %]
280
        <a href="memberentry.pl?op=modify&amp;borrowernumber=[% borrowernumber %]&amp;step=1&amp;guarantorid=[% guarantor.borrowernumber %]">Edit</a>
281
        [% ELSE %]
282
        <a href="memberentry.pl?op=modify&amp;borrowernumber=[% borrowernumber %]&amp;step=1">Edit</a>
283
        [% END %]</div>
284
285
</div>
281
</div>
286
282
287
<!-- Begin Upload Patron Image Section -->
283
<!-- Begin Upload Patron Image Section -->
Lines 513-519 function validate1(date) { Link Here
513
    <ul>
509
    <ul>
514
        <li><a href="#checkouts">[% issuecount %] Checkout(s)</a></li>
510
        <li><a href="#checkouts">[% issuecount %] Checkout(s)</a></li>
515
        [% IF relatives_issues_count %]
511
        [% IF relatives_issues_count %]
516
            <li><a href="#relatives-issues" id="relatives-issues-tab">Relatives' checkouts</a></li>
512
            <li><a href="#relatives-issues" id="relatives-issues-tab">[% relatives_issues_count %] Relatives' checkouts</a></li>
517
        [% END %]
513
        [% END %]
518
        <li><a href="#finesandcharges">Fines &amp; Charges</a></li>
514
        <li><a href="#finesandcharges">Fines &amp; Charges</a></li>
519
        <li>
515
        <li>
(-)a/koha-tmpl/intranet-tmpl/prog/js/members.js (-52 / +53 lines)
Lines 143-152 function Dopop(link) { Link Here
143
    var newin=window.open(link,'popup','width=600,height=400,resizable=no,toolbar=false,scrollbars=no,top');
143
    var newin=window.open(link,'popup','width=600,height=400,resizable=no,toolbar=false,scrollbars=no,top');
144
}
144
}
145
145
146
function Dopopguarantor(link) {
147
    var newin=window.open(link,'popup','width=800,height=500,resizable=no,toolbar=false,scrollbars=yes,top');
148
}
149
150
function clear_entry(node) {
146
function clear_entry(node) {
151
    var original = $(node).parent();
147
    var original = $(node).parent();
152
    $("textarea", original).attr('value', '');
148
    $("textarea", original).attr('value', '');
Lines 184-231 function update_category_code(category_code) { Link Here
184
}
180
}
185
181
186
function select_user(borrowernumber, borrower) {
182
function select_user(borrowernumber, borrower) {
187
    var form = $('#entryform').get(0);
183
    $('#guarantor_id').val(borrower.borrowernumber);
188
    if (form.guarantorid.value) {
184
    $('#guarantor_surname').val(borrower.surname);
189
        $("#contact-details, #quick_add_form #contact-details").find('a').remove();
185
    $('#guarantor_firstname').val(borrower.firstname);
190
        $("#contactname, #contactfirstname, #quick_add_form #contactname, #quick_add_form #contactfirstname").parent().find('span').remove();
191
    }
192
186
193
    var id = borrower.borrowernumber;
187
    $('#guarantor_add').click();
194
    form.guarantorid.value = id;
195
    $('#contact-details, #quick_add_form #contact-details')
196
        .show()
197
        .find('span')
198
        .after('<a target="blank" href="/cgi-bin/koha/members/moremember.pl?borrowernumber=' + id + '">' + id + '</a>');
199
200
    $(form.contactname)
201
        .val(borrower.surname)
202
        .before('<span>' + borrower.surname + '</span>').get(0).type = 'hidden';
203
    $("#quick_add_form #contactname").val(borrower.surname).before('<span>'+borrower.surname+'</span.').attr({type:"hidden"});
204
    $(form.contactfirstname,"#quick_add_form #contactfirstname")
205
        .val(borrower.firstname)
206
        .before('<span>' + borrower.firstname + '</span>').get(0).type = 'hidden';
207
    $("#quick_add_form #contactfirstname").val(borrower.firstname).before('<span>'+borrower.firstname+'</span.').attr({type:"hidden"});
208
209
    form.streetnumber.value = borrower.streetnumber;
210
    form.address.value = borrower.address;
211
    form.address2.value = borrower.address2;
212
    form.city.value = borrower.city;
213
    form.state.value = borrower.state;
214
    form.zipcode.value = borrower.zipcode;
215
    form.country.value = borrower.country;
216
    form.branchcode.value = borrower.branchcode;
217
218
    $("#quick_add_form #streetnumber").val(borrower.streetnumber);
219
    $("#quick_add_form #address").val(borrower.address);
220
    $("#quick_add_form #address2").val(borrower.address2);
221
    $("#quick_add_form #city").val(borrower.city);
222
    $("#quick_add_form #state").val(borrower.state);
223
    $("#quick_add_form #zipcode").val(borrower.zipcode);
224
    $("#quick_add_form #country").val(borrower.country);
225
    $("#quick_add_form select[name='branchcode']").val(borrower.branchcode);
226
227
    form.guarantorsearch.value = LABEL_CHANGE;
228
    $("#quick_add_form #guarantorsearch").val(LABEL_CHANGE);
229
188
230
    return 0;
189
    return 0;
231
}
190
}
Lines 298-310 $(document).ready(function(){ Link Here
298
    });
257
    });
299
258
300
    $("fieldset.rows input, fieldset.rows select").addClass("noEnterSubmit");
259
    $("fieldset.rows input, fieldset.rows select").addClass("noEnterSubmit");
301
    $("#guarantordelete").click(function() {
260
302
        $("#quick_add_form #contact-details, #contact-details").hide().find('a').remove();
261
    $('#guarantor_template').hide();
303
        $("#quick_add_form #guarantorid, #quick_add_form  #contactname, #quick_add_form #contactfirstname, #guarantorid, #contactname, #contactfirstname").each(function () { this.value = ""; });
262
304
        $("#quick_add_form #contactname, #quick_add_form #contactfirstname, #contactname, #contactfirstname")
263
    $('#guarantor_search').on('click', function(e) {
305
            .each(function () { this.type = 'text'; })
264
        e.preventDefault();
306
            .parent().find('span').remove();
265
        var newin = window.open('guarantor_search.pl','popup','width=600,height=400,resizable=no,toolbar=false,scrollbars=yes,top');
307
        $("#quick_add_form #guarantorsearch, #guarantorsearch").val(LABEL_SET_TO_PATRON);
266
    });
267
268
    $('#guarantor_relationships').on('click', '.guarantor_cancel', function(e) {
269
        e.preventDefault();
270
        $(this).parents('fieldset').first().remove();
271
    });
272
273
    $('#guarantor_add').on('click', function(e) {
274
        e.preventDefault();
275
        var fieldset = $('#guarantor_template').clone();
276
        fieldset.removeAttr('id');
277
278
        var guarantor_id = $('#guarantor_id').val();
279
        if ( guarantor_id ) {
280
            fieldset.find('.new_guarantor_id').first().val( guarantor_id );
281
            fieldset.find('.new_guarantor_id_text').first().text( guarantor_id );
282
        } else {
283
            fieldset.find('.guarantor_id').first().hide();
284
        }
285
        $('#guarantor_id').val("");
286
287
        var guarantor_surname = $('#guarantor_surname').val();
288
        fieldset.find('.new_guarantor_surname').first().val( guarantor_surname );
289
        fieldset.find('.new_guarantor_surname_text').first().text( guarantor_surname );
290
        $('#guarantor_surname').val("");
291
292
        var guarantor_firstname = $('#guarantor_firstname').val();
293
        fieldset.find('.new_guarantor_firstname').first().val( guarantor_firstname );
294
        fieldset.find('.new_guarantor_firstname_text').first().text( guarantor_firstname );
295
        $('#guarantor_firstname').val("");
296
297
        var guarantor_relationship = $('#relationship').val();
298
        fieldset.find('.new_guarantor_relationship').first().val( guarantor_relationship );
299
        $('#relationship').find('option:eq(0)').prop('selected', true);;
300
301
        $('#guarantor_relationships').append( fieldset );
302
        fieldset.show();
303
    });
304
305
    $("#guarantor_clear").click(function(e) {
306
        e.preventDefault();
307
        $("#contact-details").hide().find('a').remove();
308
        $("#guarantor_id, #guarantor_surname, #guarantor_firstname").val("");
308
    });
309
    });
309
310
310
    $(document.body).on('change','select[name="select_city"]',function(){
311
    $(document.body).on('change','select[name="select_city"]',function(){
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-memberentry.tt (-2 / +7 lines)
Lines 91-97 Link Here
91
                    <div class="alert">You typed in the wrong characters in the box before submitting. Please try again.</div>
91
                    <div class="alert">You typed in the wrong characters in the box before submitting. Please try again.</div>
92
                [% END %]
92
                [% END %]
93
93
94
                [% IF borrower.guarantorid && !Koha.Preference('OPACPrivacy') && Koha.Preference('AllowPatronToSetCheckoutsVisibilityForGuarantor') %]
94
                [% IF patron.guarantor_relationships && !Koha.Preference('OPACPrivacy') && Koha.Preference('AllowPatronToSetCheckoutsVisibilityForGuarantor') %]
95
                    <fieldset class="rows" id="memberentry_privacy">
95
                    <fieldset class="rows" id="memberentry_privacy">
96
                        <legend id="privacy_legend">Privacy</legend>
96
                        <legend id="privacy_legend">Privacy</legend>
97
                        <ol>
97
                        <ol>
Lines 110-116 Link Here
110
                                    <span id="update_privacy_guarantor_checkouts_message" class="alert" style="display:none"></span>
110
                                    <span id="update_privacy_guarantor_checkouts_message" class="alert" style="display:none"></span>
111
                                </span>
111
                                </span>
112
                                <span class="hint">
112
                                <span class="hint">
113
                                    Your guarantor is <i>[% guarantor.firstname %] [% guarantor.surname %]</i>
113
                                    Guaranteed by
114
                                    [% FOREACH gr IN patron.guarantor_relationships %]
115
                                        [% SET g = gr.guarantor %]
116
                                        [% g.firstname || gr.firstname %] [% g.surname || gr.surname %]
117
                                        [%- IF ! loop.last %], [% END %]
118
                                    [% END %]
114
                                </span>
119
                                </span>
115
                            </li>
120
                            </li>
116
                        </ol>
121
                        </ol>
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-privacy.tt (-2 / +7 lines)
Lines 69-75 Link Here
69
                                        </select>
69
                                        </select>
70
                                    </div>
70
                                    </div>
71
71
72
                                    [% IF borrower.guarantorid && Koha.Preference('AllowPatronToSetCheckoutsVisibilityForGuarantor') %]
72
                                    [% IF borrower.guarantor_relationships && Koha.Preference('AllowPatronToSetCheckoutsVisibilityForGuarantor') %]
73
                                        <div>
73
                                        <div>
74
                                            <label for="privacy_guarantor_checkouts">Allow your guarantor to view your current checkouts?</label>
74
                                            <label for="privacy_guarantor_checkouts">Allow your guarantor to view your current checkouts?</label>
75
                                            <select name="privacy_guarantor_checkouts">
75
                                            <select name="privacy_guarantor_checkouts">
Lines 82-88 Link Here
82
                                                [% END %]
82
                                                [% END %]
83
                                            </select>
83
                                            </select>
84
                                            <span class="hint">
84
                                            <span class="hint">
85
                                                Your guarantor is <i>[% borrower.guarantor.firstname %] [% borrower.guarantor.surname %]</i>
85
                                                Guaranteed by
86
                                                [% FOREACH gr IN borrower.guarantor_relationships %]
87
                                                    [% SET g = gr.guarantor %]
88
                                                    [% g.firstname || gr.firstname %] [% g.surname || gr.surname %]
89
                                                    [%- IF ! loop.last %], [% END %]
90
                                                [% END %]
86
                                            </span>
91
                                            </span>
87
                                        </div>
92
                                        </div>
88
                                    [% END %]
93
                                    [% END %]
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-user.tt (-5 / +5 lines)
Lines 417-440 Using this account is not recommended because some parts of Koha will not functi Link Here
417
417
418
                                    <tbody>
418
                                    <tbody>
419
                                        [% FOREACH r IN relatives %]
419
                                        [% FOREACH r IN relatives %]
420
                                            [% FOREACH i IN r.issues %]
420
                                            [% FOREACH c IN r.checkouts %]
421
                                                <tr>
421
                                                <tr>
422
                                                    <td>
422
                                                    <td>
423
                                                        <a href="/cgi-bin/koha/opac-detail.pl?biblionumber=[% i.item.biblio.biblionumber %]">
423
                                                        <a href="/cgi-bin/koha/opac-detail.pl?biblionumber=[% i.item.biblio.biblionumber %]">
424
                                                            [% i.item.biblio.title %][% IF ( i.item.enumchron ) %] [% i.item.enumchron %][% END %]
424
                                                            [% c.item.biblio.title %][% IF ( c.item.enumchron ) %] [% c.item.enumchron %][% END %]
425
                                                        </a>
425
                                                        </a>
426
                                                    </td>
426
                                                    </td>
427
427
428
                                                    <td>
428
                                                    <td>
429
                                                        [% i.date_due | $KohaDates %]
429
                                                        [% c.date_due | $KohaDates %]
430
                                                    </td>
430
                                                    </td>
431
431
432
                                                    <td>
432
                                                    <td>
433
                                                        [% i.item.barcode %]
433
                                                        [% c.item.barcode %]
434
                                                    </td>
434
                                                    </td>
435
435
436
                                                    <td>
436
                                                    <td>
437
                                                        [% i.item.itemcallnumber %]
437
                                                        [% c.item.itemcallnumber %]
438
                                                    </td>
438
                                                    </td>
439
439
440
                                                    <td>
440
                                                    <td>
(-)a/members/deletemem.pl (-7 / +5 lines)
Lines 76-86 my $issues = GetPendingIssues($member); # FIXME: wasteful call when really, Link Here
76
my $countissues = scalar(@$issues);
76
my $countissues = scalar(@$issues);
77
77
78
my $bor = C4::Members::GetMember( borrowernumber => $member );
78
my $bor = C4::Members::GetMember( borrowernumber => $member );
79
my $patron = Koha::Patrons->find( $member );
79
my $flags = C4::Members::patronflags( $bor );
80
my $flags = C4::Members::patronflags( $bor );
80
my $userenv = C4::Context->userenv;
81
my $userenv = C4::Context->userenv;
81
82
82
 
83
84
if ($bor->{category_type} eq "S") {
83
if ($bor->{category_type} eq "S") {
85
    unless(C4::Auth::haspermission($userenv->{'id'},{'staffaccess'=>1})) {
84
    unless(C4::Auth::haspermission($userenv->{'id'},{'staffaccess'=>1})) {
86
        print $input->redirect("/cgi-bin/koha/members/moremember.pl?borrowernumber=$member&error=CANT_DELETE_STAFF");
85
        print $input->redirect("/cgi-bin/koha/members/moremember.pl?borrowernumber=$member&error=CANT_DELETE_STAFF");
Lines 105-112 if (C4::Context->preference("IndependentBranches")) { Link Here
105
104
106
my $op = $input->param('op') || 'delete_confirm';
105
my $op = $input->param('op') || 'delete_confirm';
107
my $dbh = C4::Context->dbh;
106
my $dbh = C4::Context->dbh;
108
my $is_guarantor = $dbh->selectrow_array("SELECT COUNT(*) FROM borrowers WHERE guarantorid=?", undef, $member);
107
if ( $op eq 'delete_confirm' or $countissues > 0 or $flags->{'CHARGES'}  or $patron->guarantee_relationships()->count() or $deletelocal == 0) {
109
if ( $op eq 'delete_confirm' or $countissues > 0 or $flags->{'CHARGES'}  or $is_guarantor or $deletelocal == 0) {
110
    my $patron_image = Koha::Patron::Images->find($bor->{borrowernumber});
108
    my $patron_image = Koha::Patron::Images->find($bor->{borrowernumber});
111
    $template->param( picture => 1 ) if $patron_image;
109
    $template->param( picture => 1 ) if $patron_image;
112
110
Lines 136-149 if ( $op eq 'delete_confirm' or $countissues > 0 or $flags->{'CHARGES'} or $is_ Link Here
136
    if ($flags->{'CHARGES'} ne '') {
134
    if ($flags->{'CHARGES'} ne '') {
137
        $template->param(charges => $flags->{'CHARGES'}->{'amount'});
135
        $template->param(charges => $flags->{'CHARGES'}->{'amount'});
138
    }
136
    }
139
    if ($is_guarantor) {
137
    if ( $patron->guarantee_relationships->count ) {
140
        $template->param(guarantees => 1);
138
        $template->param( guarantees => 1 );
141
    }
139
    }
142
    if ($deletelocal == 0) {
140
    if ($deletelocal == 0) {
143
        $template->param(keeplocal => 1);
141
        $template->param(keeplocal => 1);
144
    }
142
    }
145
    # This is silly written but reflect the same conditions as above
143
    # This is silly written but reflect the same conditions as above
146
    if ( not $countissues > 0 and not $flags->{CHARGES} ne '' and not $is_guarantor and not $deletelocal == 0 ) {
144
    if ( not $countissues > 0 and not $flags->{CHARGES} ne '' and not $patron->guarantee_relationships->count and not $deletelocal == 0 ) {
147
        $template->param(
145
        $template->param(
148
            op         => 'delete_confirm',
146
            op         => 'delete_confirm',
149
            csrf_token => Koha::Token->new->generate_csrf({ session_id => scalar $input->cookie('CGISESSID') }),
147
            csrf_token => Koha::Token->new->generate_csrf({ session_id => scalar $input->cookie('CGISESSID') }),
(-)a/members/memberentry.pl (-57 / +87 lines)
Lines 79-85 if ( C4::Context->preference('SMSSendDriver') eq 'Email' ) { Link Here
79
    $template->param( sms_providers => \@providers );
79
    $template->param( sms_providers => \@providers );
80
}
80
}
81
81
82
my $guarantorid    = $input->param('guarantorid');
83
my $borrowernumber = $input->param('borrowernumber');
82
my $borrowernumber = $input->param('borrowernumber');
84
my $actionType     = $input->param('actionType') || '';
83
my $actionType     = $input->param('actionType') || '';
85
my $modify         = $input->param('modify');
84
my $modify         = $input->param('modify');
Lines 96-108 $nodouble = 1 if ($op eq 'modify' or $op eq 'duplicate'); # FIXME hack to rep Link Here
96
                                     # isn't a duplicate.  Marking FIXME because this
95
                                     # isn't a duplicate.  Marking FIXME because this
97
                                     # script needs to be refactored.
96
                                     # script needs to be refactored.
98
my $nok           = $input->param('nok');
97
my $nok           = $input->param('nok');
99
my $guarantorinfo = $input->param('guarantorinfo');
100
my $step          = $input->param('step') || 0;
98
my $step          = $input->param('step') || 0;
101
my @errors;
99
my @errors;
102
my $borrower_data;
100
my $borrower_data;
103
my $NoUpdateLogin;
101
my $NoUpdateLogin;
104
my $userenv = C4::Context->userenv;
102
my $userenv = C4::Context->userenv;
105
103
104
## Deal with guarantor stuff
105
my $patron = Koha::Patrons->find($borrowernumber);
106
$template->param( relationships => scalar $patron->guarantor_relationships ) if $patron;
107
108
my $guarantor_id = $input->param('guarantor_id');
109
my $guarantor = Koha::Patrons->find( $guarantor_id ) if $guarantor_id;
110
$template->param( guarantor => $guarantor );
111
112
my @delete_guarantor = $input->param('delete_guarantor');
113
foreach my $id ( @delete_guarantor ) {
114
    my $r = Koha::Patron::Relationships->find( $id );
115
    $r->delete() if $r;
116
}
106
117
107
## Deal with debarments
118
## Deal with debarments
108
$template->param(
119
$template->param(
Lines 139-152 $template->param("minPasswordLength" => $minpw); Link Here
139
my $check_BorrowerMandatoryField=C4::Context->preference("BorrowerMandatoryField");
150
my $check_BorrowerMandatoryField=C4::Context->preference("BorrowerMandatoryField");
140
my @field_check=split(/\|/,$check_BorrowerMandatoryField);
151
my @field_check=split(/\|/,$check_BorrowerMandatoryField);
141
foreach (@field_check) {
152
foreach (@field_check) {
142
	$template->param( "mandatory$_" => 1);    
153
    $template->param( "mandatory$_" => 1 );
143
}
154
}
144
# function to designate unwanted fields
155
# function to designate unwanted fields
145
my $check_BorrowerUnwantedField=C4::Context->preference("BorrowerUnwantedField");
156
my $check_BorrowerUnwantedField=C4::Context->preference("BorrowerUnwantedField");
146
@field_check=split(/\|/,$check_BorrowerUnwantedField);
157
@field_check=split(/\|/,$check_BorrowerUnwantedField);
147
foreach (@field_check) {
158
foreach (@field_check) {
148
    next unless m/\w/o;
159
    next unless m/\w/o;
149
	$template->param( "no$_" => 1);
160
    $template->param( "no$_" => 1 );
150
}
161
}
151
$template->param( "add" => 1 ) if ( $op eq 'add' );
162
$template->param( "add" => 1 ) if ( $op eq 'add' );
152
$template->param( "quickadd" => 1 ) if ( $quickadd );
163
$template->param( "quickadd" => 1 ) if ( $quickadd );
Lines 240-264 if ( ( $op eq 'insert' ) and !$nodouble ) { Link Here
240
    }
251
    }
241
}
252
}
242
253
243
  #recover all data from guarantor address phone ,fax... 
244
if ( $guarantorid ) {
245
    if (my $guarantordata=GetMember(borrowernumber => $guarantorid)) {
246
        $category_type = $guarantordata->{categorycode} eq 'I' ? 'P' : 'C';
247
        $guarantorinfo=$guarantordata->{'surname'}." , ".$guarantordata->{'firstname'};
248
        $newdata{'contactfirstname'}= $guarantordata->{'firstname'};
249
        $newdata{'contactname'}     = $guarantordata->{'surname'};
250
        $newdata{'contacttitle'}    = $guarantordata->{'title'};
251
        if ( $op eq 'add' ) {
252
	        foreach (qw(streetnumber address streettype address2
253
                        zipcode country city state phone phonepro mobile fax email emailpro branchcode
254
                        B_streetnumber B_streettype B_address B_address2
255
                        B_city B_state B_zipcode B_country B_email B_phone)) {
256
		        $newdata{$_} = $guarantordata->{$_};
257
	        }
258
        }
259
    }
260
}
261
262
###############test to take the right zipcode, country and city name ##############
254
###############test to take the right zipcode, country and city name ##############
263
# set only if parameter was passed from the form
255
# set only if parameter was passed from the form
264
$newdata{'city'}    = $input->param('city')    if defined($input->param('city'));
256
$newdata{'city'}    = $input->param('city')    if defined($input->param('city'));
Lines 402-407 if ((!$nok) and $nodouble and ($op eq 'insert' or $op eq 'save')){ Link Here
402
	if ($op eq 'insert'){
394
	if ($op eq 'insert'){
403
		# we know it's not a duplicate borrowernumber or there would already be an error
395
		# we know it's not a duplicate borrowernumber or there would already be an error
404
        $borrowernumber = &AddMember(%newdata);
396
        $borrowernumber = &AddMember(%newdata);
397
        add_guarantors( $borrowernumber, $input );
405
        $newdata{'borrowernumber'} = $borrowernumber;
398
        $newdata{'borrowernumber'} = $borrowernumber;
406
399
407
        # If 'AutoEmailOpacUser' syspref is on, email user their account details from the 'notice' that matches the user's branchcode.
400
        # If 'AutoEmailOpacUser' syspref is on, email user their account details from the 'notice' that matches the user's branchcode.
Lines 499-504 if ((!$nok) and $nodouble and ($op eq 'insert' or $op eq 'save')){ Link Here
499
                                                                # updating any columns in the borrowers table,
492
                                                                # updating any columns in the borrowers table,
500
                                                                # which can happen if we're only editing the
493
                                                                # which can happen if we're only editing the
501
                                                                # patron attributes or messaging preferences sections
494
                                                                # patron attributes or messaging preferences sections
495
        add_guarantors( $borrowernumber, $input );
502
        if (C4::Context->preference('ExtendedPatronAttributes') and $input->param('setting_extended_patron_attributes')) {
496
        if (C4::Context->preference('ExtendedPatronAttributes') and $input->param('setting_extended_patron_attributes')) {
503
            C4::Members::Attributes::SetBorrowerAttributes($borrowernumber, $extended_patron_attributes);
497
            C4::Members::Attributes::SetBorrowerAttributes($borrowernumber, $extended_patron_attributes);
504
        }
498
        }
Lines 598-608 foreach my $category_type (qw(C A S P I X)) { Link Here
598
        'categoryloop'   => \@categoryloop
592
        'categoryloop'   => \@categoryloop
599
      };
593
      };
600
}
594
}
601
595
$template->param(
602
$template->param('typeloop' => \@typeloop,
596
    typeloop      => \@typeloop,
603
        no_categories => $no_categories);
597
    no_categories => $no_categories,
604
if($no_categories){ $no_add = 1; }
598
);
605
606
599
607
my $cities = Koha::Cities->search( {}, { order_by => 'city_name' } );
600
my $cities = Koha::Cities->search( {}, { order_by => 'city_name' } );
608
my $roadtypes = C4::Koha::GetAuthorisedValues( 'ROADTYPE' );
601
my $roadtypes = C4::Koha::GetAuthorisedValues( 'ROADTYPE' );
Lines 627-650 while (@relationships) { Link Here
627
  push(@relshipdata, \%row);
620
  push(@relshipdata, \%row);
628
}
621
}
629
622
630
my %flags = ( 'gonenoaddress' => ['gonenoaddress' ],
623
my %flags = (
631
        'lost'          => ['lost']);
624
    'gonenoaddress' => ['gonenoaddress'],
625
    'lost'          => ['lost']
626
);
632
627
633
 
634
my @flagdata;
628
my @flagdata;
635
foreach (keys(%flags)) {
629
foreach ( keys(%flags) ) {
636
	my $key = $_;
630
    my $key = $_;
637
	my %row =  ('key'   => $key,
631
    my %row = (
638
		    'name'  => $flags{$key}[0]);
632
        'key'  => $key,
639
	if ($data{$key}) {
633
        'name' => $flags{$key}[0]
640
		$row{'yes'}=' checked';
634
    );
641
		$row{'no'}='';
635
    if ( $data{$key} ) {
642
    }
636
        $row{'yes'} = ' checked';
643
	else {
637
        $row{'no'}  = '';
644
		$row{'yes'}='';
638
    }
645
		$row{'no'}=' checked';
639
    else {
646
	}
640
        $row{'yes'} = '';
647
	push @flagdata,\%row;
641
        $row{'no'}  = ' checked';
642
    }
643
    push @flagdata, \%row;
648
}
644
}
649
645
650
# get Branch Loop
646
# get Branch Loop
Lines 720-726 if (C4::Context->preference('EnhancedMessagingPreferences')) { Link Here
720
    $template->param(TalkingTechItivaPhone => C4::Context->preference("TalkingTechItivaPhoneNotification"));
716
    $template->param(TalkingTechItivaPhone => C4::Context->preference("TalkingTechItivaPhoneNotification"));
721
}
717
}
722
718
723
$template->param( "showguarantor"  => ($category_type=~/A|I|S|X/) ? 0 : 1); # associate with step to know where you are
719
$template->param( "show_guarantor" => ( $category_type =~ /A|I|S|X/ ) ? 0 : 1 ); # associate with step to know where you are
724
$debug and warn "memberentry step: $step";
720
$debug and warn "memberentry step: $step";
725
$template->param(%data);
721
$template->param(%data);
726
$template->param( "step_$step"  => 1) if $step;	# associate with step to know where u are
722
$template->param( "step_$step"  => 1) if $step;	# associate with step to know where u are
Lines 735-752 $template->param( Link Here
735
  "op$op"   => 1);
731
  "op$op"   => 1);
736
732
737
$template->param(
733
$template->param(
738
  nodouble  => $nodouble,
734
    nodouble       => $nodouble,
739
  borrowernumber  => $borrowernumber, #register number
735
    borrowernumber => $borrowernumber,          #register number
740
  guarantorid => ($borrower_data->{'guarantorid'} || $guarantorid),
736
    relshiploop    => \@relshipdata,
741
  relshiploop => \@relshipdata,
737
    btitle         => $default_borrowertitle,
742
  btitle=> $default_borrowertitle,
738
    flagloop       => \@flagdata,
743
  guarantorinfo   => $guarantorinfo,
739
    category_type  => $category_type,
744
  flagloop  => \@flagdata,
740
    modify         => $modify,
745
  category_type =>$category_type,
741
    nok            => $nok,                     #flag to know if an error
746
  modify          => $modify,
742
    NoUpdateLogin  => $NoUpdateLogin,
747
  nok     => $nok,#flag to know if an error
743
);
748
  NoUpdateLogin =>  $NoUpdateLogin,
749
  );
750
744
751
# Generate CSRF token
745
# Generate CSRF token
752
$template->param( csrf_token =>
746
$template->param( csrf_token =>
Lines 868-873 sub patron_attributes_form { Link Here
868
862
869
}
863
}
870
864
865
sub add_guarantors {
866
    my ( $borrowernumber, $input ) = @_;
867
868
    my @new_guarantor_id           = scalar $input->param('new_guarantor_id');
869
    my @new_guarantor_surname      = scalar $input->param('new_guarantor_surname');
870
    my @new_guarantor_firstname    = scalar $input->param('new_guarantor_firstname');
871
    my @new_guarantor_relationship = scalar $input->param('new_guarantor_relationship');
872
873
    for ( my $i = 0 ; $i < scalar @new_guarantor_id; $i++ ) {
874
        my $guarantor_id = $new_guarantor_id[$i];
875
        my $surname      = $new_guarantor_surname[$i];
876
        my $firstname    = $new_guarantor_firstname[$i];
877
        my $relationship = $new_guarantor_relationship[$i];
878
879
        if ($guarantor_id) {
880
            Koha::Patron::Relationship->new(
881
                {
882
                    guarantee_id => $borrowernumber,
883
                    guarantor_id => $guarantor_id,
884
                    relationship => $relationship
885
                }
886
            )->store();
887
        }
888
        elsif ($surname) {
889
            Koha::Patron::Relationship->new(
890
                {
891
                    guarantee_id => $borrowernumber,
892
                    surname      => $surname,
893
                    firstname    => $firstname,
894
                    relationship => $relationship
895
                }
896
            )->store();
897
        }
898
    }
899
}
900
871
# Local Variables:
901
# Local Variables:
872
# tab-width: 8
902
# tab-width: 8
873
# End:
903
# End:
(-)a/members/moremember.pl (-15 / +13 lines)
Lines 176-197 if ( $category_type eq 'C') { Link Here
176
}
176
}
177
177
178
my @relatives;
178
my @relatives;
179
if ( my $guarantor = $patron->guarantor ) {
179
my $guarantor_relationships = $patron->guarantor_relationships;
180
    $template->param( guarantor => $guarantor );
180
my @guarantees              = $patron->guarantee_relationships->guarantees;
181
    push @relatives, $guarantor->borrowernumber;
181
my @guarantors              = $guarantor_relationships->guarantors;
182
    push @relatives, $_->borrowernumber for $patron->siblings;
182
if (@guarantors) {
183
} elsif ( $patron->contactname || $patron->contactfirstname ) {
183
    push( @relatives, $_->id ) for @guarantors;
184
    $template->param(
184
    push( @relatives, $_->id ) for $patron->siblings();
185
        guarantor => {
186
            firstname => $patron->contactfirstname,
187
            surname   => $patron->contactname,
188
        }
189
    );
190
} else {
191
    my @guarantees = $patron->guarantees;
192
    $template->param( guarantees => \@guarantees );
193
    push @relatives, $_->borrowernumber for @guarantees;
194
}
185
}
186
else {
187
    push( @relatives, $_->id ) for @guarantees;
188
}
189
$template->param(
190
    guarantor_relationships => $guarantor_relationships,
191
    guarantees              => \@guarantees,
192
);
195
193
196
my $relatives_issues_count =
194
my $relatives_issues_count =
197
  Koha::Database->new()->schema()->resultset('Issue')
195
  Koha::Database->new()->schema()->resultset('Issue')
(-)a/members/update-child.pl (-16 / +21 lines)
Lines 34-39 use C4::Auth; Link Here
34
use C4::Output;
34
use C4::Output;
35
use C4::Members;
35
use C4::Members;
36
use Koha::Patron::Categories;
36
use Koha::Patron::Categories;
37
use Koha::Patrons;
37
38
38
# use Smart::Comments;
39
# use Smart::Comments;
39
40
Lines 54-60 my ( $template, $loggedinuser, $cookie ) = get_template_and_user( Link Here
54
my $borrowernumber = $input->param('borrowernumber');
55
my $borrowernumber = $input->param('borrowernumber');
55
my $catcode        = $input->param('catcode');
56
my $catcode        = $input->param('catcode');
56
my $cattype        = $input->param('cattype');
57
my $cattype        = $input->param('cattype');
57
my $catcode_multi = $input->param('catcode_multi');
58
my $catcode_multi  = $input->param('catcode_multi');
58
my $op             = $input->param('op');
59
my $op             = $input->param('op');
59
60
60
if ( $op eq 'multi' ) {
61
if ( $op eq 'multi' ) {
Lines 69-93 if ( $op eq 'multi' ) { Link Here
69
    );
70
    );
70
    output_html_with_http_headers $input, $cookie, $template->output;
71
    output_html_with_http_headers $input, $cookie, $template->output;
71
}
72
}
72
73
elsif ( $op eq 'update' ) {
73
elsif ( $op eq 'update' ) {
74
    my $member = GetMember('borrowernumber'=>$borrowernumber);
74
    my $patron = Koha::Patrons->find($borrowernumber);
75
    $member->{'guarantorid'}  = 0;
75
    $_->delete() for $patrons->guarantor_relationships();
76
    $member->{'categorycode'} = $catcode;
76
77
    my $borcat = Koha::Patron::Categories->find($catcode);
77
    my $patron_hashref = patron->unblessed();
78
    $member->{'category_type'} = $borcat->category_type;
78
    my $borcat         = GetBorrowercategory($catcode);
79
    $member->{'description'}   = $borcat->description;
79
    $patron_hashref->{'category_type'} = $borcat->{'category_type'};
80
    delete $member->{password};
80
    $patron_hashref->{'categorycode'}  = $catcode;
81
    ModMember(%$member);
81
    $patron_hashref->{'description'}   = $borcat->{'description'};
82
    delete $patron_hashref->{password};
83
    ModMember(%$patron_hashref);
82
84
83
    if (  $catcode_multi ) {
85
    if ($catcode_multi) {
84
        $template->param(
86
        $template->param(
85
                SUCCESS        => 1,
87
            SUCCESS        => 1,
86
                borrowernumber => $borrowernumber,
88
            borrowernumber => $borrowernumber,
87
                );
89
        );
88
        output_html_with_http_headers $input, $cookie, $template->output;
90
        output_html_with_http_headers $input, $cookie, $template->output;
89
    } else {
91
    }
90
        print $input->redirect("/cgi-bin/koha/members/moremember.pl?borrowernumber=$borrowernumber");
92
    else {
93
        print $input->redirect(
94
            "/cgi-bin/koha/members/moremember.pl?borrowernumber=$borrowernumber"
95
        );
91
    }
96
    }
92
}
97
}
93
98
(-)a/misc/cronjobs/j2a.pl (-12 / +45 lines)
Lines 163-174 $verbose and print "The age limit for category $fromcat is $agelimit\n"; Link Here
163
my $itsyourbirthday = "$year-$mon-$mday";
163
my $itsyourbirthday = "$year-$mon-$mday";
164
164
165
if ( not $noaction ) {
165
if ( not $noaction ) {
166
    # Start a transaction since we need to delete from relationships and update borrowers atomically
167
    $dbh->{AutoCommit} = 0;
168
166
    if ($mybranch) {    #yep, we received a specific branch to work on.
169
    if ($mybranch) {    #yep, we received a specific branch to work on.
167
        $verbose and print "Looking for patrons of $mybranch to update from $fromcat to $tocat that were born before $itsyourbirthday\n";
170
        $verbose and print "Looking for patrons of $mybranch to update from $fromcat to $tocat that were born before $itsyourbirthday\n";
168
        my $query = qq|
171
        my $where = qq|
169
            UPDATE borrowers
170
            SET guarantorid ='0',
171
                categorycode = ?
172
            WHERE dateofbirth <= ?
172
            WHERE dateofbirth <= ?
173
              AND dateofbirth != '0000-00-00'
173
              AND dateofbirth != '0000-00-00'
174
              AND branchcode = ?
174
              AND branchcode = ?
Lines 177-186 if ( not $noaction ) { Link Here
177
                FROM categories
177
                FROM categories
178
                WHERE category_type = 'C'
178
                WHERE category_type = 'C'
179
                  AND categorycode = ?
179
                  AND categorycode = ?
180
              )|;
180
              )
181
        |;
182
183
        my $query = qq|
184
            DELETE relationships FROM relationships
185
            LEFT JOIN borrowers ON ( borrowers.borrowernumber = relationships.guarantee_id )
186
            $where
187
        |;
181
        my $sth = $dbh->prepare($query);
188
        my $sth = $dbh->prepare($query);
189
        $sth->execute( $itsyourbirthday, $mybranch, $fromcat )
190
          or ( $dbh->rollback && die "can't execute" );
191
192
        $query = qq|
193
            UPDATE borrowers
194
            SET categorycode = ?
195
            $where
196
        |;
197
        $sth = $dbh->prepare($query);
182
        my $res = $sth->execute( $tocat, $itsyourbirthday, $mybranch, $fromcat )
198
        my $res = $sth->execute( $tocat, $itsyourbirthday, $mybranch, $fromcat )
183
          or die "can't execute";
199
          or ( $dbh->rollback && die "can't execute" );
200
201
        $dbh->commit;
184
202
185
        if ( $res eq '0E0' ) {
203
        if ( $res eq '0E0' ) {
186
            print "No patrons updated\n";
204
            print "No patrons updated\n";
Lines 191-200 if ( not $noaction ) { Link Here
191
    }
209
    }
192
    else {    # branch was not supplied, processing all branches
210
    else {    # branch was not supplied, processing all branches
193
        $verbose and print "Looking in all branches for patrons to update from $fromcat to $tocat that were born before $itsyourbirthday\n";
211
        $verbose and print "Looking in all branches for patrons to update from $fromcat to $tocat that were born before $itsyourbirthday\n";
194
        my $query = qq|
212
        my $where = qq|
195
            UPDATE borrowers
196
            SET guarantorid = '0',
197
                categorycode = ?
198
            WHERE dateofbirth <= ?
213
            WHERE dateofbirth <= ?
199
              AND dateofbirth!='0000-00-00'
214
              AND dateofbirth!='0000-00-00'
200
              AND categorycode IN (
215
              AND categorycode IN (
Lines 202-211 if ( not $noaction ) { Link Here
202
                FROM categories
217
                FROM categories
203
                WHERE category_type = 'C'
218
                WHERE category_type = 'C'
204
                  AND categorycode = ?
219
                  AND categorycode = ?
205
              )|;
220
              )
221
        |;
222
223
        my $query = qq|
224
            DELETE relationships FROM relationships
225
            LEFT JOIN borrowers ON ( borrowers.borrowernumber = relationships.guarantee_id )
226
            $where
227
        |;
206
        my $sth = $dbh->prepare($query);
228
        my $sth = $dbh->prepare($query);
229
        $sth->execute( $itsyourbirthday, $fromcat )
230
          or ( $dbh->rollback && die "can't execute" );
231
232
        $query = qq|
233
            UPDATE borrowers
234
            SET categorycode = ?
235
            $where
236
        |;
237
        $sth = $dbh->prepare($query);
207
        my $res = $sth->execute( $tocat, $itsyourbirthday, $fromcat )
238
        my $res = $sth->execute( $tocat, $itsyourbirthday, $fromcat )
208
          or die "can't execute";
239
          or ( $dbh->rollback && die "can't execute" );
240
        $dbh->commit;
209
241
210
        if ( $res eq '0E0' ) {
242
        if ( $res eq '0E0' ) {
211
            print "No patrons updated\n";
243
            print "No patrons updated\n";
Lines 267-272 else { Link Here
267
        my $sth = $dbh->prepare($query);
299
        my $sth = $dbh->prepare($query);
268
        $sth->execute( $itsyourbirthday, $fromcat )
300
        $sth->execute( $itsyourbirthday, $fromcat )
269
          or die "Couldn't execute statement: " . $sth->errstr;
301
          or die "Couldn't execute statement: " . $sth->errstr;
302
        $dbh->commit;
270
303
271
        while ( my @res = $sth->fetchrow_array() ) {
304
        while ( my @res = $sth->fetchrow_array() ) {
272
            my $firstname = $res[0];
305
            my $firstname = $res[0];
(-)a/opac/opac-memberentry.pl (-2 / +2 lines)
Lines 299-305 elsif ( $action eq 'edit' ) { #Display logged in borrower's data Link Here
299
299
300
    $template->param(
300
    $template->param(
301
        borrower  => $borrower,
301
        borrower  => $borrower,
302
        guarantor => scalar Koha::Patrons->find($borrowernumber)->guarantor(),
303
        hidden => GetHiddenFields( $mandatory, 'modification' ),
302
        hidden => GetHiddenFields( $mandatory, 'modification' ),
304
        csrf_token => Koha::Token->new->generate_csrf({
303
        csrf_token => Koha::Token->new->generate_csrf({
305
            session_id => scalar $cgi->cookie('CGISESSID'),
304
            session_id => scalar $cgi->cookie('CGISESSID'),
Lines 321-327 my $captcha = random_string("CCCCC"); Link Here
321
320
322
$template->param(
321
$template->param(
323
    captcha        => $captcha,
322
    captcha        => $captcha,
324
    captcha_digest => md5_base64($captcha)
323
    captcha_digest => md5_base64($captcha),
324
    patron         => Koha::Patrons->find( $borrowernumber ),
325
);
325
);
326
326
327
output_html_with_http_headers $cgi, $cookie, $template->output, undef, { force_no_caching => 1 };
327
output_html_with_http_headers $cgi, $cookie, $template->output, undef, { force_no_caching => 1 };
(-)a/opac/opac-user.pl (-8 / +9 lines)
Lines 39-44 use Koha::Holds; Link Here
39
use Koha::Database;
39
use Koha::Database;
40
use Koha::ItemTypes;
40
use Koha::ItemTypes;
41
use Koha::Patron::Attribute::Types;
41
use Koha::Patron::Attribute::Types;
42
use Koha::Patrons;
42
use Koha::Patron::Messages;
43
use Koha::Patron::Messages;
43
use Koha::Patron::Discharge;
44
use Koha::Patron::Discharge;
44
use Koha::Patrons;
45
use Koha::Patrons;
Lines 71-76 my ( $template, $borrowernumber, $cookie ) = get_template_and_user( Link Here
71
    }
72
    }
72
);
73
);
73
74
75
my $patron = Koha::Patrons->find( $borrowernumber );
76
74
my %renewed = map { $_ => 1 } split( ':', $query->param('renewed') );
77
my %renewed = map { $_ => 1 } split( ':', $query->param('renewed') );
75
78
76
my $show_priority;
79
my $show_priority;
Lines 332-345 my $patron_messages = Koha::Patron::Messages->search( Link Here
332
if (   C4::Context->preference('AllowPatronToSetCheckoutsVisibilityForGuarantor')
335
if (   C4::Context->preference('AllowPatronToSetCheckoutsVisibilityForGuarantor')
333
    || C4::Context->preference('AllowStaffToSetCheckoutsVisibilityForGuarantor') )
336
    || C4::Context->preference('AllowStaffToSetCheckoutsVisibilityForGuarantor') )
334
{
337
{
335
    my @relatives =
338
    my @relatives;
336
      Koha::Database->new()->schema()->resultset("Borrower")->search(
339
    # Filter out guarantees that don't want guarantor to see checkouts
337
        {
340
    foreach my $gr ( $patron->guarantee_relationships() ) {
338
            privacy_guarantor_checkouts => 1,
341
        my $g = $gr->guarantee;
339
            'me.guarantorid'           => $borrowernumber
342
        push( @relatives, $g ) if $g->privacy_guarantor_checkouts;
340
        },
343
    }
341
        { prefetch => [ { 'issues' => { 'item' => 'biblio' } } ] }
342
      );
343
    $template->param( relatives => \@relatives );
344
    $template->param( relatives => \@relatives );
344
}
345
}
345
346
(-)a/t/Patron.t (-22 / +2 lines)
Lines 85-96 my $patron = Koha::Patron->new( Link Here
85
        lost                => '0',
85
        lost                => '0',
86
        debarred            => '2015-04-19',
86
        debarred            => '2015-04-19',
87
        debarredcomment     => 'You are debarred',
87
        debarredcomment     => 'You are debarred',
88
        contactname         => 'myContactname',
89
        contactfirstname    => 'myContactfirstname',
90
        contacttitle        => 'myContacttitle',
91
        guarantorid         => '123454321',
92
        borrowernotes       => 'borrowernotes',
88
        borrowernotes       => 'borrowernotes',
93
        relationship        => 'myRelationship',
94
        sex                 => 'M',
89
        sex                 => 'M',
95
        password            => 'hfkurhfe976634èj!',
90
        password            => 'hfkurhfe976634èj!',
96
        flags               => '55555',
91
        flags               => '55555',
Lines 115-121 my $patron = Koha::Patron->new( Link Here
115
110
116
# patron Accessor tests
111
# patron Accessor tests
117
subtest 'Accessor tests' => sub {
112
subtest 'Accessor tests' => sub {
118
    plan tests => 65;
113
    plan tests => 60;
119
    is( $patron->borrowernumber, '12345',                           'borrowernumber accessor returns correct value' );
114
    is( $patron->borrowernumber, '12345',                           'borrowernumber accessor returns correct value' );
120
    is( $patron->cardnumber,     '1234567890',                      'cardnumber accessor returns correct value' );
115
    is( $patron->cardnumber,     '1234567890',                      'cardnumber accessor returns correct value' );
121
    is( $patron->surname,        'mySurname',                       'surname accessor returns correct value' );
116
    is( $patron->surname,        'mySurname',                       'surname accessor returns correct value' );
Lines 156-167 subtest 'Accessor tests' => sub { Link Here
156
    is( $patron->lost,           '0',                               'lost accessor returns correct value' );
151
    is( $patron->lost,           '0',                               'lost accessor returns correct value' );
157
    is( $patron->debarred,       '2015-04-19',                      'debarred accessor returns correct value' );
152
    is( $patron->debarred,       '2015-04-19',                      'debarred accessor returns correct value' );
158
    is( $patron->debarredcomment,     'You are debarred',      'debarredcomment accessor returns correct value' );
153
    is( $patron->debarredcomment,     'You are debarred',      'debarredcomment accessor returns correct value' );
159
    is( $patron->contactname,         'myContactname',         'contactname accessor returns correct value' );
160
    is( $patron->contactfirstname,    'myContactfirstname',    'contactfirstname accessor returns correct value' );
161
    is( $patron->contacttitle,        'myContacttitle',        'contacttitle accessor returns correct value' );
162
    is( $patron->guarantorid,         '123454321',             'guarantorid accessor returns correct value' );
163
    is( $patron->borrowernotes,       'borrowernotes',         'borrowernotes accessor returns correct value' );
154
    is( $patron->borrowernotes,       'borrowernotes',         'borrowernotes accessor returns correct value' );
164
    is( $patron->relationship,        'myRelationship',        'relationship accessor returns correct value' );
165
    is( $patron->sex,                 'M',                     'sex accessor returns correct value' );
155
    is( $patron->sex,                 'M',                     'sex accessor returns correct value' );
166
    is( $patron->password,            'hfkurhfe976634èj!',    'password accessor returns correct value' );
156
    is( $patron->password,            'hfkurhfe976634èj!',    'password accessor returns correct value' );
167
    is( $patron->flags,               '55555',                 'flags accessor returns correct value' );
157
    is( $patron->flags,               '55555',                 'flags accessor returns correct value' );
Lines 185-191 subtest 'Accessor tests' => sub { Link Here
185
175
186
# patron Set tests
176
# patron Set tests
187
subtest 'Set tests' => sub {
177
subtest 'Set tests' => sub {
188
    plan tests => 65;
178
    plan tests => 60;
189
179
190
    $patron->set(
180
    $patron->set(
191
        {
181
        {
Lines 229-240 subtest 'Set tests' => sub { Link Here
229
            lost                => '1',
219
            lost                => '1',
230
            debarred            => '2016-04-19',
220
            debarred            => '2016-04-19',
231
            debarredcomment     => 'You are still debarred',
221
            debarredcomment     => 'You are still debarred',
232
            contactname         => 'SmyContactname',
233
            contactfirstname    => 'SmyContactfirstname',
234
            contacttitle        => 'SmyContacttitle',
235
            guarantorid         => '223454321',
236
            borrowernotes       => 'Sborrowernotes',
222
            borrowernotes       => 'Sborrowernotes',
237
            relationship        => 'SmyRelationship',
238
            sex                 => 'F',
223
            sex                 => 'F',
239
            password            => 'zerzerzer#',
224
            password            => 'zerzerzer#',
240
            flags               => '666666',
225
            flags               => '666666',
Lines 297-308 subtest 'Set tests' => sub { Link Here
297
    is( $patron->lost,                '1',                                'lost field set ok' );
282
    is( $patron->lost,                '1',                                'lost field set ok' );
298
    is( $patron->debarred,            '2016-04-19',                       'debarred field set ok' );
283
    is( $patron->debarred,            '2016-04-19',                       'debarred field set ok' );
299
    is( $patron->debarredcomment,     'You are still debarred',           'debarredcomment field set ok' );
284
    is( $patron->debarredcomment,     'You are still debarred',           'debarredcomment field set ok' );
300
    is( $patron->contactname,         'SmyContactname',                   'contactname field set ok' );
301
    is( $patron->contactfirstname,    'SmyContactfirstname',              'contactfirstname field set ok' );
302
    is( $patron->contacttitle,        'SmyContacttitle',                  'contacttitle field set ok' );
303
    is( $patron->guarantorid,         '223454321',                        'guarantorid field set ok' );
304
    is( $patron->borrowernotes,       'Sborrowernotes',                   'borrowernotes field set ok' );
285
    is( $patron->borrowernotes,       'Sborrowernotes',                   'borrowernotes field set ok' );
305
    is( $patron->relationship,        'SmyRelationship',                  'relationship field set ok' );
306
    is( $patron->sex,                 'F',                                'sex field set ok' );
286
    is( $patron->sex,                 'F',                                'sex field set ok' );
307
    is( $patron->password,            'zerzerzer#',                       'password field set ok' );
287
    is( $patron->password,            'zerzerzer#',                       'password field set ok' );
308
    is( $patron->flags,               '666666',                           'flags field set ok' );
288
    is( $patron->flags,               '666666',                           'flags field set ok' );
(-)a/t/db_dependent/Circulation/NoIssuesChargeGuarantees.t (-3 / +9 lines)
Lines 24-29 use t::lib::Mocks; Link Here
24
24
25
use C4::Accounts qw( manualinvoice );
25
use C4::Accounts qw( manualinvoice );
26
use C4::Circulation qw( CanBookBeIssued );
26
use C4::Circulation qw( CanBookBeIssued );
27
use Koha::Patron::Relationship;
27
28
28
my $schema = Koha::Database->new->schema;
29
my $schema = Koha::Database->new->schema;
29
$schema->storage->txn_begin;
30
$schema->storage->txn_begin;
Lines 48-59 my $patron = $builder->build( Link Here
48
my $guarantee = $builder->build(
49
my $guarantee = $builder->build(
49
    {
50
    {
50
        source => 'Borrower',
51
        source => 'Borrower',
51
        value  => {
52
            guarantorid => $patron->{borrowernumber},
53
        }
54
    }
52
    }
55
);
53
);
56
54
55
my $r = Koha::Patron::Relationship->new(
56
    {
57
        guarantor_id => $patron->{borrowernumber},
58
        guarantee_id => $guarantee->{borrowernumber},
59
        relationship => 'parent',
60
    }
61
)->store();
62
57
t::lib::Mocks::mock_preference( 'NoIssuesChargeGuarantees', '5.00' );
63
t::lib::Mocks::mock_preference( 'NoIssuesChargeGuarantees', '5.00' );
58
64
59
my ( $issuingimpossible, $needsconfirmation ) = CanBookBeIssued( $patron, $item->{barcode} );
65
my ( $issuingimpossible, $needsconfirmation ) = CanBookBeIssued( $patron, $item->{barcode} );
(-)a/t/db_dependent/Items.t (-1 / +5 lines)
Lines 466-472 subtest 'SearchItems test' => sub { Link Here
466
466
467
subtest 'Koha::Item(s) tests' => sub {
467
subtest 'Koha::Item(s) tests' => sub {
468
468
469
    plan tests => 5;
469
    plan tests => 7;
470
470
471
    $schema->storage->txn_begin();
471
    $schema->storage->txn_begin();
472
472
Lines 505-510 subtest 'Koha::Item(s) tests' => sub { Link Here
505
    is( ref($holdingbranch), 'Koha::Library', "Got Koha::Library from holding_branch method" );
505
    is( ref($holdingbranch), 'Koha::Library', "Got Koha::Library from holding_branch method" );
506
    is( $holdingbranch->branchcode(), $library2->{branchcode}, "Home branch code matches holdingbranch" );
506
    is( $holdingbranch->branchcode(), $library2->{branchcode}, "Home branch code matches holdingbranch" );
507
507
508
    my $biblio = $item->biblio();
509
    is( ref($biblio), 'Koha::Biblio', "Got Koha::Biblio from biblio method" );
510
    is( $biblio->title(), 'Silence in the library', 'Title matches biblio title' );
511
508
    $schema->storage->txn_rollback;
512
    $schema->storage->txn_rollback;
509
};
513
};
510
514
(-)a/t/db_dependent/Koha/Patrons.t (-15 / +21 lines)
Lines 31-36 use C4::Circulation; Link Here
31
use Koha::Holds;
31
use Koha::Holds;
32
use Koha::Patron;
32
use Koha::Patron;
33
use Koha::Patrons;
33
use Koha::Patrons;
34
use Koha::Patron::Relationship;
34
use Koha::Database;
35
use Koha::Database;
35
use Koha::DateUtils;
36
use Koha::DateUtils;
36
use Koha::Virtualshelves;
37
use Koha::Virtualshelves;
Lines 80-102 subtest 'library' => sub { Link Here
80
81
81
subtest 'guarantees' => sub {
82
subtest 'guarantees' => sub {
82
    plan tests => 8;
83
    plan tests => 8;
83
    my $guarantees = $new_patron_1->guarantees;
84
    my $guarantees = $new_patron_1->guarantee_relationships;
84
    is( ref($guarantees), 'Koha::Patrons', 'Koha::Patron->guarantees should return a Koha::Patrons result set in a scalar context' );
85
    is( ref($guarantees), 'Koha::Patron::Relationships', 'Koha::Patron->guarantees should return a Koha::Patrons result set in a scalar context' );
85
    is( $guarantees->count, 0, 'new_patron_1 should have 0 guarantee' );
86
    is( $guarantees->count, 0, 'new_patron_1 should have 0 guarantee relationships' );
86
    my @guarantees = $new_patron_1->guarantees;
87
    my @guarantees = $new_patron_1->guarantee_relationships;
87
    is( ref(\@guarantees), 'ARRAY', 'Koha::Patron->guarantees should return an array in a list context' );
88
    is( ref(\@guarantees), 'ARRAY', 'Koha::Patron->guarantee_relationships should return an array in a list context' );
88
    is( scalar(@guarantees), 0, 'new_patron_1 should have 0 guarantee' );
89
    is( scalar(@guarantees), 0, 'new_patron_1 should have 0 guarantee' );
89
90
90
    my $guarantee_1 = $builder->build({ source => 'Borrower', value => { guarantorid => $new_patron_1->borrowernumber }});
91
    my $guarantee_1 = $builder->build({ source => 'Borrower' });
91
    my $guarantee_2 = $builder->build({ source => 'Borrower', value => { guarantorid => $new_patron_1->borrowernumber }});
92
    my $relationship_1 = Koha::Patron::Relationship->new( { guarantor_id => $new_patron_1->id, guarantee_id => $guarantee_1->{borrowernumber} } )->store();
93
    my $guarantee_2 = $builder->build({ source => 'Borrower' });
94
    my $relationship_2 = Koha::Patron::Relationship->new( { guarantor_id => $new_patron_1->id, guarantee_id => $guarantee_2->{borrowernumber} } )->store();
92
95
93
    $guarantees = $new_patron_1->guarantees;
96
    $guarantees = $new_patron_1->guarantee_relationships;
94
    is( ref($guarantees), 'Koha::Patrons', 'Koha::Patron->guarantees should return a Koha::Patrons result set in a scalar context' );
97
    is( ref($guarantees), 'Koha::Patron::Relationships', 'Koha::Patron->guarantee_relationships should return a Koha::Patrons result set in a scalar context' );
95
    is( $guarantees->count, 2, 'new_patron_1 should have 2 guarantees' );
98
    is( $guarantees->count, 2, 'new_patron_1 should have 2 guarantees' );
96
    @guarantees = $new_patron_1->guarantees;
99
    @guarantees = $new_patron_1->guarantee_relationships;
97
    is( ref(\@guarantees), 'ARRAY', 'Koha::Patron->guarantees should return an array in a list context' );
100
    is( ref(\@guarantees), 'ARRAY', 'Koha::Patron->guarantee_relationships should return an array in a list context' );
98
    is( scalar(@guarantees), 2, 'new_patron_1 should have 2 guarantees' );
101
    is( scalar(@guarantees), 2, 'new_patron_1 should have 2 guarantees' );
99
    $_->delete for @guarantees;
102
    map { $_->guarantee->delete } @guarantees;
100
};
103
};
101
104
102
subtest 'category' => sub {
105
subtest 'category' => sub {
Lines 110-124 subtest 'siblings' => sub { Link Here
110
    plan tests => 7;
113
    plan tests => 7;
111
    my $siblings = $new_patron_1->siblings;
114
    my $siblings = $new_patron_1->siblings;
112
    is( $siblings, undef, 'Koha::Patron->siblings should not crashed if the patron has no guarantor' );
115
    is( $siblings, undef, 'Koha::Patron->siblings should not crashed if the patron has no guarantor' );
113
    my $guarantee_1 = $builder->build( { source => 'Borrower', value => { guarantorid => $new_patron_1->borrowernumber } } );
116
    my $guarantee_1 = $builder->build( { source => 'Borrower' } );
117
    my $relationship_1 = Koha::Patron::Relationship->new( { guarantor_id => $new_patron_1->borrowernumber, guarantee_id => $guarantee_1->{borrowernumber} } )->store();
114
    my $retrieved_guarantee_1 = Koha::Patrons->find($guarantee_1);
118
    my $retrieved_guarantee_1 = Koha::Patrons->find($guarantee_1);
115
    $siblings = $retrieved_guarantee_1->siblings;
119
    $siblings = $retrieved_guarantee_1->siblings;
116
    is( ref($siblings), 'Koha::Patrons', 'Koha::Patron->siblings should return a Koha::Patrons result set in a scalar context' );
120
    is( ref($siblings), 'Koha::Patrons', 'Koha::Patron->siblings should return a Koha::Patrons result set in a scalar context' );
117
    my @siblings = $retrieved_guarantee_1->siblings;
121
    my @siblings = $retrieved_guarantee_1->siblings;
118
    is( ref( \@siblings ), 'ARRAY', 'Koha::Patron->siblings should return an array in a list context' );
122
    is( ref( \@siblings ), 'ARRAY', 'Koha::Patron->siblings should return an array in a list context' );
119
    is( $siblings->count,  0,       'guarantee_1 should not have siblings yet' );
123
    is( $siblings->count,  0,       'guarantee_1 should not have siblings yet' );
120
    my $guarantee_2 = $builder->build( { source => 'Borrower', value => { guarantorid => $new_patron_1->borrowernumber } } );
124
    my $guarantee_2 = $builder->build( { source => 'Borrower' } );
121
    my $guarantee_3 = $builder->build( { source => 'Borrower', value => { guarantorid => $new_patron_1->borrowernumber } } );
125
    my $relationship_2 = Koha::Patron::Relationship->new( { guarantor_id => $new_patron_1->borrowernumber, guarantee_id => $guarantee_2->{borrowernumber} } )->store();
126
    my $guarantee_3 = $builder->build( { source => 'Borrower' } );
127
    my $relationship_3 = Koha::Patron::Relationship->new( { guarantor_id => $new_patron_1->borrowernumber, guarantee_id => $guarantee_3->{borrowernumber} } )->store();
122
    $siblings = $retrieved_guarantee_1->siblings;
128
    $siblings = $retrieved_guarantee_1->siblings;
123
    is( $siblings->count,               2,                               'guarantee_1 should have 2 siblings' );
129
    is( $siblings->count,               2,                               'guarantee_1 should have 2 siblings' );
124
    is( $guarantee_2->{borrowernumber}, $siblings->next->borrowernumber, 'guarantee_2 should exist in the guarantees' );
130
    is( $guarantee_2->{borrowernumber}, $siblings->next->borrowernumber, 'guarantee_2 should exist in the guarantees' );
(-)a/t/db_dependent/Members.t (-11 / +7 lines)
Lines 25-30 use Koha::Database; Link Here
25
use Koha::Holds;
25
use Koha::Holds;
26
use Koha::List::Patron;
26
use Koha::List::Patron;
27
use Koha::Patrons;
27
use Koha::Patrons;
28
use Koha::Patron::Relationship;
28
29
29
use t::lib::Mocks;
30
use t::lib::Mocks;
30
use t::lib::TestBuilder;
31
use t::lib::TestBuilder;
Lines 38-46 $schema->storage->txn_begin; Link Here
38
my $builder = t::lib::TestBuilder->new;
39
my $builder = t::lib::TestBuilder->new;
39
my $dbh = C4::Context->dbh;
40
my $dbh = C4::Context->dbh;
40
41
41
# Remove invalid guarantorid's as long as we have no FK
42
$dbh->do("UPDATE borrowers b1 LEFT JOIN borrowers b2 ON b2.borrowernumber=b1.guarantorid SET b1.guarantorid=NULL where b1.guarantorid IS NOT NULL AND b2.borrowernumber IS NULL");
43
44
my $library1 = $builder->build({
42
my $library1 = $builder->build({
45
    source => 'Branch',
43
    source => 'Branch',
46
});
44
});
Lines 258-264 my $borrower1 = $builder->build({ Link Here
258
            categorycode=>'STAFFER',
256
            categorycode=>'STAFFER',
259
            branchcode => $library3->{branchcode},
257
            branchcode => $library3->{branchcode},
260
            dateexpiry => '2015-01-01',
258
            dateexpiry => '2015-01-01',
261
            guarantorid=> undef,
262
        },
259
        },
263
});
260
});
264
my $bor1inlist = $borrower1->{borrowernumber};
261
my $bor1inlist = $borrower1->{borrowernumber};
Lines 268-274 my $borrower2 = $builder->build({ Link Here
268
            categorycode=>'STAFFER',
265
            categorycode=>'STAFFER',
269
            branchcode => $library3->{branchcode},
266
            branchcode => $library3->{branchcode},
270
            dateexpiry => '2015-01-01',
267
            dateexpiry => '2015-01-01',
271
            guarantorid=> undef,
272
        },
268
        },
273
});
269
});
274
270
Lines 278-284 my $guarantee = $builder->build({ Link Here
278
            categorycode=>'KIDclamp',
274
            categorycode=>'KIDclamp',
279
            branchcode => $library3->{branchcode},
275
            branchcode => $library3->{branchcode},
280
            dateexpiry => '2015-01-01',
276
            dateexpiry => '2015-01-01',
281
            guarantorid=> undef, # will be filled later
282
        },
277
        },
283
});
278
});
284
279
Lines 309-315 $patstodel = GetBorrowersToExpunge( {not_borrowed_since => '2016-01-02', patron_ Link Here
309
ok( scalar(@$patstodel) == 1 && $patstodel->[0]->{'borrowernumber'} eq $bor2inlist,'Staff patron not deleted by last issue date');
304
ok( scalar(@$patstodel) == 1 && $patstodel->[0]->{'borrowernumber'} eq $bor2inlist,'Staff patron not deleted by last issue date');
310
305
311
ModMember( borrowernumber => $bor1inlist, categorycode => 'CIVILIAN' );
306
ModMember( borrowernumber => $bor1inlist, categorycode => 'CIVILIAN' );
312
ModMember( borrowernumber => $guarantee->{borrowernumber} ,guarantorid=>$bor1inlist );
307
my $relationship = Koha::Patron::Relationship->new( { guarantor_id => $bor1inlist, guarantee_id => $guarantee->{borrowernumber} } )->store();
313
308
314
$patstodel = GetBorrowersToExpunge( {patron_list_id => $list1->patron_list_id()} );
309
$patstodel = GetBorrowersToExpunge( {patron_list_id => $list1->patron_list_id()} );
315
ok( scalar(@$patstodel)== 1 && $patstodel->[0]->{'borrowernumber'} eq $bor2inlist,'Guarantor patron not deleted from list');
310
ok( scalar(@$patstodel)== 1 && $patstodel->[0]->{'borrowernumber'} eq $bor2inlist,'Guarantor patron not deleted from list');
Lines 319-325 $patstodel = GetBorrowersToExpunge( {expired_before => '2015-01-02', patron_list Link Here
319
ok( scalar(@$patstodel) == 1 && $patstodel->[0]->{'borrowernumber'} eq $bor2inlist,'Guarantor patron not deleted by expirationdate and list');
314
ok( scalar(@$patstodel) == 1 && $patstodel->[0]->{'borrowernumber'} eq $bor2inlist,'Guarantor patron not deleted by expirationdate and list');
320
$patstodel = GetBorrowersToExpunge( {not_borrowed_since => '2016-01-02', patron_list_id => $list1->patron_list_id() } );
315
$patstodel = GetBorrowersToExpunge( {not_borrowed_since => '2016-01-02', patron_list_id => $list1->patron_list_id() } );
321
ok( scalar(@$patstodel) == 1 && $patstodel->[0]->{'borrowernumber'} eq $bor2inlist,'Guarantor patron not deleted by last issue date');
316
ok( scalar(@$patstodel) == 1 && $patstodel->[0]->{'borrowernumber'} eq $bor2inlist,'Guarantor patron not deleted by last issue date');
322
ModMember( borrowernumber => $guarantee->{borrowernumber}, guarantorid=>'' );
317
318
$relationship->delete();
323
319
324
$builder->build({
320
$builder->build({
325
        source => 'Issue',
321
        source => 'Issue',
Lines 347-355 is( scalar(@$patstodel),2,'Borrowers without issues deleted by last issue date') Link Here
347
343
348
# Test GetBorrowersToExpunge and TrackLastPatronActivity
344
# Test GetBorrowersToExpunge and TrackLastPatronActivity
349
$dbh->do(q|UPDATE borrowers SET lastseen=NULL|);
345
$dbh->do(q|UPDATE borrowers SET lastseen=NULL|);
350
$builder->build({ source => 'Borrower', value => { lastseen => '2016-01-01 01:01:01', categorycode => 'CIVILIAN', guarantorid => undef } } );
346
$builder->build({ source => 'Borrower', value => { lastseen => '2016-01-01 01:01:01', categorycode => 'CIVILIAN' } } );
351
$builder->build({ source => 'Borrower', value => { lastseen => '2016-02-02 02:02:02', categorycode => 'CIVILIAN', guarantorid => undef } } );
347
$builder->build({ source => 'Borrower', value => { lastseen => '2016-02-02 02:02:02', categorycode => 'CIVILIAN' } } );
352
$builder->build({ source => 'Borrower', value => { lastseen => '2016-03-03 03:03:03', categorycode => 'CIVILIAN', guarantorid => undef } } );
348
$builder->build({ source => 'Borrower', value => { lastseen => '2016-03-03 03:03:03', categorycode => 'CIVILIAN' } } );
353
$patstodel = GetBorrowersToExpunge( { last_seen => '1999-12-12' });
349
$patstodel = GetBorrowersToExpunge( { last_seen => '1999-12-12' });
354
is( scalar @$patstodel, 0, 'TrackLastPatronActivity - 0 patrons must be deleted' );
350
is( scalar @$patstodel, 0, 'TrackLastPatronActivity - 0 patrons must be deleted' );
355
$patstodel = GetBorrowersToExpunge( { last_seen => '2016-02-15' });
351
$patstodel = GetBorrowersToExpunge( { last_seen => '2016-02-15' });
(-)a/t/db_dependent/Patron/Relationships.t (+181 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
# This file is part of Koha.
4
#
5
# Koha is free software; you can redistribute it and/or modify it
6
# under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 3 of the License, or
8
# (at your option) any later version.
9
#
10
# Koha is distributed in the hope that it will be useful, but
11
# WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
14
#
15
# You should have received a copy of the GNU General Public License
16
# along with Koha; if not, see <http://www.gnu.org/licenses>.
17
18
use Modern::Perl;
19
20
use Test::More tests => 67;
21
22
use C4::Context;
23
24
use t::lib::TestBuilder;
25
26
BEGIN {
27
    use_ok('Koha::Objects');
28
    use_ok('Koha::Patrons');
29
    use_ok('Koha::Patron::Relationship');
30
    use_ok('Koha::Patron::Relationships');
31
}
32
33
# Start transaction
34
my $dbh = C4::Context->dbh;
35
$dbh->{AutoCommit} = 0;
36
$dbh->{RaiseError} = 1;
37
38
my $builder = t::lib::TestBuilder->new();
39
40
# Father
41
my $kyle = Koha::Patrons->find(
42
    $builder->build(
43
        {
44
            source => 'Borrower',
45
            value  => {
46
                firstname => 'Kyle',
47
                surname   => 'Hall',
48
            }
49
        }
50
    )->{borrowernumber}
51
);
52
53
# Mother
54
my $chelsea = Koha::Patrons->find(
55
    $builder->build(
56
        {
57
            source => 'Borrower',
58
            value  => {
59
                firstname => 'Chelsea',
60
                surname   => 'Hall',
61
            }
62
        }
63
    )->{borrowernumber}
64
);
65
66
# Children
67
my $daria = Koha::Patrons->find(
68
    $builder->build(
69
        {
70
            source => 'Borrower',
71
            value  => {
72
                firstname => 'Daria',
73
                surname   => 'Hall',
74
            }
75
        }
76
    )->{borrowernumber}
77
);
78
79
my $kylie = Koha::Patrons->find(
80
    $builder->build(
81
        {
82
            source => 'Borrower',
83
            value  => {
84
                firstname => 'Kylie',
85
                surname   => 'Hall',
86
            }
87
        }
88
    )->{borrowernumber}
89
);
90
91
Koha::Patron::Relationship->new({ guarantor_id => $kyle->id, guarantee_id => $daria->id, relationship => 'father' })->store();
92
Koha::Patron::Relationship->new({ guarantor_id => $kyle->id, guarantee_id => $kylie->id, relationship => 'father' })->store();
93
Koha::Patron::Relationship->new({ guarantor_id => $chelsea->id, guarantee_id => $daria->id, relationship => 'mother' })->store();
94
Koha::Patron::Relationship->new({ guarantor_id => $chelsea->id, guarantee_id => $kylie->id, relationship => 'mother' })->store();
95
Koha::Patron::Relationship->new({ firstname => 'John', surname => 'Hall', guarantee_id => $daria->id, relationship => 'grandfather' })->store();
96
Koha::Patron::Relationship->new({ firstname => 'Debra', surname => 'Hall', guarantee_id => $daria->id, relationship => 'grandmother' })->store();
97
Koha::Patron::Relationship->new({ firstname => 'John', surname => 'Hall', guarantee_id => $kylie->id, relationship => 'grandfather' })->store();
98
Koha::Patron::Relationship->new({ firstname => 'Debra', surname => 'Hall', guarantee_id => $kylie->id, relationship => 'grandmother' })->store();
99
100
my @gr;
101
102
@gr = $kyle->guarantee_relationships();
103
is( @gr, 2, 'Found 2 guarantee relationships for father' );
104
is( $gr[0]->guarantor_id, $kyle->id, 'Guarantor matches for first relationship' );
105
is( $gr[0]->guarantee_id, $daria->id, 'Guarantee matches for first relationship' );
106
is( $gr[0]->relationship, 'father', 'Relationship is father' );
107
is( ref($gr[0]->guarantee), 'Koha::Patron', 'Method guarantee returns a Koha::Patron' );
108
is( $gr[0]->guarantee->id, $daria->id, 'Koha::Patron returned is the correct guarantee' );
109
is( ref($gr[0]->guarantor), 'Koha::Patron', 'Method guarantor returns a Koha::Patron' );
110
is( $gr[0]->guarantor->id, $kyle->id, 'Koha::Patron returned is the correct guarantor' );
111
112
is( $gr[1]->guarantor_id, $kyle->id, 'Guarantor matches for first relationship' );
113
is( $gr[1]->guarantee_id, $kylie->id, 'Guarantee matches for first relationship' );
114
is( $gr[1]->relationship, 'father', 'Relationship is father' );
115
is( ref($gr[1]->guarantee), 'Koha::Patron', 'Method guarantee returns a Koha::Patron' );
116
is( $gr[1]->guarantee->id, $kylie->id, 'Koha::Patron returned is the correct guarantee' );
117
is( ref($gr[1]->guarantor), 'Koha::Patron', 'Method guarantor returns a Koha::Patron' );
118
is( $gr[1]->guarantor->id, $kyle->id, 'Koha::Patron returned is the correct guarantor' );
119
120
@gr = $chelsea->guarantee_relationships();
121
is( @gr, 2, 'Found 2 guarantee relationships for mother' );
122
is( $gr[0]->guarantor_id, $chelsea->id, 'Guarantor matches for first relationship' );
123
is( $gr[0]->guarantee_id, $daria->id, 'Guarantee matches for first relationship' );
124
is( $gr[0]->relationship, 'mother', 'Relationship is mother' );
125
is( ref($gr[0]->guarantee), 'Koha::Patron', 'Method guarantee returns a Koha::Patron' );
126
is( $gr[0]->guarantee->id, $daria->id, 'Koha::Patron returned is the correct guarantee' );
127
is( ref($gr[0]->guarantor), 'Koha::Patron', 'Method guarantor returns a Koha::Patron' );
128
is( $gr[0]->guarantor->id, $chelsea->id, 'Koha::Patron returned is the correct guarantor' );
129
130
is( $gr[1]->guarantor_id, $chelsea->id, 'Guarantor matches for first relationship' );
131
is( $gr[1]->guarantee_id, $kylie->id, 'Guarantee matches for first relationship' );
132
is( $gr[1]->relationship, 'mother', 'Relationship is mother' );
133
is( ref($gr[1]->guarantee), 'Koha::Patron', 'Method guarantee returns a Koha::Patron' );
134
is( $gr[1]->guarantee->id, $kylie->id, 'Koha::Patron returned is the correct guarantee' );
135
is( ref($gr[1]->guarantor), 'Koha::Patron', 'Method guarantor returns a Koha::Patron' );
136
is( $gr[1]->guarantor->id, $chelsea->id, 'Koha::Patron returned is the correct guarantor' );
137
138
@gr = $daria->guarantor_relationships();
139
is( @gr, 4, 'Found 4 guarantor relationships for child' );
140
is( $gr[0]->guarantor_id, $kyle->id, 'Guarantor matches for first relationship' );
141
is( $gr[0]->guarantee_id, $daria->id, 'Guarantee matches for first relationship' );
142
is( $gr[0]->relationship, 'father', 'Relationship is father' );
143
is( ref($gr[0]->guarantee), 'Koha::Patron', 'Method guarantee returns a Koha::Patron' );
144
is( $gr[0]->guarantee->id, $daria->id, 'Koha::Patron returned is the correct guarantee' );
145
is( ref($gr[0]->guarantor), 'Koha::Patron', 'Method guarantor returns a Koha::Patron' );
146
is( $gr[0]->guarantor->id, $kyle->id, 'Koha::Patron returned is the correct guarantor' );
147
148
is( $gr[1]->guarantor_id, $chelsea->id, 'Guarantor matches for first relationship' );
149
is( $gr[1]->guarantee_id, $daria->id, 'Guarantee matches for first relationship' );
150
is( $gr[1]->relationship, 'mother', 'Relationship is mother' );
151
is( ref($gr[1]->guarantee), 'Koha::Patron', 'Method guarantee returns a Koha::Patron' );
152
is( $gr[1]->guarantee->id, $daria->id, 'Koha::Patron returned is the correct guarantee' );
153
is( ref($gr[1]->guarantor), 'Koha::Patron', 'Method guarantor returns a Koha::Patron' );
154
is( $gr[1]->guarantor->id, $chelsea->id, 'Koha::Patron returned is the correct guarantor' );
155
156
is( $gr[2]->guarantor_id, undef, 'Grandfather has no id, not a Koha patron' );
157
is( $gr[2]->firstname, 'John', 'Grandfather has first name of John' );
158
is( $gr[2]->surname, 'Hall', 'Grandfather has surname of Hall' );
159
is( $gr[2]->guarantor, undef, 'Calling guarantor method for Grandfather returns undef' );
160
161
is( $gr[3]->guarantor_id, undef, 'Grandmother has no id, not a Koha patron' );
162
is( $gr[3]->firstname, 'Debra', 'Grandmother has first name of John' );
163
is( $gr[3]->surname, 'Hall', 'Grandmother has surname of Hall' );
164
is( $gr[3]->guarantor, undef, 'Calling guarantor method for Grandmother returns undef' );
165
166
my @siblings = $daria->siblings;
167
is( @siblings, 1, 'Method siblings called in list context returns list' );
168
is( ref($siblings[0]), 'Koha::Patron', 'List contains a Koha::Patron' );
169
is( $siblings[0]->firstname, 'Kylie', 'Sibling from list first name matches correctly' );
170
is( $siblings[0]->surname, 'Hall', 'Sibling from list surname matches correctly' );
171
is( $siblings[0]->id, $kylie->id, 'Sibling from list patron id matches correctly' );
172
173
my $siblings = $daria->siblings;
174
my $sibling = $siblings->next();
175
is( ref($siblings), 'Koha::Patrons', 'Calling siblings in scalar context results in a Koha::Patrons object' );
176
is( ref($sibling), 'Koha::Patron', 'Method next returns a Koha::Patron' );
177
is( $sibling->firstname, 'Kylie', 'Sibling from scalar first name matches correctly' );
178
is( $sibling->surname, 'Hall', 'Sibling from scalar surname matches correctly' );
179
is( $sibling->id, $kylie->id, 'Sibling from scalar patron id matches correctly' );
180
181
1;
(-)a/tools/import_borrowers.pl (-1 / +25 lines)
Lines 68-73 my @columnkeys = Koha::Patrons->columns(); Link Here
68
if ($extended) {
68
if ($extended) {
69
    push @columnkeys, 'patron_attributes';
69
    push @columnkeys, 'patron_attributes';
70
}
70
}
71
push( @columnkeys, qw( relationship guarantor_id  guarantor_firstname guarantor_surname ) );
71
72
72
my $input = CGI->new();
73
my $input = CGI->new();
73
our $csv  = Text::CSV->new({binary => 1});  # binary needed for non-ASCII Unicode
74
our $csv  = Text::CSV->new({binary => 1});  # binary needed for non-ASCII Unicode
Lines 258-263 if ( $uploadborrowers && length($uploadborrowers) > 0 ) { Link Here
258
            next;
259
            next;
259
        }
260
        }
260
261
262
        my $relationship        = $borrower{relationship};
263
        my $guarantor_id        = $borrower{guarantor_id};
264
        my $guarantor_firstname = $borrower{guarantor_firstname};
265
        my $guarantor_surname   = $borrower{guarantor_surname};
266
        delete $borrower{relationship};
267
        delete $borrower{guarantor_id};
268
        delete $borrower{guarantor_firstname};
269
        delete $borrower{guarantor_surname};
270
261
        if ($borrowernumber) {
271
        if ($borrowernumber) {
262
            # borrower exists
272
            # borrower exists
263
            unless ($overwrite_cardnumber) {
273
            unless ($overwrite_cardnumber) {
Lines 361-367 if ( $uploadborrowers && length($uploadborrowers) > 0 ) { Link Here
361
                $template->param('lastinvalid'=>$borrower{'surname'}.' / AddMember');
371
                $template->param('lastinvalid'=>$borrower{'surname'}.' / AddMember');
362
            }
372
            }
363
        }
373
        }
374
375
        # Add a guarantor if we are given a relationship
376
        if ( $relationship ) {
377
            $guarantor_id ||= undef;
378
            Koha::Patron::Relationship->new(
379
                {
380
                    guarantee_id => $borrowernumber,
381
                    relationship => $relationship,
382
                    guarantor_id => $guarantor_id,
383
                    firstname    => $guarantor_firstname,
384
                    surname      => $guarantor_surname,
385
                }
386
            )->store();
387
        }
364
    }
388
    }
389
365
    (@errors  ) and $template->param(  ERRORS=>\@errors  );
390
    (@errors  ) and $template->param(  ERRORS=>\@errors  );
366
    (@feedback) and $template->param(FEEDBACK=>\@feedback);
391
    (@feedback) and $template->param(FEEDBACK=>\@feedback);
367
    $template->param(
392
    $template->param(
368
- 

Return to bug 14570