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

(-)a/C4/Circulation.pm (-1 / +1 lines)
Lines 767-773 sub CanBookBeIssued { Link Here
767
    $no_issues_charge_guarantees = undef unless looks_like_number( $no_issues_charge_guarantees );
767
    $no_issues_charge_guarantees = undef unless looks_like_number( $no_issues_charge_guarantees );
768
    if ( defined $no_issues_charge_guarantees ) {
768
    if ( defined $no_issues_charge_guarantees ) {
769
        my $p = Koha::Patrons->find( $borrower->{borrowernumber} );
769
        my $p = Koha::Patrons->find( $borrower->{borrowernumber} );
770
        my @guarantees = $p->guarantees();
770
        my @guarantees = map { $_->guarantee } $p->guarantee_relationships();
771
        my $guarantees_non_issues_charges;
771
        my $guarantees_non_issues_charges;
772
        foreach my $g ( @guarantees ) {
772
        foreach my $g ( @guarantees ) {
773
            my ( $b, $n, $o ) = C4::Members::GetMemberAccountBalance( $g->id );
773
            my ( $b, $n, $o ) = C4::Members::GetMemberAccountBalance( $g->id );
(-)a/C4/Members.pm (-7 / +7 lines)
Lines 209-215 sub patronflags { Link Here
209
    $no_issues_charge_guarantees = undef unless looks_like_number( $no_issues_charge_guarantees );
209
    $no_issues_charge_guarantees = undef unless looks_like_number( $no_issues_charge_guarantees );
210
    if ( defined $no_issues_charge_guarantees ) {
210
    if ( defined $no_issues_charge_guarantees ) {
211
        my $p = Koha::Patrons->find( $patroninformation->{borrowernumber} );
211
        my $p = Koha::Patrons->find( $patroninformation->{borrowernumber} );
212
        my @guarantees = $p->guarantees();
212
        my @guarantees = map { $_->guarantee } $p->guarantee_relationships;
213
        my $guarantees_non_issues_charges;
213
        my $guarantees_non_issues_charges;
214
        foreach my $g ( @guarantees ) {
214
        foreach my $g ( @guarantees ) {
215
            my ( $b, $n, $o ) = C4::Members::GetMemberAccountBalance( $g->id );
215
            my ( $b, $n, $o ) = C4::Members::GetMemberAccountBalance( $g->id );
Lines 1095-1112 sub GetBorrowersToExpunge { Link Here
1095
        FROM   borrowers
1095
        FROM   borrowers
1096
        JOIN   categories USING (categorycode)
1096
        JOIN   categories USING (categorycode)
1097
        LEFT JOIN (
1097
        LEFT JOIN (
1098
            SELECT guarantorid
1098
            SELECT guarantor_id
1099
            FROM borrowers
1099
            FROM relationships
1100
            WHERE guarantorid IS NOT NULL
1100
            WHERE guarantor_id IS NOT NULL
1101
                AND guarantorid <> 0
1101
                AND guarantor_id <> 0
1102
        ) as tmp ON borrowers.borrowernumber=tmp.guarantorid
1102
        ) as tmp ON borrowers.borrowernumber=tmp.guarantor_id
1103
        LEFT JOIN old_issues USING (borrowernumber)
1103
        LEFT JOIN old_issues USING (borrowernumber)
1104
        LEFT JOIN issues USING (borrowernumber)|;
1104
        LEFT JOIN issues USING (borrowernumber)|;
1105
    if ( $filterpatronlist  ){
1105
    if ( $filterpatronlist  ){
1106
        $query .= q| LEFT JOIN patron_list_patrons USING (borrowernumber)|;
1106
        $query .= q| LEFT JOIN patron_list_patrons USING (borrowernumber)|;
1107
    }
1107
    }
1108
    $query .= q| WHERE  category_type <> 'S'
1108
    $query .= q| WHERE  category_type <> 'S'
1109
        AND tmp.guarantorid IS NULL
1109
        AND tmp.guarantor_id IS NULL
1110
   |;
1110
   |;
1111
    my @query_params;
1111
    my @query_params;
1112
    if ( $filterbranch && $filterbranch ne "" ) {
1112
    if ( $filterbranch && $filterbranch ne "" ) {
(-)a/Koha/Item.pm (+11 lines)
Lines 26-31 use Koha::Database; Link Here
26
use C4::Context;
26
use C4::Context;
27
use Koha::IssuingRules;
27
use Koha::IssuingRules;
28
use Koha::Item::Transfer;
28
use Koha::Item::Transfer;
29
use Koha::Biblios;
29
use Koha::Patrons;
30
use Koha::Patrons;
30
use Koha::Libraries;
31
use Koha::Libraries;
31
32
Lines 170-175 sub article_request_type { Link Here
170
    return $issuing_rule->article_requests || q{}
171
    return $issuing_rule->article_requests || q{}
171
}
172
}
172
173
174
=head3 biblio
175
176
=cut
177
178
sub biblio {
179
    my ( $self ) = @_;
180
181
    return Koha::Biblios->find( $self->biblionumber );
182
}
183
173
=head3 type
184
=head3 type
174
185
175
=cut
186
=cut
(-)a/Koha/Object.pm (-2 / +6 lines)
Lines 68-75 sub new { Link Here
68
            next if not exists $attributes->{$column_name} or defined $attributes->{$column_name};
68
            next if not exists $attributes->{$column_name} or defined $attributes->{$column_name};
69
            delete $attributes->{$column_name};
69
            delete $attributes->{$column_name};
70
        }
70
        }
71
        $self->{_result} = $schema->resultset( $class->_type() )
71
72
          ->new($attributes);
72
        eval {
73
            $self->{_result} =
74
              $schema->resultset( $class->_type() )->new($attributes);
75
        };
76
        Carp::cluck("ERROR: $@") if $@;
73
    }
77
    }
74
78
75
    croak("No _type found! Koha::Object must be subclassed!")
79
    croak("No _type found! Koha::Object must be subclassed!")
(-)a/Koha/Patron.pm (-30 / +58 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
39
39
use base qw(Koha::Object);
40
use base qw(Koha::Object);
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 checkouts
122
123
=cut
124
125
sub checkouts {
125
    my ( $self ) = @_;
126
    my ( $self ) = @_;
126
127
127
    return Koha::Patron::Images->find( $self->borrowernumber );
128
    return Koha::Checkouts->search( { borrowernumber => $self->id } );
128
}
129
}
129
130
131
=head3 library
132
133
=cut
134
130
sub library {
135
sub library {
131
    my ( $self ) = @_;
136
    my ( $self ) = @_;
132
    return Koha::Library->_new_from_dbic($self->_result->branchcode);
137
    return Koha::Library->_new_from_dbic($self->_result->branchcode);
133
}
138
}
134
139
135
=head3 guarantees
140
=head3 guarantor_relationships
141
142
Returns Koha::Patron::Relationships object for this patron's guarantors
136
143
137
Returns the guarantees (list of Koha::Patron) of this patron
144
Returns the set of relationships for the patrons that are guarantors for this patron.
145
146
This is returned instead of a Koha::Patron object because the guarantor
147
may not exist as a patron in Koha. If this is true, the guarantors name
148
exists in the Koha::Patron::Relationship object and will have no guarantor_id.
138
149
139
=cut
150
=cut
140
151
141
sub guarantees {
152
sub guarantor_relationships {
142
    my ( $self ) = @_;
153
    my ($self) = @_;
143
154
144
    return Koha::Patrons->search( { guarantorid => $self->borrowernumber } );
155
    return Koha::Patron::Relationships->search( { guarantee_id => $self->id } );
156
}
157
158
=head3 guarantee_relationships
159
160
Returns Koha::Patron::Relationships object for this patron's guarantors
161
162
Returns the set of relationships for the patrons that are guarantees for this patron.
163
164
The method returns Koha::Patron::Relationship objects for the sake
165
of consistency with the guantors method.
166
A guarantee by definition must exist as a patron in Koha.
167
168
=cut
169
170
sub guarantee_relationships {
171
    my ($self) = @_;
172
173
    return Koha::Patron::Relationships->search( { guarantor_id => $self->id } );
145
}
174
}
146
175
147
=head3 housebound_profile
176
=head3 housebound_profile
Lines 179-201 Returns the siblings of this patron. Link Here
179
=cut
208
=cut
180
209
181
sub siblings {
210
sub siblings {
182
    my ( $self ) = @_;
211
    my ($self) = @_;
183
212
184
    my $guarantor = $self->guarantor;
213
    my @guarantors = $self->guarantor_relationships()->guarantors();
185
214
186
    return unless $guarantor;
215
    return unless @guarantors;
187
216
188
    return Koha::Patrons->search(
217
    my @siblings =
189
        {
218
      map { $_->guarantee_relationships()->guarantees() } @guarantors;
190
            guarantorid => {
219
191
                '!=' => undef,
220
    return unless @siblings;
192
                '=' => $guarantor->id,
221
193
            },
222
    my %seen;
194
            borrowernumber => {
223
    @siblings =
195
                '!=' => $self->borrowernumber,
224
      grep { !$seen{ $_->id }++ && ( $_->id != $self->id ) } @siblings;
196
            }
225
197
        }
226
    return wantarray ? @siblings : Koha::Patrons->search( { borrowernumber => { -in => [ map { $_->id } @siblings ] } } );
198
    );
199
}
227
}
200
228
201
=head3 wants_check_for_previous_checkout
229
=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 (-6 / +5 lines)
Lines 585-596 my $view = $batch Link Here
585
585
586
my @relatives;
586
my @relatives;
587
if ( $borrowernumber ) {
587
if ( $borrowernumber ) {
588
    if ( $patron ) {
588
    if ( my $patron = Koha::Patrons->find( $borrower->{borrowernumber} ) ) {
589
        if ( my $guarantor = $patron->guarantor ) {
589
        if ( my @guarantors = $patron->guarantor_relationships()->guarantors() ) {
590
            push @relatives, $guarantor->borrowernumber;
590
            push( @relatives, $_->id ) for @guarantors;
591
            push @relatives, $_->borrowernumber for $patron->siblings;
591
            push( @relatives, $_->id ) for $patron->siblings();
592
        } else {
592
        } else {
593
            push @relatives, $_->borrowernumber for $patron->guarantees;
593
            push( @relatives, $_->id ) for $patron->guarantee_relationships()->guarantees();
594
        }
594
        }
595
    }
595
    }
596
}
596
}
Lines 639-645 $template->param( Link Here
639
    AudioAlerts           => C4::Context->preference("AudioAlerts"),
639
    AudioAlerts           => C4::Context->preference("AudioAlerts"),
640
    fast_cataloging   => $fast_cataloging,
640
    fast_cataloging   => $fast_cataloging,
641
    CircAutoPrintQuickSlip   => C4::Context->preference("CircAutoPrintQuickSlip"),
641
    CircAutoPrintQuickSlip   => C4::Context->preference("CircAutoPrintQuickSlip"),
642
    activeBorrowerRelationship => (C4::Context->preference('borrowerRelationship') ne ''),
643
    SuspendHoldsIntranet => C4::Context->preference('SuspendHoldsIntranet'),
642
    SuspendHoldsIntranet => C4::Context->preference('SuspendHoldsIntranet'),
644
    AutoResumeSuspendedHolds => C4::Context->preference('AutoResumeSuspendedHolds'),
643
    AutoResumeSuspendedHolds => C4::Context->preference('AutoResumeSuspendedHolds'),
645
    RoutingSerials => C4::Context->preference('RoutingSerials'),
644
    RoutingSerials => C4::Context->preference('RoutingSerials'),
(-)a/installer/data/mysql/atomicupdate/bug_14560.sql (+18 lines)
Line 0 Link Here
1
DROP TABLE IF EXISTS relationships;
2
CREATE TABLE `relationships` (
3
      id INT(11) NOT NULL AUTO_INCREMENT,
4
      guarantor_id INT(11) NULL DEFAULT NULL,
5
      guarantee_id INT(11) NOT NULL,
6
      relationship VARCHAR(100) COLLATE utf8_unicode_ci NOT NULL,
7
      surname MEDIUMTEXT COLLATE utf8_unicode_ci NULL DEFAULT NULL,
8
      firstname MEDIUMTEXT COLLATE utf8_unicode_ci NULL DEFAULT NULL,
9
      PRIMARY KEY (id),
10
      CONSTRAINT r_guarantor FOREIGN KEY ( guarantor_id ) REFERENCES borrowers ( borrowernumber ) ON UPDATE CASCADE ON DELETE CASCADE,
11
      CONSTRAINT r_guarantee FOREIGN KEY ( guarantee_id ) REFERENCES borrowers ( borrowernumber ) ON UPDATE CASCADE ON DELETE CASCADE
12
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
13
14
UPDATE borrowers LEFT JOIN borrowers guarantor ON ( borrowers.guarantorid = guarantor.borrowernumber ) SET borrowers.guarantorid = NULL WHERE guarantor.borrowernumber IS NULL;
15
16
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 != "";
17
18
ALTER TABLE borrowers DROP guarantorid, DROP relationship, DROP contactname, DROP contactfirstname, DROP contacttitle;
(-)a/installer/data/mysql/kohastructure.sql (-16 / +17 lines)
Lines 602-613 CREATE TABLE `deletedborrowers` ( -- stores data related to the patrons/borrower Link Here
602
  `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
602
  `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
603
  `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 (YYY-MM-DD)
603
  `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 (YYY-MM-DD)
604
  `debarredcomment` VARCHAR(255) DEFAULT NULL, -- comment on the stop of patron
604
  `debarredcomment` VARCHAR(255) DEFAULT NULL, -- comment on the stop of patron
605
  `contactname` mediumtext, -- used for children and profesionals to include surname or last name of guarentor or organization name
606
  `contactfirstname` text, -- used for children to include first name of guarentor
607
  `contacttitle` text, -- used for children to include title (Mr., Mrs., etc) of guarentor
608
  `guarantorid` int(11) default NULL, -- borrowernumber used for children or professionals to link them to guarentors or organizations
609
  `borrowernotes` mediumtext, -- a note on the patron/borrower's account that is only visible in the staff client
605
  `borrowernotes` mediumtext, -- a note on the patron/borrower's account that is only visible in the staff client
610
  `relationship` varchar(100) default NULL, -- used for children to include the relationship to their guarentor
611
  `sex` varchar(1) default NULL, -- patron/borrower's gender
606
  `sex` varchar(1) default NULL, -- patron/borrower's gender
612
  `password` varchar(60) default NULL, -- patron/borrower's encrypted password
607
  `password` varchar(60) default NULL, -- patron/borrower's encrypted password
613
  `flags` int(11) default NULL, -- will include a number associated with the staff member's permissions
608
  `flags` int(11) default NULL, -- will include a number associated with the staff member's permissions
Lines 1625-1636 CREATE TABLE `borrowers` ( -- this table includes information about your patrons Link Here
1625
  `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
1620
  `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
1626
  `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 (YYY-MM-DD)
1621
  `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 (YYY-MM-DD)
1627
  `debarredcomment` VARCHAR(255) DEFAULT NULL, -- comment on the stop of the patron
1622
  `debarredcomment` VARCHAR(255) DEFAULT NULL, -- comment on the stop of the patron
1628
  `contactname` mediumtext, -- used for children and profesionals to include surname or last name of guarentor or organization name
1629
  `contactfirstname` text, -- used for children to include first name of guarentor
1630
  `contacttitle` text, -- used for children to include title (Mr., Mrs., etc) of guarentor
1631
  `guarantorid` int(11) default NULL, -- borrowernumber used for children or professionals to link them to guarentors or organizations
1632
  `borrowernotes` mediumtext, -- a note on the patron/borrower's account that is only visible in the staff client
1623
  `borrowernotes` mediumtext, -- a note on the patron/borrower's account that is only visible in the staff client
1633
  `relationship` varchar(100) default NULL, -- used for children to include the relationship to their guarentor
1634
  `sex` varchar(1) default NULL, -- patron/borrower's gender
1624
  `sex` varchar(1) default NULL, -- patron/borrower's gender
1635
  `password` varchar(60) default NULL, -- patron/borrower's encrypted password
1625
  `password` varchar(60) default NULL, -- patron/borrower's encrypted password
1636
  `flags` int(11) default NULL, -- will include a number associated with the staff member's permissions
1626
  `flags` int(11) default NULL, -- will include a number associated with the staff member's permissions
Lines 1660-1666 CREATE TABLE `borrowers` ( -- this table includes information about your patrons Link Here
1660
  KEY `categorycode` (`categorycode`),
1650
  KEY `categorycode` (`categorycode`),
1661
  KEY `branchcode` (`branchcode`),
1651
  KEY `branchcode` (`branchcode`),
1662
  UNIQUE KEY `userid` (`userid`),
1652
  UNIQUE KEY `userid` (`userid`),
1663
  KEY `guarantorid` (`guarantorid`),
1664
  KEY `surname_idx` (`surname`(255)),
1653
  KEY `surname_idx` (`surname`(255)),
1665
  KEY `firstname_idx` (`firstname`(255)),
1654
  KEY `firstname_idx` (`firstname`(255)),
1666
  KEY `othernames_idx` (`othernames`(255)),
1655
  KEY `othernames_idx` (`othernames`(255)),
Lines 3399-3410 CREATE TABLE IF NOT EXISTS `borrower_modifications` ( Link Here
3399
  `lost` tinyint(1) DEFAULT NULL,
3388
  `lost` tinyint(1) DEFAULT NULL,
3400
  `debarred` date DEFAULT NULL,
3389
  `debarred` date DEFAULT NULL,
3401
  `debarredcomment` varchar(255) DEFAULT NULL,
3390
  `debarredcomment` varchar(255) DEFAULT NULL,
3402
  `contactname` mediumtext,
3403
  `contactfirstname` text,
3404
  `contacttitle` text,
3405
  `guarantorid` int(11) DEFAULT NULL,
3406
  `borrowernotes` mediumtext,
3391
  `borrowernotes` mediumtext,
3407
  `relationship` varchar(100) DEFAULT NULL,
3408
  `sex` varchar(1) DEFAULT NULL,
3392
  `sex` varchar(1) DEFAULT NULL,
3409
  `password` varchar(30) DEFAULT NULL,
3393
  `password` varchar(30) DEFAULT NULL,
3410
  `flags` int(11) DEFAULT NULL,
3394
  `flags` int(11) DEFAULT NULL,
Lines 3922-3927 CREATE TABLE `article_requests` ( Link Here
3922
  CONSTRAINT `article_requests_ibfk_4` FOREIGN KEY (`branchcode`) REFERENCES `branches` (`branchcode`) ON DELETE SET NULL ON UPDATE CASCADE
3906
  CONSTRAINT `article_requests_ibfk_4` FOREIGN KEY (`branchcode`) REFERENCES `branches` (`branchcode`) ON DELETE SET NULL ON UPDATE CASCADE
3923
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
3907
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
3924
3908
3909
--
3910
-- Table structure for table 'guarantors_guarantees'
3911
--
3912
3913
DROP TABLE IF EXISTS relationships;
3914
CREATE TABLE `relationships` (
3915
      id INT(11) NOT NULL AUTO_INCREMENT,
3916
      guarantor_id INT(11) NULL DEFAULT NULL,
3917
      guarantee_id INT(11) NOT NULL,
3918
      relationship VARCHAR(100) COLLATE utf8_unicode_ci NOT NULL,
3919
      surname MEDIUMTEXT COLLATE utf8_unicode_ci NULL DEFAULT NULL,
3920
      firstname MEDIUMTEXT COLLATE utf8_unicode_ci NULL DEFAULT NULL,
3921
      PRIMARY KEY (id),
3922
      CONSTRAINT r_guarantor FOREIGN KEY ( guarantor_id ) REFERENCES borrowers ( borrowernumber ) ON UPDATE CASCADE ON DELETE CASCADE,
3923
      CONSTRAINT r_guarantee FOREIGN KEY ( guarantee_id ) REFERENCES borrowers ( borrowernumber ) ON UPDATE CASCADE ON DELETE CASCADE
3924
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
3925
3925
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
3926
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
3926
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
3927
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
3927
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
3928
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
(-)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 (-7 / +4 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-small" 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-small" 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-small" 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 activeBorrowerRelationship ) %]
142
        [% IF ( adultborrower AND Koha.Preference('borrowerRelationship') ) %]
146
            <a id="addchild" class="btn btn-small" 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-small" 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-small" 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-small" 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 888-894 No patron matched <span class="ex">[% message | html %]</span> Link Here
888
    </li>
888
    </li>
889
889
890
    [% IF relatives_issues_count %]
890
    [% IF relatives_issues_count %]
891
        <li><a id="relatives-issues-tab" href="#relatives-issues">Relatives' checkouts</a></li>
891
        <li><a id="relatives-issues-tab" href="#relatives-issues">[% relatives_issues_count %] Relatives' checkouts</a></li>
892
    [% END %]
892
    [% END %]
893
893
894
    <li>
894
    <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 383-488 $(document).ready(function() { Link Here
383
	</fieldset>
392
	</fieldset>
384
[% END # hide fieldset %]
393
[% END # hide fieldset %]
385
394
386
[% IF ( showguarantor ) %]
395
[% IF show_guarantor || guarantor %]
387
    <input type="hidden" id="guarantorid" name="guarantorid"   value="[% guarantorid %]" />
396
    [% SET possible_relationships = Koha.Preference('borrowerRelationship') %]
388
    [% UNLESS step_6 %]
397
    <fieldset class="rows">
389
        <input type="hidden" name="branchcode" value="[% branchcode %]" />
398
        <legend>Guarantor information</legend>
390
    [% END %]
399
391
    <fieldset id="memberentry_guarantor" class="rows">
400
        <span id="guarantor_relationships">
392
        <legend id="guarantor_lgd">Guarantor information</legend>
401
            [% FOREACH r IN relationships %]
393
        <ol>
402
                <fieldset class="rows">
394
[% IF ( P ) %]
403
                    <ol>
395
	        [% IF ( guarantorid ) %]
404
                        [% IF catetory_type == 'P' %]
396
	        <li id="contact-details">
405
                            [% IF ( r.guarantor_id ) %]
397
	        [% ELSE %]
406
                                <li id="contact-details">
398
	        <li id="contact-details" style="display: none">
407
                            [% ELSE %]
399
	        [% END %]
408
                                <li id="contact-details" style="display: none">
400
	            <span class="label">Organization #:</span> [% IF ( guarantorid ) %] <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% guarantorid %]" target="blank">[% guarantorid %]</a>[% END %]
409
                            [% END %]
401
	        </li>
410
                                <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 %]
402
	        <li>
411
                            </li>
403
	            <label for="contactname">Organization name: </label>
412
404
	            [% IF ( guarantorid ) %]
413
                            <li>
405
	            <span>[% contactname %]</span>
414
                                <label for="guarantor_surname">Organization name: </label>
406
	            <input name="contactname" id="contactname" type="hidden" size="20" value="[% contactname | html %]" />
415
                                [% IF ( r.guarantor_id ) %]
407
	            [% ELSE %]
416
                                    <span>[% r.guarantor.surname %]</span>
408
                    <input name="contactname" id="contactname" type="text" size="20" value="[% contactname | html %]" />
417
                                [% END %]
409
	            [% END %]
418
                            </li>
410
	        </li>
419
                        [% ELSE %]
411
[% ELSE %]
420
                            [% IF category_type == 'C'  %]
412
 [% IF ( C ) %]
421
                                [% IF ( r.guarantor_id ) %]
413
 [% IF ( guarantorid ) %]
422
                                    <li id="contact-details">
414
 <li id="contact-details">
423
                                [% ELSE %]
415
 [% ELSE %]
424
                                    <li id="contact-details" style="display: none">
416
 <li id="contact-details" style="display: none">
425
                                [% END %]
417
 [% END %]
426
418
     <span class="label">Patron #:</span> [% IF ( guarantorid ) %] <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% guarantorid %]" target="blank">[% guarantorid %]</a>[% END %]
427
                                    <span class="label">Patron #:</span>
419
 </li>
428
                                    [% IF ( r.guarantor_id ) %]
420
        [% UNLESS nocontactname %]
429
                                        <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% r.guarantor_id %]" target="blank">[% r.guarantor_id %]</a>
421
 <li>
430
                                    [% END %]
422
     <label for="contactname">Surname: </label>
431
423
     [% IF ( guarantorid ) %]
432
                                </li>
424
     <span>[% contactname %]</span>
433
425
     <input name="contactname" id="contactname" type="hidden" size="20" value="[% contactname | html %]" />
434
                                [% IF r.surname || r.guarantor.surname %]
426
     [% ELSE %]
435
                                    <li>
427
        <input name="contactname" id="contactname" type="text" size="20" value="[% contactname | html %]" />
436
                                        <label for="guarantor_surname">Surname: </label>
428
     [% END %]
437
                                        <span>[% r.surname || r.guarantor.surname %]</span>
429
 </li>
438
                                    </li>
430
        [% END %]
439
                                [% END %]
431
        [% UNLESS nocontactfirstname %]
440
432
 <li>
441
                                [% IF r.firstname || r.guarantor.firstname  %]
433
     <label for="contactfirstname">First name: </label>
442
                                    <li>
434
     [% IF ( guarantorid ) %]
443
                                        <label for="guarantor_firstname">First name: </label>
435
     <span>[% contactfirstname %]</span>
444
                                        <span>[% r.firstname || r.guarantor.firstname %]</span>
436
     <input name="contactfirstname" id="contactfirstname" type="hidden" size="20" value="[% contactfirstname | html %]" />
445
                                    </li>
437
     [% ELSE %]
446
                                [% END %]
438
        <input name="contactfirstname" id="contactfirstname" type="text" size="20" value="[% contactfirstname | html %]" />
447
439
     [% END %]
448
                                <li>
440
 </li>
449
                                    <label for="relationship">Relationship: </label>
441
        [% END %]
450
                                    <span>[% r.relationship %]</span>
442
 [% IF ( relshiploop ) %]
451
                                </li>
443
 <li>
452
444
     <label for="relationship">Relationship: </label>
453
                                <li>
445
     <select name="relationship" id="relationship" >
454
                                    <label for="delete_guarantor">Delete: </label>
446
         [% FOREACH relshiploo IN relshiploop %]
455
                                    <input type="checkbox" name="delete_guarantor" value="[% r.id %]" />
447
         [% IF ( relshiploo.selected ) %]
456
                                </li>
448
         <option value="[% relshiploo.relationship %]" selected="selected" >[% relshiploo.relationship %]</option>
457
                            [% END %]
449
         [% ELSE %]
458
                        [% END %]
450
         <option value="[% relshiploo.relationship %]">[% relshiploo.relationship %]</option>
459
                    </ol>
451
         [% END %]
460
                </fieldset>
452
         [% END %]
461
            [% END # END relationships foreach %]
453
     </select>
462
        </span>
454
 </li>
463
455
 [% END %]
464
        <fieldset class="rows guarantor" id="guarantor_template">
456
 [% END %]
465
            <ol>
457
[% END %]
466
                <li class="guarantor_id">
458
        <li>
467
                    <span class="label">Patron #:</span>
459
            <span class="label">&nbsp;</span>
468
                    <span class="new_guarantor_id_text"></span>
460
            [% IF ( guarantorid ) %]
469
                    <input type="hidden" class="new_guarantor_id" name="new_guarantor_id" value=""/>
461
            <input id="guarantorsearch" type="button" value="Change" onclick="Dopopguarantor('guarantor_search.pl');" />
470
                </li>
462
            [% ELSE %]
471
463
            <input id="guarantorsearch" type="button" value="Set to patron" onclick="Dopopguarantor('guarantor_search.pl');" />
472
                <li>
464
            [% END %]
473
                    <label for="guarantor_surname">Surname: </label>
465
            <input id="guarantordelete" type="button" value="Delete" />
474
                    <span class="new_guarantor_surname_text"></span>
466
        </li>
475
                    <input type="hidden" class="new_guarantor_surname" name="new_guarantor_surname" value=""/>
467
    [% IF guarantorid && Koha.Preference('AllowStaffToSetCheckoutsVisibilityForGuarantor') %]
476
                </li>
468
        <li>
477
469
            <label for="privacy_guarantor_checkouts">Show checkouts to guarantor</label>
478
                <li>
470
            <select name="privacy_guarantor_checkouts" id="privacy_guarantor_checkouts">
479
                    <label for="guarantor_firstname">First name: </label>
471
                [% IF privacy_guarantor_checkouts %]
480
                    <span class="new_guarantor_firstname_text"></span>
472
                    <option value="0">No</option>
481
                    <input type="hidden" class="new_guarantor_firstname" name="new_guarantor_firstname" value=""/>
473
                    <option value="1" selected>Yes</option>
482
                </li>
483
484
                <li>
485
                    <label for="guarantor_relationship">Relationship: </label>
486
                    <select class="new_guarantor_relationship" name="new_guarantor_relationship">
487
                        [% FOREACH pr IN possible_relationships.split('\|') %]
488
                            <option value="[% pr %]">[% pr %]</option>
489
                        [% END %]
490
                    </select>
491
                </li>
492
493
                <li>
494
                    <label for="guarantor_cancel">&nbsp;</label>
495
                    <span><a href="#" class="guarantor_cancel">Cancel</a></span>
496
                </li>
497
            </ol>
498
        </fieldset>
499
500
        <fieldset class="rows">
501
            <legend>Add new guarantor</legend>
502
            <ol>
503
                <input type="hidden" id="guarantor_id" value=""/>
504
505
                [% IF catetory_type == 'P' %]
506
                    <li>
507
                        <label for="guarantor_surname">Organization name: </label>
508
                        <input name="guarantor_surname" id="guarantor_surname" type="hidden" size="20"/>
509
                    </li>
474
                [% ELSE %]
510
                [% ELSE %]
475
                    <option value="0" selected>No</option>
511
                    <li>
476
                    <option value="1">Yes</option>
512
                        <label for="guarantor_surname">Surname: </label>
513
                        <input name="guarantor_surname" id="guarantor_surname" type="text" size="20" />
514
                    </li>
515
516
                    <li>
517
                        <label for="guarantor_firstname">First name: </label>
518
                        <input name="guarantor_firstname" id="guarantor_firstname" type="text" size="20" />
519
                    </li>
520
521
                    [% IF ( possible_relationships ) %]
522
                        <li>
523
                            <label for="relationship">Relationship: </label>
524
                            <select name="relationship" id="relationship" >
525
                                [% FOREACH pr IN possible_relationships.split('\|') %]
526
                                    <option value="[% pr %]">[% pr %]</option>
527
                                [% END %]
528
                            </select>
529
                        </li>
530
                    [% END %]
477
                [% END %]
531
                [% END %]
478
            </select>
479
            <div class="hint">Allow guarantor of this patron to view this patron's checkouts from the OPAC</div>
480
        </li>
481
    [% END %]
482
        </ol>
483
    </fieldset>
484
532
533
                <li>
534
                    <span class="label">&nbsp;</span>
535
                    <a href="#" id="guarantor_add" class="btn btn-small"><i class="fa fa-plus"></i> Add guarantor</a>
536
                    <a href="#" id="guarantor_search" class="btn btn-small"><i class="fa fa-search"></i> Set to patron</a>
537
                    <a href="#" id="guarantor_clear">Clear</a>
538
                </li>
539
540
                [% IF relationships && Koha.Preference('AllowStaffToSetCheckoutsVisibilityForGuarantor') %]
541
                    <li>
542
                        <label for="privacy_guarantor_checkouts">Show checkouts to guarantors</label>
543
                        <select name="privacy_guarantor_checkouts" id="privacy_guarantor_checkouts">
544
                            [% IF privacy_guarantor_checkouts %]
545
                                <option value="0">No</option>
546
                                <option value="1" selected>Yes</option>
547
                            [% ELSE %]
548
                                <option value="0" selected>No</option>
549
                                <option value="1">Yes</option>
550
                            [% END %]
551
                        </select>
552
                        <div class="hint">Allow guarantors of this patron to view this patron's checkouts from the OPAC</div>
553
                    </li>
554
                [% END %]
555
            </ol>
556
        </fieldset>
557
    </fieldset>
485
[% END %]
558
[% END %]
559
560
486
[% UNLESS noaddress && noaddress2 && nocity && nostate && nozipcode && nocountry %]
561
[% UNLESS noaddress && noaddress2 && nocity && nostate && nozipcode && nocountry %]
487
    [% IF Koha.Preference( 'AddressFormat' ) %]
562
    [% IF Koha.Preference( 'AddressFormat' ) %]
488
        [% INCLUDE "member-main-address-style-${ Koha.Preference( 'AddressFormat' ) }.inc" %]
563
        [% 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 255-279 function validate1(date) { Link Here
255
                [% END %]
255
                [% END %]
256
            </ul>
256
            </ul>
257
        </li>
257
        </li>
258
    [% ELSIF guarantor %]
258
    [% ELSIF guarantor_relationships %]
259
        <li>
259
        [% FOREACH gr IN guarantor_relationships %]
260
            <span class="label">Guarantor:</span>
260
            <li>
261
            [% IF guarantor.borrowernumber %]
261
                <span class="label">Guarantor:</span>
262
                <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% guarantor.borrowernumber %]">[% guarantor.firstname | html %] [% guarantor.surname | html %]</a>
262
                [% IF gr.guarantor_id %]
263
            [% ELSE %]
263
                    [% SET guarantor = gr.guarantor %]
264
                [% guarantor.firstname | html %] [% guarantor.surname | html %]
264
                    <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% guarantor.id %]">[% guarantor.firstname %] [% guarantor.surname %]</a>
265
            [% END %]
265
                [% ELSE %]
266
        </li>
266
                    [% gr.firstname %] [% gr.surname %]
267
                [% END %]
268
            </li>
269
        [% END %]
267
    [% END %]
270
    [% END %]
268
</ol>
271
</ol>
269
</div>
272
</div>
270
      <div class="action">
271
        [% IF ( guarantor.borrowernumber ) %]
272
        <a href="memberentry.pl?op=modify&amp;borrowernumber=[% borrowernumber %]&amp;step=1&amp;guarantorid=[% guarantor.borrowernumber %]">Edit</a>
273
        [% ELSE %]
274
        <a href="memberentry.pl?op=modify&amp;borrowernumber=[% borrowernumber %]&amp;step=1">Edit</a>
275
        [% END %]</div>
276
277
</div>
273
</div>
278
274
279
<!-- Begin Upload Patron Image Section -->
275
<!-- Begin Upload Patron Image Section -->
Lines 499-505 function validate1(date) { Link Here
499
    <ul>
495
    <ul>
500
        <li><a href="#checkouts">[% issuecount %] Checkout(s)</a></li>
496
        <li><a href="#checkouts">[% issuecount %] Checkout(s)</a></li>
501
        [% IF relatives_issues_count %]
497
        [% IF relatives_issues_count %]
502
            <li><a href="#relatives-issues" id="relatives-issues-tab">Relatives' checkouts</a></li>
498
            <li><a href="#relatives-issues" id="relatives-issues-tab">[% relatives_issues_count %] Relatives' checkouts</a></li>
503
        [% END %]
499
        [% END %]
504
        <li><a href="#finesandcharges">Fines &amp; Charges</a></li>
500
        <li><a href="#finesandcharges">Fines &amp; Charges</a></li>
505
        <li>
501
        <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
    $("#select_city").change(function(){
311
    $("#select_city").change(function(){
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-memberentry.tt (-2 / +7 lines)
Lines 89-95 Link Here
89
                    <div class="alert">You typed in the wrong characters in the box before submitting. Please try again.</div>
89
                    <div class="alert">You typed in the wrong characters in the box before submitting. Please try again.</div>
90
                [% END %]
90
                [% END %]
91
91
92
                [% IF borrower.guarantorid && !Koha.Preference('OPACPrivacy') && Koha.Preference('AllowPatronToSetCheckoutsVisibilityForGuarantor') %]
92
                [% IF patron.guarantor_relationships && !Koha.Preference('OPACPrivacy') && Koha.Preference('AllowPatronToSetCheckoutsVisibilityForGuarantor') %]
93
                    <fieldset class="rows" id="memberentry_privacy">
93
                    <fieldset class="rows" id="memberentry_privacy">
94
                        <legend id="privacy_legend">Privacy</legend>
94
                        <legend id="privacy_legend">Privacy</legend>
95
                        <ol>
95
                        <ol>
Lines 108-114 Link Here
108
                                    <span id="update_privacy_guarantor_checkouts_message" class="alert" style="display:none"></span>
108
                                    <span id="update_privacy_guarantor_checkouts_message" class="alert" style="display:none"></span>
109
                                </span>
109
                                </span>
110
                                <span class="hint">
110
                                <span class="hint">
111
                                    Your guarantor is <i>[% guarantor.firstname %] [% guarantor.surname %]</i>
111
                                    Guaranteed by
112
                                    [% FOREACH gr IN patron.guarantor_relationships %]
113
                                        [% SET g = gr.guarantor %]
114
                                        [% g.firstname || gr.firstname %] [% g.surname || gr.surname %]
115
                                        [%- IF ! loop.last %], [% END %]
116
                                    [% END %]
112
                                </span>
117
                                </span>
113
                            </li>
118
                            </li>
114
                        </ol>
119
                        </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 369-392 Using this account is not recommended because some parts of Koha will not functi Link Here
369
369
370
                                    <tbody>
370
                                    <tbody>
371
                                        [% FOREACH r IN relatives %]
371
                                        [% FOREACH r IN relatives %]
372
                                            [% FOREACH i IN r.issues %]
372
                                            [% FOREACH c IN r.checkouts %]
373
                                                <tr>
373
                                                <tr>
374
                                                    <td>
374
                                                    <td>
375
                                                        <a href="/cgi-bin/koha/opac-detail.pl?biblionumber=[% i.item.biblio.biblionumber %]">
375
                                                        <a href="/cgi-bin/koha/opac-detail.pl?biblionumber=[% i.item.biblio.biblionumber %]">
376
                                                            [% i.item.biblio.title %][% IF ( i.item.enumchron ) %] [% i.item.enumchron %][% END %]
376
                                                            [% c.item.biblio.title %][% IF ( c.item.enumchron ) %] [% c.item.enumchron %][% END %]
377
                                                        </a>
377
                                                        </a>
378
                                                    </td>
378
                                                    </td>
379
379
380
                                                    <td>
380
                                                    <td>
381
                                                        [% i.date_due | $KohaDates %]
381
                                                        [% c.date_due | $KohaDates %]
382
                                                    </td>
382
                                                    </td>
383
383
384
                                                    <td>
384
                                                    <td>
385
                                                        [% i.item.barcode %]
385
                                                        [% c.item.barcode %]
386
                                                    </td>
386
                                                    </td>
387
387
388
                                                    <td>
388
                                                    <td>
389
                                                        [% i.item.itemcallnumber %]
389
                                                        [% c.item.itemcallnumber %]
390
                                                    </td>
390
                                                    </td>
391
391
392
                                                    <td>
392
                                                    <td>
(-)a/members/deletemem.pl (-8 / +6 lines)
Lines 78-88 my $issues = GetPendingIssues($member); # FIXME: wasteful call when really, Link Here
78
my $countissues = scalar(@$issues);
78
my $countissues = scalar(@$issues);
79
79
80
my $bor = C4::Members::GetMember( borrowernumber => $member );
80
my $bor = C4::Members::GetMember( borrowernumber => $member );
81
my $patron = Koha::Patrons->find( $member );
81
my $flags = C4::Members::patronflags( $bor );
82
my $flags = C4::Members::patronflags( $bor );
82
my $userenv = C4::Context->userenv;
83
my $userenv = C4::Context->userenv;
83
84
84
 
85
86
if ($bor->{category_type} eq "S") {
85
if ($bor->{category_type} eq "S") {
87
    unless(C4::Auth::haspermission($userenv->{'id'},{'staffaccess'=>1})) {
86
    unless(C4::Auth::haspermission($userenv->{'id'},{'staffaccess'=>1})) {
88
        print $input->redirect("/cgi-bin/koha/members/moremember.pl?borrowernumber=$member&error=CANT_DELETE_STAFF");
87
        print $input->redirect("/cgi-bin/koha/members/moremember.pl?borrowernumber=$member&error=CANT_DELETE_STAFF");
Lines 107-114 if (C4::Context->preference("IndependentBranches")) { Link Here
107
106
108
my $op = $input->param('op') || 'delete_confirm';
107
my $op = $input->param('op') || 'delete_confirm';
109
my $dbh = C4::Context->dbh;
108
my $dbh = C4::Context->dbh;
110
my $is_guarantor = $dbh->selectrow_array("SELECT COUNT(*) FROM borrowers WHERE guarantorid=?", undef, $member);
109
if ( $op eq 'delete_confirm' or $countissues > 0 or $flags->{'CHARGES'}  or $patron->guarantee_relationships()->count() or $deletelocal == 0) {
111
if ( $op eq 'delete_confirm' or $countissues > 0 or $flags->{'CHARGES'}  or $is_guarantor or $deletelocal == 0) {
112
    my $patron_image = Koha::Patron::Images->find($bor->{borrowernumber});
110
    my $patron_image = Koha::Patron::Images->find($bor->{borrowernumber});
113
    $template->param( picture => 1 ) if $patron_image;
111
    $template->param( picture => 1 ) if $patron_image;
114
112
Lines 128-134 if ( $op eq 'delete_confirm' or $countissues > 0 or $flags->{'CHARGES'} or $is_ Link Here
128
        phone => $bor->{'phone'},
126
        phone => $bor->{'phone'},
129
        email => $bor->{'email'},
127
        email => $bor->{'email'},
130
        branchcode => $bor->{'branchcode'},
128
        branchcode => $bor->{'branchcode'},
131
		activeBorrowerRelationship => (C4::Context->preference('borrowerRelationship') ne ''),
129
        activeBorrowerRelationship => (C4::Context->preference('borrowerRelationship') ne ''),
132
        RoutingSerials => C4::Context->preference('RoutingSerials'),
130
        RoutingSerials => C4::Context->preference('RoutingSerials'),
133
    );
131
    );
134
    if ($countissues >0) {
132
    if ($countissues >0) {
Lines 137-150 if ( $op eq 'delete_confirm' or $countissues > 0 or $flags->{'CHARGES'} or $is_ Link Here
137
    if ($flags->{'CHARGES'} ne '') {
135
    if ($flags->{'CHARGES'} ne '') {
138
        $template->param(charges => $flags->{'CHARGES'}->{'amount'});
136
        $template->param(charges => $flags->{'CHARGES'}->{'amount'});
139
    }
137
    }
140
    if ($is_guarantor) {
138
    if ( $patron->guarantee_relationships->count ) {
141
        $template->param(guarantees => 1);
139
        $template->param( guarantees => 1 );
142
    }
140
    }
143
    if ($deletelocal == 0) {
141
    if ($deletelocal == 0) {
144
        $template->param(keeplocal => 1);
142
        $template->param(keeplocal => 1);
145
    }
143
    }
146
    # This is silly written but reflect the same conditions as above
144
    # This is silly written but reflect the same conditions as above
147
    if ( not $countissues > 0 and not $flags->{CHARGES} ne '' and not $is_guarantor and not $deletelocal == 0 ) {
145
    if ( not $countissues > 0 and not $flags->{CHARGES} ne '' and not $patron->guarantee_relationships->count and not $deletelocal == 0 ) {
148
        $template->param(
146
        $template->param(
149
            op         => 'delete_confirm',
147
            op         => 'delete_confirm',
150
            csrf_token => Koha::Token->new->generate_csrf(
148
            csrf_token => Koha::Token->new->generate_csrf(
(-)a/members/memberentry.pl (-57 / +87 lines)
Lines 81-87 if ( C4::Context->preference('SMSSendDriver') eq 'Email' ) { Link Here
81
    $template->param( sms_providers => \@providers );
81
    $template->param( sms_providers => \@providers );
82
}
82
}
83
83
84
my $guarantorid    = $input->param('guarantorid');
85
my $borrowernumber = $input->param('borrowernumber');
84
my $borrowernumber = $input->param('borrowernumber');
86
my $actionType     = $input->param('actionType') || '';
85
my $actionType     = $input->param('actionType') || '';
87
my $modify         = $input->param('modify');
86
my $modify         = $input->param('modify');
Lines 98-110 $nodouble = 1 if ($op eq 'modify' or $op eq 'duplicate'); # FIXME hack to rep Link Here
98
                                     # isn't a duplicate.  Marking FIXME because this
97
                                     # isn't a duplicate.  Marking FIXME because this
99
                                     # script needs to be refactored.
98
                                     # script needs to be refactored.
100
my $nok           = $input->param('nok');
99
my $nok           = $input->param('nok');
101
my $guarantorinfo = $input->param('guarantorinfo');
102
my $step          = $input->param('step') || 0;
100
my $step          = $input->param('step') || 0;
103
my @errors;
101
my @errors;
104
my $borrower_data;
102
my $borrower_data;
105
my $NoUpdateLogin;
103
my $NoUpdateLogin;
106
my $userenv = C4::Context->userenv;
104
my $userenv = C4::Context->userenv;
107
105
106
## Deal with guarantor stuff
107
my $patron = Koha::Patrons->find($borrowernumber);
108
$template->param( relationships => scalar $patron->guarantor_relationships ) if $patron;
109
110
my $guarantor_id = $input->param('guarantor_id');
111
my $guarantor = Koha::Patrons->find( $guarantor_id ) if $guarantor_id;
112
$template->param( guarantor => $guarantor );
113
114
my @delete_guarantor = $input->param('delete_guarantor');
115
foreach my $id ( @delete_guarantor ) {
116
    my $r = Koha::Patron::Relationships->find( $id );
117
    $r->delete() if $r;
118
}
108
119
109
## Deal with debarments
120
## Deal with debarments
110
$template->param(
121
$template->param(
Lines 141-154 $template->param("minPasswordLength" => $minpw); Link Here
141
my $check_BorrowerMandatoryField=C4::Context->preference("BorrowerMandatoryField");
152
my $check_BorrowerMandatoryField=C4::Context->preference("BorrowerMandatoryField");
142
my @field_check=split(/\|/,$check_BorrowerMandatoryField);
153
my @field_check=split(/\|/,$check_BorrowerMandatoryField);
143
foreach (@field_check) {
154
foreach (@field_check) {
144
	$template->param( "mandatory$_" => 1);    
155
    $template->param( "mandatory$_" => 1 );
145
}
156
}
146
# function to designate unwanted fields
157
# function to designate unwanted fields
147
my $check_BorrowerUnwantedField=C4::Context->preference("BorrowerUnwantedField");
158
my $check_BorrowerUnwantedField=C4::Context->preference("BorrowerUnwantedField");
148
@field_check=split(/\|/,$check_BorrowerUnwantedField);
159
@field_check=split(/\|/,$check_BorrowerUnwantedField);
149
foreach (@field_check) {
160
foreach (@field_check) {
150
    next unless m/\w/o;
161
    next unless m/\w/o;
151
	$template->param( "no$_" => 1);
162
    $template->param( "no$_" => 1 );
152
}
163
}
153
$template->param( "add" => 1 ) if ( $op eq 'add' );
164
$template->param( "add" => 1 ) if ( $op eq 'add' );
154
$template->param( "quickadd" => 1 ) if ( $quickadd );
165
$template->param( "quickadd" => 1 ) if ( $quickadd );
Lines 242-266 if ( ( $op eq 'insert' ) and !$nodouble ) { Link Here
242
    }
253
    }
243
}
254
}
244
255
245
  #recover all data from guarantor address phone ,fax... 
246
if ( $guarantorid ) {
247
    if (my $guarantordata=GetMember(borrowernumber => $guarantorid)) {
248
        $category_type = $guarantordata->{categorycode} eq 'I' ? 'P' : 'C';
249
        $guarantorinfo=$guarantordata->{'surname'}." , ".$guarantordata->{'firstname'};
250
        $newdata{'contactfirstname'}= $guarantordata->{'firstname'};
251
        $newdata{'contactname'}     = $guarantordata->{'surname'};
252
        $newdata{'contacttitle'}    = $guarantordata->{'title'};
253
        if ( $op eq 'add' ) {
254
	        foreach (qw(streetnumber address streettype address2
255
                        zipcode country city state phone phonepro mobile fax email emailpro branchcode
256
                        B_streetnumber B_streettype B_address B_address2
257
                        B_city B_state B_zipcode B_country B_email B_phone)) {
258
		        $newdata{$_} = $guarantordata->{$_};
259
	        }
260
        }
261
    }
262
}
263
264
###############test to take the right zipcode, country and city name ##############
256
###############test to take the right zipcode, country and city name ##############
265
# set only if parameter was passed from the form
257
# set only if parameter was passed from the form
266
$newdata{'city'}    = $input->param('city')    if defined($input->param('city'));
258
$newdata{'city'}    = $input->param('city')    if defined($input->param('city'));
Lines 403-408 if ((!$nok) and $nodouble and ($op eq 'insert' or $op eq 'save')){ Link Here
403
	if ($op eq 'insert'){
395
	if ($op eq 'insert'){
404
		# we know it's not a duplicate borrowernumber or there would already be an error
396
		# we know it's not a duplicate borrowernumber or there would already be an error
405
        $borrowernumber = &AddMember(%newdata);
397
        $borrowernumber = &AddMember(%newdata);
398
        add_guarantors( $borrowernumber, $input );
406
        $newdata{'borrowernumber'} = $borrowernumber;
399
        $newdata{'borrowernumber'} = $borrowernumber;
407
400
408
        # If 'AutoEmailOpacUser' syspref is on, email user their account details from the 'notice' that matches the user's branchcode.
401
        # If 'AutoEmailOpacUser' syspref is on, email user their account details from the 'notice' that matches the user's branchcode.
Lines 500-505 if ((!$nok) and $nodouble and ($op eq 'insert' or $op eq 'save')){ Link Here
500
                                                                # updating any columns in the borrowers table,
493
                                                                # updating any columns in the borrowers table,
501
                                                                # which can happen if we're only editing the
494
                                                                # which can happen if we're only editing the
502
                                                                # patron attributes or messaging preferences sections
495
                                                                # patron attributes or messaging preferences sections
496
        add_guarantors( $borrowernumber, $input );
503
        if (C4::Context->preference('ExtendedPatronAttributes') and $input->param('setting_extended_patron_attributes')) {
497
        if (C4::Context->preference('ExtendedPatronAttributes') and $input->param('setting_extended_patron_attributes')) {
504
            C4::Members::Attributes::SetBorrowerAttributes($borrowernumber, $extended_patron_attributes);
498
            C4::Members::Attributes::SetBorrowerAttributes($borrowernumber, $extended_patron_attributes);
505
        }
499
        }
Lines 600-610 foreach my $category_type (qw(C A S P I X)) { Link Here
600
        'categoryloop'   => \@categoryloop
594
        'categoryloop'   => \@categoryloop
601
      };
595
      };
602
}
596
}
603
597
$template->param(
604
$template->param('typeloop' => \@typeloop,
598
    typeloop      => \@typeloop,
605
        no_categories => $no_categories);
599
    no_categories => $no_categories,
606
if($no_categories){ $no_add = 1; }
600
);
607
608
601
609
my $cities = Koha::Cities->search( {}, { order_by => 'city_name' } );
602
my $cities = Koha::Cities->search( {}, { order_by => 'city_name' } );
610
my $roadtypes = C4::Koha::GetAuthorisedValues( 'ROADTYPE' );
603
my $roadtypes = C4::Koha::GetAuthorisedValues( 'ROADTYPE' );
Lines 629-652 while (@relationships) { Link Here
629
  push(@relshipdata, \%row);
622
  push(@relshipdata, \%row);
630
}
623
}
631
624
632
my %flags = ( 'gonenoaddress' => ['gonenoaddress' ],
625
my %flags = (
633
        'lost'          => ['lost']);
626
    'gonenoaddress' => ['gonenoaddress'],
627
    'lost'          => ['lost']
628
);
634
629
635
 
636
my @flagdata;
630
my @flagdata;
637
foreach (keys(%flags)) {
631
foreach ( keys(%flags) ) {
638
	my $key = $_;
632
    my $key = $_;
639
	my %row =  ('key'   => $key,
633
    my %row = (
640
		    'name'  => $flags{$key}[0]);
634
        'key'  => $key,
641
	if ($data{$key}) {
635
        'name' => $flags{$key}[0]
642
		$row{'yes'}=' checked';
636
    );
643
		$row{'no'}='';
637
    if ( $data{$key} ) {
644
    }
638
        $row{'yes'} = ' checked';
645
	else {
639
        $row{'no'}  = '';
646
		$row{'yes'}='';
640
    }
647
		$row{'no'}=' checked';
641
    else {
648
	}
642
        $row{'yes'} = '';
649
	push @flagdata,\%row;
643
        $row{'no'}  = ' checked';
644
    }
645
    push @flagdata, \%row;
650
}
646
}
651
647
652
# get Branch Loop
648
# get Branch Loop
Lines 722-728 if (C4::Context->preference('EnhancedMessagingPreferences')) { Link Here
722
    $template->param(TalkingTechItivaPhone => C4::Context->preference("TalkingTechItivaPhoneNotification"));
718
    $template->param(TalkingTechItivaPhone => C4::Context->preference("TalkingTechItivaPhoneNotification"));
723
}
719
}
724
720
725
$template->param( "showguarantor"  => ($category_type=~/A|I|S|X/) ? 0 : 1); # associate with step to know where you are
721
$template->param( "show_guarantor" => ( $category_type =~ /A|I|S|X/ ) ? 0 : 1 ); # associate with step to know where you are
726
$debug and warn "memberentry step: $step";
722
$debug and warn "memberentry step: $step";
727
$template->param(%data);
723
$template->param(%data);
728
$template->param( "step_$step"  => 1) if $step;	# associate with step to know where u are
724
$template->param( "step_$step"  => 1) if $step;	# associate with step to know where u are
Lines 737-754 $template->param( Link Here
737
  "op$op"   => 1);
733
  "op$op"   => 1);
738
734
739
$template->param(
735
$template->param(
740
  nodouble  => $nodouble,
736
    nodouble       => $nodouble,
741
  borrowernumber  => $borrowernumber, #register number
737
    borrowernumber => $borrowernumber,          #register number
742
  guarantorid => ($borrower_data->{'guarantorid'} || $guarantorid),
738
    relshiploop    => \@relshipdata,
743
  relshiploop => \@relshipdata,
739
    btitle         => $default_borrowertitle,
744
  btitle=> $default_borrowertitle,
740
    flagloop       => \@flagdata,
745
  guarantorinfo   => $guarantorinfo,
741
    category_type  => $category_type,
746
  flagloop  => \@flagdata,
742
    modify         => $modify,
747
  category_type =>$category_type,
743
    nok            => $nok,                     #flag to know if an error
748
  modify          => $modify,
744
    NoUpdateLogin  => $NoUpdateLogin,
749
  nok     => $nok,#flag to know if an error
745
);
750
  NoUpdateLogin =>  $NoUpdateLogin,
751
  );
752
746
753
# Generate CSRF token
747
# Generate CSRF token
754
$template->param(
748
$template->param(
Lines 869-874 sub patron_attributes_form { Link Here
869
863
870
}
864
}
871
865
866
sub add_guarantors {
867
    my ( $borrowernumber, $input ) = @_;
868
869
    my @new_guarantor_id           = scalar $input->param('new_guarantor_id');
870
    my @new_guarantor_surname      = scalar $input->param('new_guarantor_surname');
871
    my @new_guarantor_firstname    = scalar $input->param('new_guarantor_firstname');
872
    my @new_guarantor_relationship = scalar $input->param('new_guarantor_relationship');
873
874
    for ( my $i = 0 ; $i < scalar @new_guarantor_id; $i++ ) {
875
        my $guarantor_id = $new_guarantor_id[$i];
876
        my $surname      = $new_guarantor_surname[$i];
877
        my $firstname    = $new_guarantor_firstname[$i];
878
        my $relationship = $new_guarantor_relationship[$i];
879
880
        if ($guarantor_id) {
881
            Koha::Patron::Relationship->new(
882
                {
883
                    guarantee_id => $borrowernumber,
884
                    guarantor_id => $guarantor_id,
885
                    relationship => $relationship
886
                }
887
            )->store();
888
        }
889
        elsif ($surname) {
890
            Koha::Patron::Relationship->new(
891
                {
892
                    guarantee_id => $borrowernumber,
893
                    surname      => $surname,
894
                    firstname    => $firstname,
895
                    relationship => $relationship
896
                }
897
            )->store();
898
        }
899
    }
900
}
901
872
# Local Variables:
902
# Local Variables:
873
# tab-width: 8
903
# tab-width: 8
874
# End:
904
# End:
(-)a/members/moremember.pl (-17 / +14 lines)
Lines 165-188 if ( $category_type eq 'C') { Link Here
165
    $template->param( 'catcode' => $patron_categories->next )  if $patron_categories->count == 1;
165
    $template->param( 'catcode' => $patron_categories->next )  if $patron_categories->count == 1;
166
}
166
}
167
167
168
my $patron = Koha::Patrons->find($data->{borrowernumber});
168
my $patron = Koha::Patrons->find( $data->{borrowernumber} );
169
my @relatives;
169
my @relatives;
170
if ( my $guarantor = $patron->guarantor ) {
170
my $guarantor_relationships = $patron->guarantor_relationships;
171
    $template->param( guarantor => $guarantor );
171
my @guarantees              = $patron->guarantee_relationships->guarantees;
172
    push @relatives, $guarantor->borrowernumber;
172
my @guarantors              = $guarantor_relationships->guarantors;
173
    push @relatives, $_->borrowernumber for $patron->siblings;
173
if (@guarantors) {
174
} elsif ( $patron->contactname || $patron->contactfirstname ) {
174
    push( @relatives, $_->id ) for @guarantors;
175
    $template->param(
175
    push( @relatives, $_->id ) for $patron->siblings();
176
        guarantor => {
177
            firstname => $patron->contactfirstname,
178
            surname   => $patron->contactname,
179
        }
180
    );
181
} else {
182
    my @guarantees = $patron->guarantees;
183
    $template->param( guarantees => \@guarantees );
184
    push @relatives, $_->borrowernumber for @guarantees;
185
}
176
}
177
else {
178
    push( @relatives, $_->id ) for @guarantees;
179
}
180
$template->param(
181
    guarantor_relationships => $guarantor_relationships,
182
    guarantees              => \@guarantees,
183
);
186
184
187
my $relatives_issues_count =
185
my $relatives_issues_count =
188
  Koha::Database->new()->schema()->resultset('Issue')
186
  Koha::Database->new()->schema()->resultset('Issue')
Lines 341-347 $template->param( Link Here
341
    quickslip       => $quickslip,
339
    quickslip       => $quickslip,
342
    housebound_role => $patron->housebound_role,
340
    housebound_role => $patron->housebound_role,
343
    privacy_guarantor_checkouts => $data->{'privacy_guarantor_checkouts'},
341
    privacy_guarantor_checkouts => $data->{'privacy_guarantor_checkouts'},
344
    activeBorrowerRelationship => (C4::Context->preference('borrowerRelationship') ne ''),
345
    AutoResumeSuspendedHolds => C4::Context->preference('AutoResumeSuspendedHolds'),
342
    AutoResumeSuspendedHolds => C4::Context->preference('AutoResumeSuspendedHolds'),
346
    SuspendHoldsIntranet => C4::Context->preference('SuspendHoldsIntranet'),
343
    SuspendHoldsIntranet => C4::Context->preference('SuspendHoldsIntranet'),
347
    RoutingSerials => C4::Context->preference('RoutingSerials'),
344
    RoutingSerials => C4::Context->preference('RoutingSerials'),
(-)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 282-288 elsif ( $action eq 'edit' ) { #Display logged in borrower's data Link Here
282
282
283
    $template->param(
283
    $template->param(
284
        borrower  => $borrower,
284
        borrower  => $borrower,
285
        guarantor => scalar Koha::Patrons->find($borrowernumber)->guarantor(),
286
        hidden => GetHiddenFields( $mandatory, 'modification' ),
285
        hidden => GetHiddenFields( $mandatory, 'modification' ),
287
        csrf_token => Koha::Token->new->generate_csrf({
286
        csrf_token => Koha::Token->new->generate_csrf({
288
            id     => Encode::encode( 'UTF-8', $borrower->{userid} ),
287
            id     => Encode::encode( 'UTF-8', $borrower->{userid} ),
Lines 301-307 my $captcha = random_string("CCCCC"); Link Here
301
300
302
$template->param(
301
$template->param(
303
    captcha        => $captcha,
302
    captcha        => $captcha,
304
    captcha_digest => md5_base64($captcha)
303
    captcha_digest => md5_base64($captcha),
304
    patron         => Koha::Patrons->find( $borrowernumber ),
305
);
305
);
306
306
307
output_html_with_http_headers $cgi, $cookie, $template->output, undef, { force_no_caching => 1 };
307
output_html_with_http_headers $cgi, $cookie, $template->output, undef, { force_no_caching => 1 };
(-)a/opac/opac-user.pl (-8 / +9 lines)
Lines 36-41 use C4::Letters; Link Here
36
use Koha::DateUtils;
36
use Koha::DateUtils;
37
use Koha::Holds;
37
use Koha::Holds;
38
use Koha::Database;
38
use Koha::Database;
39
use Koha::Patrons;
39
use Koha::Patron::Messages;
40
use Koha::Patron::Messages;
40
use Koha::Patron::Discharge;
41
use Koha::Patron::Discharge;
41
use Koha::Patrons;
42
use Koha::Patrons;
Lines 68-73 my ( $template, $borrowernumber, $cookie ) = get_template_and_user( Link Here
68
    }
69
    }
69
);
70
);
70
71
72
my $patron = Koha::Patrons->find( $borrowernumber );
73
71
my %renewed = map { $_ => 1 } split( ':', $query->param('renewed') );
74
my %renewed = map { $_ => 1 } split( ':', $query->param('renewed') );
72
75
73
my $show_priority;
76
my $show_priority;
Lines 316-329 my $patron_messages = Koha::Patron::Messages->search( Link Here
316
if (   C4::Context->preference('AllowPatronToSetCheckoutsVisibilityForGuarantor')
319
if (   C4::Context->preference('AllowPatronToSetCheckoutsVisibilityForGuarantor')
317
    || C4::Context->preference('AllowStaffToSetCheckoutsVisibilityForGuarantor') )
320
    || C4::Context->preference('AllowStaffToSetCheckoutsVisibilityForGuarantor') )
318
{
321
{
319
    my @relatives =
322
    my @relatives;
320
      Koha::Database->new()->schema()->resultset("Borrower")->search(
323
    # Filter out guarantees that don't want guarantor to see checkouts
321
        {
324
    foreach my $gr ( $patron->guarantee_relationships() ) {
322
            privacy_guarantor_checkouts => 1,
325
        my $g = $gr->guarantee;
323
            'me.guarantorid'           => $borrowernumber
326
        push( @relatives, $g ) if $g->privacy_guarantor_checkouts;
324
        },
327
    }
325
        { prefetch => [ { 'issues' => { 'item' => 'biblio' } } ] }
326
      );
327
    $template->param( relatives => \@relatives );
328
    $template->param( relatives => \@relatives );
328
}
329
}
329
330
(-)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.t (-1 / +8 lines)
Lines 17-23 Link Here
17
17
18
use Modern::Perl;
18
use Modern::Perl;
19
19
20
use Test::More tests => 91;
20
use Test::More tests => 93;
21
21
22
BEGIN {
22
BEGIN {
23
    require_ok('C4::Circulation');
23
    require_ok('C4::Circulation');
Lines 37-42 use C4::Overdues qw(UpdateFine CalcFine); Link Here
37
use Koha::DateUtils;
37
use Koha::DateUtils;
38
use Koha::Database;
38
use Koha::Database;
39
use Koha::Subscriptions;
39
use Koha::Subscriptions;
40
use Koha::Patron;
40
41
41
my $schema = Koha::Database->schema;
42
my $schema = Koha::Database->schema;
42
$schema->storage->txn_begin;
43
$schema->storage->txn_begin;
Lines 312-317 C4::Context->dbh->do("DELETE FROM accountlines"); Link Here
312
    $datedue = dt_from_string( $issue->date_due() );
313
    $datedue = dt_from_string( $issue->date_due() );
313
    is (defined $issue2, 1, "Item 2 checked out, due date: " . $issue2->date_due());
314
    is (defined $issue2, 1, "Item 2 checked out, due date: " . $issue2->date_due());
314
315
316
    my $patron = Koha::Patrons->find( $renewing_borrower->{borrowernumber} );
317
    my @checkouts = $patron->checkouts();
318
    is( @checkouts, 2, "Patron has 2 checkouts" );
319
    is( $checkouts[0]->borrowernumber, $patron->id, 'Checkout 1 patron matches' );
320
    is( $checkouts[1]->borrowernumber, $patron->id, 'Checkout 2 patron matches' );
321
315
322
316
    my $borrowing_borrowernumber = GetItemIssue($itemnumber)->{borrowernumber};
323
    my $borrowing_borrowernumber = GetItemIssue($itemnumber)->{borrowernumber};
317
    is ($borrowing_borrowernumber, $renewing_borrowernumber, "Item checked out to $renewing_borrower->{firstname} $renewing_borrower->{surname}");
324
    is ($borrowing_borrowernumber, $renewing_borrowernumber, "Item checked out to $renewing_borrower->{firstname} $renewing_borrower->{surname}");
(-)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 30-35 use C4::Members; Link Here
30
use Koha::Holds;
30
use Koha::Holds;
31
use Koha::Patron;
31
use Koha::Patron;
32
use Koha::Patrons;
32
use Koha::Patrons;
33
use Koha::Patron::Relationship;
33
use Koha::Database;
34
use Koha::Database;
34
use Koha::DateUtils;
35
use Koha::DateUtils;
35
use Koha::Virtualshelves;
36
use Koha::Virtualshelves;
Lines 79-101 subtest 'library' => sub { Link Here
79
80
80
subtest 'guarantees' => sub {
81
subtest 'guarantees' => sub {
81
    plan tests => 8;
82
    plan tests => 8;
82
    my $guarantees = $new_patron_1->guarantees;
83
    my $guarantees = $new_patron_1->guarantee_relationships;
83
    is( ref($guarantees), 'Koha::Patrons', 'Koha::Patron->guarantees should return a Koha::Patrons result set in a scalar context' );
84
    is( ref($guarantees), 'Koha::Patron::Relationships', 'Koha::Patron->guarantees should return a Koha::Patrons result set in a scalar context' );
84
    is( $guarantees->count, 0, 'new_patron_1 should have 0 guarantee' );
85
    is( $guarantees->count, 0, 'new_patron_1 should have 0 guarantee relationships' );
85
    my @guarantees = $new_patron_1->guarantees;
86
    my @guarantees = $new_patron_1->guarantee_relationships;
86
    is( ref(\@guarantees), 'ARRAY', 'Koha::Patron->guarantees should return an array in a list context' );
87
    is( ref(\@guarantees), 'ARRAY', 'Koha::Patron->guarantee_relationships should return an array in a list context' );
87
    is( scalar(@guarantees), 0, 'new_patron_1 should have 0 guarantee' );
88
    is( scalar(@guarantees), 0, 'new_patron_1 should have 0 guarantee' );
88
89
89
    my $guarantee_1 = $builder->build({ source => 'Borrower', value => { guarantorid => $new_patron_1->borrowernumber }});
90
    my $guarantee_1 = $builder->build({ source => 'Borrower' });
90
    my $guarantee_2 = $builder->build({ source => 'Borrower', value => { guarantorid => $new_patron_1->borrowernumber }});
91
    my $relationship_1 = Koha::Patron::Relationship->new( { guarantor_id => $new_patron_1->id, guarantee_id => $guarantee_1->{borrowernumber} } )->store();
92
    my $guarantee_2 = $builder->build({ source => 'Borrower' });
93
    my $relationship_2 = Koha::Patron::Relationship->new( { guarantor_id => $new_patron_1->id, guarantee_id => $guarantee_2->{borrowernumber} } )->store();
91
94
92
    $guarantees = $new_patron_1->guarantees;
95
    $guarantees = $new_patron_1->guarantee_relationships;
93
    is( ref($guarantees), 'Koha::Patrons', 'Koha::Patron->guarantees should return a Koha::Patrons result set in a scalar context' );
96
    is( ref($guarantees), 'Koha::Patron::Relationships', 'Koha::Patron->guarantee_relationships should return a Koha::Patrons result set in a scalar context' );
94
    is( $guarantees->count, 2, 'new_patron_1 should have 2 guarantees' );
97
    is( $guarantees->count, 2, 'new_patron_1 should have 2 guarantees' );
95
    @guarantees = $new_patron_1->guarantees;
98
    @guarantees = $new_patron_1->guarantee_relationships;
96
    is( ref(\@guarantees), 'ARRAY', 'Koha::Patron->guarantees should return an array in a list context' );
99
    is( ref(\@guarantees), 'ARRAY', 'Koha::Patron->guarantee_relationships should return an array in a list context' );
97
    is( scalar(@guarantees), 2, 'new_patron_1 should have 2 guarantees' );
100
    is( scalar(@guarantees), 2, 'new_patron_1 should have 2 guarantees' );
98
    $_->delete for @guarantees;
101
    map { $_->guarantee->delete } @guarantees;
99
};
102
};
100
103
101
subtest 'category' => sub {
104
subtest 'category' => sub {
Lines 109-123 subtest 'siblings' => sub { Link Here
109
    plan tests => 7;
112
    plan tests => 7;
110
    my $siblings = $new_patron_1->siblings;
113
    my $siblings = $new_patron_1->siblings;
111
    is( $siblings, undef, 'Koha::Patron->siblings should not crashed if the patron has no guarantor' );
114
    is( $siblings, undef, 'Koha::Patron->siblings should not crashed if the patron has no guarantor' );
112
    my $guarantee_1 = $builder->build( { source => 'Borrower', value => { guarantorid => $new_patron_1->borrowernumber } } );
115
    my $guarantee_1 = $builder->build( { source => 'Borrower' } );
116
    my $relationship_1 = Koha::Patron::Relationship->new( { guarantor_id => $new_patron_1->borrowernumber, guarantee_id => $guarantee_1->{borrowernumber} } )->store();
113
    my $retrieved_guarantee_1 = Koha::Patrons->find($guarantee_1);
117
    my $retrieved_guarantee_1 = Koha::Patrons->find($guarantee_1);
114
    $siblings = $retrieved_guarantee_1->siblings;
118
    $siblings = $retrieved_guarantee_1->siblings;
115
    is( ref($siblings), 'Koha::Patrons', 'Koha::Patron->siblings should return a Koha::Patrons result set in a scalar context' );
119
    is( ref($siblings), 'Koha::Patrons', 'Koha::Patron->siblings should return a Koha::Patrons result set in a scalar context' );
116
    my @siblings = $retrieved_guarantee_1->siblings;
120
    my @siblings = $retrieved_guarantee_1->siblings;
117
    is( ref( \@siblings ), 'ARRAY', 'Koha::Patron->siblings should return an array in a list context' );
121
    is( ref( \@siblings ), 'ARRAY', 'Koha::Patron->siblings should return an array in a list context' );
118
    is( $siblings->count,  0,       'guarantee_1 should not have siblings yet' );
122
    is( $siblings->count,  0,       'guarantee_1 should not have siblings yet' );
119
    my $guarantee_2 = $builder->build( { source => 'Borrower', value => { guarantorid => $new_patron_1->borrowernumber } } );
123
    my $guarantee_2 = $builder->build( { source => 'Borrower' } );
120
    my $guarantee_3 = $builder->build( { source => 'Borrower', value => { guarantorid => $new_patron_1->borrowernumber } } );
124
    my $relationship_2 = Koha::Patron::Relationship->new( { guarantor_id => $new_patron_1->borrowernumber, guarantee_id => $guarantee_2->{borrowernumber} } )->store();
125
    my $guarantee_3 = $builder->build( { source => 'Borrower' } );
126
    my $relationship_3 = Koha::Patron::Relationship->new( { guarantor_id => $new_patron_1->borrowernumber, guarantee_id => $guarantee_3->{borrowernumber} } )->store();
121
    $siblings = $retrieved_guarantee_1->siblings;
127
    $siblings = $retrieved_guarantee_1->siblings;
122
    is( $siblings->count,               2,                               'guarantee_1 should have 2 siblings' );
128
    is( $siblings->count,               2,                               'guarantee_1 should have 2 siblings' );
123
    is( $guarantee_2->{borrowernumber}, $siblings->next->borrowernumber, 'guarantee_2 should exist in the guarantees' );
129
    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 39-47 my $builder = t::lib::TestBuilder->new; Link Here
39
my $dbh = C4::Context->dbh;
40
my $dbh = C4::Context->dbh;
40
$dbh->{RaiseError} = 1;
41
$dbh->{RaiseError} = 1;
41
42
42
# Remove invalid guarantorid's as long as we have no FK
43
$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");
44
45
my $library1 = $builder->build({
43
my $library1 = $builder->build({
46
    source => 'Branch',
44
    source => 'Branch',
47
});
45
});
Lines 259-265 my $borrower1 = $builder->build({ Link Here
259
            categorycode=>'STAFFER',
257
            categorycode=>'STAFFER',
260
            branchcode => $library3->{branchcode},
258
            branchcode => $library3->{branchcode},
261
            dateexpiry => '2015-01-01',
259
            dateexpiry => '2015-01-01',
262
            guarantorid=> undef,
263
        },
260
        },
264
});
261
});
265
my $bor1inlist = $borrower1->{borrowernumber};
262
my $bor1inlist = $borrower1->{borrowernumber};
Lines 269-275 my $borrower2 = $builder->build({ Link Here
269
            categorycode=>'STAFFER',
266
            categorycode=>'STAFFER',
270
            branchcode => $library3->{branchcode},
267
            branchcode => $library3->{branchcode},
271
            dateexpiry => '2015-01-01',
268
            dateexpiry => '2015-01-01',
272
            guarantorid=> undef,
273
        },
269
        },
274
});
270
});
275
271
Lines 279-285 my $guarantee = $builder->build({ Link Here
279
            categorycode=>'KIDclamp',
275
            categorycode=>'KIDclamp',
280
            branchcode => $library3->{branchcode},
276
            branchcode => $library3->{branchcode},
281
            dateexpiry => '2015-01-01',
277
            dateexpiry => '2015-01-01',
282
            guarantorid=> undef, # will be filled later
283
        },
278
        },
284
});
279
});
285
280
Lines 310-316 $patstodel = GetBorrowersToExpunge( {not_borrowed_since => '2016-01-02', patron_ Link Here
310
ok( scalar(@$patstodel) == 1 && $patstodel->[0]->{'borrowernumber'} eq $bor2inlist,'Staff patron not deleted by last issue date');
305
ok( scalar(@$patstodel) == 1 && $patstodel->[0]->{'borrowernumber'} eq $bor2inlist,'Staff patron not deleted by last issue date');
311
306
312
ModMember( borrowernumber => $bor1inlist, categorycode => 'CIVILIAN' );
307
ModMember( borrowernumber => $bor1inlist, categorycode => 'CIVILIAN' );
313
ModMember( borrowernumber => $guarantee->{borrowernumber} ,guarantorid=>$bor1inlist );
308
my $relationship = Koha::Patron::Relationship->new( { guarantor_id => $bor1inlist, guarantee_id => $guarantee->{borrowernumber} } )->store();
314
309
315
$patstodel = GetBorrowersToExpunge( {patron_list_id => $list1->patron_list_id()} );
310
$patstodel = GetBorrowersToExpunge( {patron_list_id => $list1->patron_list_id()} );
316
ok( scalar(@$patstodel)== 1 && $patstodel->[0]->{'borrowernumber'} eq $bor2inlist,'Guarantor patron not deleted from list');
311
ok( scalar(@$patstodel)== 1 && $patstodel->[0]->{'borrowernumber'} eq $bor2inlist,'Guarantor patron not deleted from list');
Lines 320-326 $patstodel = GetBorrowersToExpunge( {expired_before => '2015-01-02', patron_list Link Here
320
ok( scalar(@$patstodel) == 1 && $patstodel->[0]->{'borrowernumber'} eq $bor2inlist,'Guarantor patron not deleted by expirationdate and list');
315
ok( scalar(@$patstodel) == 1 && $patstodel->[0]->{'borrowernumber'} eq $bor2inlist,'Guarantor patron not deleted by expirationdate and list');
321
$patstodel = GetBorrowersToExpunge( {not_borrowed_since => '2016-01-02', patron_list_id => $list1->patron_list_id() } );
316
$patstodel = GetBorrowersToExpunge( {not_borrowed_since => '2016-01-02', patron_list_id => $list1->patron_list_id() } );
322
ok( scalar(@$patstodel) == 1 && $patstodel->[0]->{'borrowernumber'} eq $bor2inlist,'Guarantor patron not deleted by last issue date');
317
ok( scalar(@$patstodel) == 1 && $patstodel->[0]->{'borrowernumber'} eq $bor2inlist,'Guarantor patron not deleted by last issue date');
323
ModMember( borrowernumber => $guarantee->{borrowernumber}, guarantorid=>'' );
318
319
$relationship->delete();
324
320
325
$builder->build({
321
$builder->build({
326
        source => 'Issue',
322
        source => 'Issue',
Lines 348-356 is( scalar(@$patstodel),2,'Borrowers without issues deleted by last issue date') Link Here
348
344
349
# Test GetBorrowersToExpunge and TrackLastPatronActivity
345
# Test GetBorrowersToExpunge and TrackLastPatronActivity
350
$dbh->do(q|UPDATE borrowers SET lastseen=NULL|);
346
$dbh->do(q|UPDATE borrowers SET lastseen=NULL|);
351
$builder->build({ source => 'Borrower', value => { lastseen => '2016-01-01 01:01:01', categorycode => 'CIVILIAN', guarantorid => undef } } );
347
$builder->build({ source => 'Borrower', value => { lastseen => '2016-01-01 01:01:01', categorycode => 'CIVILIAN' } } );
352
$builder->build({ source => 'Borrower', value => { lastseen => '2016-02-02 02:02:02', categorycode => 'CIVILIAN', guarantorid => undef } } );
348
$builder->build({ source => 'Borrower', value => { lastseen => '2016-02-02 02:02:02', categorycode => 'CIVILIAN' } } );
353
$builder->build({ source => 'Borrower', value => { lastseen => '2016-03-03 03:03:03', categorycode => 'CIVILIAN', guarantorid => undef } } );
349
$builder->build({ source => 'Borrower', value => { lastseen => '2016-03-03 03:03:03', categorycode => 'CIVILIAN' } } );
354
$patstodel = GetBorrowersToExpunge( { last_seen => '1999-12-12' });
350
$patstodel = GetBorrowersToExpunge( { last_seen => '1999-12-12' });
355
is( scalar @$patstodel, 0, 'TrackLastPatronActivity - 0 patrons must be deleted' );
351
is( scalar @$patstodel, 0, 'TrackLastPatronActivity - 0 patrons must be deleted' );
356
$patstodel = GetBorrowersToExpunge( { last_seen => '2016-02-15' });
352
$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 / +24 lines)
Lines 70-75 my @columnkeys = Koha::Patrons->columns(); Link Here
70
if ($extended) {
70
if ($extended) {
71
    push @columnkeys, 'patron_attributes';
71
    push @columnkeys, 'patron_attributes';
72
}
72
}
73
push( @columnkeys, qw( relationship guarantor_id  guarantor_firstname guarantor_surname ) );
73
74
74
my $input = CGI->new();
75
my $input = CGI->new();
75
our $csv  = Text::CSV->new({binary => 1});  # binary needed for non-ASCII Unicode
76
our $csv  = Text::CSV->new({binary => 1});  # binary needed for non-ASCII Unicode
Lines 261-266 if ( $uploadborrowers && length($uploadborrowers) > 0 ) { Link Here
261
            next;
262
            next;
262
        }
263
        }
263
264
265
        my $relationship        = $borrower{relationship};
266
        my $guarantor_id        = $borrower{guarantor_id};
267
        my $guarantor_firstname = $borrower{guarantor_firstname};
268
        my $guarantor_surname   = $borrower{guarantor_surname};
269
        delete $borrower{relationship};
270
        delete $borrower{guarantor_id};
271
        delete $borrower{guarantor_firstname};
272
        delete $borrower{guarantor_surname};
273
264
        if ($borrowernumber) {
274
        if ($borrowernumber) {
265
            # borrower exists
275
            # borrower exists
266
            unless ($overwrite_cardnumber) {
276
            unless ($overwrite_cardnumber) {
Lines 364-370 if ( $uploadborrowers && length($uploadborrowers) > 0 ) { Link Here
364
                $template->param('lastinvalid'=>$borrower{'surname'}.' / AddMember');
374
                $template->param('lastinvalid'=>$borrower{'surname'}.' / AddMember');
365
            }
375
            }
366
        }
376
        }
377
378
        # Add a guarantor if we are given a relationship
379
        if ( $relationship ) {
380
            Koha::Patron::Relationship->new(
381
                {
382
                    guarantee_id => $borrowernumber,
383
                    relationship => $relationship,
384
                    guarantor_id => $guarantor_id,
385
                    firstname    => $guarantor_firstname,
386
                    surname      => $guarantor_surname,
387
                }
388
            )->store();
389
        }
367
    }
390
    }
391
368
    (@errors  ) and $template->param(  ERRORS=>\@errors  );
392
    (@errors  ) and $template->param(  ERRORS=>\@errors  );
369
    (@feedback) and $template->param(FEEDBACK=>\@feedback);
393
    (@feedback) and $template->param(FEEDBACK=>\@feedback);
370
    $template->param(
394
    $template->param(
371
- 

Return to bug 14570