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 1100-1117 sub GetBorrowersToExpunge { Link Here
1100
        FROM   borrowers
1100
        FROM   borrowers
1101
        JOIN   categories USING (categorycode)
1101
        JOIN   categories USING (categorycode)
1102
        LEFT JOIN (
1102
        LEFT JOIN (
1103
            SELECT guarantorid
1103
            SELECT guarantor_id
1104
            FROM borrowers
1104
            FROM relationships
1105
            WHERE guarantorid IS NOT NULL
1105
            WHERE guarantor_id IS NOT NULL
1106
                AND guarantorid <> 0
1106
                AND guarantor_id <> 0
1107
        ) as tmp ON borrowers.borrowernumber=tmp.guarantorid
1107
        ) as tmp ON borrowers.borrowernumber=tmp.guarantor_id
1108
        LEFT JOIN old_issues USING (borrowernumber)
1108
        LEFT JOIN old_issues USING (borrowernumber)
1109
        LEFT JOIN issues USING (borrowernumber)|;
1109
        LEFT JOIN issues USING (borrowernumber)|;
1110
    if ( $filterpatronlist  ){
1110
    if ( $filterpatronlist  ){
1111
        $query .= q| LEFT JOIN patron_list_patrons USING (borrowernumber)|;
1111
        $query .= q| LEFT JOIN patron_list_patrons USING (borrowernumber)|;
1112
    }
1112
    }
1113
    $query .= q| WHERE  category_type <> 'S'
1113
    $query .= q| WHERE  category_type <> 'S'
1114
        AND tmp.guarantorid IS NULL
1114
        AND tmp.guarantor_id IS NULL
1115
   |;
1115
   |;
1116
    my @query_params;
1116
    my @query_params;
1117
    if ( $filterbranch && $filterbranch ne "" ) {
1117
    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 (-32 / +50 lines)
Lines 25-39 use Carp; Link Here
25
use C4::Context;
25
use C4::Context;
26
use C4::Log;
26
use C4::Log;
27
use Koha::Checkouts;
27
use Koha::Checkouts;
28
use Koha::Old::Checkouts;
28
use Koha::Database;
29
use Koha::Database;
29
use Koha::DateUtils;
30
use Koha::DateUtils;
30
use Koha::Holds;
31
use Koha::Holds;
31
use Koha::Old::Checkouts;
32
use Koha::Patrons;
32
use Koha::Patron::Categories;
33
use Koha::Patron::Categories;
34
use Koha::Patron::Relationships;
33
use Koha::Patron::HouseboundProfile;
35
use Koha::Patron::HouseboundProfile;
34
use Koha::Patron::HouseboundRole;
36
use Koha::Patron::HouseboundRole;
35
use Koha::Patron::Images;
37
use Koha::Patron::Images;
36
use Koha::Patrons;
37
use Koha::Virtualshelves;
38
use Koha::Virtualshelves;
38
39
39
use base qw(Koha::Object);
40
use base qw(Koha::Object);
Lines 106-146 sub category { Link Here
106
    return Koha::Patron::Category->_new_from_dbic( $self->_result->categorycode );
107
    return Koha::Patron::Category->_new_from_dbic( $self->_result->categorycode );
107
}
108
}
108
109
109
=head3 guarantor
110
=head3 image
110
111
Returns a Koha::Patron object for this patron's guarantor
112
111
113
=cut
112
=cut
114
113
115
sub guarantor {
114
sub image {
116
    my ( $self ) = @_;
115
    my ( $self ) = @_;
117
116
118
    return unless $self->guarantorid();
117
    return Koha::Patron::Images->find( $self->borrowernumber )
119
120
    return Koha::Patrons->find( $self->guarantorid() );
121
}
118
}
122
119
123
sub image {
120
=head3 library
124
    my ( $self ) = @_;
125
121
126
    return Koha::Patron::Images->find( $self->borrowernumber );
122
=cut
127
}
128
123
129
sub library {
124
sub library {
130
    my ( $self ) = @_;
125
    my ( $self ) = @_;
131
    return Koha::Library->_new_from_dbic($self->_result->branchcode);
126
    return Koha::Library->_new_from_dbic($self->_result->branchcode);
132
}
127
}
133
128
134
=head3 guarantees
129
=head3 guarantor_relationships
130
131
Returns Koha::Patron::Relationships object for this patron's guarantors
132
133
Returns the set of relationships for the patrons that are guarantors for this patron.
135
134
136
Returns the guarantees (list of Koha::Patron) of this patron
135
This is returned instead of a Koha::Patron object because the guarantor
136
may not exist as a patron in Koha. If this is true, the guarantors name
137
exists in the Koha::Patron::Relationship object and will have no guarantor_id.
137
138
138
=cut
139
=cut
139
140
140
sub guarantees {
141
sub guarantor_relationships {
141
    my ( $self ) = @_;
142
    my ($self) = @_;
142
143
143
    return Koha::Patrons->search( { guarantorid => $self->borrowernumber } );
144
    return Koha::Patron::Relationships->search( { guarantee_id => $self->id } );
145
}
146
147
=head3 guarantee_relationships
148
149
Returns Koha::Patron::Relationships object for this patron's guarantors
150
151
Returns the set of relationships for the patrons that are guarantees for this patron.
152
153
The method returns Koha::Patron::Relationship objects for the sake
154
of consistency with the guantors method.
155
A guarantee by definition must exist as a patron in Koha.
156
157
=cut
158
159
sub guarantee_relationships {
160
    my ($self) = @_;
161
162
    return Koha::Patron::Relationships->search( { guarantor_id => $self->id } );
144
}
163
}
145
164
146
=head3 housebound_profile
165
=head3 housebound_profile
Lines 178-200 Returns the siblings of this patron. Link Here
178
=cut
197
=cut
179
198
180
sub siblings {
199
sub siblings {
181
    my ( $self ) = @_;
200
    my ($self) = @_;
182
201
183
    my $guarantor = $self->guarantor;
202
    my @guarantors = $self->guarantor_relationships()->guarantors();
184
203
185
    return unless $guarantor;
204
    return unless @guarantors;
186
205
187
    return Koha::Patrons->search(
206
    my @siblings =
188
        {
207
      map { $_->guarantee_relationships()->guarantees() } @guarantors;
189
            guarantorid => {
208
190
                '!=' => undef,
209
    return unless @siblings;
191
                '=' => $guarantor->id,
210
192
            },
211
    my %seen;
193
            borrowernumber => {
212
    @siblings =
194
                '!=' => $self->borrowernumber,
213
      grep { !$seen{ $_->id }++ && ( $_->id != $self->id ) } @siblings;
195
            }
214
196
        }
215
    return wantarray ? @siblings : Koha::Patrons->search( { borrowernumber => { -in => [ map { $_->id } @siblings ] } } );
197
    );
198
}
216
}
199
217
200
=head3 wants_check_for_previous_checkout
218
=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 (+17 lines)
Line 0 Link Here
1
CREATE TABLE `relationships` (
2
      id INT(11) NOT NULL AUTO_INCREMENT,
3
      guarantor_id INT(11) NULL DEFAULT NULL,
4
      guarantee_id INT(11) NOT NULL,
5
      relationship VARCHAR(100) COLLATE utf8_unicode_ci NOT NULL,
6
      surname MEDIUMTEXT COLLATE utf8_unicode_ci NULL DEFAULT NULL,
7
      firstname MEDIUMTEXT COLLATE utf8_unicode_ci NULL DEFAULT NULL,
8
      PRIMARY KEY (id),
9
      CONSTRAINT r_guarantor FOREIGN KEY ( guarantor_id ) REFERENCES borrowers ( borrowernumber ) ON UPDATE CASCADE ON DELETE CASCADE,
10
      CONSTRAINT r_guarantee FOREIGN KEY ( guarantee_id ) REFERENCES borrowers ( borrowernumber ) ON UPDATE CASCADE ON DELETE CASCADE
11
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
12
13
UPDATE borrowers LEFT JOIN borrowers guarantor ON ( borrowers.guarantorid = guarantor.borrowernumber ) SET borrowers.guarantorid = NULL WHERE guarantor.borrowernumber IS NULL;
14
15
INSERT INTO relationships ( guarantor_id, guarantee_id, relationship, surname, firstname ) SELECT guarantorid, borrowernumber, relationship, contactname, contactfirstname FROM borrowers WHERE guarantorid IS NOT NULL OR contactname != "";
16
17
ALTER TABLE borrowers DROP guarantorid, DROP relationship, DROP contactname, DROP contactfirstname, DROP contacttitle;
(-)a/installer/data/mysql/kohastructure.sql (-16 / +17 lines)
Lines 600-611 CREATE TABLE `deletedborrowers` ( -- stores data related to the patrons/borrower Link Here
600
  `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
600
  `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
601
  `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)
601
  `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)
602
  `debarredcomment` VARCHAR(255) DEFAULT NULL, -- comment on the stop of patron
602
  `debarredcomment` VARCHAR(255) DEFAULT NULL, -- comment on the stop of patron
603
  `contactname` mediumtext, -- used for children and profesionals to include surname or last name of guarentor or organization name
604
  `contactfirstname` text, -- used for children to include first name of guarentor
605
  `contacttitle` text, -- used for children to include title (Mr., Mrs., etc) of guarentor
606
  `guarantorid` int(11) default NULL, -- borrowernumber used for children or professionals to link them to guarentors or organizations
607
  `borrowernotes` mediumtext, -- a note on the patron/borrower's account that is only visible in the staff client
603
  `borrowernotes` mediumtext, -- a note on the patron/borrower's account that is only visible in the staff client
608
  `relationship` varchar(100) default NULL, -- used for children to include the relationship to their guarentor
609
  `sex` varchar(1) default NULL, -- patron/borrower's gender
604
  `sex` varchar(1) default NULL, -- patron/borrower's gender
610
  `password` varchar(60) default NULL, -- patron/borrower's encrypted password
605
  `password` varchar(60) default NULL, -- patron/borrower's encrypted password
611
  `flags` int(11) default NULL, -- will include a number associated with the staff member's permissions
606
  `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 3952-3957 CREATE TABLE deletedbiblio_metadata ( Link Here
3952
    CONSTRAINT `deletedrecord_metadata_fk_1` FOREIGN KEY (biblionumber) REFERENCES deletedbiblio (biblionumber) ON DELETE CASCADE ON UPDATE CASCADE
3936
    CONSTRAINT `deletedrecord_metadata_fk_1` FOREIGN KEY (biblionumber) REFERENCES deletedbiblio (biblionumber) ON DELETE CASCADE ON UPDATE CASCADE
3953
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
3937
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
3954
3938
3939
--
3940
-- Table structure for table 'guarantors_guarantees'
3941
--
3942
3943
DROP TABLE IF EXISTS relationships;
3944
CREATE TABLE `relationships` (
3945
      id INT(11) NOT NULL AUTO_INCREMENT,
3946
      guarantor_id INT(11) NULL DEFAULT NULL,
3947
      guarantee_id INT(11) NOT NULL,
3948
      relationship VARCHAR(100) COLLATE utf8_unicode_ci NOT NULL,
3949
      surname MEDIUMTEXT COLLATE utf8_unicode_ci NULL DEFAULT NULL,
3950
      firstname MEDIUMTEXT COLLATE utf8_unicode_ci NULL DEFAULT NULL,
3951
      PRIMARY KEY (id),
3952
      CONSTRAINT r_guarantor FOREIGN KEY ( guarantor_id ) REFERENCES borrowers ( borrowernumber ) ON UPDATE CASCADE ON DELETE CASCADE,
3953
      CONSTRAINT r_guarantee FOREIGN KEY ( guarantee_id ) REFERENCES borrowers ( borrowernumber ) ON UPDATE CASCADE ON DELETE CASCADE
3954
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
3955
3955
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
3956
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
3956
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
3957
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
3957
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
3958
/*!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-default btn-sm" href="/cgi-bin/koha/members/memberentry.pl?op=modify&amp;destination=circ&amp;borrowernumber=[% borrowernumber %]&amp;guarantorid=[% guarantor.borrowernumber %]&amp;categorycode=[% categorycode %]">
138
        [% ELSE %]
139
            <a id="editpatron" class="btn btn-default btn-sm" href="/cgi-bin/koha/members/memberentry.pl?op=modify&amp;destination=circ&amp;borrowernumber=[% borrowernumber %]&amp;categorycode=[% categorycode %]">
136
            <a id="editpatron" class="btn btn-default btn-sm" href="/cgi-bin/koha/members/memberentry.pl?op=modify&amp;destination=circ&amp;borrowernumber=[% borrowernumber %]&amp;categorycode=[% categorycode %]">
140
        [% END %]
137
                <i class="fa fa-pencil"></i> Edit
141
        <i class="fa fa-pencil"></i> Edit</a>
138
            </a>
142
    [% END %]
139
    [% END %]
143
140
144
    [% IF ( CAN_user_borrowers ) %]
141
    [% IF ( CAN_user_borrowers ) %]
145
        [% IF ( adultborrower AND activeBorrowerRelationship ) %]
142
        [% IF ( adultborrower AND Koha.Preference('borrowerRelationship') ) %]
146
            <a id="addchild" class="btn btn-default btn-sm" href="/cgi-bin/koha/members/memberentry.pl?op=add&amp;guarantorid=[% borrowernumber %]"><i class="fa fa-plus"></i> Add child</a>
143
            <a id="addchild" class="btn btn-default btn-sm" href="/cgi-bin/koha/members/memberentry.pl?op=add&amp;guarantor_id=[% borrowernumber %]"><i class="fa fa-plus"></i> Add child</a>
147
        [% END %]
144
        [% END %]
148
        [% IF ( CAN_user_borrowers ) %]
145
        [% IF ( CAN_user_borrowers ) %]
149
            <a id="changepassword" class="btn btn-default btn-sm" href="/cgi-bin/koha/members/member-password.pl?member=[% borrowernumber %]"><i class="fa fa-lock"></i> Change password</a>
146
            <a id="changepassword" class="btn btn-default btn-sm" href="/cgi-bin/koha/members/member-password.pl?member=[% borrowernumber %]"><i class="fa fa-lock"></i> Change password</a>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt (-1 / +1 lines)
Lines 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 259-283 function validate1(date) { Link Here
259
                [% END %]
259
                [% END %]
260
            </ul>
260
            </ul>
261
        </li>
261
        </li>
262
    [% ELSIF guarantor %]
262
    [% ELSIF guarantor_relationships %]
263
        <li>
263
        [% FOREACH gr IN guarantor_relationships %]
264
            <span class="label">Guarantor:</span>
264
            <li>
265
            [% IF guarantor.borrowernumber %]
265
                <span class="label">Guarantor:</span>
266
                <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% guarantor.borrowernumber %]">[% guarantor.firstname | html %] [% guarantor.surname | html %]</a>
266
                [% IF gr.guarantor_id %]
267
            [% ELSE %]
267
                    [% SET guarantor = gr.guarantor %]
268
                [% guarantor.firstname | html %] [% guarantor.surname | html %]
268
                    <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% guarantor.id %]">[% guarantor.firstname %] [% guarantor.surname %]</a>
269
            [% END %]
269
                [% ELSE %]
270
        </li>
270
                    [% gr.firstname %] [% gr.surname %]
271
                [% END %]
272
            </li>
273
        [% END %]
271
    [% END %]
274
    [% END %]
272
</ol>
275
</ol>
273
</div>
276
</div>
274
      <div class="action">
275
        [% IF ( guarantor.borrowernumber ) %]
276
        <a href="memberentry.pl?op=modify&amp;borrowernumber=[% borrowernumber %]&amp;step=1&amp;guarantorid=[% guarantor.borrowernumber %]">Edit</a>
277
        [% ELSE %]
278
        <a href="memberentry.pl?op=modify&amp;borrowernumber=[% borrowernumber %]&amp;step=1">Edit</a>
279
        [% END %]</div>
280
281
</div>
277
</div>
282
278
283
<!-- Begin Upload Patron Image Section -->
279
<!-- Begin Upload Patron Image Section -->
Lines 503-509 function validate1(date) { Link Here
503
    <ul>
499
    <ul>
504
        <li><a href="#checkouts">[% issuecount %] Checkout(s)</a></li>
500
        <li><a href="#checkouts">[% issuecount %] Checkout(s)</a></li>
505
        [% IF relatives_issues_count %]
501
        [% IF relatives_issues_count %]
506
            <li><a href="#relatives-issues" id="relatives-issues-tab">Relatives' checkouts</a></li>
502
            <li><a href="#relatives-issues" id="relatives-issues-tab">[% relatives_issues_count %] Relatives' checkouts</a></li>
507
        [% END %]
503
        [% END %]
508
        <li><a href="#finesandcharges">Fines &amp; Charges</a></li>
504
        <li><a href="#finesandcharges">Fines &amp; Charges</a></li>
509
        <li>
505
        <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 599-609 foreach my $category_type (qw(C A S P I X)) { Link Here
599
        'categoryloop'   => \@categoryloop
593
        'categoryloop'   => \@categoryloop
600
      };
594
      };
601
}
595
}
602
596
$template->param(
603
$template->param('typeloop' => \@typeloop,
597
    typeloop      => \@typeloop,
604
        no_categories => $no_categories);
598
    no_categories => $no_categories,
605
if($no_categories){ $no_add = 1; }
599
);
606
607
600
608
my $cities = Koha::Cities->search( {}, { order_by => 'city_name' } );
601
my $cities = Koha::Cities->search( {}, { order_by => 'city_name' } );
609
my $roadtypes = C4::Koha::GetAuthorisedValues( 'ROADTYPE' );
602
my $roadtypes = C4::Koha::GetAuthorisedValues( 'ROADTYPE' );
Lines 628-651 while (@relationships) { Link Here
628
  push(@relshipdata, \%row);
621
  push(@relshipdata, \%row);
629
}
622
}
630
623
631
my %flags = ( 'gonenoaddress' => ['gonenoaddress' ],
624
my %flags = (
632
        'lost'          => ['lost']);
625
    'gonenoaddress' => ['gonenoaddress'],
626
    'lost'          => ['lost']
627
);
633
628
634
 
635
my @flagdata;
629
my @flagdata;
636
foreach (keys(%flags)) {
630
foreach ( keys(%flags) ) {
637
	my $key = $_;
631
    my $key = $_;
638
	my %row =  ('key'   => $key,
632
    my %row = (
639
		    'name'  => $flags{$key}[0]);
633
        'key'  => $key,
640
	if ($data{$key}) {
634
        'name' => $flags{$key}[0]
641
		$row{'yes'}=' checked';
635
    );
642
		$row{'no'}='';
636
    if ( $data{$key} ) {
643
    }
637
        $row{'yes'} = ' checked';
644
	else {
638
        $row{'no'}  = '';
645
		$row{'yes'}='';
639
    }
646
		$row{'no'}=' checked';
640
    else {
647
	}
641
        $row{'yes'} = '';
648
	push @flagdata,\%row;
642
        $row{'no'}  = ' checked';
643
    }
644
    push @flagdata, \%row;
649
}
645
}
650
646
651
# get Branch Loop
647
# get Branch Loop
Lines 721-727 if (C4::Context->preference('EnhancedMessagingPreferences')) { Link Here
721
    $template->param(TalkingTechItivaPhone => C4::Context->preference("TalkingTechItivaPhoneNotification"));
717
    $template->param(TalkingTechItivaPhone => C4::Context->preference("TalkingTechItivaPhoneNotification"));
722
}
718
}
723
719
724
$template->param( "showguarantor"  => ($category_type=~/A|I|S|X/) ? 0 : 1); # associate with step to know where you are
720
$template->param( "show_guarantor" => ( $category_type =~ /A|I|S|X/ ) ? 0 : 1 ); # associate with step to know where you are
725
$debug and warn "memberentry step: $step";
721
$debug and warn "memberentry step: $step";
726
$template->param(%data);
722
$template->param(%data);
727
$template->param( "step_$step"  => 1) if $step;	# associate with step to know where u are
723
$template->param( "step_$step"  => 1) if $step;	# associate with step to know where u are
Lines 736-753 $template->param( Link Here
736
  "op$op"   => 1);
732
  "op$op"   => 1);
737
733
738
$template->param(
734
$template->param(
739
  nodouble  => $nodouble,
735
    nodouble       => $nodouble,
740
  borrowernumber  => $borrowernumber, #register number
736
    borrowernumber => $borrowernumber,          #register number
741
  guarantorid => ($borrower_data->{'guarantorid'} || $guarantorid),
737
    relshiploop    => \@relshipdata,
742
  relshiploop => \@relshipdata,
738
    btitle         => $default_borrowertitle,
743
  btitle=> $default_borrowertitle,
739
    flagloop       => \@flagdata,
744
  guarantorinfo   => $guarantorinfo,
740
    category_type  => $category_type,
745
  flagloop  => \@flagdata,
741
    modify         => $modify,
746
  category_type =>$category_type,
742
    nok            => $nok,                     #flag to know if an error
747
  modify          => $modify,
743
    NoUpdateLogin  => $NoUpdateLogin,
748
  nok     => $nok,#flag to know if an error
744
);
749
  NoUpdateLogin =>  $NoUpdateLogin,
750
  );
751
745
752
# Generate CSRF token
746
# Generate CSRF token
753
$template->param(
747
$template->param(
Lines 868-873 sub patron_attributes_form { Link Here
868
862
869
}
863
}
870
864
865
sub add_guarantors {
866
    my ( $borrowernumber, $input ) = @_;
867
868
    my @new_guarantor_id           = scalar $input->param('new_guarantor_id');
869
    my @new_guarantor_surname      = scalar $input->param('new_guarantor_surname');
870
    my @new_guarantor_firstname    = scalar $input->param('new_guarantor_firstname');
871
    my @new_guarantor_relationship = scalar $input->param('new_guarantor_relationship');
872
873
    for ( my $i = 0 ; $i < scalar @new_guarantor_id; $i++ ) {
874
        my $guarantor_id = $new_guarantor_id[$i];
875
        my $surname      = $new_guarantor_surname[$i];
876
        my $firstname    = $new_guarantor_firstname[$i];
877
        my $relationship = $new_guarantor_relationship[$i];
878
879
        if ($guarantor_id) {
880
            Koha::Patron::Relationship->new(
881
                {
882
                    guarantee_id => $borrowernumber,
883
                    guarantor_id => $guarantor_id,
884
                    relationship => $relationship
885
                }
886
            )->store();
887
        }
888
        elsif ($surname) {
889
            Koha::Patron::Relationship->new(
890
                {
891
                    guarantee_id => $borrowernumber,
892
                    surname      => $surname,
893
                    firstname    => $firstname,
894
                    relationship => $relationship
895
                }
896
            )->store();
897
        }
898
    }
899
}
900
871
# Local Variables:
901
# Local Variables:
872
# tab-width: 8
902
# tab-width: 8
873
# End:
903
# End:
(-)a/members/moremember.pl (-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 / +25 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
            $guarantor_id ||= undef;
381
            Koha::Patron::Relationship->new(
382
                {
383
                    guarantee_id => $borrowernumber,
384
                    relationship => $relationship,
385
                    guarantor_id => $guarantor_id,
386
                    firstname    => $guarantor_firstname,
387
                    surname      => $guarantor_surname,
388
                }
389
            )->store();
390
        }
367
    }
391
    }
392
368
    (@errors  ) and $template->param(  ERRORS=>\@errors  );
393
    (@errors  ) and $template->param(  ERRORS=>\@errors  );
369
    (@feedback) and $template->param(FEEDBACK=>\@feedback);
394
    (@feedback) and $template->param(FEEDBACK=>\@feedback);
370
    $template->param(
395
    $template->param(
371
- 

Return to bug 14570