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

(-)a/C4/Circulation.pm (-1 / +1 lines)
Lines 862-868 sub CanBookBeIssued { Link Here
862
    $no_issues_charge_guarantees = undef unless looks_like_number( $no_issues_charge_guarantees );
862
    $no_issues_charge_guarantees = undef unless looks_like_number( $no_issues_charge_guarantees );
863
    if ( defined $no_issues_charge_guarantees ) {
863
    if ( defined $no_issues_charge_guarantees ) {
864
        my $p = Koha::Patrons->find( $borrower->{borrowernumber} );
864
        my $p = Koha::Patrons->find( $borrower->{borrowernumber} );
865
        my @guarantees = $p->guarantees();
865
        my @guarantees = map { $_->guarantee } $p->guarantee_relationships();
866
        my $guarantees_non_issues_charges;
866
        my $guarantees_non_issues_charges;
867
        foreach my $g ( @guarantees ) {
867
        foreach my $g ( @guarantees ) {
868
            my ( $b, $n, $o ) = C4::Members::GetMemberAccountBalance( $g->id );
868
            my ( $b, $n, $o ) = C4::Members::GetMemberAccountBalance( $g->id );
(-)a/C4/Members.pm (-6 / +6 lines)
Lines 1820-1837 sub GetBorrowersToExpunge { Link Here
1820
        FROM   borrowers
1820
        FROM   borrowers
1821
        JOIN   categories USING (categorycode)
1821
        JOIN   categories USING (categorycode)
1822
        LEFT JOIN (
1822
        LEFT JOIN (
1823
            SELECT guarantorid
1823
            SELECT guarantor_id
1824
            FROM borrowers
1824
            FROM relationships
1825
            WHERE guarantorid IS NOT NULL
1825
            WHERE guarantor_id IS NOT NULL
1826
                AND guarantorid <> 0
1826
                AND guarantor_id <> 0
1827
        ) as tmp ON borrowers.borrowernumber=tmp.guarantorid
1827
        ) as tmp ON borrowers.borrowernumber=tmp.guarantor_id
1828
        LEFT JOIN old_issues USING (borrowernumber)
1828
        LEFT JOIN old_issues USING (borrowernumber)
1829
        LEFT JOIN issues USING (borrowernumber)|;
1829
        LEFT JOIN issues USING (borrowernumber)|;
1830
    if ( $filterpatronlist  ){
1830
    if ( $filterpatronlist  ){
1831
        $query .= q| LEFT JOIN patron_list_patrons USING (borrowernumber)|;
1831
        $query .= q| LEFT JOIN patron_list_patrons USING (borrowernumber)|;
1832
    }
1832
    }
1833
    $query .= q| WHERE  category_type <> 'S'
1833
    $query .= q| WHERE  category_type <> 'S'
1834
        AND tmp.guarantorid IS NULL
1834
        AND tmp.guarantor_id IS NULL
1835
   |;
1835
   |;
1836
    my @query_params;
1836
    my @query_params;
1837
    if ( $filterbranch && $filterbranch ne "" ) {
1837
    if ( $filterbranch && $filterbranch ne "" ) {
(-)a/Koha/Item.pm (+11 lines)
Lines 23-28 use Carp; Link Here
23
23
24
use Koha::Database;
24
use Koha::Database;
25
25
26
use Koha::Biblios;
26
use Koha::Patrons;
27
use Koha::Patrons;
27
use Koha::Libraries;
28
use Koha::Libraries;
28
29
Lines 107-112 sub last_returned_by { Link Here
107
    }
108
    }
108
}
109
}
109
110
111
=head3 biblio
112
113
=cut
114
115
sub biblio {
116
    my ( $self ) = @_;
117
118
    return Koha::Biblios->find( $self->biblionumber );
119
}
120
110
=head3 type
121
=head3 type
111
122
112
=cut
123
=cut
(-)a/Koha/Patron.pm (-30 / +55 lines)
Lines 24-29 use Carp; Link Here
24
use Koha::Database;
24
use Koha::Database;
25
use Koha::Patrons;
25
use Koha::Patrons;
26
use Koha::Patron::Images;
26
use Koha::Patron::Images;
27
use Koha::Patron::Checkouts;
28
use Koha::Patron::Relationships;
27
29
28
use base qw(Koha::Object);
30
use base qw(Koha::Object);
29
31
Lines 37-72 Koha::Patron - Koha Patron Object class Link Here
37
39
38
=cut
40
=cut
39
41
40
=head3 guarantor
42
=head3 image
41
42
Returns a Koha::Patron object for this patron's guarantor
43
43
44
=cut
44
=cut
45
45
46
sub guarantor {
46
sub image {
47
    my ( $self ) = @_;
47
    my ( $self ) = @_;
48
48
49
    return unless $self->guarantorid();
49
    return Koha::Patron::Images->find( $self->borrowernumber )
50
51
    return Koha::Patrons->find( $self->guarantorid() );
52
}
50
}
53
51
54
sub image {
52
=head3 checkouts
53
54
=cut
55
56
sub checkouts {
55
    my ( $self ) = @_;
57
    my ( $self ) = @_;
56
58
57
    return Koha::Patron::Images->find( $self->borrowernumber )
59
    return Koha::Patron::Checkouts->search( { borrowernumber => $self->id } );
58
}
60
}
59
61
60
=head3 guarantees
62
=head3 guarantor_relationships
63
64
Returns Koha::Patron::Relationships object for this patron's guarantor
65
66
Returns the set of relationships for the patrons that are guarantors for this patron.
61
67
62
Returns the guarantees (list of Koha::Patron) of this patron
68
This is returned instead of a Koha::Patron object because the guarantor
69
may not exist as a patron in Koha. If this is true, the guarantors name
70
exists in the Koha::Patron::Relationship object and will have no guarantor_id.
63
71
64
=cut
72
=cut
65
73
66
sub guarantees {
74
sub guarantor_relationships {
67
    my ( $self ) = @_;
75
    my ($self) = @_;
68
76
69
    return Koha::Patrons->search( { guarantorid => $self->borrowernumber } );
77
    return Koha::Patron::Relationships->search( { guarantee_id => $self->id } );
78
}
79
80
=head3 guarantee_relationships
81
82
Returns Koha::Patron::Relationships object for this patron's guarantors
83
84
Returns the set of relationships for the patrons that are guarantees for this patron.
85
86
The method returns Koha::Patron::Relationship objects for the sake
87
of consistency with the guantors method.
88
A guarantee by definition must exist as a patron in Koha.
89
90
=cut
91
92
sub guarantee_relationships {
93
    my ($self) = @_;
94
95
    return Koha::Patron::Relationships->search( { guarantor_id => $self->id } );
70
}
96
}
71
97
72
=head3 siblings
98
=head3 siblings
Lines 76-98 Returns the siblings of this patron. Link Here
76
=cut
102
=cut
77
103
78
sub siblings {
104
sub siblings {
79
    my ( $self ) = @_;
105
    my ($self) = @_;
106
107
    my @guarantors = $self->guarantor_relationships()->guarantors();
108
109
    return unless @guarantors;
110
111
    my @siblings =
112
      map { $_->guarantee_relationships()->guarantees() } @guarantors;
113
114
    return unless @siblings;
115
116
    my %seen;
117
    @siblings =
118
      grep { !$seen{ $_->id }++ && ( $_->id != $self->id ) } @siblings;
80
119
81
    my $guarantor = $self->guarantor;
120
    return wantarray ? @siblings : Koha::Patrons->search( { borrowernumber => { -in => [ map { $_->id } @siblings ] } } );
82
83
    return unless $guarantor;
84
85
    return Koha::Patrons->search(
86
        {
87
            guarantorid => {
88
                '!=' => undef,
89
                '=' => $guarantor->id,
90
            },
91
            borrowernumber => {
92
                '!=' => $self->borrowernumber,
93
            }
94
        }
95
    );
96
}
121
}
97
122
98
=head3 type
123
=head3 type
(-)a/Koha/Patron/Checkout.pm (+57 lines)
Line 0 Link Here
1
package Koha::Patron::Checkout;
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 C4::Context;
23
24
use Koha::Database;
25
use Koha::Items;
26
27
use base qw(Koha::Object);
28
29
=head1 NAME
30
31
Koha::Patron::Checkout - Koha Checkout Object class
32
33
=head1 API
34
35
=head2 Class Methods
36
37
=cut
38
39
=head3 item
40
41
=cut
42
43
sub item {
44
    my ( $self ) = @_;
45
46
    return Koha::Items->find( $self->itemnumber );
47
}
48
49
=head3 _type
50
51
=cut
52
53
sub _type {
54
    return 'Issue';
55
}
56
57
1;
(-)a/Koha/Patron/Checkouts.pm (+50 lines)
Line 0 Link Here
1
package Koha::Patron::Checkouts;
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 Koha::Patron::Checkout;
25
26
use base qw(Koha::Objects);
27
28
=head1 NAME
29
30
Koha::Patron::Checkouts - Koha Checkout Object set class
31
32
=head1 API
33
34
=head2 Class Methods
35
36
=cut
37
38
=head3 _type
39
40
=cut
41
42
sub _type {
43
    return 'Issue';
44
}
45
46
sub object_class {
47
    return 'Koha::Patron::Checkout';
48
}
49
50
1;
(-)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/Borrower.pm (-2 / +32 lines)
Lines 1008-1013 __PACKAGE__->has_many( Link Here
1008
  { cascade_copy => 0, cascade_delete => 0 },
1008
  { cascade_copy => 0, cascade_delete => 0 },
1009
);
1009
);
1010
1010
1011
=head2 relationships_guarantees
1012
1013
Type: has_many
1014
1015
Related object: L<Koha::Schema::Result::Relationship>
1016
1017
=cut
1018
1019
__PACKAGE__->has_many(
1020
  "relationships_guarantees",
1021
  "Koha::Schema::Result::Relationship",
1022
  { "foreign.guarantee_id" => "self.borrowernumber" },
1023
  { cascade_copy => 0, cascade_delete => 0 },
1024
);
1025
1026
=head2 relationships_guarantors
1027
1028
Type: has_many
1029
1030
Related object: L<Koha::Schema::Result::Relationship>
1031
1032
=cut
1033
1034
__PACKAGE__->has_many(
1035
  "relationships_guarantors",
1036
  "Koha::Schema::Result::Relationship",
1037
  { "foreign.guarantor_id" => "self.borrowernumber" },
1038
  { cascade_copy => 0, cascade_delete => 0 },
1039
);
1040
1011
=head2 reserves
1041
=head2 reserves
1012
1042
1013
Type: has_many
1043
Type: has_many
Lines 1204-1211 Composing rels: L</aqorder_users> -> ordernumber Link Here
1204
__PACKAGE__->many_to_many("ordernumbers", "aqorder_users", "ordernumber");
1234
__PACKAGE__->many_to_many("ordernumbers", "aqorder_users", "ordernumber");
1205
1235
1206
1236
1207
# Created by DBIx::Class::Schema::Loader v0.07042 @ 2016-02-14 12:46:14
1237
# Created by DBIx::Class::Schema::Loader v0.07042 @ 2016-05-03 13:19:34
1208
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:bI6qJYw+ulTUwA7XMCkkRw
1238
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:1u8SP/oLjNEtEIOYd14t9w
1209
1239
1210
__PACKAGE__->belongs_to(
1240
__PACKAGE__->belongs_to(
1211
    "guarantor",
1241
    "guarantor",
(-)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 (-4 / +4 lines)
Lines 596-606 my $view = $batch Link Here
596
my @relatives;
596
my @relatives;
597
if ( $borrowernumber ) {
597
if ( $borrowernumber ) {
598
    if ( my $patron = Koha::Patrons->find( $borrower->{borrowernumber} ) ) {
598
    if ( my $patron = Koha::Patrons->find( $borrower->{borrowernumber} ) ) {
599
        if ( my $guarantor = $patron->guarantor ) {
599
        if ( my @guarantors = $patron->guarantor_relationships()->guarantors() ) {
600
            push @relatives, $guarantor->borrowernumber;
600
            push( @relatives, $_->id ) for @guarantors;
601
            push @relatives, $_->borrowernumber for $patron->siblings;
601
            push( @relatives, $_->id ) for $patron->siblings();
602
        } else {
602
        } else {
603
            push @relatives, $_->borrowernumber for $patron->guarantees;
603
            push( @relatives, $_->id ) for $patron->guarantee_relationships()->guarantees();
604
        }
604
        }
605
    }
605
    }
606
}
606
}
(-)a/installer/data/mysql/atomicupdate/bug_14560.sql (+18 lines)
Line 0 Link Here
1
DROP TABLE IF EXISTS relationships;
2
CREATE TABLE `relationships` (
3
      id INT(11) NOT NULL AUTO_INCREMENT,
4
      guarantor_id INT(11) NULL DEFAULT NULL,
5
      guarantee_id INT(11) NOT NULL,
6
      relationship VARCHAR(100) COLLATE utf8_unicode_ci NOT NULL,
7
      surname MEDIUMTEXT COLLATE utf8_unicode_ci NULL DEFAULT NULL,
8
      firstname MEDIUMTEXT COLLATE utf8_unicode_ci NULL DEFAULT NULL,
9
      PRIMARY KEY (id),
10
      CONSTRAINT r_guarantor FOREIGN KEY ( guarantor_id ) REFERENCES borrowers ( borrowernumber ) ON UPDATE CASCADE ON DELETE CASCADE,
11
      CONSTRAINT r_guarantee FOREIGN KEY ( guarantee_id ) REFERENCES borrowers ( borrowernumber ) ON UPDATE CASCADE ON DELETE CASCADE
12
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
13
14
UPDATE borrowers LEFT JOIN borrowers guarantor ON ( borrowers.guarantorid = guarantor.borrowernumber ) SET borrowers.guarantorid = NULL WHERE guarantor.borrowernumber IS NULL;
15
16
INSERT INTO relationships ( guarantor_id, guarantee_id, relationship, surname, firstname ) SELECT guarantorid, borrowernumber, relationship, contactname, contactfirstname FROM borrowers WHERE guarantorid IS NOT NULL OR contactname != "";
17
18
ALTER TABLE borrowers DROP guarantorid, DROP relationship, DROP contactname, DROP contactfirstname, DROP contacttitle;
(-)a/installer/data/mysql/kohastructure.sql (-16 / +17 lines)
Lines 591-602 CREATE TABLE `deletedborrowers` ( -- stores data related to the patrons/borrower Link Here
591
  `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
591
  `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
592
  `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)
592
  `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)
593
  `debarredcomment` VARCHAR(255) DEFAULT NULL, -- comment on the stop of patron
593
  `debarredcomment` VARCHAR(255) DEFAULT NULL, -- comment on the stop of patron
594
  `contactname` mediumtext, -- used for children and profesionals to include surname or last name of guarentor or organization name
595
  `contactfirstname` text, -- used for children to include first name of guarentor
596
  `contacttitle` text, -- used for children to include title (Mr., Mrs., etc) of guarentor
597
  `guarantorid` int(11) default NULL, -- borrowernumber used for children or professionals to link them to guarentors or organizations
598
  `borrowernotes` mediumtext, -- a note on the patron/borrower's account that is only visible in the staff client
594
  `borrowernotes` mediumtext, -- a note on the patron/borrower's account that is only visible in the staff client
599
  `relationship` varchar(100) default NULL, -- used for children to include the relationship to their guarentor
600
  `sex` varchar(1) default NULL, -- patron/borrower's gender
595
  `sex` varchar(1) default NULL, -- patron/borrower's gender
601
  `password` varchar(60) default NULL, -- patron/borrower's encrypted password
596
  `password` varchar(60) default NULL, -- patron/borrower's encrypted password
602
  `flags` int(11) default NULL, -- will include a number associated with the staff member's permissions
597
  `flags` int(11) default NULL, -- will include a number associated with the staff member's permissions
Lines 1596-1607 CREATE TABLE `borrowers` ( -- this table includes information about your patrons Link Here
1596
  `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
1591
  `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
1597
  `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)
1592
  `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)
1598
  `debarredcomment` VARCHAR(255) DEFAULT NULL, -- comment on the stop of the patron
1593
  `debarredcomment` VARCHAR(255) DEFAULT NULL, -- comment on the stop of the patron
1599
  `contactname` mediumtext, -- used for children and profesionals to include surname or last name of guarentor or organization name
1600
  `contactfirstname` text, -- used for children to include first name of guarentor
1601
  `contacttitle` text, -- used for children to include title (Mr., Mrs., etc) of guarentor
1602
  `guarantorid` int(11) default NULL, -- borrowernumber used for children or professionals to link them to guarentors or organizations
1603
  `borrowernotes` mediumtext, -- a note on the patron/borrower's account that is only visible in the staff client
1594
  `borrowernotes` mediumtext, -- a note on the patron/borrower's account that is only visible in the staff client
1604
  `relationship` varchar(100) default NULL, -- used for children to include the relationship to their guarentor
1605
  `sex` varchar(1) default NULL, -- patron/borrower's gender
1595
  `sex` varchar(1) default NULL, -- patron/borrower's gender
1606
  `password` varchar(60) default NULL, -- patron/borrower's encrypted password
1596
  `password` varchar(60) default NULL, -- patron/borrower's encrypted password
1607
  `flags` int(11) default NULL, -- will include a number associated with the staff member's permissions
1597
  `flags` int(11) default NULL, -- will include a number associated with the staff member's permissions
Lines 1628-1634 CREATE TABLE `borrowers` ( -- this table includes information about your patrons Link Here
1628
  KEY `categorycode` (`categorycode`),
1618
  KEY `categorycode` (`categorycode`),
1629
  KEY `branchcode` (`branchcode`),
1619
  KEY `branchcode` (`branchcode`),
1630
  UNIQUE KEY `userid` (`userid`),
1620
  UNIQUE KEY `userid` (`userid`),
1631
  KEY `guarantorid` (`guarantorid`),
1632
  KEY `surname_idx` (`surname`(255)),
1621
  KEY `surname_idx` (`surname`(255)),
1633
  KEY `firstname_idx` (`firstname`(255)),
1622
  KEY `firstname_idx` (`firstname`(255)),
1634
  KEY `othernames_idx` (`othernames`(255)),
1623
  KEY `othernames_idx` (`othernames`(255)),
Lines 3349-3360 CREATE TABLE IF NOT EXISTS `borrower_modifications` ( Link Here
3349
  `lost` tinyint(1) DEFAULT NULL,
3338
  `lost` tinyint(1) DEFAULT NULL,
3350
  `debarred` date DEFAULT NULL,
3339
  `debarred` date DEFAULT NULL,
3351
  `debarredcomment` varchar(255) DEFAULT NULL,
3340
  `debarredcomment` varchar(255) DEFAULT NULL,
3352
  `contactname` mediumtext,
3353
  `contactfirstname` text,
3354
  `contacttitle` text,
3355
  `guarantorid` int(11) DEFAULT NULL,
3356
  `borrowernotes` mediumtext,
3341
  `borrowernotes` mediumtext,
3357
  `relationship` varchar(100) DEFAULT NULL,
3358
  `sex` varchar(1) DEFAULT NULL,
3342
  `sex` varchar(1) DEFAULT NULL,
3359
  `password` varchar(30) DEFAULT NULL,
3343
  `password` varchar(30) DEFAULT NULL,
3360
  `flags` int(11) DEFAULT NULL,
3344
  `flags` int(11) DEFAULT NULL,
Lines 3774-3779 CREATE TABLE `hold_fill_targets` ( Link Here
3774
    REFERENCES `branches` (`branchcode`) ON DELETE CASCADE ON UPDATE CASCADE
3758
    REFERENCES `branches` (`branchcode`) ON DELETE CASCADE ON UPDATE CASCADE
3775
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
3759
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
3776
3760
3761
--
3762
-- Table structure for table 'guarantors_guarantees'
3763
--
3764
3765
DROP TABLE IF EXISTS relationships;
3766
CREATE TABLE `relationships` (
3767
      id INT(11) NOT NULL AUTO_INCREMENT,
3768
      guarantor_id INT(11) NULL DEFAULT NULL,
3769
      guarantee_id INT(11) NOT NULL,
3770
      relationship VARCHAR(100) COLLATE utf8_unicode_ci NOT NULL,
3771
      surname MEDIUMTEXT COLLATE utf8_unicode_ci NULL DEFAULT NULL,
3772
      firstname MEDIUMTEXT COLLATE utf8_unicode_ci NULL DEFAULT NULL,
3773
      PRIMARY KEY (id),
3774
      CONSTRAINT r_guarantor FOREIGN KEY ( guarantor_id ) REFERENCES borrowers ( borrowernumber ) ON UPDATE CASCADE ON DELETE CASCADE,
3775
      CONSTRAINT r_guarantee FOREIGN KEY ( guarantee_id ) REFERENCES borrowers ( borrowernumber ) ON UPDATE CASCADE ON DELETE CASCADE
3776
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
3777
3777
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
3778
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
3778
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
3779
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
3779
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
3780
/*!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 (-6 / +3 lines)
Lines 136-152 function searchToHold(){ Link Here
136
136
137
<div id="toolbar" class="btn-toolbar">
137
<div id="toolbar" class="btn-toolbar">
138
    [% IF ( CAN_user_borrowers ) %]
138
    [% IF ( CAN_user_borrowers ) %]
139
        [% IF ( guarantor ) %]
140
            <a id="editpatron" class="btn btn-small" href="/cgi-bin/koha/members/memberentry.pl?op=modify&amp;destination=circ&amp;borrowernumber=[% borrowernumber %]&amp;guarantorid=[% guarantorborrowernumber %]&amp;categorycode=[% categorycode %]">
141
        [% ELSE %]
142
            <a id="editpatron" class="btn btn-small" href="/cgi-bin/koha/members/memberentry.pl?op=modify&amp;destination=circ&amp;borrowernumber=[% borrowernumber %]&amp;categorycode=[% categorycode %]">
139
            <a id="editpatron" class="btn btn-small" href="/cgi-bin/koha/members/memberentry.pl?op=modify&amp;destination=circ&amp;borrowernumber=[% borrowernumber %]&amp;categorycode=[% categorycode %]">
143
        [% END %]
140
                <i class="fa fa-pencil"></i> Edit
144
        <i class="fa fa-pencil"></i> Edit</a>
141
            </a>
145
    [% END %]
142
    [% END %]
146
143
147
    [% IF ( CAN_user_borrowers ) %]
144
    [% IF ( CAN_user_borrowers ) %]
148
        [% IF ( adultborrower AND activeBorrowerRelationship ) %]
145
        [% IF ( adultborrower AND activeBorrowerRelationship ) %]
149
            <a id="addchild" class="btn btn-small" href="/cgi-bin/koha/members/memberentry.pl?op=add&amp;guarantorid=[% borrowernumber %]"><i class="fa fa-plus"></i> Add child</a>
146
            <a id="addchild" class="btn btn-small" href="/cgi-bin/koha/members/memberentry.pl?op=add&amp;guarantor_id=[% borrowernumber %]"><i class="fa fa-plus"></i> Add child</a>
150
        [% END %]
147
        [% END %]
151
        [% IF ( CAN_user_borrowers ) %]
148
        [% IF ( CAN_user_borrowers ) %]
152
            <a id="changepassword" class="btn btn-small" href="/cgi-bin/koha/members/member-password.pl?member=[% borrowernumber %]"><i class="fa fa-lock"></i> Change password</a>
149
            <a id="changepassword" class="btn btn-small" href="/cgi-bin/koha/members/member-password.pl?member=[% borrowernumber %]"><i class="fa fa-lock"></i> Change password</a>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt (-1 / +1 lines)
Lines 892-898 No patron matched <span class="ex">[% message %]</span> Link Here
892
    </li>
892
    </li>
893
893
894
    [% IF relatives_issues_count %]
894
    [% IF relatives_issues_count %]
895
        <li><a id="relatives-issues-tab" href="#relatives-issues">Relatives' checkouts</a></li>
895
        <li><a id="relatives-issues-tab" href="#relatives-issues">[% relatives_issues_count %] Relatives' checkouts</a></li>
896
    [% END %]
896
    [% END %]
897
897
898
    <li>
898
    <li>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt (-125 / +198 lines)
Lines 1-3 Link Here
1
[% USE To %]
1
[% USE Koha %]
2
[% USE Koha %]
2
[% USE KohaDates %]
3
[% USE KohaDates %]
3
[% INCLUDE 'doc-head-open.inc' %]
4
[% INCLUDE 'doc-head-open.inc' %]
Lines 6-39 Link Here
6
[% INCLUDE 'calendar.inc' %]
7
[% INCLUDE 'calendar.inc' %]
7
<script type="text/javascript">
8
<script type="text/javascript">
8
//<![CDATA[
9
//<![CDATA[
9
$(document).ready(function() {
10
    $(document).ready(function() {
10
	[% IF categorycode %]
11
        [% IF categorycode %]
11
		update_category_code( "[% categorycode %]" );
12
            update_category_code( "[% categorycode %]" );
12
	[% ELSE %]
13
        [% ELSE %]
13
		if ( $("#categorycode_entry").length > 0 ){
14
            if ( $("#categorycode_entry").length > 0 ){
14
			var category_code = $("#categorycode_entry").find("option:selected").val();
15
                var category_code = $("#categorycode_entry").find("option:selected").val();
15
			update_category_code( category_code );
16
                update_category_code( category_code );
16
		}
17
            }
17
	[% END %]
18
        [% END %]
18
});
19
19
20
        var MSG_SEPARATOR = _("Separator must be / in field %s");
20
        [% IF guarantor %]
21
        var MSG_INCORRECT_DAY = _("Invalid day entered in field %s");
21
            select_user( '[% guarantor.borrowernumber %]', [% To.json( guarantor.unblessed ) %] );
22
        var MSG_INCORRECT_MONTH = _("Invalid month entered in field %s");
22
            $('#guarantor_add').ready(function() {
23
        var MSG_INCORRECT_YEAR = _("Invalid year entered in field %s");
23
                $('#guarantor_add').click();
24
        var MSG_DUPLICATE_PATRON = _("Warning: Duplicate patron");
24
            });
25
        var MSG_DUPLICATE_ORGANIZATION = _("Warning: Duplicate organization");
25
        [% END %]
26
        var MSG_LATE_EXPIRY = _("Warning: Expiration date falls before enrollment date");
26
    });
27
        var MSG_DUPLICATE_SUSPICION = _("Please confirm whether this is a duplicate patron");
27
28
        var MSG_PASSWORD_MISMATCH = _("The passwords entered do not match");
28
    var MSG_SEPARATOR = _("Separator must be / in field %s");
29
        var MSG_PASSWORD_CONTAINS_TRAILING_SPACES = _("Password contains leading and/or trailing spaces.");
29
    var MSG_INCORRECT_DAY = _("Invalid day entered in field %s");
30
        var MSG_MONTH = _("%s month")
30
    var MSG_INCORRECT_MONTH = _("Invalid month entered in field %s");
31
        var MSG_MONTHS = _("%s months")
31
    var MSG_INCORRECT_YEAR = _("Invalid year entered in field %s");
32
        var MSG_YEAR = _("%s year")
32
    var MSG_DUPLICATE_PATRON = _("Warning: Duplicate patron");
33
        var MSG_YEARS = _("%s years")
33
    var MSG_DUPLICATE_ORGANIZATION = _("Warning: Duplicate organization");
34
        var LABEL_CHANGE = _("Change");
34
    var MSG_LATE_EXPIRY = _("Warning: Expiration date falls before enrollment date");
35
        var LABEL_SET_TO_PATRON = _("Set to patron");
35
    var MSG_DUPLICATE_SUSPICION = _("Please confirm whether this is a duplicate patron");
36
        var LABEL_AGE = _("Age");
36
    var MSG_PASSWORD_MISMATCH = _("The passwords entered do not match");
37
    var MSG_PASSWORD_CONTAINS_TRAILING_SPACES = _("Password contains leading and/or trailing spaces.");
38
    var MSG_MONTH = _("%s month")
39
    var MSG_MONTHS = _("%s months")
40
    var MSG_YEAR = _("%s year")
41
    var MSG_YEARS = _("%s years")
42
    var LABEL_CHANGE = _("Change");
43
    var LABEL_SET_TO_PATRON = _("Set to patron");
44
    var LABEL_AGE = _("Age");
37
45
38
//]]>
46
//]]>
39
</script>
47
</script>
Lines 289-394 $(document).ready(function() { Link Here
289
	</fieldset>
297
	</fieldset>
290
[% END # hide fieldset %]
298
[% END # hide fieldset %]
291
299
292
[% IF ( showguarantor ) %]
300
[% IF show_guarantor || guarantor %]
293
    <input type="hidden" id="guarantorid" name="guarantorid"   value="[% guarantorid %]" />
301
    [% SET possible_relationships = Koha.Preference('borrowerRelationship') %]
294
    [% UNLESS step_6 %]
302
    <fieldset class="rows">
295
        <input type="hidden" name="branchcode" value="[% branchcode %]" />
303
        <legend>Guarantor information</legend>
296
    [% END %]
304
297
    <fieldset id="memberentry_guarantor" class="rows">
305
        <span id="guarantor_relationships">
298
        <legend id="guarantor_lgd">Guarantor information</legend>
306
            [% FOREACH r IN relationships %]
299
        <ol>
307
                <fieldset class="rows">
300
[% IF ( P ) %]
308
                    <ol>
301
	        [% IF ( guarantorid ) %]
309
                        [% IF catetory_type == 'P' %]
302
	        <li id="contact-details">
310
                            [% IF ( r.guarantor_id ) %]
303
	        [% ELSE %]
311
                                <li id="contact-details">
304
	        <li id="contact-details" style="display: none">
312
                            [% ELSE %]
305
	        [% END %]
313
                                <li id="contact-details" style="display: none">
306
	            <span class="label">Organization #:</span> [% IF ( guarantorid ) %] <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% guarantorid %]" target="blank">[% guarantorid %]</a>[% END %]
314
                            [% END %]
307
	        </li>
315
                                <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 %]
308
	        <li>
316
                            </li>
309
	            <label for="contactname">Organization name: </label>
317
310
	            [% IF ( guarantorid ) %]
318
                            <li>
311
	            <span>[% contactname %]</span>
319
                                <label for="guarantor_surname">Organization name: </label>
312
	            <input name="contactname" id="contactname" type="hidden" size="20" value="[% contactname %]" />
320
                                [% IF ( r.guarantor_id ) %]
313
	            [% ELSE %]
321
                                    <span>[% r.guarantor.surname %]</span>
314
                    <input name="contactname" id="contactname" type="text" size="20" value="[% contactname %]" />
322
                                [% END %]
315
	            [% END %]
323
                            </li>
316
	        </li>
324
                        [% ELSE %]
317
[% ELSE %]
325
                            [% IF category_type == 'C'  %]
318
 [% IF ( C ) %]
326
                                [% IF ( r.guarantor_id ) %]
319
 [% IF ( guarantorid ) %]
327
                                    <li id="contact-details">
320
 <li id="contact-details">
328
                                [% ELSE %]
321
 [% ELSE %]
329
                                    <li id="contact-details" style="display: none">
322
 <li id="contact-details" style="display: none">
330
                                [% END %]
323
 [% END %]
331
324
     <span class="label">Patron #:</span> [% IF ( guarantorid ) %] <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% guarantorid %]" target="blank">[% guarantorid %]</a>[% END %]
332
                                    <span class="label">Patron #:</span>
325
 </li>
333
                                    [% IF ( r.guarantor_id ) %]
326
        [% UNLESS nocontactname %]
334
                                        <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% r.guarantor_id %]" target="blank">[% r.guarantor_id %]</a>
327
 <li>
335
                                    [% END %]
328
     <label for="contactname">Surname: </label>
336
329
     [% IF ( guarantorid ) %]
337
                                </li>
330
     <span>[% contactname %]</span>
338
331
     <input name="contactname" id="contactname" type="hidden" size="20" value="[% contactname %]" />
339
                                [% IF r.surname || r.guarantor.surname %]
332
     [% ELSE %]
340
                                    <li>
333
        <input name="contactname" id="contactname" type="text" size="20" value="[% contactname %]" />
341
                                        <label for="guarantor_surname">Surname: </label>
334
     [% END %]
342
                                        <span>[% r.surname || r.guarantor.surname %]</span>
335
 </li>
343
                                    </li>
336
        [% END %]
344
                                [% END %]
337
        [% UNLESS nocontactfirstname %]
345
338
 <li>
346
                                [% IF r.firstname || r.guarantor.firstname  %]
339
     <label for="contactfirstname">First name: </label>
347
                                    <li>
340
     [% IF ( guarantorid ) %]
348
                                        <label for="guarantor_firstname">First name: </label>
341
     <span>[% contactfirstname %]</span>
349
                                        <span>[% r.firstname || r.guarantor.firstname %]</span>
342
     <input name="contactfirstname" id="contactfirstname" type="hidden" size="20" value="[% contactfirstname %]" />
350
                                    </li>
343
     [% ELSE %]
351
                                [% END %]
344
        <input name="contactfirstname" id="contactfirstname" type="text" size="20" value="[% contactfirstname %]" />
352
345
     [% END %]
353
                                <li>
346
 </li>
354
                                    <label for="relationship">Relationship: </label>
347
        [% END %]
355
                                    <span>[% r.relationship %]</span>
348
 [% IF ( relshiploop ) %]
356
                                </li>
349
 <li>
357
350
     <label for="relationship">Relationship: </label>
358
                                <li>
351
     <select name="relationship" id="relationship" >
359
                                    <label for="delete_guarantor">Delete: </label>
352
         [% FOREACH relshiploo IN relshiploop %]
360
                                    <input type="checkbox" name="delete_guarantor" value="[% r.id %]" />
353
         [% IF ( relshiploo.selected ) %]
361
                                </li>
354
         <option value="[% relshiploo.relationship %]" selected="selected" >[% relshiploo.relationship %]</option>
362
                            [% END %]
355
         [% ELSE %]
363
                        [% END %]
356
         <option value="[% relshiploo.relationship %]">[% relshiploo.relationship %]</option>
364
                    </ol>
357
         [% END %]
365
                </fieldset>
358
         [% END %]
366
            [% END # END relationships foreach %]
359
     </select>
367
        </span>
360
 </li>
368
361
 [% END %]
369
        <fieldset class="rows guarantor" id="guarantor_template">
362
 [% END %]
370
            <ol>
363
[% END %]
371
                <li class="guarantor_id">
364
        <li>
372
                    <span class="label">Patron #:</span>
365
            <span class="label">&nbsp;</span>
373
                    <span class="new_guarantor_id_text"></span>
366
            [% IF ( guarantorid ) %]
374
                    <input type="hidden" class="new_guarantor_id" name="new_guarantor_id" value=""/>
367
            <input id="guarantorsearch" type="button" value="Change" onclick="Dopopguarantor('guarantor_search.pl');" />
375
                </li>
368
            [% ELSE %]
376
369
            <input id="guarantorsearch" type="button" value="Set to patron" onclick="Dopopguarantor('guarantor_search.pl');" />
377
                <li>
370
            [% END %]
378
                    <label for="guarantor_surname">Surname: </label>
371
            <input id="guarantordelete" type="button" value="Delete" />
379
                    <span class="new_guarantor_surname_text"></span>
372
        </li>
380
                    <input type="hidden" class="new_guarantor_surname" name="new_guarantor_surname" value=""/>
373
    [% IF guarantorid && Koha.Preference('AllowStaffToSetCheckoutsVisibilityForGuarantor') %]
381
                </li>
374
        <li>
382
375
            <label for="privacy_guarantor_checkouts">Show checkouts to guarantor</label>
383
                <li>
376
            <select name="privacy_guarantor_checkouts" id="privacy_guarantor_checkouts">
384
                    <label for="guarantor_firstname">First name: </label>
377
                [% IF privacy_guarantor_checkouts %]
385
                    <span class="new_guarantor_firstname_text"></span>
378
                    <option value="0">No</option>
386
                    <input type="hidden" class="new_guarantor_firstname" name="new_guarantor_firstname" value=""/>
379
                    <option value="1" selected>Yes</option>
387
                </li>
388
389
                <li>
390
                    <label for="guarantor_relationship">Relationship: </label>
391
                    <select class="new_guarantor_relationship" name="new_guarantor_relationship">
392
                        [% FOREACH pr IN possible_relationships.split('\|') %]
393
                            <option value="[% pr %]">[% pr %]</option>
394
                        [% END %]
395
                    </select>
396
                </li>
397
398
                <li>
399
                    <label for="guarantor_cancel">&nbsp;</label>
400
                    <span><a href="#" class="guarantor_cancel">Cancel</a></span>
401
                </li>
402
            </ol>
403
        </fieldset>
404
405
        <fieldset class="rows">
406
            <legend>Add new guarantor</legend>
407
            <ol>
408
                <input type="hidden" id="guarantor_id" value=""/>
409
410
                [% IF catetory_type == 'P' %]
411
                    <li>
412
                        <label for="guarantor_surname">Organization name: </label>
413
                        <input name="guarantor_surname" id="guarantor_surname" type="hidden" size="20"/>
414
                    </li>
380
                [% ELSE %]
415
                [% ELSE %]
381
                    <option value="0" selected>No</option>
416
                    <li>
382
                    <option value="1">Yes</option>
417
                        <label for="guarantor_surname">Surname: </label>
418
                        <input name="guarantor_surname" id="guarantor_surname" type="text" size="20" />
419
                    </li>
420
421
                    <li>
422
                        <label for="guarantor_firstname">First name: </label>
423
                        <input name="guarantor_firstname" id="guarantor_firstname" type="text" size="20" />
424
                    </li>
425
426
                    [% IF ( possible_relationships ) %]
427
                        <li>
428
                            <label for="relationship">Relationship: </label>
429
                            <select name="relationship" id="relationship" >
430
                                [% FOREACH pr IN possible_relationships.split('\|') %]
431
                                    <option value="[% pr %]">[% pr %]</option>
432
                                [% END %]
433
                            </select>
434
                        </li>
435
                    [% END %]
383
                [% END %]
436
                [% END %]
384
            </select>
385
            <div class="hint">Allow guarantor of this patron to view this patron's checkouts from the OPAC</div>
386
        </li>
387
    [% END %]
388
        </ol>
389
    </fieldset>
390
437
438
                <li>
439
                    <span class="label">&nbsp;</span>
440
                    <a href="#" id="guarantor_add" class="btn btn-small"><i class="fa fa-plus"></i> Add guarantor</a>
441
                    <a href="#" id="guarantor_search" class="btn btn-small"><i class="fa fa-search"></i> Set to patron</a>
442
                    <a href="#" id="guarantor_clear">Clear</a>
443
                </li>
444
445
                [% IF relationships && Koha.Preference('AllowStaffToSetCheckoutsVisibilityForGuarantor') %]
446
                    <li>
447
                        <label for="privacy_guarantor_checkouts">Show checkouts to guarantors</label>
448
                        <select name="privacy_guarantor_checkouts" id="privacy_guarantor_checkouts">
449
                            [% IF privacy_guarantor_checkouts %]
450
                                <option value="0">No</option>
451
                                <option value="1" selected>Yes</option>
452
                            [% ELSE %]
453
                                <option value="0" selected>No</option>
454
                                <option value="1">Yes</option>
455
                            [% END %]
456
                        </select>
457
                        <div class="hint">Allow guarantors of this patron to view this patron's checkouts from the OPAC</div>
458
                    </li>
459
                [% END %]
460
            </ol>
461
        </fieldset>
462
    </fieldset>
391
[% END %]
463
[% END %]
464
392
[% UNLESS noaddress && noaddress2 && nocity && nostate && nozipcode && nocountry %]
465
[% UNLESS noaddress && noaddress2 && nocity && nostate && nozipcode && nocountry %]
393
    [% IF Koha.Preference( 'AddressFormat' ) %]
466
    [% IF Koha.Preference( 'AddressFormat' ) %]
394
        [% INCLUDE "member-main-address-style-${ Koha.Preference( 'AddressFormat' ) }.inc" %]
467
        [% INCLUDE "member-main-address-style-${ Koha.Preference( 'AddressFormat' ) }.inc" %]
Lines 491-503 $(document).ready(function() { Link Here
491
    [% END # UNLESS noB_address && noB_city && noB_state && noB_phone && noB_email %]
564
    [% END # UNLESS noB_address && noB_city && noB_state && noB_phone && noB_email %]
492
[% END %]
565
[% END %]
493
[% IF ( step_2 ) %]
566
[% IF ( step_2 ) %]
494
    [% UNLESS noaltcontactsurname && noaltcontactfirstname && noaltcontactaddress1 && noaltcontactaddress2 && noaltcontactaddress3 && noaltcontactstate && noaltcontactzipcode && noaltcontactcountry && noaltcontactphone %]
567
    [% UNLESS noaltcontactsurname && noaltguarantor_firstname && noaltcontactaddress1 && noaltcontactaddress2 && noaltcontactaddress3 && noaltcontactstate && noaltcontactzipcode && noaltcontactcountry && noaltcontactphone %]
495
        [% IF Koha.Preference( 'AddressFormat' ) %]
568
        [% IF Koha.Preference( 'AddressFormat' ) %]
496
            [% INCLUDE "member-alt-contact-style-${ Koha.Preference( 'AddressFormat' ) }.inc" %]
569
            [% INCLUDE "member-alt-contact-style-${ Koha.Preference( 'AddressFormat' ) }.inc" %]
497
        [% ELSE %]
570
        [% ELSE %]
498
            [% INCLUDE 'member-alt-contact-style-us.inc' %]
571
            [% INCLUDE 'member-alt-contact-style-us.inc' %]
499
        [% END %]
572
        [% END %]
500
    [% END # UNLESS noaltcontactsurname && noaltcontactfirstname etc %]
573
    [% END # UNLESS noaltcontactsurname && noaltguarantor_firstname etc %]
501
574
502
[% END %]
575
[% END %]
503
[% IF ( step_3 ) %]
576
[% IF ( step_3 ) %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember-brief.tt (-7 / +20 lines)
Lines 50-62 Link Here
50
    <li><span class="label">Initials: </span>[% initials %]</li>
50
    <li><span class="label">Initials: </span>[% initials %]</li>
51
    <li><span class="label">Date of birth:</span>[% dateofbirth | $KohaDates %]</li>
51
    <li><span class="label">Date of birth:</span>[% dateofbirth | $KohaDates %]</li>
52
    <li><span class="label">Gender:</span>[% IF ( sex == 'F' ) %]Female[% ELSIF ( sex == 'M' ) %]Male[% ELSE %][% sex %][% END %]</li>[% END %]
52
    <li><span class="label">Gender:</span>[% IF ( sex == 'F' ) %]Female[% ELSIF ( sex == 'M' ) %]Male[% ELSE %][% sex %][% END %]</li>[% END %]
53
    [% IF ( isguarantee ) %]
53
    [% IF guarantees %]
54
        [% IF ( guaranteeloop ) %]
54
        <li>
55
            <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>
55
            <span class="label">Guarantees:</span>
56
        [% END %]
56
            <ul>
57
    [% ELSE %]
57
                [% FOREACH guarantee IN guarantees %]
58
        [% IF ( guarantorborrowernumber ) %]
58
                    <li><a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% guarantee.borrowernumber %]">[% guarantee.firstname %] [% guarantee.surname %]</a></li>
59
            <li><span class="label">Guarantor:</span><a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% guarantorborrowernumber %]">[% guarantorsurname %], [% guarantorfirstname %]</a></li>
59
                [% END %]
60
            </ul>
61
        </li>
62
    [% ELSIF guarantor_relationships %]
63
        [% FOREACH gr IN guarantor_relationships %]
64
            <li>
65
                <span class="label">Guarantor:</span>
66
                [% IF gr.guarantor_id %]
67
                    [% SET guarantor = gr.guarantor %]
68
                    <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% guarantor.id %]">[% guarantor.firstname %] [% guarantor.surname %]</a>
69
                [% ELSE %]
70
                    [% gr.firstname %] [% gr.surname %]
71
                [% END %]
72
            </li>
60
        [% END %]
73
        [% END %]
61
    [% END %]
74
    [% END %]
62
	</ol>
75
	</ol>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt (-17 / +13 lines)
Lines 247-271 function validate1(date) { Link Here
247
                [% END %]
247
                [% END %]
248
            </ul>
248
            </ul>
249
        </li>
249
        </li>
250
    [% ELSIF guarantor %]
250
    [% ELSIF guarantor_relationships %]
251
        <li>
251
        [% FOREACH gr IN guarantor_relationships %]
252
            <span class="label">Guarantor:</span>
252
            <li>
253
            [% IF guarantor.borrowernumber %]
253
                <span class="label">Guarantor:</span>
254
                <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% guarantor.borrowernumber %]">[% guarantor.firstname %] [% guarantor.surname %]</a>
254
                [% IF gr.guarantor_id %]
255
            [% ELSE %]
255
                    [% SET guarantor = gr.guarantor %]
256
                [% guarantor.firstname %] [% guarantor.surname %]
256
                    <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% guarantor.id %]">[% guarantor.firstname %] [% guarantor.surname %]</a>
257
            [% END %]
257
                [% ELSE %]
258
        </li>
258
                    [% gr.firstname %] [% gr.surname %]
259
                [% END %]
260
            </li>
261
        [% END %]
259
    [% END %]
262
    [% END %]
260
</ol>
263
</ol>
261
</div>
264
</div>
262
      <div class="action">
263
        [% IF ( guarantorborrowernumber ) %]
264
        <a href="memberentry.pl?op=modify&amp;borrowernumber=[% borrowernumber %]&amp;step=1&amp;guarantorid=[% guarantorborrowernumber %]">Edit</a>
265
        [% ELSE %]
266
        <a href="memberentry.pl?op=modify&amp;borrowernumber=[% borrowernumber %]&amp;step=1">Edit</a>
267
        [% END %]</div>
268
269
</div>
265
</div>
270
266
271
<!-- Begin Upload Patron Image Section -->
267
<!-- Begin Upload Patron Image Section -->
Lines 449-455 function validate1(date) { Link Here
449
    <ul>
445
    <ul>
450
        <li><a href="#checkouts">[% issuecount %] Checkout(s)</a></li>
446
        <li><a href="#checkouts">[% issuecount %] Checkout(s)</a></li>
451
        [% IF relatives_issues_count %]
447
        [% IF relatives_issues_count %]
452
            <li><a href="#relatives-issues" id="relatives-issues-tab">Relatives' checkouts</a></li>
448
            <li><a href="#relatives-issues" id="relatives-issues-tab">[% relatives_issues_count %] Relatives' checkouts</a></li>
453
        [% END %]
449
        [% END %]
454
        <li><a href="#finesandcharges">Fines &amp; Charges</a></li>
450
        <li><a href="#finesandcharges">Fines &amp; Charges</a></li>
455
        <li>
451
        <li>
(-)a/koha-tmpl/intranet-tmpl/prog/js/members.js (-39 / +51 lines)
Lines 142-151 function Dopop(link) { Link Here
142
    var newin=window.open(link,'popup','width=600,height=400,resizable=no,toolbar=false,scrollbars=no,top');
142
    var newin=window.open(link,'popup','width=600,height=400,resizable=no,toolbar=false,scrollbars=no,top');
143
}
143
}
144
144
145
function Dopopguarantor(link) {
146
    var newin=window.open(link,'popup','width=800,height=500,resizable=no,toolbar=false,scrollbars=yes,top');
147
}
148
149
function clear_entry(node) {
145
function clear_entry(node) {
150
    var original = $(node).parent();
146
    var original = $(node).parent();
151
    $("textarea", original).attr('value', '');
147
    $("textarea", original).attr('value', '');
Lines 183-218 function update_category_code(category_code) { Link Here
183
}
179
}
184
180
185
function select_user(borrowernumber, borrower) {
181
function select_user(borrowernumber, borrower) {
186
    var form = $('#entryform').get(0);
182
    $('#guarantor_id').val(borrower.borrowernumber);
187
    if (form.guarantorid.value) {
183
    $('#guarantor_surname').val(borrower.surname);
188
        $("#contact-details").find('a').remove();
184
    $('#guarantor_firstname').val(borrower.firstname);
189
        $("#contactname, #contactfirstname").parent().find('span').remove();
190
    }
191
185
192
    var id = borrower.borrowernumber;
186
    $('#guarantor_add').click();
193
    form.guarantorid.value = id;
194
    $('#contact-details')
195
        .show()
196
        .find('span')
197
        .after('<a target="blank" href="/cgi-bin/koha/members/moremember.pl?borrowernumber=' + id + '">' + id + '</a>');
198
199
    $(form.contactname)
200
        .val(borrower.surname)
201
        .before('<span>' + borrower.surname + '</span>').get(0).type = 'hidden';
202
    $(form.contactfirstname)
203
        .val(borrower.firstname)
204
        .before('<span>' + borrower.firstname + '</span>').get(0).type = 'hidden';
205
206
    form.streetnumber.value = borrower.streetnumber;
207
    form.address.value = borrower.address;
208
    form.address2.value = borrower.address2;
209
    form.city.value = borrower.city;
210
    form.state.value = borrower.state;
211
    form.zipcode.value = borrower.zipcode;
212
    form.country.value = borrower.country;
213
    form.branchcode.value = borrower.branchcode;
214
215
    form.guarantorsearch.value = LABEL_CHANGE;
216
187
217
    return 0;
188
    return 0;
218
}
189
}
Lines 286-298 $(document).ready(function(){ Link Here
286
257
287
    $("fieldset.rows input, fieldset.rows select").addClass("noEnterSubmit");
258
    $("fieldset.rows input, fieldset.rows select").addClass("noEnterSubmit");
288
259
289
    $("#guarantordelete").click(function() {
260
    $('#guarantor_template').hide();
261
262
    $('#guarantor_search').on('click', function(e) {
263
        e.preventDefault();
264
        var newin = window.open('guarantor_search.pl','popup','width=600,height=400,resizable=no,toolbar=false,scrollbars=yes,top');
265
    });
266
267
    $('#guarantor_relationships').on('click', '.guarantor_cancel', function(e) {
268
        e.preventDefault();
269
        $(this).parents('fieldset').first().remove();
270
    });
271
272
    $('#guarantor_add').on('click', function(e) {
273
        e.preventDefault();
274
        var fieldset = $('#guarantor_template').clone();
275
        fieldset.removeAttr('id');
276
277
        var guarantor_id = $('#guarantor_id').val();
278
        if ( guarantor_id ) {
279
            fieldset.find('.new_guarantor_id').first().val( guarantor_id );
280
            fieldset.find('.new_guarantor_id_text').first().text( guarantor_id );
281
        } else {
282
            fieldset.find('.guarantor_id').first().hide();
283
        }
284
        $('#guarantor_id').val("");
285
286
        var guarantor_surname = $('#guarantor_surname').val();
287
        fieldset.find('.new_guarantor_surname').first().val( guarantor_surname );
288
        fieldset.find('.new_guarantor_surname_text').first().text( guarantor_surname );
289
        $('#guarantor_surname').val("");
290
291
        var guarantor_firstname = $('#guarantor_firstname').val();
292
        fieldset.find('.new_guarantor_firstname').first().val( guarantor_firstname );
293
        fieldset.find('.new_guarantor_firstname_text').first().text( guarantor_firstname );
294
        $('#guarantor_firstname').val("");
295
296
        var guarantor_relationship = $('#relationship').val();
297
        fieldset.find('.new_guarantor_relationship').first().val( guarantor_relationship );
298
        $('#relationship').find('option:eq(0)').prop('selected', true);;
299
300
        $('#guarantor_relationships').append( fieldset );
301
        fieldset.show();
302
    });
303
304
    $("#guarantor_clear").click(function(e) {
305
        e.preventDefault();
290
        $("#contact-details").hide().find('a').remove();
306
        $("#contact-details").hide().find('a').remove();
291
        $("#guarantorid, #contactname, #contactfirstname").each(function () { this.value = ""; });
307
        $("#guarantor_id, #guarantor_surname, #guarantor_firstname").val("");
292
        $("#contactname, #contactfirstname")
293
            .each(function () { this.type = 'text'; })
294
            .parent().find('span').remove();
295
        $("#guarantorsearch").val(LABEL_SET_TO_PATRON);
296
    });
308
    });
297
309
298
    $("#select_city").change(function(){
310
    $("#select_city").change(function(){
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-memberentry.tt (-2 / +7 lines)
Lines 85-91 Link Here
85
                    <div class="alert">You typed in the wrong characters in the box before submitting. Please try again.</div>
85
                    <div class="alert">You typed in the wrong characters in the box before submitting. Please try again.</div>
86
                [% END %]
86
                [% END %]
87
87
88
                [% IF borrower.guarantorid && !Koha.Preference('OPACPrivacy') && Koha.Preference('AllowPatronToSetCheckoutsVisibilityForGuarantor') %]
88
                [% IF patron.guarantor_relationships && !Koha.Preference('OPACPrivacy') && Koha.Preference('AllowPatronToSetCheckoutsVisibilityForGuarantor') %]
89
                    <fieldset class="rows" id="memberentry_privacy">
89
                    <fieldset class="rows" id="memberentry_privacy">
90
                        <legend id="privacy_legend">Privacy</legend>
90
                        <legend id="privacy_legend">Privacy</legend>
91
                        <ol>
91
                        <ol>
Lines 104-110 Link Here
104
                                    <span id="update_privacy_guarantor_checkouts_message" class="alert" style="display:none"></span>
104
                                    <span id="update_privacy_guarantor_checkouts_message" class="alert" style="display:none"></span>
105
                                </span>
105
                                </span>
106
                                <span class="hint">
106
                                <span class="hint">
107
                                    Your guarantor is <i>[% guarantor.firstname %] [% guarantor.surname %]</i>
107
                                    Guaranteed by
108
                                    [% FOREACH gr IN patron.guarantor_relationships %]
109
                                        [% SET g = gr.guarantor %]
110
                                        [% g.firstname || gr.firstname %] [% g.surname || gr.surname %]
111
                                        [%- IF ! loop.last %], [% END %]
112
                                    [% END %]
108
                                </span>
113
                                </span>
109
                            </li>
114
                            </li>
110
                        </ol>
115
                        </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 350-373 Link Here
350
350
351
                                    <tbody>
351
                                    <tbody>
352
                                        [% FOREACH r IN relatives %]
352
                                        [% FOREACH r IN relatives %]
353
                                            [% FOREACH i IN r.issues %]
353
                                            [% FOREACH c IN r.checkouts %]
354
                                                <tr>
354
                                                <tr>
355
                                                    <td>
355
                                                    <td>
356
                                                        <a href="/cgi-bin/koha/opac-detail.pl?biblionumber=[% i.item.biblio.biblionumber %]">
356
                                                        <a href="/cgi-bin/koha/opac-detail.pl?biblionumber=[% i.item.biblio.biblionumber %]">
357
                                                            [% i.item.biblio.title %]
357
                                                            [% c.item.biblio.title %]
358
                                                        </a>
358
                                                        </a>
359
                                                    </td>
359
                                                    </td>
360
360
361
                                                    <td>
361
                                                    <td>
362
                                                        [% i.date_due | $KohaDates %]
362
                                                        [% c.date_due | $KohaDates %]
363
                                                    </td>
363
                                                    </td>
364
364
365
                                                    <td>
365
                                                    <td>
366
                                                        [% i.item.barcode %]
366
                                                        [% c.item.barcode %]
367
                                                    </td>
367
                                                    </td>
368
368
369
                                                    <td>
369
                                                    <td>
370
                                                        [% i.item.itemcallnumber %]
370
                                                        [% c.item.itemcallnumber %]
371
                                                    </td>
371
                                                    </td>
372
372
373
                                                    <td>
373
                                                    <td>
(-)a/members/deletemem.pl (-12 / +10 lines)
Lines 74-84 my $issues = GetPendingIssues($member); # FIXME: wasteful call when really, Link Here
74
my $countissues = scalar(@$issues);
74
my $countissues = scalar(@$issues);
75
75
76
my ($bor)=GetMemberDetails($member,'');
76
my ($bor)=GetMemberDetails($member,'');
77
my $patron = Koha::Patrons->find( $member );
77
my $flags=$bor->{flags};
78
my $flags=$bor->{flags};
78
my $userenv = C4::Context->userenv;
79
my $userenv = C4::Context->userenv;
79
80
80
 
81
82
if ($bor->{category_type} eq "S") {
81
if ($bor->{category_type} eq "S") {
83
    unless(C4::Auth::haspermission($userenv->{'id'},{'staffaccess'=>1})) {
82
    unless(C4::Auth::haspermission($userenv->{'id'},{'staffaccess'=>1})) {
84
        print $input->redirect("/cgi-bin/koha/members/moremember.pl?borrowernumber=$member&error=CANT_DELETE_STAFF");
83
        print $input->redirect("/cgi-bin/koha/members/moremember.pl?borrowernumber=$member&error=CANT_DELETE_STAFF");
Lines 101-113 if (C4::Context->preference("IndependentBranches")) { Link Here
101
    }
100
    }
102
}
101
}
103
102
104
my $dbh = C4::Context->dbh;
103
if (
105
my $sth=$dbh->prepare("Select * from borrowers where guarantorid=?");
104
       $countissues > 0
106
$sth->execute($member);
105
    || $flags->{'CHARGES'} 
107
my $data=$sth->fetchrow_hashref;
106
    || $patron->guarantee_relationships()->count()
108
if ($countissues > 0 or $flags->{'CHARGES'}  or $data->{'borrowernumber'} or $deletelocal == 0){
107
    || $deletelocal == 0 )
109
    #   print $input->header;
108
{
110
111
    my $patron_image = Koha::Patron::Images->find($bor->{borrowernumber});
109
    my $patron_image = Koha::Patron::Images->find($bor->{borrowernumber});
112
    $template->param( picture => 1 ) if $patron_image;
110
    $template->param( picture => 1 ) if $patron_image;
113
111
Lines 128-134 if ($countissues > 0 or $flags->{'CHARGES'} or $data->{'borrowernumber'} or $de Link Here
128
        email => $bor->{'email'},
126
        email => $bor->{'email'},
129
        branchcode => $bor->{'branchcode'},
127
        branchcode => $bor->{'branchcode'},
130
        branchname => GetBranchName($bor->{'branchcode'}),
128
        branchname => GetBranchName($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-144 if ($countissues > 0 or $flags->{'CHARGES'} or $data->{'borrowernumber'} or $de 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 ($data->{'borrowernumber'}) {
138
    if ( $patron->guarantor_relationships() ) {
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);
(-)a/members/memberentry.pl (-62 / +110 lines)
Lines 75-81 if ( C4::Context->preference('SMSSendDriver') eq 'Email' ) { Link Here
75
    $template->param( sms_providers => \@providers );
75
    $template->param( sms_providers => \@providers );
76
}
76
}
77
77
78
my $guarantorid    = $input->param('guarantorid');
79
my $borrowernumber = $input->param('borrowernumber');
78
my $borrowernumber = $input->param('borrowernumber');
80
my $actionType     = $input->param('actionType') || '';
79
my $actionType     = $input->param('actionType') || '';
81
my $modify         = $input->param('modify');
80
my $modify         = $input->param('modify');
Lines 91-103 $nodouble = 1 if ($op eq 'modify' or $op eq 'duplicate'); # FIXME hack to rep Link Here
91
                                     # isn't a duplicate.  Marking FIXME because this
90
                                     # isn't a duplicate.  Marking FIXME because this
92
                                     # script needs to be refactored.
91
                                     # script needs to be refactored.
93
my $nok           = $input->param('nok');
92
my $nok           = $input->param('nok');
94
my $guarantorinfo = $input->param('guarantorinfo');
95
my $step          = $input->param('step') || 0;
93
my $step          = $input->param('step') || 0;
96
my @errors;
94
my @errors;
97
my $borrower_data;
95
my $borrower_data;
98
my $NoUpdateLogin;
96
my $NoUpdateLogin;
99
my $userenv = C4::Context->userenv;
97
my $userenv = C4::Context->userenv;
100
98
99
## Deal with guarantor stuff
100
my $patron = Koha::Patrons->find($borrowernumber);
101
$template->param( relationships => scalar $patron->guarantor_relationships ) if $patron;
102
103
my $guarantor_id = $input->param('guarantor_id');
104
my $guarantor = Koha::Patrons->find( $guarantor_id ) if $guarantor_id;
105
$template->param( guarantor => $guarantor );
106
107
my @delete_guarantor = $input->param('delete_guarantor');
108
foreach my $id ( @delete_guarantor ) {
109
    my $r = Koha::Patron::Relationships->find( $id );
110
    $r->delete() if $r;
111
}
101
112
102
## Deal with debarments
113
## Deal with debarments
103
$template->param(
114
$template->param(
Lines 134-147 $template->param("minPasswordLength" => $minpw); Link Here
134
my $check_BorrowerMandatoryField=C4::Context->preference("BorrowerMandatoryField");
145
my $check_BorrowerMandatoryField=C4::Context->preference("BorrowerMandatoryField");
135
my @field_check=split(/\|/,$check_BorrowerMandatoryField);
146
my @field_check=split(/\|/,$check_BorrowerMandatoryField);
136
foreach (@field_check) {
147
foreach (@field_check) {
137
	$template->param( "mandatory$_" => 1);    
148
    $template->param( "mandatory$_" => 1 );
138
}
149
}
139
# function to designate unwanted fields
150
# function to designate unwanted fields
140
my $check_BorrowerUnwantedField=C4::Context->preference("BorrowerUnwantedField");
151
my $check_BorrowerUnwantedField=C4::Context->preference("BorrowerUnwantedField");
141
@field_check=split(/\|/,$check_BorrowerUnwantedField);
152
@field_check=split(/\|/,$check_BorrowerUnwantedField);
142
foreach (@field_check) {
153
foreach (@field_check) {
143
    next unless m/\w/o;
154
    next unless m/\w/o;
144
	$template->param( "no$_" => 1);
155
    $template->param( "no$_" => 1 );
145
}
156
}
146
$template->param( "add" => 1 ) if ( $op eq 'add' );
157
$template->param( "add" => 1 ) if ( $op eq 'add' );
147
$template->param( "duplicate" => 1 ) if ( $op eq 'duplicate' );
158
$template->param( "duplicate" => 1 ) if ( $op eq 'duplicate' );
Lines 237-261 if ( ( $op eq 'insert' ) and !$nodouble ) { Link Here
237
    }
248
    }
238
}
249
}
239
250
240
  #recover all data from guarantor address phone ,fax... 
241
if ( $guarantorid ) {
242
    if (my $guarantordata=GetMember(borrowernumber => $guarantorid)) {
243
        $category_type = $guarantordata->{categorycode} eq 'I' ? 'P' : 'C';
244
        $guarantorinfo=$guarantordata->{'surname'}." , ".$guarantordata->{'firstname'};
245
        $newdata{'contactfirstname'}= $guarantordata->{'firstname'};
246
        $newdata{'contactname'}     = $guarantordata->{'surname'};
247
        $newdata{'contacttitle'}    = $guarantordata->{'title'};
248
        if ( $op eq 'add' ) {
249
	        foreach (qw(streetnumber address streettype address2
250
                        zipcode country city state phone phonepro mobile fax email emailpro branchcode
251
                        B_streetnumber B_streettype B_address B_address2
252
                        B_city B_state B_zipcode B_country B_email B_phone)) {
253
		        $newdata{$_} = $guarantordata->{$_};
254
	        }
255
        }
256
    }
257
}
258
259
###############test to take the right zipcode, country and city name ##############
251
###############test to take the right zipcode, country and city name ##############
260
# set only if parameter was passed from the form
252
# set only if parameter was passed from the form
261
$newdata{'city'}    = $input->param('city')    if defined($input->param('city'));
253
$newdata{'city'}    = $input->param('city')    if defined($input->param('city'));
Lines 380-385 if ((!$nok) and $nodouble and ($op eq 'insert' or $op eq 'save')){ Link Here
380
	if ($op eq 'insert'){
372
	if ($op eq 'insert'){
381
		# we know it's not a duplicate borrowernumber or there would already be an error
373
		# we know it's not a duplicate borrowernumber or there would already be an error
382
        $borrowernumber = &AddMember(%newdata);
374
        $borrowernumber = &AddMember(%newdata);
375
        add_guarantors( $borrowernumber );
383
        $newdata{'borrowernumber'} = $borrowernumber;
376
        $newdata{'borrowernumber'} = $borrowernumber;
384
377
385
        # If 'AutoEmailOpacUser' syspref is on, email user their account details from the 'notice' that matches the user's branchcode.
378
        # If 'AutoEmailOpacUser' syspref is on, email user their account details from the 'notice' that matches the user's branchcode.
Lines 435-440 if ((!$nok) and $nodouble and ($op eq 'insert' or $op eq 'save')){ Link Here
435
                                                                # updating any columns in the borrowers table,
428
                                                                # updating any columns in the borrowers table,
436
                                                                # which can happen if we're only editing the
429
                                                                # which can happen if we're only editing the
437
                                                                # patron attributes or messaging preferences sections
430
                                                                # patron attributes or messaging preferences sections
431
        add_guarantors( $borrowernumber );
438
        if (C4::Context->preference('ExtendedPatronAttributes') and $input->param('setting_extended_patron_attributes')) {
432
        if (C4::Context->preference('ExtendedPatronAttributes') and $input->param('setting_extended_patron_attributes')) {
439
            C4::Members::Attributes::SetBorrowerAttributes($borrowernumber, $extended_patron_attributes);
433
            C4::Members::Attributes::SetBorrowerAttributes($borrowernumber, $extended_patron_attributes);
440
        }
434
        }
Lines 513-541 my @typeloop; Link Here
513
my $no_categories = 1;
507
my $no_categories = 1;
514
my $no_add;
508
my $no_add;
515
foreach (qw(C A S P I X)) {
509
foreach (qw(C A S P I X)) {
516
    my $action="WHERE category_type=?";
510
    my $action = "WHERE category_type=?";
517
    my ($categories,$labels)=GetborCatFromCatType($_,$action);
511
518
    if(scalar(@$categories) > 0){ $no_categories = 0; }
512
    my ( $categories, $labels ) = GetborCatFromCatType( $_, $action );
519
	my @categoryloop;
513
520
	foreach my $cat (@$categories){
514
    if ( scalar(@$categories) > 0 ) { $no_categories = 0; }
521
		push @categoryloop,{'categorycode' => $cat,
515
522
			  'categoryname' => $labels->{$cat},
516
    my @categoryloop;
523
			  'categorycodeselected' => ((defined($borrower_data->{'categorycode'}) && 
517
    foreach my $cat (@$categories) {
524
                                                     $cat eq $borrower_data->{'categorycode'}) 
518
        push @categoryloop,
525
                                                     || (defined($categorycode) && $cat eq $categorycode)),
519
          {
526
		};
520
            'categorycode'         => $cat,
527
	}
521
            'categoryname'         => $labels->{$cat},
528
	my %typehash;
522
            'categorycodeselected' => (
529
	$typehash{'typename'}=$_;
523
                (
530
    my $typedescription = "typename_".$typehash{'typename'};
524
                    defined( $borrower_data->{'categorycode'} )
531
	$typehash{'categoryloop'}=\@categoryloop;
525
                      && $cat eq $borrower_data->{'categorycode'}
532
	push @typeloop,{'typename' => $_,
526
                )
527
                  || ( defined($categorycode) && $cat eq $categorycode )
528
            ),
529
          };
530
    }
531
532
    my %typehash;
533
    $typehash{'typename'} = $_;
534
535
    my $typedescription = "typename_" . $typehash{'typename'};
536
    $typehash{'categoryloop'} = \@categoryloop;
537
538
    push @typeloop,
539
      {
540
        'typename'       => $_,
533
        $typedescription => 1,
541
        $typedescription => 1,
534
	  'categoryloop' => \@categoryloop};
542
        'categoryloop'   => \@categoryloop
543
      };
535
}
544
}
536
$template->param('typeloop' => \@typeloop,
545
$template->param(
537
        no_categories => $no_categories);
546
    'typeloop'    => \@typeloop,
538
if($no_categories){ $no_add = 1; }
547
    no_categories => $no_categories
548
);
549
if ($no_categories) { $no_add = 1; }
539
550
540
551
541
my $cities = Koha::Cities->search( {}, { order_by => 'city_name' } );
552
my $cities = Koha::Cities->search( {}, { order_by => 'city_name' } );
Lines 569-592 while (@relationships) { Link Here
569
  push(@relshipdata, \%row);
580
  push(@relshipdata, \%row);
570
}
581
}
571
582
572
my %flags = ( 'gonenoaddress' => ['gonenoaddress' ],
583
my %flags = (
573
        'lost'          => ['lost']);
584
    'gonenoaddress' => ['gonenoaddress'],
585
    'lost'          => ['lost']
586
);
574
587
575
 
576
my @flagdata;
588
my @flagdata;
577
foreach (keys(%flags)) {
589
foreach ( keys(%flags) ) {
578
	my $key = $_;
590
    my $key = $_;
579
	my %row =  ('key'   => $key,
591
    my %row = (
580
		    'name'  => $flags{$key}[0]);
592
        'key'  => $key,
581
	if ($data{$key}) {
593
        'name' => $flags{$key}[0]
582
		$row{'yes'}=' checked';
594
    );
583
		$row{'no'}='';
595
    if ( $data{$key} ) {
596
        $row{'yes'} = ' checked';
597
        $row{'no'}  = '';
584
    }
598
    }
585
	else {
599
    else {
586
		$row{'yes'}='';
600
        $row{'yes'} = '';
587
		$row{'no'}=' checked';
601
        $row{'no'}  = ' checked';
588
	}
602
    }
589
	push @flagdata,\%row;
603
    push @flagdata, \%row;
590
}
604
}
591
605
592
# get Branch Loop
606
# get Branch Loop
Lines 662-668 if (C4::Context->preference('EnhancedMessagingPreferences')) { Link Here
662
    $template->param(TalkingTechItivaPhone => C4::Context->preference("TalkingTechItivaPhoneNotification"));
676
    $template->param(TalkingTechItivaPhone => C4::Context->preference("TalkingTechItivaPhoneNotification"));
663
}
677
}
664
678
665
$template->param( "showguarantor"  => ($category_type=~/A|I|S|X/) ? 0 : 1); # associate with step to know where you are
679
$template->param( "show_guarantor" => ( $category_type =~ /A|I|S|X/ ) ? 0 : 1 ); # associate with step to know where you are
666
$debug and warn "memberentry step: $step";
680
$debug and warn "memberentry step: $step";
667
$template->param(%data);
681
$template->param(%data);
668
$template->param( "step_$step"  => 1) if $step;	# associate with step to know where u are
682
$template->param( "step_$step"  => 1) if $step;	# associate with step to know where u are
Lines 680-689 $template->param( branchloop => $branchloop ) if ( $branchloop ); Link Here
680
$template->param(
694
$template->param(
681
  nodouble  => $nodouble,
695
  nodouble  => $nodouble,
682
  borrowernumber  => $borrowernumber, #register number
696
  borrowernumber  => $borrowernumber, #register number
683
  guarantorid => ($borrower_data->{'guarantorid'} || $guarantorid),
684
  relshiploop => \@relshipdata,
697
  relshiploop => \@relshipdata,
685
  borrotitlepopup => $borrotitlepopup,
698
  borrotitlepopup => $borrotitlepopup,
686
  guarantorinfo   => $guarantorinfo,
687
  flagloop  => \@flagdata,
699
  flagloop  => \@flagdata,
688
  category_type =>$category_type,
700
  category_type =>$category_type,
689
  modify          => $modify,
701
  modify          => $modify,
Lines 795-800 sub patron_attributes_form { Link Here
795
807
796
}
808
}
797
809
810
sub add_guarantors {
811
    my ($borrowernumber) = @_;
812
813
    my @new_guarantor_id           = $input->param('new_guarantor_id');
814
    my @new_guarantor_surname      = $input->param('new_guarantor_surname');
815
    my @new_guarantor_firstname    = $input->param('new_guarantor_firstname');
816
    my @new_guarantor_relationship = $input->param('new_guarantor_relationship');
817
818
    for ( my $i = 0 ; $i < scalar @new_guarantor_id; $i++ ) {
819
        my $guarantor_id = $new_guarantor_id[$i];
820
        my $surname      = $new_guarantor_surname[$i];
821
        my $firstname    = $new_guarantor_firstname[$i];
822
        my $relationship = $new_guarantor_relationship[$i];
823
824
        if ($guarantor_id) {
825
            Koha::Patron::Relationship->new(
826
                {
827
                    guarantee_id => $borrowernumber,
828
                    guarantor_id => $guarantor_id,
829
                    relationship => $relationship
830
                }
831
            )->store();
832
        }
833
        elsif ($surname) {
834
            Koha::Patron::Relationship->new(
835
                {
836
                    guarantee_id => $borrowernumber,
837
                    surname      => $surname,
838
                    firstname    => $firstname,
839
                    relationship => $relationship
840
                }
841
            )->store();
842
        }
843
    }
844
}
845
798
# Local Variables:
846
# Local Variables:
799
# tab-width: 8
847
# tab-width: 8
800
# End:
848
# End:
(-)a/members/moremember.pl (-16 / +14 lines)
Lines 163-186 if ( $category_type eq 'C') { Link Here
163
   $template->param( 'catcode' =>    $catcodes->[0])  if $cnt == 1;
163
   $template->param( 'catcode' =>    $catcodes->[0])  if $cnt == 1;
164
}
164
}
165
165
166
my $patron = Koha::Patrons->find($data->{borrowernumber});
166
my $patron = Koha::Patrons->find( $data->{borrowernumber} );
167
my @relatives;
167
my @relatives;
168
if ( my $guarantor = $patron->guarantor ) {
168
my $guarantor_relationships = $patron->guarantor_relationships();
169
    $template->param( guarantor => $guarantor );
169
my @guarantees              = $patron->guarantee_relationships()->guarantees();
170
    push @relatives, $guarantor->borrowernumber;
170
my @guarantors              = $guarantor_relationships->guarantors();
171
    push @relatives, $_->borrowernumber for $patron->siblings;
171
if (@guarantors) {
172
} elsif ( $patron->contactname || $patron->contactfirstname ) {
172
    push( @relatives, $_->id ) for @guarantors;
173
    $template->param(
173
    push( @relatives, $_->id ) for $patron->siblings();
174
        guarantor => {
175
            firstname => $patron->contactfirstname,
176
            surname   => $patron->contactname,
177
        }
178
    );
179
} else {
180
    my @guarantees = $patron->guarantees;
181
    $template->param( guarantees => \@guarantees );
182
    push @relatives, $_->borrowernumber for @guarantees;
183
}
174
}
175
else {
176
    push( @relatives, $_->id ) for @guarantees;
177
}
178
$template->param(
179
    guarantor_relationships => $guarantor_relationships,
180
    guarantees              => \@guarantees,
181
);
184
182
185
my $relatives_issues_count =
183
my $relatives_issues_count =
186
  Koha::Database->new()->schema()->resultset('Issue')
184
  Koha::Database->new()->schema()->resultset('Issue')
(-)a/members/update-child.pl (-21 / +26 lines)
Lines 33-38 use C4::Context; Link Here
33
use C4::Auth;
33
use C4::Auth;
34
use C4::Output;
34
use C4::Output;
35
use C4::Members;
35
use C4::Members;
36
use Koha::Patrons;
36
37
37
# use Smart::Comments;
38
# use Smart::Comments;
38
39
Lines 53-102 my ( $template, $loggedinuser, $cookie ) = get_template_and_user( Link Here
53
my $borrowernumber = $input->param('borrowernumber');
54
my $borrowernumber = $input->param('borrowernumber');
54
my $catcode        = $input->param('catcode');
55
my $catcode        = $input->param('catcode');
55
my $cattype        = $input->param('cattype');
56
my $cattype        = $input->param('cattype');
56
my $catcode_multi = $input->param('catcode_multi');
57
my $catcode_multi  = $input->param('catcode_multi');
57
my $op             = $input->param('op');
58
my $op             = $input->param('op');
58
59
59
if ( $op eq 'multi' ) {
60
if ( $op eq 'multi' ) {
61
    # FIXME - what are the possible upgrade paths?  C -> A , C -> S ...
62
    #   currently just allowing C -> A because of limitation of API.
60
    my ( $catcodes, $labels ) =
63
    my ( $catcodes, $labels ) =
61
		# FIXME - what are the possible upgrade paths?  C -> A , C -> S ...
62
		#   currently just allowing C -> A because of limitation of API.
63
      GetborCatFromCatType( 'A', 'WHERE category_type = ?' );
64
      GetborCatFromCatType( 'A', 'WHERE category_type = ?' );
64
    my @rows;
65
    my @rows;
65
    foreach my $k ( keys %$labels ) {
66
    foreach my $k ( keys %$labels ) {
66
        my $row;
67
        my $row;
67
        $row->{catcode} = $k;
68
        $row->{catdesc} = $labels->{$k};
69
        my $borcat = GetBorrowercategory( $row->{catcode} );
68
        my $borcat = GetBorrowercategory( $row->{catcode} );
70
        $row->{cattype} = $borcat->{'category_type'};
69
        $row->{cattype} = $borcat->{'category_type'};
70
        $row->{catcode} = $k;
71
        $row->{catdesc} = $labels->{$k};
71
        push @rows, $row;
72
        push @rows, $row;
72
    }
73
    }
73
    $template->param(
74
    $template->param(
74
        MULTI          => 1,
75
        MULTI          => 1,
75
        CATCODE_MULTI          => 1,
76
        CATCODE_MULTI  => 1,
76
        borrowernumber => $borrowernumber,
77
        borrowernumber => $borrowernumber,
77
        CAT_LOOP       => \@rows,
78
        CAT_LOOP       => \@rows,
78
    );
79
    );
79
    output_html_with_http_headers $input, $cookie, $template->output;
80
    output_html_with_http_headers $input, $cookie, $template->output;
80
}
81
}
81
82
elsif ( $op eq 'update' ) {
82
elsif ( $op eq 'update' ) {
83
    my $member = GetMember('borrowernumber'=>$borrowernumber);
83
    my $patron = Koha::Patrons->find($borrowernumber);
84
    $member->{'guarantorid'}  = 0;
84
    $_->delete() for $patrons->guarantor_relationships();
85
    $member->{'categorycode'} = $catcode;
85
86
    my $borcat = GetBorrowercategory($catcode);
86
    my $patron_hashref = patron->unblessed();
87
    $member->{'category_type'} = $borcat->{'category_type'};
87
    my $borcat         = GetBorrowercategory($catcode);
88
    $member->{'description'}   = $borcat->{'description'};
88
    $patron_hashref->{'category_type'} = $borcat->{'category_type'};
89
    delete $member->{password};
89
    $patron_hashref->{'categorycode'}  = $catcode;
90
    ModMember(%$member);
90
    $patron_hashref->{'description'}   = $borcat->{'description'};
91
    delete $patron_hashref->{password};
92
    ModMember(%$patron_hashref);
91
93
92
    if (  $catcode_multi ) {
94
    if ($catcode_multi) {
93
        $template->param(
95
        $template->param(
94
                SUCCESS        => 1,
96
            SUCCESS        => 1,
95
                borrowernumber => $borrowernumber,
97
            borrowernumber => $borrowernumber,
96
                );
98
        );
97
        output_html_with_http_headers $input, $cookie, $template->output;
99
        output_html_with_http_headers $input, $cookie, $template->output;
98
    } else {
100
    }
99
        print $input->redirect("/cgi-bin/koha/members/moremember.pl?borrowernumber=$borrowernumber");
101
    else {
102
        print $input->redirect(
103
            "/cgi-bin/koha/members/moremember.pl?borrowernumber=$borrowernumber"
104
        );
100
    }
105
    }
101
}
106
}
102
107
(-)a/misc/cronjobs/j2a.pl (-12 / +43 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" );
209
240
210
        if ( $res eq '0E0' ) {
241
        if ( $res eq '0E0' ) {
211
            print "No patrons updated\n";
242
            print "No patrons updated\n";
(-)a/opac/opac-memberentry.pl (-2 / +3 lines)
Lines 31-36 use C4::Branch qw(GetBranchesLoop); Link Here
31
use C4::Scrubber;
31
use C4::Scrubber;
32
use Email::Valid;
32
use Email::Valid;
33
use Koha::DateUtils;
33
use Koha::DateUtils;
34
use Koha::Patrons;
34
use Koha::Patron::Images;
35
use Koha::Patron::Images;
35
36
36
my $cgi = new CGI;
37
my $cgi = new CGI;
Lines 240-246 elsif ( $action eq 'edit' ) { #Display logged in borrower's data Link Here
240
241
241
    $template->param(
242
    $template->param(
242
        borrower  => $borrower,
243
        borrower  => $borrower,
243
        guarantor => scalar Koha::Patrons->find($borrowernumber)->guarantor(),
244
        hidden => GetHiddenFields( $mandatory, 'modification' ),
244
        hidden => GetHiddenFields( $mandatory, 'modification' ),
245
    );
245
    );
246
246
Lines 255-261 my $captcha = random_string("CCCCC"); Link Here
255
255
256
$template->param(
256
$template->param(
257
    captcha        => $captcha,
257
    captcha        => $captcha,
258
    captcha_digest => md5_base64($captcha)
258
    captcha_digest => md5_base64($captcha),
259
    patron         => Koha::Patrons->find( $borrowernumber ),
259
);
260
);
260
261
261
output_html_with_http_headers $cgi, $cookie, $template->output, undef, { force_no_caching => 1 };
262
output_html_with_http_headers $cgi, $cookie, $template->output, undef, { force_no_caching => 1 };
(-)a/opac/opac-user.pl (-8 / +9 lines)
Lines 38-43 use Koha::DateUtils; Link Here
38
use Koha::Patron::Debarments qw(IsDebarred);
38
use Koha::Patron::Debarments qw(IsDebarred);
39
use Koha::Holds;
39
use Koha::Holds;
40
use Koha::Database;
40
use Koha::Database;
41
use Koha::Patrons;
41
use Koha::Patron::Messages;
42
use Koha::Patron::Messages;
42
43
43
use constant ATTRIBUTE_SHOW_BARCODE => 'SHOW_BCODE';
44
use constant ATTRIBUTE_SHOW_BARCODE => 'SHOW_BCODE';
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 333-346 if ( $borr->{'opacnote'} ) { Link Here
333
if (   C4::Context->preference('AllowPatronToSetCheckoutsVisibilityForGuarantor')
336
if (   C4::Context->preference('AllowPatronToSetCheckoutsVisibilityForGuarantor')
334
    || C4::Context->preference('AllowStaffToSetCheckoutsVisibilityForGuarantor') )
337
    || C4::Context->preference('AllowStaffToSetCheckoutsVisibilityForGuarantor') )
335
{
338
{
336
    my @relatives =
339
    my @relatives;
337
      Koha::Database->new()->schema()->resultset("Borrower")->search(
340
    # Filter out guarantees that don't want guarantor to see checkouts
338
        {
341
    foreach my $gr ( $patron->guarantee_relationships() ) {
339
            privacy_guarantor_checkouts => 1,
342
        my $g = $gr->guarantee;
340
            'me.guarantorid'           => $borrowernumber
343
        push( @relatives, $g ) if $g->privacy_guarantor_checkouts;
341
        },
344
    }
342
        { prefetch => [ { 'issues' => { 'item' => 'biblio' } } ] }
343
      );
344
    $template->param( relatives => \@relatives );
345
    $template->param( relatives => \@relatives );
345
}
346
}
346
347
(-)a/t/Patron.t (-6 / +2 lines)
Lines 104-110 my $patron = Koha::Patron->new( Link Here
104
        contactname         => 'myContactname',
104
        contactname         => 'myContactname',
105
        contactfirstname    => 'myContactfirstname',
105
        contactfirstname    => 'myContactfirstname',
106
        contacttitle        => 'myContacttitle',
106
        contacttitle        => 'myContacttitle',
107
        guarantorid         => '123454321',
108
        borrowernotes       => 'borrowernotes',
107
        borrowernotes       => 'borrowernotes',
109
        relationship        => 'myRelationship',
108
        relationship        => 'myRelationship',
110
        sex                 => 'M',
109
        sex                 => 'M',
Lines 131-137 my $patron = Koha::Patron->new( Link Here
131
130
132
# patron Accessor tests
131
# patron Accessor tests
133
subtest 'Accessor tests' => sub {
132
subtest 'Accessor tests' => sub {
134
    plan tests => 65;
133
    plan tests => 64;
135
    is( $patron->borrowernumber, '12345',                           'borrowernumber accessor returns correct value' );
134
    is( $patron->borrowernumber, '12345',                           'borrowernumber accessor returns correct value' );
136
    is( $patron->cardnumber,     '1234567890',                      'cardnumber accessor returns correct value' );
135
    is( $patron->cardnumber,     '1234567890',                      'cardnumber accessor returns correct value' );
137
    is( $patron->surname,        'mySurname',                       'surname accessor returns correct value' );
136
    is( $patron->surname,        'mySurname',                       'surname accessor returns correct value' );
Lines 175-181 subtest 'Accessor tests' => sub { Link Here
175
    is( $patron->contactname,         'myContactname',         'contactname accessor returns correct value' );
174
    is( $patron->contactname,         'myContactname',         'contactname accessor returns correct value' );
176
    is( $patron->contactfirstname,    'myContactfirstname',    'contactfirstname accessor returns correct value' );
175
    is( $patron->contactfirstname,    'myContactfirstname',    'contactfirstname accessor returns correct value' );
177
    is( $patron->contacttitle,        'myContacttitle',        'contacttitle accessor returns correct value' );
176
    is( $patron->contacttitle,        'myContacttitle',        'contacttitle accessor returns correct value' );
178
    is( $patron->guarantorid,         '123454321',             'guarantorid accessor returns correct value' );
179
    is( $patron->borrowernotes,       'borrowernotes',         'borrowernotes accessor returns correct value' );
177
    is( $patron->borrowernotes,       'borrowernotes',         'borrowernotes accessor returns correct value' );
180
    is( $patron->relationship,        'myRelationship',        'relationship accessor returns correct value' );
178
    is( $patron->relationship,        'myRelationship',        'relationship accessor returns correct value' );
181
    is( $patron->sex,                 'M',                     'sex accessor returns correct value' );
179
    is( $patron->sex,                 'M',                     'sex accessor returns correct value' );
Lines 201-207 subtest 'Accessor tests' => sub { Link Here
201
199
202
# patron Set tests
200
# patron Set tests
203
subtest 'Set tests' => sub {
201
subtest 'Set tests' => sub {
204
    plan tests => 65;
202
    plan tests => 64;
205
203
206
    $patron->set(
204
    $patron->set(
207
        {
205
        {
Lines 248-254 subtest 'Set tests' => sub { Link Here
248
            contactname         => 'SmyContactname',
246
            contactname         => 'SmyContactname',
249
            contactfirstname    => 'SmyContactfirstname',
247
            contactfirstname    => 'SmyContactfirstname',
250
            contacttitle        => 'SmyContacttitle',
248
            contacttitle        => 'SmyContacttitle',
251
            guarantorid         => '223454321',
252
            borrowernotes       => 'Sborrowernotes',
249
            borrowernotes       => 'Sborrowernotes',
253
            relationship        => 'SmyRelationship',
250
            relationship        => 'SmyRelationship',
254
            sex                 => 'F',
251
            sex                 => 'F',
Lines 316-322 subtest 'Set tests' => sub { Link Here
316
    is( $patron->contactname,         'SmyContactname',                   'contactname field set ok' );
313
    is( $patron->contactname,         'SmyContactname',                   'contactname field set ok' );
317
    is( $patron->contactfirstname,    'SmyContactfirstname',              'contactfirstname field set ok' );
314
    is( $patron->contactfirstname,    'SmyContactfirstname',              'contactfirstname field set ok' );
318
    is( $patron->contacttitle,        'SmyContacttitle',                  'contacttitle field set ok' );
315
    is( $patron->contacttitle,        'SmyContacttitle',                  'contacttitle field set ok' );
319
    is( $patron->guarantorid,         '223454321',                        'guarantorid field set ok' );
320
    is( $patron->borrowernotes,       'Sborrowernotes',                   'borrowernotes field set ok' );
316
    is( $patron->borrowernotes,       'Sborrowernotes',                   'borrowernotes field set ok' );
321
    is( $patron->relationship,        'SmyRelationship',                  'relationship field set ok' );
317
    is( $patron->relationship,        'SmyRelationship',                  'relationship field set ok' );
322
    is( $patron->sex,                 'F',                                'sex field set ok' );
318
    is( $patron->sex,                 'F',                                'sex field set ok' );
(-)a/t/db_dependent/Circulation.t (-1 / +8 lines)
Lines 27-36 use C4::Reserves; Link Here
27
use C4::Overdues qw(UpdateFine);
27
use C4::Overdues qw(UpdateFine);
28
use Koha::DateUtils;
28
use Koha::DateUtils;
29
use Koha::Database;
29
use Koha::Database;
30
use Koha::Patron;
30
31
31
use t::lib::TestBuilder;
32
use t::lib::TestBuilder;
32
33
33
use Test::More tests => 84;
34
use Test::More tests => 87;
34
35
35
BEGIN {
36
BEGIN {
36
    use_ok('C4::Circulation');
37
    use_ok('C4::Circulation');
Lines 302-307 C4::Context->dbh->do("DELETE FROM accountlines"); Link Here
302
    $datedue = dt_from_string( $issue->date_due() );
303
    $datedue = dt_from_string( $issue->date_due() );
303
    is (defined $issue2, 1, "Item 2 checked out, due date: " . $issue2->date_due());
304
    is (defined $issue2, 1, "Item 2 checked out, due date: " . $issue2->date_due());
304
305
306
    my $patron = Koha::Patrons->find( $renewing_borrower->{borrowernumber} );
307
    my @checkouts = $patron->checkouts();
308
    is( @checkouts, 2, "Patron has 2 checkouts" );
309
    is( $checkouts[0]->borrowernumber, $patron->id, 'Checkout 1 patron matches' );
310
    is( $checkouts[1]->borrowernumber, $patron->id, 'Checkout 2 patron matches' );
311
305
312
306
    my $borrowing_borrowernumber = GetItemIssue($itemnumber)->{borrowernumber};
313
    my $borrowing_borrowernumber = GetItemIssue($itemnumber)->{borrowernumber};
307
    is ($borrowing_borrowernumber, $renewing_borrowernumber, "Item checked out to $renewing_borrower->{firstname} $renewing_borrower->{surname}");
314
    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 23-28 use t::lib::TestBuilder; Link Here
23
23
24
use C4::Accounts qw( manualinvoice );
24
use C4::Accounts qw( manualinvoice );
25
use C4::Circulation qw( CanBookBeIssued );
25
use C4::Circulation qw( CanBookBeIssued );
26
use Koha::Patron::Relationship;
26
27
27
my $schema = Koha::Database->new->schema;
28
my $schema = Koha::Database->new->schema;
28
$schema->storage->txn_begin;
29
$schema->storage->txn_begin;
Lines 47-58 my $patron = $builder->build( Link Here
47
my $guarantee = $builder->build(
48
my $guarantee = $builder->build(
48
    {
49
    {
49
        source => 'Borrower',
50
        source => 'Borrower',
50
        value  => {
51
            guarantorid => $patron->{borrowernumber},
52
        }
53
    }
51
    }
54
);
52
);
55
53
54
my $r = Koha::Patron::Relationship->new(
55
    {
56
        guarantor_id => $patron->{borrowernumber},
57
        guarantee_id => $guarantee->{borrowernumber},
58
        relationship => 'parent',
59
    }
60
)->store();
61
56
C4::Context->set_preference( 'NoIssuesChargeGuarantees', '5.00' );
62
C4::Context->set_preference( 'NoIssuesChargeGuarantees', '5.00' );
57
63
58
my ( $issuingimpossible, $needsconfirmation ) = CanBookBeIssued( $patron, $item->{barcode} );
64
my ( $issuingimpossible, $needsconfirmation ) = CanBookBeIssued( $patron, $item->{barcode} );
(-)a/t/db_dependent/Items.t (-1 / +5 lines)
Lines 426-432 subtest 'SearchItems test' => sub { Link Here
426
426
427
subtest 'Koha::Item(s) tests' => sub {
427
subtest 'Koha::Item(s) tests' => sub {
428
428
429
    plan tests => 5;
429
    plan tests => 7;
430
430
431
    $schema->storage->txn_begin();
431
    $schema->storage->txn_begin();
432
432
Lines 455-460 subtest 'Koha::Item(s) tests' => sub { Link Here
455
    is( ref($holdingbranch), 'Koha::Library', "Got Koha::Library from holding_branch method" );
455
    is( ref($holdingbranch), 'Koha::Library', "Got Koha::Library from holding_branch method" );
456
    is( $holdingbranch->branchcode(), $library2->{branchcode}, "Home branch code matches holdingbranch" );
456
    is( $holdingbranch->branchcode(), $library2->{branchcode}, "Home branch code matches holdingbranch" );
457
457
458
    my $biblio = $item->biblio();
459
    is( ref($biblio), 'Koha::Biblio', "Got Koha::Biblio from biblio method" );
460
    is( $biblio->title(), 'Silence in the library', 'Title matches biblio title' );
461
458
    $schema->storage->txn_rollback;
462
    $schema->storage->txn_rollback;
459
};
463
};
460
464
(-)a/t/db_dependent/Koha/Patrons.t (-15 / +21 lines)
Lines 23-28 use Test::More tests => 5; Link Here
23
23
24
use Koha::Patron;
24
use Koha::Patron;
25
use Koha::Patrons;
25
use Koha::Patrons;
26
use Koha::Patron::Relationship;
26
use Koha::Database;
27
use Koha::Database;
27
28
28
use t::lib::TestBuilder;
29
use t::lib::TestBuilder;
Lines 58-95 is( $retrieved_patron_1->cardnumber, $new_patron_1->cardnumber, 'Find a patron b Link Here
58
59
59
subtest 'guarantees' => sub {
60
subtest 'guarantees' => sub {
60
    plan tests => 8;
61
    plan tests => 8;
61
    my $guarantees = $new_patron_1->guarantees;
62
    my $guarantees = $new_patron_1->guarantee_relationships;
62
    is( ref($guarantees), 'Koha::Patrons', 'Koha::Patron->guarantees should return a Koha::Patrons result set in a scalar context' );
63
    is( ref($guarantees), 'Koha::Patron::Relationships', 'Koha::Patron->guarantees should return a Koha::Patrons result set in a scalar context' );
63
    is( $guarantees->count, 0, 'new_patron_1 should have 0 guarantee' );
64
    is( $guarantees->count, 0, 'new_patron_1 should have 0 guarantee relationships' );
64
    my @guarantees = $new_patron_1->guarantees;
65
    my @guarantees = $new_patron_1->guarantee_relationships;
65
    is( ref(\@guarantees), 'ARRAY', 'Koha::Patron->guarantees should return an array in a list context' );
66
    is( ref(\@guarantees), 'ARRAY', 'Koha::Patron->guarantee_relationships should return an array in a list context' );
66
    is( scalar(@guarantees), 0, 'new_patron_1 should have 0 guarantee' );
67
    is( scalar(@guarantees), 0, 'new_patron_1 should have 0 guarantee' );
67
68
68
    my $guarantee_1 = $builder->build({ source => 'Borrower', value => { guarantorid => $new_patron_1->borrowernumber }});
69
    my $guarantee_1 = $builder->build({ source => 'Borrower' });
69
    my $guarantee_2 = $builder->build({ source => 'Borrower', value => { guarantorid => $new_patron_1->borrowernumber }});
70
    my $relationship_1 = Koha::Patron::Relationship->new( { guarantor_id => $new_patron_1->id, guarantee_id => $guarantee_1->{borrowernumber} } )->store();
71
    my $guarantee_2 = $builder->build({ source => 'Borrower' });
72
    my $relationship_2 = Koha::Patron::Relationship->new( { guarantor_id => $new_patron_1->id, guarantee_id => $guarantee_2->{borrowernumber} } )->store();
70
73
71
    $guarantees = $new_patron_1->guarantees;
74
    $guarantees = $new_patron_1->guarantee_relationships;
72
    is( ref($guarantees), 'Koha::Patrons', 'Koha::Patron->guarantees should return a Koha::Patrons result set in a scalar context' );
75
    is( ref($guarantees), 'Koha::Patron::Relationships', 'Koha::Patron->guarantee_relationships should return a Koha::Patrons result set in a scalar context' );
73
    is( $guarantees->count, 2, 'new_patron_1 should have 2 guarantees' );
76
    is( $guarantees->count, 2, 'new_patron_1 should have 2 guarantees' );
74
    @guarantees = $new_patron_1->guarantees;
77
    @guarantees = $new_patron_1->guarantee_relationships;
75
    is( ref(\@guarantees), 'ARRAY', 'Koha::Patron->guarantees should return an array in a list context' );
78
    is( ref(\@guarantees), 'ARRAY', 'Koha::Patron->guarantee_relationships should return an array in a list context' );
76
    is( scalar(@guarantees), 2, 'new_patron_1 should have 2 guarantees' );
79
    is( scalar(@guarantees), 2, 'new_patron_1 should have 2 guarantees' );
77
    $_->delete for @guarantees;
80
    map { $_->guarantee->delete } @guarantees;
78
};
81
};
79
82
80
subtest 'siblings' => sub {
83
subtest 'siblings' => sub {
81
    plan tests => 7;
84
    plan tests => 7;
82
    my $siblings = $new_patron_1->siblings;
85
    my $siblings = $new_patron_1->siblings;
83
    is( $siblings, undef, 'Koha::Patron->siblings should not crashed if the patron has no guarantor' );
86
    is( $siblings, undef, 'Koha::Patron->siblings should not crashed if the patron has no guarantor' );
84
    my $guarantee_1 = $builder->build( { source => 'Borrower', value => { guarantorid => $new_patron_1->borrowernumber } } );
87
    my $guarantee_1 = $builder->build( { source => 'Borrower' } );
88
    my $relationship_1 = Koha::Patron::Relationship->new( { guarantor_id => $new_patron_1->borrowernumber, guarantee_id => $guarantee_1->{borrowernumber} } )->store();
85
    my $retrieved_guarantee_1 = Koha::Patrons->find($guarantee_1);
89
    my $retrieved_guarantee_1 = Koha::Patrons->find($guarantee_1);
86
    $siblings = $retrieved_guarantee_1->siblings;
90
    $siblings = $retrieved_guarantee_1->siblings;
87
    is( ref($siblings), 'Koha::Patrons', 'Koha::Patron->siblings should return a Koha::Patrons result set in a scalar context' );
91
    is( ref($siblings), 'Koha::Patrons', 'Koha::Patron->siblings should return a Koha::Patrons result set in a scalar context' );
88
    my @siblings = $retrieved_guarantee_1->siblings;
92
    my @siblings = $retrieved_guarantee_1->siblings;
89
    is( ref( \@siblings ), 'ARRAY', 'Koha::Patron->siblings should return an array in a list context' );
93
    is( ref( \@siblings ), 'ARRAY', 'Koha::Patron->siblings should return an array in a list context' );
90
    is( $siblings->count,  0,       'guarantee_1 should not have siblings yet' );
94
    is( $siblings->count,  0,       'guarantee_1 should not have siblings yet' );
91
    my $guarantee_2 = $builder->build( { source => 'Borrower', value => { guarantorid => $new_patron_1->borrowernumber } } );
95
    my $guarantee_2 = $builder->build( { source => 'Borrower' } );
92
    my $guarantee_3 = $builder->build( { source => 'Borrower', value => { guarantorid => $new_patron_1->borrowernumber } } );
96
    my $relationship_2 = Koha::Patron::Relationship->new( { guarantor_id => $new_patron_1->borrowernumber, guarantee_id => $guarantee_2->{borrowernumber} } )->store();
97
    my $guarantee_3 = $builder->build( { source => 'Borrower' } );
98
    my $relationship_3 = Koha::Patron::Relationship->new( { guarantor_id => $new_patron_1->borrowernumber, guarantee_id => $guarantee_3->{borrowernumber} } )->store();
93
    $siblings = $retrieved_guarantee_1->siblings;
99
    $siblings = $retrieved_guarantee_1->siblings;
94
    is( $siblings->count,               2,                               'guarantee_1 should have 2 siblings' );
100
    is( $siblings->count,               2,                               'guarantee_1 should have 2 siblings' );
95
    is( $guarantee_2->{borrowernumber}, $siblings->next->borrowernumber, 'guarantee_2 should exist in the guarantees' );
101
    is( $guarantee_2->{borrowernumber}, $siblings->next->borrowernumber, 'guarantee_2 should exist in the guarantees' );
(-)a/t/db_dependent/Members.t (-2 / +4 lines)
Lines 23-28 use Data::Dumper; Link Here
23
use C4::Context;
23
use C4::Context;
24
use Koha::Database;
24
use Koha::Database;
25
use Koha::List::Patron;
25
use Koha::List::Patron;
26
use Koha::Patron::Relationship;
26
27
27
28
28
use t::lib::Mocks;
29
use t::lib::Mocks;
Lines 329-335 $patstodel = GetBorrowersToExpunge( {not_borrowed_since => '2016-01-02', patron_ Link Here
329
ok( scalar(@$patstodel) == 1 && $patstodel->[0]->{'borrowernumber'} eq $bor2inlist,'Staff patron not deleted by last issue date');
330
ok( scalar(@$patstodel) == 1 && $patstodel->[0]->{'borrowernumber'} eq $bor2inlist,'Staff patron not deleted by last issue date');
330
331
331
ModMember( borrowernumber => $bor1inlist, categorycode => 'CIVILIAN' );
332
ModMember( borrowernumber => $bor1inlist, categorycode => 'CIVILIAN' );
332
ModMember( borrowernumber => $guarantee->{borrowernumber} ,guarantorid=>$bor1inlist );
333
my $relationship = Koha::Patron::Relationship->new( { guarantor_id => $bor1inlist, guarantee_id => $guarantee->{borrowernumber} } )->store();
333
334
334
$patstodel = GetBorrowersToExpunge( {patron_list_id => $list1->patron_list_id()} );
335
$patstodel = GetBorrowersToExpunge( {patron_list_id => $list1->patron_list_id()} );
335
ok( scalar(@$patstodel)== 1 && $patstodel->[0]->{'borrowernumber'} eq $bor2inlist,'Guarantor patron not deleted from list');
336
ok( scalar(@$patstodel)== 1 && $patstodel->[0]->{'borrowernumber'} eq $bor2inlist,'Guarantor patron not deleted from list');
Lines 339-345 $patstodel = GetBorrowersToExpunge( {expired_before => '2015-01-02', patron_list Link Here
339
ok( scalar(@$patstodel) == 1 && $patstodel->[0]->{'borrowernumber'} eq $bor2inlist,'Guarantor patron not deleted by expirationdate and list');
340
ok( scalar(@$patstodel) == 1 && $patstodel->[0]->{'borrowernumber'} eq $bor2inlist,'Guarantor patron not deleted by expirationdate and list');
340
$patstodel = GetBorrowersToExpunge( {not_borrowed_since => '2016-01-02', patron_list_id => $list1->patron_list_id() } );
341
$patstodel = GetBorrowersToExpunge( {not_borrowed_since => '2016-01-02', patron_list_id => $list1->patron_list_id() } );
341
ok( scalar(@$patstodel) == 1 && $patstodel->[0]->{'borrowernumber'} eq $bor2inlist,'Guarantor patron not deleted by last issue date');
342
ok( scalar(@$patstodel) == 1 && $patstodel->[0]->{'borrowernumber'} eq $bor2inlist,'Guarantor patron not deleted by last issue date');
342
ModMember( borrowernumber => $guarantee->{borrowernumber}, guarantorid=>'' );
343
344
$relationship->delete();
343
345
344
$builder->build({
346
$builder->build({
345
        source => 'Issue',
347
        source => 'Issue',
(-)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 / +26 lines)
Lines 312-317 if ( $uploadborrowers && length($uploadborrowers) > 0 ) { Link Here
312
                }
312
                }
313
            }
313
            }
314
314
315
            # Add a guarantor if we are given a relationship
316
            if ( $borrower{relationship} ) {
317
                Koha::Patron::Relationship->new(
318
                    {
319
                        guarantee_id => $borrowernumber,
320
                        relationship => $borrower{relationship},
321
                        guarantor_id => $borrower{guarantorid} || undef,
322
                        firstname    => $borrower{contactfirstname} || undef,
323
                        surname      => $borrower{contactsurname} || undef,
324
                    }
325
                )->store();
326
            }
327
315
            if ($extended) {
328
            if ($extended) {
316
                if ($ext_preserve) {
329
                if ($ext_preserve) {
317
                    my $old_attributes = GetBorrowerAttributes($borrowernumber);
330
                    my $old_attributes = GetBorrowerAttributes($borrowernumber);
Lines 339-344 if ( $uploadborrowers && length($uploadborrowers) > 0 ) { Link Here
339
                    );
352
                    );
340
                }
353
                }
341
354
355
                # Add a guarantor if we are given a relationship
356
                if ( $borrower{relationship} ) {
357
                    Koha::Patron::Relationship->new(
358
                        {
359
                            guarantee_id => $borrowernumber,
360
                            relationship => $borrower{relationship},
361
                            guarantor_id => $borrower{guarantorid} || undef,
362
                            firstname    => $borrower{contactfirstname} || undef,
363
                            surname      => $borrower{contactsurname} || undef,
364
                        }
365
                    )->store();
366
                }
367
342
                if ($extended) {
368
                if ($extended) {
343
                    SetBorrowerAttributes($borrowernumber, $patron_attributes);
369
                    SetBorrowerAttributes($borrowernumber, $patron_attributes);
344
                }
370
                }
345
- 

Return to bug 14570