Browse Source

Bug 12461 - Add patron clubs feature

This features would add the ability to create clubs which patrons may be
enrolled in. It would be particularly useful for tracking summer reading
programs, book clubs and other such clubs.

Test Plan:
1) Apply this patch
2) Run updatedatabase.pl
3) Ensure your staff user has the new 'Patron clubs' permissions
4) Under the tools menu, click the "Patron clubs" link
5) Create a new club template
   * Here you can add fields that can be filled out at the time
     a new club is created based on the template, or a new enrollment
     is created for a given club based on the template.
6) Create a new club based on that template
7) Attempt to enroll a patron in that club
8) Create a club with email required set
9) Attempt to enroll a patron without an email address in that club
10) Create a club that is enrollable from the OPAC
11) Attempt to enroll a patron in that club
12) Attempt to cancel a club enrollment from the OPAC
13) Attempt to cancel a club enrollment from the staff interface

Followed test plan, works as expected.
Signed-off-by: Marc Véron <veron@veron.ch>
17.05.x
Kyle Hall 10 years ago
parent
commit
4f1eefdbb8
  1. 5
      C4/Auth.pm
  2. 16
      C4/Members.pm
  3. 92
      Koha/Club.pm
  4. 78
      Koha/Club/Enrollment.pm
  5. 56
      Koha/Club/Enrollment/Field.pm
  6. 60
      Koha/Club/Enrollment/Fields.pm
  7. 60
      Koha/Club/Enrollments.pm
  8. 66
      Koha/Club/Field.pm
  9. 60
      Koha/Club/Fields.pm
  10. 75
      Koha/Club/Template.pm
  11. 54
      Koha/Club/Template/EnrollmentField.pm
  12. 60
      Koha/Club/Template/EnrollmentFields.pm
  13. 54
      Koha/Club/Template/Field.pm
  14. 60
      Koha/Club/Template/Fields.pm
  15. 60
      Koha/Club/Templates.pm
  16. 92
      Koha/Clubs.pm
  17. 38
      Koha/Patron.pm
  18. 4
      Koha/Schema/Result/AuthorisedValue.pm
  19. 15
      Koha/Schema/Result/Borrower.pm
  20. 49
      Koha/Schema/Result/Branch.pm
  21. 197
      Koha/Schema/Result/Club.pm
  22. 201
      Koha/Schema/Result/ClubEnrollment.pm
  23. 112
      Koha/Schema/Result/ClubEnrollmentField.pm
  24. 112
      Koha/Schema/Result/ClubField.pm
  25. 195
      Koha/Schema/Result/ClubTemplate.pm
  26. 119
      Koha/Schema/Result/ClubTemplateEnrollmentField.pm
  27. 119
      Koha/Schema/Result/ClubTemplateField.pm
  28. 4
      Koha/Template/Plugin/AuthorisedValues.pm
  29. 1
      Koha/Template/Plugin/Borrowers.pm
  30. 107
      clubs/clubs-add-modify.pl
  31. 60
      clubs/clubs.pl
  32. 55
      clubs/patron-clubs-tab.pl
  33. 50
      clubs/patron-enroll.pl
  34. 152
      clubs/templates-add-modify.pl
  35. 131
      installer/data/mysql/atomicupdate/bug_12461.sql
  36. 126
      installer/data/mysql/kohastructure.sql
  37. 3
      installer/data/mysql/userflags.sql
  38. 5
      installer/data/mysql/userpermissions.sql
  39. 4
      koha-tmpl/intranet-tmpl/prog/en/includes/permissions.inc
  40. 3
      koha-tmpl/intranet-tmpl/prog/en/includes/tools-menu.inc
  41. 23
      koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt
  42. 115
      koha-tmpl/intranet-tmpl/prog/en/modules/clubs/clubs-add-modify.tt
  43. 252
      koha-tmpl/intranet-tmpl/prog/en/modules/clubs/clubs.tt
  44. 102
      koha-tmpl/intranet-tmpl/prog/en/modules/clubs/patron-clubs-tab.tt
  45. 66
      koha-tmpl/intranet-tmpl/prog/en/modules/clubs/patron-enroll.tt
  46. 216
      koha-tmpl/intranet-tmpl/prog/en/modules/clubs/templates-add-modify.tt
  47. 22
      koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt
  48. 5
      koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt
  49. 102
      koha-tmpl/opac-tmpl/bootstrap/en/modules/clubs/clubs-tab.tt
  50. 66
      koha-tmpl/opac-tmpl/bootstrap/en/modules/clubs/enroll.tt
  51. 24
      koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-user.tt
  52. 2
      members/moremember.pl
  53. 52
      opac/clubs/clubs-tab.pl
  54. 49
      opac/clubs/enroll.pl
  55. 47
      opac/svc/club/cancel_enrollment
  56. 77
      opac/svc/club/enroll
  57. 46
      svc/club/cancel_enrollment
  58. 48
      svc/club/delete
  59. 74
      svc/club/enroll
  60. 49
      svc/club/template/delete
  61. 221
      t/db_dependent/Clubs.t

5
C4/Auth.pm

@ -260,7 +260,7 @@ sub get_template_and_user {
my $all_perms = get_all_subpermissions();
my @flagroots = qw(circulate catalogue parameters borrowers permissions reserveforothers borrow
editcatalogue updatecharges management tools editauthorities serials reports acquisition);
editcatalogue updatecharges management tools editauthorities serials reports acquisition clubs);
# We are going to use the $flags returned by checkauth
# to create the template's parameters that will indicate
@ -283,8 +283,9 @@ sub get_template_and_user {
$template->param( CAN_user_staffaccess => 1 );
$template->param( CAN_user_plugins => 1 );
$template->param( CAN_user_coursereserves => 1 );
foreach my $module ( keys %$all_perms ) {
$template->param( CAN_user_clubs => 1 );
foreach my $module ( keys %$all_perms ) {
foreach my $subperm ( keys %{ $all_perms->{$module} } ) {
$template->param( "CAN_user_${module}_${subperm}" => 1 );
}

16
C4/Members.pm

@ -974,20 +974,10 @@ addresses.
sub GetFirstValidEmailAddress {
my $borrowernumber = shift;
my $dbh = C4::Context->dbh;
my $sth = $dbh->prepare( "SELECT email, emailpro, B_email FROM borrowers where borrowernumber = ? ");
$sth->execute( $borrowernumber );
my $data = $sth->fetchrow_hashref;
if ($data->{'email'}) {
return $data->{'email'};
} elsif ($data->{'emailpro'}) {
return $data->{'emailpro'};
} elsif ($data->{'B_email'}) {
return $data->{'B_email'};
} else {
return '';
}
my $borrower = Koha::Patrons->find( $borrowernumber );
return $borrower->first_valid_email_address();
}
=head2 GetNoticeEmailAddress

92
Koha/Club.pm

@ -0,0 +1,92 @@
package Koha::Club;
# Copyright ByWater Solutions 2014
#
# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation; either version 3 of the License, or (at your option) any later
# version.
#
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with Koha; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
use Modern::Perl;
use Carp;
use Koha::Database;
use Koha::Club::Templates;
use Koha::Club::Fields;
use Koha::Libraries;
use base qw(Koha::Object);
=head1 NAME
Koha::Club - Koha Club Object class
=head1 API
=head2 Class Methods
=cut
=head3 club_template
=cut
sub club_template {
my ($self) = @_;
return unless $self->club_template_id();
return Koha::Club::Templates->find( $self->club_template_id() );
}
=head3 club_fields
=cut
sub club_fields {
my ($self) = @_;
return unless $self->id();
return Koha::Club::Fields->search( { club_id => $self->id() } );
}
=head3 club_fields
=cut
sub branch {
my ($self) = @_;
return unless $self->branchcode();
return Koha::Libraries->find( $self->branchcode() );
}
=head3 type
=cut
sub _type {
return 'Club';
}
=head1 AUTHOR
Kyle M Hall <kyle@bywatersolutions.com>
=cut
1;

78
Koha/Club/Enrollment.pm

@ -0,0 +1,78 @@
package Koha::Club::Enrollment;
# Copyright ByWater Solutions 2014
#
# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation; either version 3 of the License, or (at your option) any later
# version.
#
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with Koha; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
use Modern::Perl;
use Carp;
use Koha::Database;
use Koha::Clubs;
use base qw(Koha::Object);
=head1 NAME
Koha::Club::Enrollment
Represents a "pattern" on which many clubs can be created.
In this way we can directly compare different clubs of the same 'template'
for statistical purposes.
=head1 API
=head2 Class Methods
=cut
=head3 cancel
=cut
sub cancel {
my ( $self ) = @_;
$self->_result()->update( { date_canceled => \'NOW()' } );
return $self;
}
=head3 club
=cut
sub club {
my ( $self ) = @_;
return Koha::Clubs->find( $self->club_id() );
}
=head3 type
=cut
sub _type {
return 'ClubEnrollment';
}
=head1 AUTHOR
Kyle M Hall <kyle@bywatersolutions.com>
=cut
1;

56
Koha/Club/Enrollment/Field.pm

@ -0,0 +1,56 @@
package Koha::Club::Enrollment::Field;
# Copyright ByWater Solutions 2014
#
# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation; either version 3 of the License, or (at your option) any later
# version.
#
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with Koha; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
use Modern::Perl;
use Carp;
use Koha::Database;
use base qw(Koha::Object);
=head1 NAME
Koha::Club::Enrollment::Field
Represents a "pattern" on which many clubs can be created.
In this way we can directly compare different clubs of the same 'template'
for statistical purposes.
=head1 API
=head2 Class Methods
=cut
=head3 type
=cut
sub _type {
return 'ClubEnrollmentField';
}
=head1 AUTHOR
Kyle M Hall <kyle@bywatersolutions.com>
=cut
1;

60
Koha/Club/Enrollment/Fields.pm

@ -0,0 +1,60 @@
package Koha::Club::Enrollment::Fields;
# Copyright ByWater Solutions 2014
#
# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation; either version 3 of the License, or (at your option) any later
# version.
#
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with Koha; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
use Modern::Perl;
use Carp;
use Koha::Database;
use Koha::Club::Enrollment::Field;
use base qw(Koha::Objects);
=head1 NAME
Koha::Club::Enrollment::Fields
This object represents a collection of club enrollemnt fields.
=head1 API
=head2 Class Methods
=cut
=head3 type
=cut
sub _type {
return 'ClubEnrollmentField';
}
sub object_class {
return 'Koha::Club::Enrollment::Field';
}
=head1 AUTHOR
Kyle M Hall <kyle@bywatersolutions.com>
=cut
1;

60
Koha/Club/Enrollments.pm

@ -0,0 +1,60 @@
package Koha::Club::Enrollments;
# Copyright ByWater Solutions 2014
#
# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation; either version 3 of the License, or (at your option) any later
# version.
#
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with Koha; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
use Modern::Perl;
use Carp;
use Koha::Database;
use Koha::Club::Enrollment;
use base qw(Koha::Objects);
=head1 NAME
Koha::Club::Enrollments
This object represents a collection of club templates.
=head1 API
=head2 Class Methods
=cut
=head3 type
=cut
sub _type {
return 'ClubEnrollment';
}
sub object_class {
return 'Koha::Club::Enrollment';
}
=head1 AUTHOR
Kyle M Hall <kyle@bywatersolutions.com>
=cut
1;

66
Koha/Club/Field.pm

@ -0,0 +1,66 @@
package Koha::Club::Field;
# Copyright ByWater Solutions 2014
#
# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation; either version 3 of the License, or (at your option) any later
# version.
#
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with Koha; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
use Modern::Perl;
use Carp;
use Koha::Database;
use Koha::Club::Template::Fields;
use base qw(Koha::Object);
=head1 NAME
Koha::Club::Field
Represents the value set at creation time for a Koha::Club::Template::Field
=head1 API
=head2 Class Methods
=cut
=head3 club_template_field
=cut
sub club_template_field {
my ( $self ) = @_;
return Koha::Club::Template::Fields->find( $self->club_template_field_id );
}
=head3 type
=cut
sub _type {
return 'ClubField';
}
=head1 AUTHOR
Kyle M Hall <kyle@bywatersolutions.com>
=cut
1;

60
Koha/Club/Fields.pm

@ -0,0 +1,60 @@
package Koha::Club::Fields;
# Copyright ByWater Solutions 2014
#
# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation; either version 3 of the License, or (at your option) any later
# version.
#
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with Koha; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
use Modern::Perl;
use Carp;
use Koha::Database;
use Koha::Club::Field;
use base qw(Koha::Objects);
=head1 NAME
Koha::Club::Fields
Represents a collection of club fields.
=head1 API
=head2 Class Methods
=cut
=head3 type
=cut
sub _type {
return 'ClubField';
}
sub object_class {
return 'Koha::Club::Field';
}
=head1 AUTHOR
Kyle M Hall <kyle@bywatersolutions.com>
=cut
1;

75
Koha/Club/Template.pm

@ -0,0 +1,75 @@
package Koha::Club::Template;
# Copyright ByWater Solutions 2014
#
# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation; either version 3 of the License, or (at your option) any later
# version.
#
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with Koha; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
use Modern::Perl;
use Carp;
use Koha::Database;
use Koha::Club::Template::Fields;
use Koha::Club::Template::EnrollmentFields;
use base qw(Koha::Object);
=head1 NAME
Koha::Club::Template
Represents a "pattern" on which many clubs can be created.
In this way we can directly compare different clubs of the same 'template'
for statistical purposes.
=head1 API
=head2 Class Methods
=cut
=head3 club_template_fields
=cut
sub club_template_fields {
my ($self) = @_;
return Koha::Club::Template::Fields->search( { club_template_id => $self->id() } );
}
sub club_template_enrollment_fields {
my ($self) = @_;
return Koha::Club::Template::EnrollmentFields->search( { club_template_id => $self->id() } );
}
=head3 type
=cut
sub _type {
return 'ClubTemplate';
}
=head1 AUTHOR
Kyle M Hall <kyle@bywatersolutions.com>
=cut
1;

54
Koha/Club/Template/EnrollmentField.pm

@ -0,0 +1,54 @@
package Koha::Club::Template::EnrollmentField;
# Copyright ByWater Solutions 2014
#
# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation; either version 3 of the License, or (at your option) any later
# version.
#
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with Koha; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
use Modern::Perl;
use Carp;
use Koha::Database;
use base qw(Koha::Object);
=head1 NAME
Koha::Club::Template::EnrollemntField
Represents a club field that is only set at the time a patron is enrolled
=head1 API
=head2 Class Methods
=cut
=head3 type
=cut
sub _type {
return 'ClubTemplateEnrollmentField';
}
=head1 AUTHOR
Kyle M Hall <kyle@bywatersolutions.com>
=cut
1;

60
Koha/Club/Template/EnrollmentFields.pm

@ -0,0 +1,60 @@
package Koha::Club::Template::EnrollmentFields;
# Copyright ByWater Solutions 2014
#
# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation; either version 3 of the License, or (at your option) any later
# version.
#
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with Koha; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
use Modern::Perl;
use Carp;
use Koha::Database;
use Koha::Club::Template::EnrollmentField;
use base qw(Koha::Objects);
=head1 NAME
Koha::Club::Template::EnrollemntFields
Represents a colleciton of club fields that are only set at the time a patron is enrolled
=head1 API
=head2 Class Methods
=cut
=head3 type
=cut
sub _type {
return 'ClubTemplateEnrollmentField';
}
sub object_class {
return 'Koha::Club::Template::EnrollmentField';
}
=head1 AUTHOR
Kyle M Hall <kyle@bywatersolutions.com>
=cut
1;

54
Koha/Club/Template/Field.pm

@ -0,0 +1,54 @@
package Koha::Club::Template::Field;
# Copyright ByWater Solutions 2014
#
# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation; either version 3 of the License, or (at your option) any later
# version.
#
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with Koha; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
use Modern::Perl;
use Carp;
use Koha::Database;
use base qw(Koha::Object);
=head1 NAME
Koha::Club::Template::Field
Represents a club field that is set when the club is created
=head1 API
=head2 Class Methods
=cut
=head3 type
=cut
sub _type {
return 'ClubTemplateField';
}
=head1 AUTHOR
Kyle M Hall <kyle@bywatersolutions.com>
=cut
1;

60
Koha/Club/Template/Fields.pm

@ -0,0 +1,60 @@
package Koha::Club::Template::Fields;
# Copyright ByWater Solutions 2014
#
# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation; either version 3 of the License, or (at your option) any later
# version.
#
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with Koha; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
use Modern::Perl;
use Carp;
use Koha::Database;
use Koha::Club::Template::Field;
use base qw(Koha::Objects);
=head1 NAME
Koha::Club::Template::Fields
Represents a collection of club fields that are set when the club is created
=head1 API
=head2 Class Methods
=cut
=head3 type
=cut
sub _type {
return 'ClubTemplateField';
}
sub object_class {
return 'Koha::Club::Template::Field';
}
=head1 AUTHOR
Kyle M Hall <kyle@bywatersolutions.com>
=cut
1;

60
Koha/Club/Templates.pm

@ -0,0 +1,60 @@
package Koha::Club::Templates;
# Copyright ByWater Solutions 2014
#
# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation; either version 3 of the License, or (at your option) any later
# version.
#
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with Koha; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
use Modern::Perl;
use Carp;
use Koha::Database;
use Koha::Club::Template;
use base qw(Koha::Objects);
=head1 NAME
Koha::Club::Templates
This object represents a collection of club templates.
=head1 API
=head2 Class Methods
=cut
=head3 type
=cut
sub _type {
return 'ClubTemplate';
}
sub object_class {
return 'Koha::Club::Template';
}
=head1 AUTHOR
Kyle M Hall <kyle@bywatersolutions.com>
=cut
1;

92
Koha/Clubs.pm

@ -0,0 +1,92 @@
package Koha::Clubs;
# Copyright ByWater Solutions 2014
#
# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation; either version 3 of the License, or (at your option) any later
# version.
#
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with Koha; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
use Modern::Perl;
use Carp;
use Koha::Database;
use Koha::Club;
use base qw(Koha::Objects);
=head1 NAME
Koha::Clubs - Koha Clubs Object class
This object represents a collection of clubs a patron may enroll in.
=head1 API
=head2 Class Methods
=cut
=head3 get_enrollable
=cut
sub get_enrollable {
my ( $self, $params ) = @_;
# We need to filter out all the already enrolled in clubs
my $borrower = $params->{borrower};
if ($borrower) {
delete( $params->{borrower} );
my @enrollments = $borrower->get_club_enrollments();
if (@enrollments) {
$params->{'me.id'} = { -not_in => [ map { $_->club()->id() } @enrollments ] };
}
}
my $rs = $self->_resultset()->search( $params, { prefetch => 'club_template' } );
if (wantarray) {
my $class = ref($self) ? ref($self) : $self;
return $class->_wrap( $rs->all() );
}
else {
my $class = ref($self) ? ref($self) : $self;
return $class->_new_from_dbic($rs);
}
}
=head3 type
=cut
sub _type {
return 'Club';
}
sub object_class {
return 'Koha::Club';
}
=head1 AUTHOR
Kyle M Hall <kyle@bywatersolutions.com>
=cut
1;

38
Koha/Patron.pm

@ -35,6 +35,7 @@ use Koha::Patron::HouseboundRole;
use Koha::Patron::Images;
use Koha::Patrons;
use Koha::Virtualshelves;
use Koha::Club::Enrollments;
use base qw(Koha::Object);
@ -584,6 +585,43 @@ sub holds {
return Koha::Holds->_new_from_dbic($holds_rs);
}
=head3 first_valid_email_address
=cut
sub first_valid_email_address {
my ($self) = @_;
return $self->email() || $self->emailpro() || $self->B_email() || q{};
}
=head3 get_club_enrollments
=cut
sub get_club_enrollments {
my ($self) = @_;
return Koha::Club::Enrollments->search( { borrowernumber => $self->borrowernumber(), date_canceled => undef } );
}
=head3 get_enrollable_clubs
=cut
sub get_enrollable_clubs {
my ( $self, $is_enrollable_from_opac ) = @_;
my $params;
$params->{is_enrollable_from_opac} = $is_enrollable_from_opac
if $is_enrollable_from_opac;
$params->{is_email_required} = 0 unless $self->first_valid_email_address();
$params->{borrower} = $self;
return Koha::Clubs->get_enrollable($params);
}
=head3 type
=cut

4
Koha/Schema/Result/AuthorisedValue.pm

@ -130,8 +130,8 @@ __PACKAGE__->belongs_to(
);
# Created by DBIx::Class::Schema::Loader v0.07045 @ 2016-08-30 11:52:45
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:LOArv8JQ0aiTZgcy+jb7pA
# Created by DBIx::Class::Schema::Loader v0.07040 @ 2015-01-12 09:54:50
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:IzI/WpMbwvfZ8BpHtRCsiQ
# You can replace this text with custom content, and it will be preserved on regeneration

15
Koha/Schema/Result/Borrower.pm

@ -855,6 +855,21 @@ __PACKAGE__->belongs_to(
{ is_deferrable => 1, on_delete => "RESTRICT", on_update => "RESTRICT" },
);
=head2 club_enrollments
Type: has_many
Related object: L<Koha::Schema::Result::ClubEnrollment>
=cut
__PACKAGE__->has_many(
"club_enrollments",
"Koha::Schema::Result::ClubEnrollment",
{ "foreign.borrowernumber" => "self.borrowernumber" },
{ cascade_copy => 0, cascade_delete => 0 },
);
=head2 course_instructors
Type: has_many

49
Koha/Schema/Result/Branch.pm

@ -352,6 +352,51 @@ __PACKAGE__->has_many(
{ cascade_copy => 0, cascade_delete => 0 },
);
=head2 club_enrollments
Type: has_many
Related object: L<Koha::Schema::Result::ClubEnrollment>
=cut
__PACKAGE__->has_many(
"club_enrollments",
"Koha::Schema::Result::ClubEnrollment",
{ "foreign.branchcode" => "self.branchcode" },
{ cascade_copy => 0, cascade_delete => 0 },
);
=head2 club_templates
Type: has_many
Related object: L<Koha::Schema::Result::ClubTemplate>
=cut
__PACKAGE__->has_many(
"club_templates",
"Koha::Schema::Result::ClubTemplate",
{ "foreign.branchcode" => "self.branchcode" },
{ cascade_copy => 0, cascade_delete => 0 },
);
=head2 clubs
Type: has_many
Related object: L<Koha::Schema::Result::Club>
=cut
__PACKAGE__->has_many(
"clubs",
"Koha::Schema::Result::Club",
{ "foreign.branchcode" => "self.branchcode" },
{ cascade_copy => 0, cascade_delete => 0 },
);
=head2 collections
Type: has_many
@ -543,8 +588,8 @@ Composing rels: L</branchrelations> -> categorycode
__PACKAGE__->many_to_many("categorycodes", "branchrelations", "categorycode");
# Created by DBIx::Class::Schema::Loader v0.07042 @ 2016-10-24 13:56:21
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:/9YwsU+GXK+fzc6IX2Tj5g
# Created by DBIx::Class::Schema::Loader v0.07040 @ 2015-01-12 09:56:17
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:lvjA8x8u5RKeZQ0+uiLm7A
# You can replace this text with custom code or comments, and it will be preserved on regeneration

197
Koha/Schema/Result/Club.pm

@ -0,0 +1,197 @@
use utf8;
package Koha::Schema::Result::Club;
# Created by DBIx::Class::Schema::Loader
# DO NOT MODIFY THE FIRST PART OF THIS FILE
=head1 NAME
Koha::Schema::Result::Club
=cut
use strict;
use warnings;
use base 'DBIx::Class::Core';
=head1 TABLE: C<clubs>
=cut
__PACKAGE__->table("clubs");
=head1 ACCESSORS
=head2 id
data_type: 'integer'
is_auto_increment: 1
is_nullable: 0
=head2 club_template_id
data_type: 'integer'
is_foreign_key: 1
is_nullable: 0
=head2 name
data_type: 'tinytext'
is_nullable: 0
=head2 description
data_type: 'text'
is_nullable: 1
=head2 date_start
data_type: 'date'
datetime_undef_if_invalid: 1
is_nullable: 1
=head2 date_end
data_type: 'date'
datetime_undef_if_invalid: 1
is_nullable: 1
=head2 branchcode
data_type: 'varchar'
is_foreign_key: 1
is_nullable: 1
size: 11
=head2 date_created
data_type: 'timestamp'
datetime_undef_if_invalid: 1
default_value: current_timestamp
is_nullable: 0
=head2 date_updated
data_type: 'timestamp'
datetime_undef_if_invalid: 1
is_nullable: 1
=cut
__PACKAGE__->add_columns(
"id",
{ data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
"club_template_id",
{ data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
"name",
{ data_type => "tinytext", is_nullable => 0 },
"description",
{ data_type => "text", is_nullable => 1 },
"date_start",
{ data_type => "date", datetime_undef_if_invalid => 1, is_nullable => 1 },
"date_end",
{ data_type => "date", datetime_undef_if_invalid => 1, is_nullable => 1 },
"branchcode",
{ data_type => "varchar", is_foreign_key => 1, is_nullable => 1, size => 11 },
"date_created",
{
data_type => "timestamp",
datetime_undef_if_invalid => 1,
default_value => \"current_timestamp",
is_nullable => 0,
},
"date_updated",
{
data_type => "timestamp",
datetime_undef_if_invalid => 1,
is_nullable => 1,
},
);
=head1 PRIMARY KEY
=over 4
=item * L</id>
=back
=cut
__PACKAGE__->set_primary_key("id");
=head1 RELATIONS
=head2 branchcode
Type: belongs_to
Related object: L<Koha::Schema::Result::Branch>
=cut
__PACKAGE__->belongs_to(
"branchcode",
"Koha::Schema::Result::Branch",
{ branchcode => "branchcode" },
{
is_deferrable => 1,
join_type => "LEFT",
on_delete => "RESTRICT",
on_update => "RESTRICT",
},
);
=head2 club_enrollments
Type: has_many
Related object: L<Koha::Schema::Result::ClubEnrollment>
=cut
__PACKAGE__->has_many(
"club_enrollments",
"Koha::Schema::Result::ClubEnrollment",
{ "foreign.club_id" => "self.id" },
{ cascade_copy => 0, cascade_delete => 0 },
);
=head2 club_fields
Type: has_many
Related object: L<Koha::Schema::Result::ClubField>
=cut
__PACKAGE__->has_many(
"club_fields",
"Koha::Schema::Result::ClubField",
{ "foreign.club_id" => "self.id" },
{ cascade_copy => 0, cascade_delete => 0 },
);
=head2 club_template
Type: belongs_to
Related object: L<Koha::Schema::Result::ClubTemplate>
=cut
__PACKAGE__->belongs_to(
"club_template",
"Koha::Schema::Result::ClubTemplate",
{ id => "club_template_id" },
{ is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
);
# Created by DBIx::Class::Schema::Loader v0.07040 @ 2015-01-12 09:56:17
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:nMwJy/qR8aWu12hQq4rORQ
# You can replace this text with custom content, and it will be preserved on regeneration
1;

201
Koha/Schema/Result/ClubEnrollment.pm

@ -0,0 +1,201 @@
use utf8;
package Koha::Schema::Result::ClubEnrollment;
# Created by DBIx::Class::Schema::Loader
# DO NOT MODIFY THE FIRST PART OF THIS FILE
=head1 NAME
Koha::Schema::Result::ClubEnrollment
=cut
use strict;
use warnings;
use base 'DBIx::Class::Core';
=head1 TABLE: C<club_enrollments>
=cut
__PACKAGE__->table("club_enrollments");
=head1 ACCESSORS
=head2 id
data_type: 'integer'
is_auto_increment: 1
is_nullable: 0
=head2 club_id
data_type: 'integer'
is_foreign_key: 1
is_nullable: 0
=head2 borrowernumber
data_type: 'integer'
is_foreign_key: 1
is_nullable: 0
=head2 date_enrolled
data_type: 'timestamp'
datetime_undef_if_invalid: 1
default_value: current_timestamp
is_nullable: 0
=head2 date_canceled
data_type: 'timestamp'
datetime_undef_if_invalid: 1
is_nullable: 1
=head2 date_created
data_type: 'timestamp'
datetime_undef_if_invalid: 1
default_value: '0000-00-00 00:00:00'
is_nullable: 0
=head2 date_updated
data_type: 'timestamp'
datetime_undef_if_invalid: 1
is_nullable: 1
=head2 branchcode
data_type: 'varchar'
is_foreign_key: 1
is_nullable: 1
size: 11
=cut
__PACKAGE__->add_columns(
"id",
{ data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
"club_id",
{ data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
"borrowernumber",
{ data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
"date_enrolled",
{
data_type => "timestamp",
datetime_undef_if_invalid => 1,
default_value => \"current_timestamp",
is_nullable => 0,
},
"date_canceled",
{
data_type => "timestamp",
datetime_undef_if_invalid => 1,
is_nullable => 1,
},
"date_created",
{
data_type => "timestamp",
datetime_undef_if_invalid => 1,
default_value => "0000-00-00 00:00:00",
is_nullable => 0,
},
"date_updated",
{
data_type => "timestamp",
datetime_undef_if_invalid => 1,
is_nullable => 1,
},
"branchcode",
{ data_type => "varchar", is_foreign_key => 1, is_nullable => 1, size => 11 },
);
=head1 PRIMARY KEY
=over 4
=item * L</id>
=back
=cut
__PACKAGE__->set_primary_key("id");
=head1 RELATIONS
=head2 borrowernumber
Type: belongs_to
Related object: L<Koha::Schema::Result::Borrower>
=cut
__PACKAGE__->belongs_to(
"borrowernumber",
"Koha::Schema::Result::Borrower",
{ borrowernumber => "borrowernumber" },
{ is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
);
=head2 branchcode
Type: belongs_to
Related object: L<Koha::Schema::Result::Branch>
=cut
__PACKAGE__->belongs_to(
"branchcode",
"Koha::Schema::Result::Branch",
{ branchcode => "branchcode" },
{
is_deferrable => 1,
join_type => "LEFT",
on_delete => "SET NULL",
on_update => "CASCADE",
},
);
=head2 club
Type: belongs_to
Related object: L<Koha::Schema::Result::Club>
=cut
__PACKAGE__->belongs_to(
"club",
"Koha::Schema::Result::Club",
{ id => "club_id" },
{ is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
);
=head2 club_enrollment_fields
Type: has_many
Related object: L<Koha::Schema::Result::ClubEnrollmentField>
=cut
__PACKAGE__->has_many(
"club_enrollment_fields",
"Koha::Schema::Result::ClubEnrollmentField",
{ "foreign.club_enrollment_id" => "self.id" },
{ cascade_copy => 0, cascade_delete => 0 },
);
# Created by DBIx::Class::Schema::Loader v0.07040 @ 2015-01-12 09:56:17
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:9ypc+smG/VlgtWW66PhvHQ
# You can replace this text with custom content, and it will be preserved on regeneration
1;

112
Koha/Schema/Result/ClubEnrollmentField.pm

@ -0,0 +1,112 @@
use utf8;
package Koha::Schema::Result::ClubEnrollmentField;
# Created by DBIx::Class::Schema::Loader
# DO NOT MODIFY THE FIRST PART OF THIS FILE
=head1 NAME
Koha::Schema::Result::ClubEnrollmentField
=cut
use strict;
use warnings;
use base 'DBIx::Class::Core';
=head1 TABLE: C<club_enrollment_fields>
=cut
__PACKAGE__->table("club_enrollment_fields");
=head1 ACCESSORS
=head2 id
data_type: 'integer'
is_auto_increment: 1
is_nullable: 0
=head2 club_enrollment_id
data_type: 'integer'
is_foreign_key: 1
is_nullable: 0
=head2 club_template_enrollment_field_id
data_type: 'integer'
is_foreign_key: 1
is_nullable: 0
=head2 value
data_type: 'text'
is_nullable: 0
=cut
__PACKAGE__->add_columns(
"id",
{ data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
"club_enrollment_id",
{ data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
"club_template_enrollment_field_id",
{ data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
"value",
{ data_type => "text", is_nullable => 0 },
);
=head1 PRIMARY KEY
=over 4
=item * L</id>
=back
=cut
__PACKAGE__->set_primary_key("id");
=head1 RELATIONS
=head2 club_enrollment
Type: belongs_to
Related object: L<Koha::Schema::Result::ClubEnrollment>
=cut
__PACKAGE__->belongs_to(
"club_enrollment",
"Koha::Schema::Result::ClubEnrollment",
{ id => "club_enrollment_id" },
{ is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
);
=head2 club_template_enrollment_field
Type: belongs_to
Related object: L<Koha::Schema::Result::ClubTemplateEnrollmentField>
=cut
__PACKAGE__->belongs_to(
"club_template_enrollment_field",
"Koha::Schema::Result::ClubTemplateEnrollmentField",
{ id => "club_template_enrollment_field_id" },
{ is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
);
# Created by DBIx::Class::Schema::Loader v0.07040 @ 2015-01-12 09:56:17
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:2ANAs3mh3i/kd3Qxrcd5IA
# You can replace this text with custom content, and it will be preserved on regeneration
1;

112
Koha/Schema/Result/ClubField.pm

@ -0,0 +1,112 @@
use utf8;
package Koha::Schema::Result::ClubField;
# Created by DBIx::Class::Schema::Loader
# DO NOT MODIFY THE FIRST PART OF THIS FILE
=head1 NAME
Koha::Schema::Result::ClubField
=cut
use strict;
use warnings;
use base 'DBIx::Class::Core';
=head1 TABLE: C<club_fields>
=cut
__PACKAGE__->table("club_fields");
=head1 ACCESSORS
=head2 id
data_type: 'integer'
is_auto_increment: 1
is_nullable: 0
=head2 club_template_field_id
data_type: 'integer'
is_foreign_key: 1
is_nullable: 0
=head2 club_id
data_type: 'integer'
is_foreign_key: 1
is_nullable: 0
=head2 value
data_type: 'text'
is_nullable: 1
=cut
__PACKAGE__->add_columns(
"id",
{ data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
"club_template_field_id",
{ data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
"club_id",
{ data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
"value",
{ data_type => "text", is_nullable => 1 },
);
=head1 PRIMARY KEY
=over 4
=item * L</id>
=back
=cut
__PACKAGE__->set_primary_key("id");
=head1 RELATIONS
=head2 club
Type: belongs_to
Related object: L<Koha::Schema::Result::Club>
=cut
__PACKAGE__->belongs_to(
"club",
"Koha::Schema::Result::Club",
{ id => "club_id" },
{ is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
);
=head2 club_template_field
Type: belongs_to
Related object: L<Koha::Schema::Result::ClubTemplateField>
=cut
__PACKAGE__->belongs_to(
"club_template_field",
"Koha::Schema::Result::ClubTemplateField",
{ id => "club_template_field_id" },
{ is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
);
# Created by DBIx::Class::Schema::Loader v0.07040 @ 2015-01-12 09:56:17
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:m4GLLIVIHgRpRhCGLh12DQ
# You can replace this text with custom content, and it will be preserved on regeneration
1;

195
Koha/Schema/Result/ClubTemplate.pm

@ -0,0 +1,195 @@
use utf8;
package Koha::Schema::Result::ClubTemplate;
# Created by DBIx::Class::Schema::Loader
# DO NOT MODIFY THE FIRST PART OF THIS FILE
=head1 NAME
Koha::Schema::Result::ClubTemplate
=cut
use strict;
use warnings;
use base 'DBIx::Class::Core';
=head1 TABLE: C<club_templates>
=cut
__PACKAGE__->table("club_templates");
=head1 ACCESSORS
=head2 id
data_type: 'integer'
is_auto_increment: 1
is_nullable: 0
=head2 name
data_type: 'tinytext'
is_nullable: 0
=head2 description
data_type: 'text'
is_nullable: 1
=head2 is_enrollable_from_opac
data_type: 'tinyint'
default_value: 0
is_nullable: 0
=head2 is_email_required
data_type: 'tinyint'
default_value: 0
is_nullable: 0
=head2 branchcode
data_type: 'varchar'
is_foreign_key: 1
is_nullable: 1
size: 10
=head2 date_created
data_type: 'timestamp'
datetime_undef_if_invalid: 1
default_value: current_timestamp
is_nullable: 0
=head2 date_updated
data_type: 'timestamp'
datetime_undef_if_invalid: 1
is_nullable: 1
=head2 is_deletable
data_type: 'tinyint'
default_value: 1
is_nullable: 0
=cut
__PACKAGE__->add_columns(
"id",
{ data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
"name",
{ data_type => "tinytext", is_nullable => 0 },
"description",
{ data_type => "text", is_nullable => 1 },
"is_enrollable_from_opac",
{ data_type => "tinyint", default_value => 0, is_nullable => 0 },
"is_email_required",
{ data_type => "tinyint", default_value => 0, is_nullable => 0 },
"branchcode",
{ data_type => "varchar", is_foreign_key => 1, is_nullable => 1, size => 10 },
"date_created",
{
data_type => "timestamp",
datetime_undef_if_invalid => 1,
default_value => \"current_timestamp",
is_nullable => 0,
},
"date_updated",
{
data_type => "timestamp",
datetime_undef_if_invalid => 1,
is_nullable => 1,
},
"is_deletable",
{ data_type => "tinyint", default_value => 1, is_nullable => 0 },
);
=head1 PRIMARY KEY
=over 4
=item * L</id>
=back
=cut
__PACKAGE__->set_primary_key("id");
=head1 RELATIONS
=head2 branchcode
Type: belongs_to
Related object: L<Koha::Schema::Result::Branch>
=cut
__PACKAGE__->belongs_to(
"branchcode",
"Koha::Schema::Result::Branch",
{ branchcode => "branchcode" },
{
is_deferrable => 1,
join_type => "LEFT",
on_delete => "SET NULL",
on_update => "CASCADE",
},
);
=head2 club_template_enrollment_fields
Type: has_many
Related object: L<Koha::Schema::Result::ClubTemplateEnrollmentField>
=cut
__PACKAGE__->has_many(
"club_template_enrollment_fields",
"Koha::Schema::Result::ClubTemplateEnrollmentField",
{ "foreign.club_template_id" => "self.id" },
{ cascade_copy => 0, cascade_delete => 0 },
);
=head2 club_template_fields
Type: has_many
Related object: L<Koha::Schema::Result::ClubTemplateField>
=cut
__PACKAGE__->has_many(
"club_template_fields",
"Koha::Schema::Result::ClubTemplateField",
{ "foreign.club_template_id" => "self.id" },
{ cascade_copy => 0, cascade_delete => 0 },
);
=head2 clubs
Type: has_many
Related object: L<Koha::Schema::Result::Club>
=cut
__PACKAGE__->has_many(
"clubs",
"Koha::Schema::Result::Club",
{ "foreign.club_template_id" => "self.id" },
{ cascade_copy => 0, cascade_delete => 0 },
);
# Created by DBIx::Class::Schema::Loader v0.07040 @ 2015-01-12 09:56:17
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:j5aiACVUGzrdng4+jt6mfg
1;

119
Koha/Schema/Result/ClubTemplateEnrollmentField.pm

@ -0,0 +1,119 @@
use utf8;
package Koha::Schema::Result::ClubTemplateEnrollmentField;
# Created by DBIx::Class::Schema::Loader
# DO NOT MODIFY THE FIRST PART OF THIS FILE
=head1 NAME
Koha::Schema::Result::ClubTemplateEnrollmentField
=cut
use strict;
use warnings;
use base 'DBIx::Class::Core';
=head1 TABLE: C<club_template_enrollment_fields>
=cut
__PACKAGE__->table("club_template_enrollment_fields");
=head1 ACCESSORS
=head2 id
data_type: 'integer'
is_auto_increment: 1
is_nullable: 0
=head2 club_template_id
data_type: 'integer'
is_foreign_key: 1
is_nullable: 0
=head2 name
data_type: 'tinytext'
is_nullable: 0
=head2 description
data_type: 'text'
is_nullable: 1
=head2 authorised_value_category
data_type: 'varchar'
is_nullable: 1
size: 16
=cut
__PACKAGE__->add_columns(
"id",
{ data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
"club_template_id",
{ data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
"name",
{ data_type => "tinytext", is_nullable => 0 },
"description",
{ data_type => "text", is_nullable => 1 },
"authorised_value_category",
{ data_type => "varchar", is_nullable => 1, size => 16 },
);
=head1 PRIMARY KEY
=over 4
=item * L</id>
=back
=cut
__PACKAGE__->set_primary_key("id");
=head1 RELATIONS
=head2 club_enrollment_fields
Type: has_many
Related object: L<Koha::Schema::Result::ClubEnrollmentField>
=cut
__PACKAGE__->has_many(
"club_enrollment_fields",
"Koha::Schema::Result::ClubEnrollmentField",
{ "foreign.club_template_enrollment_field_id" => "self.id" },
{ cascade_copy => 0, cascade_delete => 0 },
);
=head2 club_template
Type: belongs_to
Related object: L<Koha::Schema::Result::ClubTemplate>
=cut
__PACKAGE__->belongs_to(
"club_template",
"Koha::Schema::Result::ClubTemplate",
{ id => "club_template_id" },
{ is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
);
# Created by DBIx::Class::Schema::Loader v0.07040 @ 2015-01-12 09:56:17
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:KGo2mEIAkTVYSPsOLoaBCg
# You can replace this text with custom content, and it will be preserved on regeneration
1;

119
Koha/Schema/Result/ClubTemplateField.pm

@ -0,0 +1,119 @@
use utf8;
package Koha::Schema::Result::ClubTemplateField;
# Created by DBIx::Class::Schema::Loader
# DO NOT MODIFY THE FIRST PART OF THIS FILE
=head1 NAME
Koha::Schema::Result::ClubTemplateField
=cut
use strict;
use warnings;
use base 'DBIx::Class::Core';
=head1 TABLE: C<club_template_fields>
=cut
__PACKAGE__->table("club_template_fields");
=head1 ACCESSORS
=head2 id
data_type: 'integer'
is_auto_increment: 1
is_nullable: 0
=head2 club_template_id
data_type: 'integer'
is_foreign_key: 1
is_nullable: 0
=head2 name
data_type: 'tinytext'
is_nullable: 0
=head2 description
data_type: 'text'
is_nullable: 1
=head2 authorised_value_category
data_type: 'varchar'
is_nullable: 1
size: 16
=cut
__PACKAGE__->add_columns(
"id",
{ data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
"club_template_id",
{ data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
"name",
{ data_type => "tinytext", is_nullable => 0 },
"description",
{ data_type => "text", is_nullable => 1 },
"authorised_value_category",
{ data_type => "varchar", is_nullable => 1, size => 16 },
);
=head1 PRIMARY KEY
=over 4
=item * L</id>
=back
=cut
__PACKAGE__->set_primary_key("id");
=head1 RELATIONS
=head2 club_fields
Type: has_many
Related object: L<Koha::Schema::Result::ClubField>
=cut
__PACKAGE__->has_many(
"club_fields",
"Koha::Schema::Result::ClubField",
{ "foreign.club_template_field_id" => "self.id" },
{ cascade_copy => 0, cascade_delete => 0 },
);
=head2 club_template
Type: belongs_to
Related object: L<Koha::Schema::Result::ClubTemplate>
=cut
__PACKAGE__->belongs_to(
"club_template",
"Koha::Schema::Result::ClubTemplate",
{ id => "club_template_id" },
{ is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
);
# Created by DBIx::Class::Schema::Loader v0.07040 @ 2015-01-12 09:56:17
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:P73ABSn2tzlTYbD3nov21g
# You can replace this text with custom content, and it will be preserved on regeneration
1;

4
Koha/Template/Plugin/AuthorisedValues.pm

@ -35,8 +35,8 @@ sub GetByCode {
}
sub Get {
my ( $self, $category, $opac ) = @_;
return GetAuthorisedValues( $category, $opac );
my ( $self, $category, $selected, $opac ) = @_;
return GetAuthorisedValues( $category, $selected, $opac );
}
sub GetAuthValueDropbox {

1
Koha/Template/Plugin/Borrowers.pm

@ -57,5 +57,4 @@ sub HasOverdues {
return Koha::Patrons->find( $borrowernumber )->has_overdues;
}
1;

107
clubs/clubs-add-modify.pl

@ -0,0 +1,107 @@
#!/usr/bin/perl
# Copyright 2013 ByWater Solutions
#
# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Koha is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Koha; if not, see <http://www.gnu.org/licenses>.
use Modern::Perl;
use CGI;
use C4::Auth;
use C4::Output;
use Koha::Database;
use Koha::DateUtils qw(dt_from_string);
use Koha::Clubs;
use Koha::Club::Fields;
my $cgi = new CGI;
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
{
template_name => 'clubs/clubs-add-modify.tt',
query => $cgi,
type => 'intranet',
authnotrequired => 0,
flagsrequired => { clubs => 'edit_clubs' },
}
);
my $schema = Koha::Database->new()->schema();
my $id = $cgi->param('id');
my $club = $id ? Koha::Clubs->find($id) : Koha::Club->new();
my $stored = $cgi->param('name') ? $id ? 'updated' : 'stored' : undef;
my $club_template_id = $cgi->param('club_template_id');
my $club_template = $club->club_template() || Koha::Club::Templates->find($club_template_id);
$club_template_id ||= $club_template->id();
my $date_start = $cgi->param('date_start');
$date_start = $date_start ? dt_from_string($date_start) : undef;
my $date_end = $cgi->param('date_end');
$date_end = $date_end ? dt_from_string($date_end) : undef;
if ( $cgi->param('name') ) { # Update or create club
$club->set(
{
club_template_id => $cgi->param('club_template_id') || undef,
name => $cgi->param('name') || undef,
description => $cgi->param('description') || undef,
branchcode => $cgi->param('branchcode') || undef,
date_start => $date_start,
date_end => $date_end,
date_updated => dt_from_string(),
}
)->store();
my @club_template_field_id = $cgi->multi_param('club_template_field_id');
my @club_field_id = $cgi->multi_param('club_field_id');
my @club_field = $cgi->multi_param('club_field');
for ( my $i = 0 ; $i < @club_template_field_id ; $i++ ) {
my $club_template_field_id = $club_template_field_id[$i] || undef;
my $club_field_id = $club_field_id[$i] || undef;
my $club_field = $club_field[$i] || undef;
my $field =
$club_field_id
? Koha::Club::Fields->find($club_field_id)
: Koha::Club::Field->new();
$field->set(
{
club_id => $club->id(),
club_template_field_id => $club_template_field_id,
value => $club_field,
}
)->store();
}
$id ||= $club->id();
print $cgi->redirect("/cgi-bin/koha/clubs/clubs.pl?stored=$stored&club_id=$id");
exit;
}
$club = Koha::Clubs->find($id);
$template->param(
club_template => $club_template,
club => $club,
);
output_html_with_http_headers( $cgi, $cookie, $template->output );

60
clubs/clubs.pl

@ -0,0 +1,60 @@
#!/usr/bin/perl
# Copyright 2013 ByWater Solutions
#
# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Koha is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Koha; if not, see <http://www.gnu.org/licenses>.
use Modern::Perl;
use CGI;
use C4::Auth;
use C4::Output;
use Koha::Clubs;
use Koha::Club::Templates;
my $cgi = new CGI;
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
{
template_name => "clubs/clubs.tt",
query => $cgi,
type => "intranet",
authnotrequired => 0,
flagsrequired => { clubs => '*' },
}
);
my $stored = $cgi->param('stored');
my $club_template_id = $cgi->param('club_template_id');
my $club_id = $cgi->param('club_id');
my $club_template = $club_template_id ? Koha::Club::Templates->find( $club_template_id ) : undef;
my $club = $club_id ? Koha::Clubs->find( $club_id ) : undef;
my @club_templates = Koha::Club::Templates->search();
my @clubs = Koha::Clubs->search();
$template->param(
stored => $stored,
club_template => $club_template,
club => $club,
club_templates => \@club_templates,
clubs => \@clubs,
);
output_html_with_http_headers( $cgi, $cookie, $template->output );

55
clubs/patron-clubs-tab.pl

@ -0,0 +1,55 @@
#!/usr/bin/perl
# Copyright 2013 ByWater Solutions
#
# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Koha is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Koha; if not, see <http://www.gnu.org/licenses>.
use Modern::Perl;
use CGI;
use C4::Auth;
use C4::Output;
use Koha::Patrons;
use Koha::Club::Enrollments;
my $cgi = new CGI;
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
{
template_name => "clubs/patron-clubs-tab.tt",
query => $cgi,
type => "intranet",
authnotrequired => 0,
flagsrequired => { clubs => '*' },
}
);
my $patronnumber = $cgi->param('borrowernumber');
my $patron = Koha::Patrons->find($patronnumber);
my @enrollments = $patron->get_club_enrollments();
my @clubs = $patron->get_enrollable_clubs();
$template->param(
enrollments => \@enrollments,
clubs => \@clubs,
borrowernumber => $patronnumber
);
output_html_with_http_headers( $cgi, $cookie, $template->output );

50
clubs/patron-enroll.pl

@ -0,0 +1,50 @@
#!/usr/bin/perl
# Copyright 2013 ByWater Solutions
#
# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Koha is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Koha; if not, see <http://www.gnu.org/licenses>.
use Modern::Perl;
use CGI;
use C4::Auth;
use C4::Output;
use Koha::Clubs;
my $cgi = new CGI;
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
{
template_name => "clubs/patron-enroll.tt",
query => $cgi,
type => "intranet",
authnotrequired => 0,
flagsrequired => { clubs => '*' },
}
);
my $id = $cgi->param('id');
my $borrowernumber = $cgi->param('borrowernumber');
my $club = Koha::Clubs->find($id);
$template->param(
club => $club,
borrowernumber => $borrowernumber,
);
output_html_with_http_headers( $cgi, $cookie, $template->output );

152
clubs/templates-add-modify.pl

@ -0,0 +1,152 @@
#!/usr/bin/perl
# Copyright 2013 ByWater Solutions
#
# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Koha is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Koha; if not, see <http://www.gnu.org/licenses>.
use Modern::Perl;
use CGI;
use C4::Auth;
use C4::Output;
use Koha::DateUtils qw(dt_from_string);
use Koha::Club::Templates;
use Koha::Club::Template::Fields;
use Koha::Club::Template::EnrollmentFields;
use Koha::Database;
my $schema = Koha::Database->new()->schema();
my $cgi = new CGI;
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
{
template_name => 'clubs/templates-add-modify.tt',
query => $cgi,
type => 'intranet',
authnotrequired => 0,
flagsrequired => { clubs => 'edit_templates' },
}
);
my $id = $cgi->param('id');
my $club_template;
my $stored;
if ( $cgi->param('name') ) { # Update or create club
if ($id) {
$club_template = Koha::Club::Templates->find($id);
$stored = 'updated';
}
else {
$club_template = Koha::Club::Template->new();
$stored = 'created';
}
$club_template->set(
{
id => $id || undef,
name => $cgi->param('name') || undef,
description => $cgi->param('description') || undef,
branchcode => $cgi->param('branchcode') || undef,
date_updated => dt_from_string(),
is_email_required => $cgi->param('is_email_required') ? 1 : 0,
is_enrollable_from_opac => $cgi->param('is_enrollable_from_opac') ? 1 : 0,
}
)->store();
$id ||= $club_template->id();
# Update club creation fields
my @field_id = $cgi->multi_param('club_template_field_id');
my @field_name = $cgi->multi_param('club_template_field_name');
my @field_description = $cgi->multi_param('club_template_field_description');
my @field_authorised_value_category = $cgi->multi_param('club_template_field_authorised_value_category');
my @field_delete = $cgi->multi_param('club_template_field_delete');
for ( my $i = 0 ; $i < @field_id ; $i++ ) {
my $field_id = $field_id[$i];
my $field_name = $field_name[$i];
my $field_description = $field_description[$i];
my $field_authorised_value_category = $field_authorised_value_category[$i];
my $field =
$field_id
? Koha::Club::Template::Fields->find($field_id)
: Koha::Club::Template::Field->new();
if ( grep( /^$field_id$/, @field_delete ) ) {
$field->delete();
}
else {
$field->set(
{
club_template_id => $id,
name => $field_name,
description => $field_description,
authorised_value_category => $field_authorised_value_category,
}
)->store();
}
}
# Update club enrollment fields
@field_id = $cgi->multi_param('club_template_enrollment_field_id');
@field_name = $cgi->multi_param('club_template_enrollment_field_name');
@field_description = $cgi->multi_param('club_template_enrollment_field_description');
@field_authorised_value_category = $cgi->multi_param('club_template_enrollment_field_authorised_value_category');
@field_delete = $cgi->multi_param('club_template_enrollment_field_delete');
for ( my $i = 0 ; $i < @field_id ; $i++ ) {
my $field_id = $field_id[$i];
my $field_name = $field_name[$i];
my $field_description = $field_description[$i];
my $field_authorised_value_category = $field_authorised_value_category[$i];
my $field =
$field_id
? Koha::Club::Template::EnrollmentFields->find($field_id)
: Koha::Club::Template::EnrollmentField->new();
if ( grep( /^$field_id$/, @field_delete ) ) {
$field->delete();
}
else {
$field->set(
{
id => $field_id,
club_template_id => $id,
name => $field_name,
description => $field_description,
authorised_value_category => $field_authorised_value_category,
}
)->store();
}
}
print $cgi->redirect("/cgi-bin/koha/clubs/clubs.pl?stored=$stored&club_template_id=$id");
exit;
}
$club_template ||= Koha::Club::Templates->find($id);
$template->param( club_template => $club_template );
output_html_with_http_headers( $cgi, $cookie, $template->output );

131
installer/data/mysql/atomicupdate/bug_12461.sql

@ -0,0 +1,131 @@
--
-- Table structure for table 'club_templates'
--
CREATE TABLE IF NOT EXISTS club_templates (
id int(11) NOT NULL AUTO_INCREMENT,
`name` tinytext NOT NULL,
description text,
is_enrollable_from_opac tinyint(1) NOT NULL DEFAULT '0',
is_email_required tinyint(1) NOT NULL DEFAULT '0',
branchcode varchar(10) NULL DEFAULT NULL,
date_created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
date_updated timestamp NULL DEFAULT NULL,
is_deletable tinyint(1) NOT NULL DEFAULT '1',
PRIMARY KEY (id),
KEY ct_branchcode (branchcode),
CONSTRAINT `club_templates_ibfk_1` FOREIGN KEY (branchcode) REFERENCES `branches` (branchcode) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
--
-- Table structure for table 'clubs'
--
CREATE TABLE IF NOT EXISTS clubs (
id int(11) NOT NULL AUTO_INCREMENT,
club_template_id int(11) NOT NULL,
`name` tinytext NOT NULL,
description text,
date_start date DEFAULT NULL,
date_end date DEFAULT NULL,
branchcode varchar(10) NULL DEFAULT NULL,
date_created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
date_updated timestamp NULL DEFAULT NULL,
PRIMARY KEY (id),
KEY club_template_id (club_template_id),
KEY branchcode (branchcode),
CONSTRAINT clubs_ibfk_1 FOREIGN KEY (club_template_id) REFERENCES club_templates (id) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT clubs_ibfk_2 FOREIGN KEY (branchcode) REFERENCES branches (branchcode)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
--
-- Table structure for table 'club_enrollments'
--
CREATE TABLE IF NOT EXISTS club_enrollments (
id int(11) NOT NULL AUTO_INCREMENT,
club_id int(11) NOT NULL,
borrowernumber int(11) NOT NULL,
date_enrolled timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
date_canceled timestamp NULL DEFAULT NULL,
date_created timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
date_updated timestamp NULL DEFAULT NULL,
branchcode varchar(10) NULL DEFAULT NULL,
PRIMARY KEY (id),
KEY club_id (club_id),
KEY borrowernumber (borrowernumber),
KEY branchcode (branchcode),
CONSTRAINT club_enrollments_ibfk_1 FOREIGN KEY (club_id) REFERENCES clubs (id) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT club_enrollments_ibfk_2 FOREIGN KEY (borrowernumber) REFERENCES borrowers (borrowernumber) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT club_enrollments_ibfk_3 FOREIGN KEY (branchcode) REFERENCES branches (branchcode) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
--
-- Table structure for table 'club_template_enrollment_fields'
--
CREATE TABLE IF NOT EXISTS club_template_enrollment_fields (
id int(11) NOT NULL AUTO_INCREMENT,
club_template_id int(11) NOT NULL,
`name` tinytext NOT NULL,
description text,
authorised_value_category varchar(16) DEFAULT NULL,
PRIMARY KEY (id),
KEY club_template_id (club_template_id),
CONSTRAINT club_template_enrollment_fields_ibfk_1 FOREIGN KEY (club_template_id) REFERENCES club_templates (id) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
--
-- Table structure for table 'club_enrollment_fields'
--
CREATE TABLE IF NOT EXISTS club_enrollment_fields (
id int(11) NOT NULL AUTO_INCREMENT,
club_enrollment_id int(11) NOT NULL,
club_template_enrollment_field_id int(11) NOT NULL,
`value` text NOT NULL,
PRIMARY KEY (id),
KEY club_enrollment_id (club_enrollment_id),
KEY club_template_enrollment_field_id (club_template_enrollment_field_id),
CONSTRAINT club_enrollment_fields_ibfk_1 FOREIGN KEY (club_enrollment_id) REFERENCES club_enrollments (id) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT club_enrollment_fields_ibfk_2 FOREIGN KEY (club_template_enrollment_field_id) REFERENCES club_template_enrollment_fields (id) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
--
-- Table structure for table 'club_template_fields'
--
CREATE TABLE IF NOT EXISTS club_template_fields (
id int(11) NOT NULL AUTO_INCREMENT,
club_template_id int(11) NOT NULL,
`name` tinytext NOT NULL,
description text,
authorised_value_category varchar(16) DEFAULT NULL,
PRIMARY KEY (id),
KEY club_template_id (club_template_id),
CONSTRAINT club_template_fields_ibfk_1 FOREIGN KEY (club_template_id) REFERENCES club_templates (id) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
--
-- Table structure for table 'club_fields'
--
CREATE TABLE IF NOT EXISTS club_fields (
id int(11) NOT NULL AUTO_INCREMENT,
club_template_field_id int(11) NOT NULL,
club_id int(11) NOT NULL,
`value` text,
PRIMARY KEY (id),
KEY club_template_field_id (club_template_field_id),
KEY club_id (club_id),
CONSTRAINT club_fields_ibfk_3 FOREIGN KEY (club_template_field_id) REFERENCES club_template_fields (id) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT club_fields_ibfk_4 FOREIGN KEY (club_id) REFERENCES clubs (id) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
INSERT IGNORE INTO userflags (bit, flag, flagdesc, defaulton) VALUES (21, 'clubs', 'Patron clubs', '0');
INSERT IGNORE INTO permissions (module_bit, code, description) VALUES
(21, 'edit_templates', 'Create and update club templates'),
(21, 'edit_clubs', 'Create and update clubs'),
(21, 'enroll', 'Enroll patrons in clubs')
;

126
installer/data/mysql/kohastructure.sql

@ -3954,6 +3954,132 @@ CREATE TABLE deletedbiblio_metadata (
CONSTRAINT `deletedrecord_metadata_fk_1` FOREIGN KEY (biblionumber) REFERENCES deletedbiblio (biblionumber) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
--
-- Table structure for table 'club_templates'
--
CREATE TABLE IF NOT EXISTS club_templates (
id int(11) NOT NULL AUTO_INCREMENT,
`name` tinytext NOT NULL,
description text,
is_enrollable_from_opac tinyint(1) NOT NULL DEFAULT '0',
is_email_required tinyint(1) NOT NULL DEFAULT '0',
branchcode varchar(10) NULL DEFAULT NULL,
date_created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
date_updated timestamp NULL DEFAULT NULL,
is_deletable tinyint(1) NOT NULL DEFAULT '1',
PRIMARY KEY (id),
KEY ct_branchcode (branchcode),
CONSTRAINT `club_templates_ibfk_1` FOREIGN KEY (`branchcode`) REFERENCES `branches` (`branchcode`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
--
-- Table structure for table 'clubs'
--
CREATE TABLE IF NOT EXISTS clubs (
id int(11) NOT NULL AUTO_INCREMENT,
club_template_id int(11) NOT NULL,
`name` tinytext NOT NULL,
description text,
date_start date DEFAULT NULL,
date_end date DEFAULT NULL,
branchcode varchar(10) NULL DEFAULT NULL,
date_created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
date_updated timestamp NULL DEFAULT NULL,
PRIMARY KEY (id),
KEY club_template_id (club_template_id),
KEY branchcode (branchcode),
CONSTRAINT clubs_ibfk_1 FOREIGN KEY (club_template_id) REFERENCES club_templates (id) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT clubs_ibfk_2 FOREIGN KEY (branchcode) REFERENCES branches (branchcode)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
--
-- Table structure for table 'club_enrollments'
--
CREATE TABLE IF NOT EXISTS club_enrollments (
id int(11) NOT NULL AUTO_INCREMENT,
club_id int(11) NOT NULL,
borrowernumber int(11) NOT NULL,
date_enrolled timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
date_canceled timestamp NULL DEFAULT NULL,
date_created timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
date_updated timestamp NULL DEFAULT NULL,
branchcode varchar(10) NULL DEFAULT NULL,
PRIMARY KEY (id),
KEY club_id (club_id),
KEY borrowernumber (borrowernumber),
KEY branchcode (branchcode),
CONSTRAINT club_enrollments_ibfk_1 FOREIGN KEY (club_id) REFERENCES clubs (id) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT club_enrollments_ibfk_2 FOREIGN KEY (borrowernumber) REFERENCES borrowers (borrowernumber) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT club_enrollments_ibfk_3 FOREIGN KEY (branchcode) REFERENCES branches (branchcode) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
--
-- Table structure for table 'club_template_enrollment_fields'
--
CREATE TABLE IF NOT EXISTS club_template_enrollment_fields (
id int(11) NOT NULL AUTO_INCREMENT,
club_template_id int(11) NOT NULL,
`name` tinytext NOT NULL,
description text,
authorised_value_category varchar(16) DEFAULT NULL,
PRIMARY KEY (id),
KEY club_template_id (club_template_id),
CONSTRAINT club_template_enrollment_fields_ibfk_1 FOREIGN KEY (club_template_id) REFERENCES club_templates (id) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
--
-- Table structure for table 'club_enrollment_fields'
--
CREATE TABLE IF NOT EXISTS club_enrollment_fields (
id int(11) NOT NULL AUTO_INCREMENT,
club_enrollment_id int(11) NOT NULL,
club_template_enrollment_field_id int(11) NOT NULL,
`value` text NOT NULL,
PRIMARY KEY (id),
KEY club_enrollment_id (club_enrollment_id),
KEY club_template_enrollment_field_id (club_template_enrollment_field_id),
CONSTRAINT club_enrollment_fields_ibfk_1 FOREIGN KEY (club_enrollment_id) REFERENCES club_enrollments (id) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT club_enrollment_fields_ibfk_2 FOREIGN KEY (club_template_enrollment_field_id) REFERENCES club_template_enrollment_fields (id) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
--
-- Table structure for table 'club_template_fields'
--
CREATE TABLE IF NOT EXISTS club_template_fields (
id int(11) NOT NULL AUTO_INCREMENT,
club_template_id int(11) NOT NULL,
`name` tinytext NOT NULL,
description text,
authorised_value_category varchar(16) DEFAULT NULL,
PRIMARY KEY (id),
KEY club_template_id (club_template_id),
CONSTRAINT club_template_fields_ibfk_1 FOREIGN KEY (club_template_id) REFERENCES club_templates (id) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
--
-- Table structure for table 'club_fields'
--
CREATE TABLE IF NOT EXISTS club_fields (
id int(11) NOT NULL AUTO_INCREMENT,
club_template_field_id int(11) NOT NULL,
club_id int(11) NOT NULL,
`value` text,
PRIMARY KEY (id),
KEY club_template_field_id (club_template_field_id),
KEY club_id (club_id),
CONSTRAINT club_fields_ibfk_3 FOREIGN KEY (club_template_field_id) REFERENCES club_template_fields (id) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT club_fields_ibfk_4 FOREIGN KEY (club_id) REFERENCES clubs (id) ON DELETE CASCADE ON UPDATE CASCADE
>>>>>>> Bug 12461 - Add patron clubs feature
>>>>>>> Bug 12461 - Add patron clubs feature
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;

3
installer/data/mysql/userflags.sql

@ -17,5 +17,6 @@ INSERT INTO userflags (bit, flag, flagdesc, defaulton) VALUES
(17,'staffaccess','Allow staff members to modify permissions for other staff members',0),
(18,'coursereserves','Course reserves',0),
(19, 'plugins', 'Koha plugins', '0'),
(20, 'lists', 'Lists', 0)
(20, 'lists', 'Lists', 0),
(21, 'clubs', 'Patron clubs', '0')
;

5
installer/data/mysql/userpermissions.sql

@ -78,5 +78,8 @@ INSERT INTO permissions (module_bit, code, description) VALUES
(19, 'tool', 'Use tool plugins'),
(19, 'report', 'Use report plugins'),
(19, 'configure', 'Configure plugins'),
(20, 'delete_public_lists', 'Delete public lists')
(20, 'delete_public_lists', 'Delete public lists'),
(21, 'edit_templates', 'Create and update club templates'),
(21, 'edit_clubs', 'Create and update clubs'),
(21, 'enroll', 'Enroll patrons in clubs')
;

4
koha-tmpl/intranet-tmpl/prog/en/includes/permissions.inc

@ -19,6 +19,7 @@
[%- CASE 'coursereserves' -%]<span>Course reserves</span>
[%- CASE 'plugins' -%]<span>Koha plugins</span>
[%- CASE 'lists' -%]<span>Lists</span>
[%- CASE 'clubs' -%]<span>Patron clubs</span>
[%- END -%]
[%- END -%]
@ -103,5 +104,8 @@
[%- CASE 'delete_public_lists' -%]<span>Delete public lists</span>
[%- CASE 'upload_general_files' -%]<span>Upload any file</span>
[%- CASE 'upload_manage' -%]<span>Manage uploaded files (<i>Useless without upload_general_files</i>)</span>
[%- CASE 'edit_clubs' -%]<span>Create and edit clubs</span>
[%- CASE 'edit_templates' -%]<span>Create and edit club templates</span>
[%- CASE 'enroll' -%]<span>Enroll patrons in clubs</span>
[%- END -%]
[%- END -%]

3
koha-tmpl/intranet-tmpl/prog/en/includes/tools-menu.inc

@ -25,6 +25,9 @@
[% IF ( CAN_user_tools_manage_patron_lists ) %]
<li><a href="/cgi-bin/koha/patron_lists/lists.pl">Patron lists</a></li>
[% END %]
[% IF (CAN_user_clubs) %]
<li><a href="/cgi-bin/koha/clubs/clubs.pl">Patron clubs</a></li>
[% END %]
[% IF ( CAN_user_tools_moderate_comments ) %]
<li><a href="/cgi-bin/koha/reviews/reviewswaiting.pl">Comments</a></li>
[% END %]

23
koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt

@ -97,6 +97,13 @@ $(document).ready(function() {
}
});
if ( $('#clubs-tab').length ) {
$('#clubs-tab-link').on('click', function() {
$('#clubs-tab').text(_("Loading..."));
$('#clubs-tab').load('/cgi-bin/koha/clubs/patron-clubs-tab.pl?borrowernumber=[% borrowernumber %]');
});
}
[% IF !( CircAutoPrintQuickSlip == 'clear' ) %]
// listen submit to trigger qslip on empty checkout
$('#mainform').bind('submit',function() {
@ -891,6 +898,16 @@ No patron matched <span class="ex">[% message | html %]</span>
[% END %]
</li>
[% SET enrollments = patron.get_club_enrollments.size || 0 %]
[% SET enrollable = patron.get_enrollable_clubs.size || 0 %]
[% IF CAN_user_clubs && ( enrollable || enrollments ) %]
<li>
<a id="clubs-tab-link" href="#clubs-tab">
Clubs ([% enrollments %]/[% enrollable %])
</a>
</li>
[% END %]
[% IF relatives_issues_count %]
<li><a id="relatives-issues-tab" href="#relatives-issues">Relatives' checkouts</a></li>
[% END %]
@ -939,6 +956,12 @@ No patron matched <span class="ex">[% message | html %]</span>
</div>
[% END %]
[% IF CAN_user_clubs && ( enrollable || enrollments ) %]
<div id="clubs-tab">
Loading...
</div>
[% END %]
[% INCLUDE borrower_debarments.inc %]
<div id="reserves">

115
koha-tmpl/intranet-tmpl/prog/en/modules/clubs/clubs-add-modify.tt

@ -0,0 +1,115 @@
[% USE KohaDates %]
[% USE Branches %]
[% USE AuthorisedValues %]
[% SET AuthorisedValuesCategories = AuthorisedValues.GetCategories %]
[% INCLUDE 'doc-head-open.inc' %]
<title>Koha &rsaquo; Tools &rsaquo; Patron clubs &rsaquo; Club</title>
[% INCLUDE 'doc-head-close.inc' %]
[% INCLUDE 'calendar.inc' %]
</head>
<body id="clubs_add_modify" class="clubs">
[% INCLUDE 'header.inc' %]
[% INCLUDE 'cat-search.inc' %]
<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; <a href="/cgi-bin/koha/tools/tools-home.pl">Tools</a> &rsaquo; <a href="clubs.pl">Patron clubs</a> &rsaquo; Add / modify club</div>
<div class="yui-t7">
<div class="yui-main">
<form method="post" class="validated">
<input type="hidden" name="id" value="[% club.id %]" />
<input type="hidden" name="club_template_id" value="[% club_template.id %]" />
<fieldset class="rows">
<legend>
[% IF club %]
Modify club <i>[% club.name %]</i>
[% ELSE %]
Create a new <i>[% club_template.name %]</i> club
[% END %]
</legend>
<ol>
<li>
<label class="required" for="name">Name:</label>
<input id="club-name" name="name" type="text" value="[% club.name %]" required="required"/>
<span class="required">Required</span>
</li>
<li>
<label for="description">Description:</label>
<input id="club-template-name" name="description" type="text" value="[% club.description %]" />
</li>
<li>
<label for="date_start">Start date:</label>
<input name="date_start" id="from" size="10" readonly="readonly" class="datepickerfrom" value="[% club.date_start | $KohaDates %]">
</li>
<li>
<label for="date_end">End date:</label>
<input name="date_end" id="to" size="10" readonly="readonly" class="datepickerto" value="[% club.date_end | $KohaDates %]" >
</li>
<li>
<label for="name">Library:</label>
<select name="branchcode" id="club-template-branchcode">
<option value="">&nbsp</option>
[% PROCESS options_for_libraries libraries => Branches.all( selected => club.branch.branchcode ) %]
</select>
</li>
[% IF club %]
[% FOREACH f IN club.club_fields %]
<li>
<input type="hidden" name="club_template_field_id" value="[% f.club_template_field.id %]" />
<input type="hidden" name="club_field_id" value="[% f.id %]" />
<label for="club_field">[% f.club_template_field.name %]</label>
[% IF f.club_template_field.authorised_value_category %]
<select name="club_field">
[% FOREACH a IN AuthorisedValues.Get( f.club_template_field.authorised_value_category ) %]
[% IF a.authorised_value == f.value %]
<option value="[% a.authorised_value %]" selected="selected">[% a.lib %]</option>
[% ELSE %]
<option value="[% a.authorised_value %]">[% a.lib %]</option>
[% END %]
[% END %]
</select>
[% ELSE %]
<input type="text" name="club_field" value="[% f.value %]" />
[% END %]
</li>
[% END %]
[% ELSE %]
[% FOREACH f IN club_template.club_template_fields %]
<li>
<input type="hidden" name="club_template_field_id" value="[% f.id %]" />
<label for="club_field">[% f.name %]</label>
[% IF f.authorised_value_category %]
<select name="club_field">
[% FOREACH a IN AuthorisedValues.Get( f.authorised_value_category ) %]
<option value="[% a.authorised_value %]">[% a.lib %]</option>
[% END %]
</select>
[% ELSE %]
<input type="text" name="club_field" />
[% END %]
</li>
[% END %]
[% END %]
</ol>
</fieldset>
<fieldset class="action">
<input type="submit" class="btn btn-default" value="Save" />
<a href="clubs.pl" class="cancel">Cancel</a>
</fieldset>
</form>
</div>
</div>
[% INCLUDE 'intranet-bottom.inc' %]

252
koha-tmpl/intranet-tmpl/prog/en/modules/clubs/clubs.tt

@ -0,0 +1,252 @@
[% USE Branches %]
[% USE Koha %]
[% INCLUDE 'doc-head-open.inc' %]
<title>Koha &rsaquo; Tools &rsaquo; Patron clubs</title>
[% INCLUDE 'doc-head-close.inc' %]
<link rel="stylesheet" type="text/css" href="[% interface %]/[% theme %]/css/datatables.css" />
[% INCLUDE 'datatables.inc' %]
<script type="text/javascript">
//<![CDATA[
$(document).ready(function() {
tTable = $('#club-templates-table').dataTable($.extend(true, {}, dataTablesDefaults, {
"sPaginationType": "four_button",
"sDom": 'C<"top pager"ilpf><"#filter_c">tr<"bottom pager"ip>',
"aoColumnDefs": [
{ "aTargets": [ -1, -2 ], "bSortable": false, "bSearchable": false },
]
} ));
cTable = $('#clubs-table').dataTable($.extend(true, {}, dataTablesDefaults, {
"sPaginationType": "four_button",
"sDom": 'C<"top pager"ilpf><"#filter_c">tr<"bottom pager"ip>',
"aoColumnDefs": [
{ "aTargets": [ -1, -2 ], "bSortable": false, "bSearchable": false },
]
} ));
});
function ConfirmDeleteTemplate( id, name, a ) {
if ( confirm( _("Are you sure you want to delete the club template %s?" ).format(name) ) ) {
$.ajax({
type: "POST",
url: '/cgi-bin/koha/svc/club/template/delete',
data: { id: id },
success: function( data ) {
if ( data.success ) {
tTable.fnDeleteRow(a.closest("tr")[0]);
} else {
alert(_("Unable to delete template!"));
}
},
dataType: 'json'
});
}
}
function ConfirmDeleteClub( id, name, a ) {
if ( confirm( _("Are you sure you want to delete the club %s?" ).format(name) ) ) {
$.ajax({
type: "POST",
url: '/cgi-bin/koha/svc/club/delete',
data: { id: id },
success: function( data ) {
if ( data.success ) {
cTable.fnDeleteRow(a.closest("tr")[0]);
} else {
alert(_("Unable to delete club!"));
}
},
dataType: 'json'
});
}
}
//]]>
</script>
</head>
<body id="clubs_clubs" class="clubs">
[% INCLUDE 'header.inc' %]
[% INCLUDE 'cat-search.inc' %]
<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; <a href="/cgi-bin/koha/tools/tools-home.pl">Tools</a> &rsaquo; Patron clubs</div>
<div id="doc3" class="yui-t2">
<div id="bd">
<div id="yui-main">
<div class="yui-b">
<h1>Patron clubs</h1>
[% IF club_template %]
<div class="dialog message">
[% IF stored == 'updated' %]
<p>Club template <i>[% club_template.name %]</i> was updated.</p>
[% ELSE %]
<p>Club template <i>[% club_template.name %]</i> was saved.</p>
[% END %]
</div>
[% ELSIF club %]
<div class="dialog message">
[% IF stored == 'updated' %]
<p>Club <i>[% club.name %]</i> was updated.</p>
[% ELSE %]
<p>Club <i>[% club.name %]</i> was saved.</p>
[% END %]
</div>
[% END %]
<h3>Club templates</h3>
[% IF CAN_user_clubs_edit_templates %]
<div class="btn-toolbar">
<div class="btn-group">
<a class="btn btn-default" href="templates-add-modify.pl"><i class="fa fa-plus"></i> New club template</a>
</div>
</div>
[% END %]
<table id="club-templates-table">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
<th>Public enrollment</th>
<th>Email required</th>
<th>Library</th>
<th>&nbsp;</th>
<th>&nbsp;</th>
</tr>
</thead>
<tbody>
[% IF club_templates %]
[% FOREACH t IN club_templates %]
<tr>
<td>[% t.name %]</td>
<td>[% t.description %]</td>
<td>
[% IF t.is_enrollable_from_opac %]
Yes
[% ELSE %]
No
[% END %]
</td>
<td>
[% IF t.is_email_required %]
Yes
[% ELSE %]
No
[% END %]
</td>
<td>[% Branches.GetName( t.branchcode ) %]</td>
<td>
[% IF CAN_user_clubs_edit_templates %]
<a class="btn btn-default" style="white-space:nowrap" href="templates-add-modify.pl?id=[% t.id %]">
<i class="fa fa-edit"></i> Edit
</a>
[% END %]
</td>
<td>
[% IF CAN_user_clubs_edit_templates %]
<a class="btn btn-default" href="#" onclick='ConfirmDeleteTemplate([% t.id %], "[% t.name | html %]", $(this) ); return false;'>
<i class="fa fa-trash"></i> Delete
</a>
[% END %]
</td>
</tr>
[% END %]
[% ELSE %]
<tr>
<td colspan="7">
No club templates defined.
</td>
</td>
[% END %]
</tbody>
</table>
<h3>Clubs</h3>
[% IF CAN_user_clubs_edit_clubs %]
<div class="btn-toolbar">
<div class="btn-group">
<button class="btn btn-default dropdown-toggle" data-toggle="dropdown"><i class="fa fa-plus"></i> New club <span class="caret"></span></button>
<ul class="dropdown-menu">
[% FOREACH t IN club_templates %]
<li><a href="/cgi-bin/koha/clubs/clubs-add-modify.pl?club_template_id=[% t.id %]">[% t.name %]</a></li>
[% END %]
</ul>
</div>
</div>
[% END %]
<table id="clubs-table">
<thead>
<tr>
<th>Name</th>
<th>Template</th>
<th>Description</th>
<th>Public enrollment</th>
<th>Email required</th>
<th>Library</th>
<th>&nbsp;</th>
<th>&nbsp;</th>
</tr>
</thead>
<tbody>
[% IF clubs %]
[% FOREACH c IN clubs %]
<tr>
<td>[% c.name %]</td>
<td>[% c.club_template.name %]</td>
<td>[% c.description %]</td>
<td>
[% IF c.club_template.is_enrollable_from_opac %]
Yes
[% ELSE %]
No
[% END %]
</td>
<td>
[% IF c.club_template.is_email_required %]
Yes
[% ELSE %]
No
[% END %]
</td>
<td>[% Branches.GetName( c.branchcode ) %]</td>
<td>
[% IF CAN_user_clubs_edit_clubs %]
<a class="btn btn-default" style="white-space:nowrap" href="clubs-add-modify.pl?id=[% c.id %]">
<i class="fa fa-edit"></i> Edit
</a>
[% END %]
</td>
<td>
[% IF CAN_user_clubs_edit_clubs %]
<a class="btn btn-default" href="#" onclick='ConfirmDeleteClub([% c.id %], "[% c.name | html %]", $(this) ); return false;'>
<i class="fa fa-trash"></i> Delete
</a>
[% END %]
</td>
</tr>
[% END %]
[% ELSE %]
<tr>
<td colspan="8">
No club templates defined.
</td>
</td>
[% END %]
</tbody>
</table>
</div>
</div>
<div class="yui-b noprint">
[% INCLUDE 'tools-menu.inc' %]
</div>
</div>
</div>
[% INCLUDE 'intranet-bottom.inc' %]

102
koha-tmpl/intranet-tmpl/prog/en/modules/clubs/patron-clubs-tab.tt

@ -0,0 +1,102 @@
[% USE KohaDates %]
[% IF enrollments %]
<table>
<thead>
<tr>
<th colspan="4">
Clubs currently enrolled in
</th>
</tr>
<tr>
<th>Name</th>
<th>Description</th>
<th>Date enrolled</th>
[% IF CAN_user_clubs_enroll %]<th>&nbsp;</th>[% END %]
</tr>
</thead>
<tbody>
[% FOREACH e IN enrollments %]
<tr>
<td>[% e.club.name %]</td>
<td>[% e.club.description %]</td>
<td>[% e.date_enrolled | $KohaDates %]</td>
[% IF CAN_user_clubs_enroll %]
<td>
<a class="btn btn-xs" onclick="cancelEnrollment( [% e.id %] )">
<i class="fa fa-remove"></i> Cancel
</a>
</td>
[% END %]
</tr>
[% END %]
</tbody>
</table>
[% END %]
[% IF clubs %]
<table>
<thead>
<tr>
<th colspan="3">
Clubs not enrolled in
</th>
</tr>
<tr>
<th>Name</th>
<th>Description</th>
[% IF CAN_user_clubs_enroll %]<th>&nbsp;</th>[% END %]
</tr>
</thead>
<tbody>
[% FOREACH c IN clubs %]
<tr>
<td>[% c.name %]</td>
<td>[% c.description %]</td>
[% IF CAN_user_clubs_enroll %]
<td>
<a class="btn btn-xs" onclick="loadEnrollmentForm([% c.id %])">
<i class="fa fa-plus"></i> Enroll
</a>
</td>
[% END %]
</tr>
[% END %]
</tbody>
</table>
[% END %]
[% IF CAN_user_clubs_enroll %]
<script type="text/javascript">
function loadEnrollmentForm( id ) {
$("body").css("cursor", "progress");
$('#clubs-tab').load('/cgi-bin/koha/clubs/patron-enroll.pl?borrowernumber=[% borrowernumber %]&id=' + id, function() {
$("body").css("cursor", "default");
});
return false;
}
function cancelEnrollment( id ) {
$("body").css("cursor", "progress");
$.ajax({
type: "POST",
url: '/cgi-bin/koha/svc/club/cancel_enrollment',
data: { id: id },
success: function( data ) {
if ( data.success ) {
$('#clubs-tab').load('/cgi-bin/koha/clubs/patron-clubs-tab.pl?borrowernumber=[% borrowernumber %]', function() {
$("body").css("cursor", "default");
});
} else {
alert(_("Unable to cancel enrollment!"));
}
},
dataType: 'json'
});
return false;
}
</script>
[% END %]

66
koha-tmpl/intranet-tmpl/prog/en/modules/clubs/patron-enroll.tt

@ -0,0 +1,66 @@
[% USE AuthorisedValues %]
[% SET AuthorisedValuesCategories = AuthorisedValues.GetCategories %]
<h3>
Enroll in <i>[% club.name %]</i>
</h3>
<div class="container">
<form id="patron-enrollment-form">
<input type="hidden" name="id" value="[% club.id %]" />
<input type="hidden" name="borrowernumber" value="[% borrowernumber %]" />
<fieldset class="rows">
<ol>
[% FOREACH f IN club.club_template.club_template_enrollment_fields %]
<li>
<label>[% f.name %]</label>
[% IF f.authorised_value_category %]
<select name="[% f.id %]">
[% FOREACH a IN AuthorisedValues.Get( f.authorised_value_category ) %]
<option value="[% a.authorised_value %]">[% a.lib %]</option>
[% END %]
</select>
[% ELSE %]
<input type="text" name="[% f.id %]" />
[% END %]
<span class="hint">[% f.description %]</span>
</li>
[% END %]
<li>
<a href="#" class="btn btn-default" onclick="addEnrollment(); return false;"><i class="fa fa-plus"></i> Enroll</a>
<a href="#" onclick="showClubs(); return false;">Cancel</a>
</li>
</ol>
</fieldset>
</form>
</div>
<script type="text/javascript">
function addEnrollment() {
$("body").css("cursor", "progress");
$.ajax({
type: "POST",
url: '/cgi-bin/koha/svc/club/enroll',
data: $( "#patron-enrollment-form" ).serialize(),
success: function( data ) {
if ( data.success ) {
$('#clubs-tab').load('/cgi-bin/koha/clubs/patron-clubs-tab.pl?borrowernumber=[% borrowernumber %]&id=[% club.id %]', function() {
$("body").css("cursor", "default");
});
} else {
alert(_("Unable to create enrollment!"));
}
},
dataType: 'json'
});
return false;
}
function showClubs() {
$("body").css("cursor", "progress");
$('#clubs-tab').load('/cgi-bin/koha/clubs/patron-clubs-tab.pl?borrowernumber=[% borrowernumber %]&id=[% club.id %]', function() {
$("body").css("cursor", "default");
});
}
</script>

216
koha-tmpl/intranet-tmpl/prog/en/modules/clubs/templates-add-modify.tt

@ -0,0 +1,216 @@
[% USE Branches %]
[% USE AuthorisedValues %]
[% INCLUDE 'doc-head-open.inc' %]
<title>Koha &rsaquo; Tools &rsaquo; Patron clubs &rsaquo; Club template</title>
[% INCLUDE 'doc-head-close.inc' %]
</head>
<body id="clubs_templates_add_modify" class="clubs">
[% INCLUDE 'header.inc' %]
[% INCLUDE 'cat-search.inc' %]
<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; <a href="/cgi-bin/koha/tools/tools-home.pl">Tools</a> &rsaquo; <a href="clubs.pl">Patron clubs</a> &rsaquo; Add / modify club template</div>
<div class="yui-t7">
<div class="yui-main">
<form method="post" class="validated">
<input type="hidden" name="id" value="[% club_template.id %]" />
<fieldset class="rows">
<legend>
[% IF club_template %]
Modify club template <i>[% club_template.name %]</i>
[% ELSE %]
Create a new club template
[% END %]
</legend>
<ol>
<li>
<label class="required" for="name">Name:</label>
<input id="club-template-name" name="name" type="text" value="[% club_template.name %]" required="required"/>
<span class="required">Required</span>
</li>
<li>
<label for="description">Description:</label>
<input id="club-template-description" name="description" type="text" value="[% club_template.description %]" />
</li>
<li>
<label for="is_enrollable_from_opac">Allow public enrollment:</label>
[% IF club_template.is_enrollable_from_opac %]
<input type="checkbox" id="club-template-is-enrollable-from-opac" name="is_enrollable_from_opac" checked="checked" />
[% ELSE %]
<input type="checkbox" id="club-template-is-enrollable-from-opac" name="is_enrollable_from_opac" />
[% END %]
<span class="hint">If a template allows public enrollment, patrons can enroll in a club based on this template from the public catalog.</span>
</li>
<li>
<label for="is_email_required">Require valid email address:</label>
[% IF club_template.is_email_required %]
<input type="checkbox" id="club-template-is-email-required" name="is_email_required" checked="checked" />
[% ELSE %]
<input type="checkbox" id="club-template-is-email-required" name="is_email_required" />
[% END %]
<span class="hint">If set, a club based on this template can only be enrolled in by patrons with a valid email address.</span>
</li>
<li>
<label for="branchcode">Library:</label>
<select name="branchcode" id="club-template-branchcode">
<option value="">&nbsp</option>
[% PROCESS options_for_libraries libraries => Branches.all( selected => club_template.branchcode ) %]
</select>
<span class="hint">If set, only librarians logged in with this branch will be able to modify this club template.</span>
</li>
</ol>
<h2>Club fields:</h2>
<p><span class="hint">These fields will be used in the creation of clubs based on this template</span></p>
<span id="club-template-fields">
[% FOREACH f IN club_template.club_template_fields %]
<ul>
<input type="hidden" name="club_template_field_id" value="[% f.id %]" />
<li>
<label for="field-name-[% f.id %]">Name:</label>
<input name="club_template_field_name" id="field-name-[% f.id %]" value="[% f.name %]" />
</li>
<li>
<label for="field-description-[% f.id %]">Description:</label>
<input name="club_template_field_description" id="field-description-[% f.id %]" value="[% f.description %]" />
</li>
<li>
<label for="field-description-[% f.id %]">Authorised value category:</label>
<select name="club_template_field_authorised_value_category" id="field-authorised-value-category-[% f.id %]">
<option value="">&nbsp;</option>
[% PROCESS options_for_authorised_value_categories authorised_value_categories => AuthorisedValues.GetCategories( selected => f.authorised_value_category) %]
</select>
</li>
<li>
<label for="field-delete-[% f.id %]">Delete field:</label>
<input type="checkbox" name="club_template_field_delete" id="field-delete-[% f.id %]" value="[% f.id %]" />
</li>
<hr/>
</ul>
[% END %]
</span>
<div class="btn-toolbar">
<a href="#" class="btn btn-default" onclick="$('#new-field-template').clone().attr('id','').show().appendTo('#club-template-fields'); return false;">
<i class="fa fa-plus"></i> Add new field
</a>
</div>
<h2>Enrollment fields:</h2>
<p><span class="hint">These fields will be used when enrolling a patron in a club based on this template</span></p>
<span id="club-template-enrollment-fields">
[% FOREACH f IN club_template.club_template_enrollment_fields %]
<ul>
<input type="hidden" name="club_template_enrollment_field_id" value="[% f.id %]" />
<li>
<label for="enrollment-field-name-[% f.id %]">Name:</label>
<input name="club_template_enrollment_field_name" id="enrollment-field-name-[% f.id %]" value="[% f.name %]" />
</li>
<li>
<label for="enrollment-field-description-[% f.id %]">Description:</label>
<input name="club_template_enrollment_field_description" id="enrollment-field-description-[% f.id %]" value="[% f.description %]" />
</li>
<li>
<label for="enrollment-field-description-[% f.id %]">Authorised value category:</label>
<select name="club_template_enrollment_field_authorised_value_category" id="enrollment-field-authorised-value-category-[% f.id %]">
<option value="">&nbsp;</option>
[% PROCESS options_for_authorised_value_categories authorised_value_categories => AuthorisedValues.GetCategories( selected => f.authorised_value_category) %]
</select>
</li>
<li>
<label for="enrollment-field-delete-[% f.id %]">Delete field:</label>
<input type="checkbox" name="club_template_enrollment_field_delete" id="enrollment-field-delete-[% f.id %]" value="[% f.id %]" />
</li>
<hr/>
</ul>
[% END %]
</span>
<div class="btn-toolbar">
<a href="#" class="btn btn-default" onclick="$('#new-enrollment-field-template').clone().attr('id','').show().appendTo('#club-template-enrollment-fields'); return false;">
<i class="fa fa-plus"></i> Add new field
</a>
</div>
</fieldset>
<fieldset class="action">
<input type="hidden" name="id" value="[% club_template.id %]" />
<input type="submit" class="btn btn-default" value="Save" />
<a href="clubs.pl" class="cancel">Cancel</a>
</fieldset>
</form>
</div>
</div>
<span id="new-field-template" style="display:none">
<ul>
<input type="hidden" name="club_template_field_id" value="" />
<li>
<label for="club_template_field_name">Name:</label>
<input name="club_template_field_name" />
</li>
<li>
<label for="club_template_field_description">Description:</label>
<input name="club_template_field_description" />
</li>
<li>
<label for="club_template_field_authorised_value_category">Authorised value category:</label>
<select name="club_template_field_authorised_value_category">
<option value="">&nbsp;</option>
[% PROCESS options_for_authorised_value_categories authorised_value_categories => AuthorisedValues.GetCategories() %]
</select>
</li>
<a href="#" onclick="$(this).parent().remove(); return false;">Cancel</a>
<hr/>
</ul>
</span>
<span id="new-enrollment-field-template" style="display:none">
<ul>
<input type="hidden" name="club_template_enrollment_field_id" value="" />
<li>
<label for="club_template_enrollment_field_name">Name:</label>
<input name="club_template_enrollment_field_name" />
</li>
<li>
<label for="club_template_enrollment_field_description">Description:</label>
<input name="club_template_enrollment_field_description" />
</li>
<li>
<label for="club_template_enrollment_field_authorised_value_category">Authorised value category:</label>
<select name="club_template_enrollment_field_authorised_value_category">
<option value="">&nbsp;</option>
[% PROCESS options_for_authorised_value_categories authorised_value_categories => AuthorisedValues.GetCategories() %]
</select>
</li>
<a href="#" onclick="$(this).parent().remove(); return false;">Cancel</a>
<hr/>
</ul>
</span>
[% INCLUDE 'intranet-bottom.inc' %]

22
koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt

@ -48,6 +48,13 @@ var MSG_EXPORT_SELECT_CHECKOUTS = _("You must select checkout(s) to export");
columns_settings = [% ColumnsSettings.GetColumns( 'members', 'moremember', 'issues-table', 'json' ) %]
$(document).ready(function() {
if ( $('#clubs-tab').length ) {
$('#clubs-tab-link').on('click', function() {
$('#clubs-tab').text(_("Loading..."));
$('#clubs-tab').load('/cgi-bin/koha/clubs/patron-clubs-tab.pl?borrowernumber=[% borrowernumber %]');
});
}
$('#finesholdsissues').tabs({
// Correct table sizing for tables hidden in tabs
// http://www.datatables.net/examples/api/tabs_and_scrolling.html
@ -519,6 +526,15 @@ function validate1(date) {
</li>
[% END %]
<li><a id="debarments-tab-link" href="#reldebarments">[% debarments.size %] Restrictions</a></li>
[% SET enrollments = borrower.get_club_enrollments.size || 0 %]
[% SET enrollable = borrower.get_enrollable_clubs.size || 0 %]
[% IF CAN_user_clubs && ( enrollments || enrollable ) %]
<li>
<a id="clubs-tab-link" href="#clubs-tab">
Clubs ([% enrollments %]/[% enrollable %])
</a>
</li>
[% END %]
</ul>
[% INCLUDE "checkouts-table.inc" %]
@ -554,6 +570,12 @@ function validate1(date) {
[% END %]
</div>
[% IF CAN_user_clubs && ( enrollments || enrollable ) %]
<div id="clubs-tab">
Loading...
</div>
[% END %]
[% INCLUDE borrower_debarments.inc %]
<div id="reserves">

5
koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt

@ -20,6 +20,11 @@
<dd>Manage lists of patrons.</dd>
[% END %]
[% IF (CAN_user_clubs) %]
<dt><a href="/cgi-bin/koha/clubs/clubs.pl">Patron clubs</a>
<dd>Manage patron clubs..</dd>
[% END %]
[% IF ( CAN_user_tools_moderate_comments ) %]
<dt><a href="/cgi-bin/koha/reviews/reviewswaiting.pl">Comments</a> [% IF ( pendingcomments ) %]<span class="number_box"><a href="/cgi-bin/koha/reviews/reviewswaiting.pl">[% pendingcomments %]</a></span>[% END %]</dt>
<dd>Moderate patron comments. </dd>

102
koha-tmpl/opac-tmpl/bootstrap/en/modules/clubs/clubs-tab.tt

@ -0,0 +1,102 @@
[% USE KohaDates %]
[% IF enrollments %]
<table id="clubs-table-enrolled" class="table table-bordered table-striped">
<thead>
<tr>
<th colspan="4">
Clubs you are currently enrolled in
</th>
</tr>
<tr>
<th>Name</th>
<th>Description</th>
<th>Date enrolled</th>
<th>&nbsp;</th>
</tr>
</thead>
<tbody>
[% FOREACH e IN enrollments %]
<tr>
<td>[% e.club.name %]</td>
<td>[% e.club.description %]</td>
<td>[% e.date_enrolled | $KohaDates %]</td>
[% IF e.club.club_template.is_enrollable_from_opac %]
<td>
<a class="btn btn-xs" onclick="cancelEnrollment( [% e.id %] )">
<i class="icon-remove"></i> Cancel
</a>
</td>
[% END %]
</tr>
[% END %]
</tbody>
</table>
[% END %]
[% IF clubs %]
<table id="clubs-table-unenrolled" class="table table-bordered table-striped">
<thead>
<tr>
<th colspan="3">
Clubs you can enroll in
</th>
</tr>
<tr>
<th>Name</th>
<th>Description</th>
<th>&nbsp;</th>
</tr>
</thead>
<tbody>
[% FOREACH c IN clubs %]
<tr>
<td>[% c.name %]</td>
<td>[% c.description %]</td>
<td>
[% IF !c.club_template.is_email_required || ( c.club_template.is_email_required && borrower.FirstValidEmailAddress ) %]
<a class="btn btn-xs" onclick="loadEnrollmentForm([% c.id %])">
<i class="icon-plus"></i> Enroll
</a>
[% ELSE %]
<span class="hint">You must have an email address to enroll</span>
[% END %]
</td>
</tr>
[% END %]
</tbody>
</table>
[% END %]
<script type="text/javascript">
function loadEnrollmentForm( id ) {
$("body").css("cursor", "progress");
$('#opac-user-clubs').load('/cgi-bin/koha/clubs/enroll.pl?borrowernumber=[% borrower.borrowernumber %]&id=' + id, function() {
$("body").css("cursor", "default");
});
return false;
}
function cancelEnrollment( id ) {
$("body").css("cursor", "progress");
$.ajax({
type: "POST",
url: '/cgi-bin/koha/svc/club/cancel_enrollment',
data: { id: id },
success: function( data ) {
if ( data.success ) {
$('#opac-user-clubs').load('/cgi-bin/koha/clubs/clubs-tab.pl?borrowernumber=[% borrower.borrowernumber %]', function() {
$("body").css("cursor", "default");
});
} else {
alert(_("Unable to cancel enrollment!"));
}
},
dataType: 'json'
});
return false;
}
</script>

66
koha-tmpl/opac-tmpl/bootstrap/en/modules/clubs/enroll.tt

@ -0,0 +1,66 @@
[% USE AuthorisedValues %]
[% SET AuthorisedValuesCategories = AuthorisedValues.GetCategories %]
<h3>
Enroll in <i>[% club.name %]</i>
</h3>
<div class="container">
<form id="patron-enrollment-form">
<input type="hidden" name="id" value="[% club.id %]" />
<input type="hidden" name="borrowernumber" value="[% borrowernumber %]" />
<fieldset class="rows">
<ol>
[% FOREACH f IN club.club_template.club_template_enrollment_fields %]
<li>
<label>[% f.name %]</label>
[% IF f.authorised_value_category %]
<select name="[% f.id %]">
[% FOREACH a IN AuthorisedValues.Get( f.authorised_value_category ) %]
<option value="[% a.authorised_value %]">[% a.lib %]</option>
[% END %]
</select>
[% ELSE %]
<input type="text" name="[% f.id %]" />
[% END %]
<span class="hint">[% f.description %]</span>
</li>
[% END %]
<li>
<a href="#" class="btn btn-default" onclick="addEnrollment(); return false;"><i class="fa fa-plus"></i> Enroll</a>
<a href="#" onclick="showClubs(); return false;">Cancel</a>
</li>
</ol>
</fieldset>
</form>
</div>
<script type="text/javascript">
function addEnrollment() {
$("body").css("cursor", "progress");
$.ajax({
type: "POST",
url: '/cgi-bin/koha/svc/club/enroll',
data: $( "#patron-enrollment-form" ).serialize(),
success: function( data ) {
if ( data.success ) {
$('#opac-user-clubs').load('/cgi-bin/koha/clubs/clubs-tab.pl?borrowernumber=[% borrowernumber %]&id=[% club.id %]', function() {
$("body").css("cursor", "default");
});
} else {
alert(_("Unable to create enrollment!"));
}
},
dataType: 'json'
});
return false;
}
function showClubs() {
$("body").css("cursor", "progress");
$('#opac-user-clubs').load('/cgi-bin/koha/clubs/clubs-tab.pl?borrowernumber=[% borrowernumber %]&id=[% club.id %]', function() {
$("body").css("cursor", "default");
});
}
</script>

24
koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-user.tt

@ -82,7 +82,7 @@ Using this account is not recommended because some parts of Koha will not functi
[% ELSIF error == 'too_soon' %]
It is too soon after the checkout date for this item to be renewed.
[% ELSIF error == 'on_reserve' %]
This item is on hold for another patron.
This item is on hold for another borrower.
[% END %]
[% END %]
</span>
@ -133,6 +133,15 @@ Using this account is not recommended because some parts of Koha will not functi
[% IF ( BORROWER_INFO.amountoverzero ) %]<li><a href="#opac-user-fines">Fines ([% amountoutstanding | $Price %])</a></li>[% END %]
[% IF ( BORROWER_INFO.amountlessthanzero ) %]<li><a href="#opac-user-fines">Credits ([% amountoutstanding | $Price %])</a></li>[% END %]
[% END %]
[% IF borrower.get_club_enrollments.size || borrower.get_enrollable_clubs(1).size %]
<li>
<a id="opac-user-clubs-tab-link" href="#opac-user-clubs">
Clubs ([% borrower.get_club_enrollments.size %]/[% borrower.get_enrollable_clubs(1).size || 0 %])
</a>
</li>
[% END %]
[% IF ( RESERVES.count ) %]<li><a href="#opac-user-holds">Holds ([% RESERVES.count %])</a></li>[% END %]
[% IF Koha.Preference('ArticleRequests') && borrower.article_requests_current %]<li><a href="#opac-user-article-requests">Article requests ([% borrower.article_requests_current.count %])</a></li>[% END %]
[% IF ( OverDriveCirculation ) %]
@ -315,6 +324,12 @@ Using this account is not recommended because some parts of Koha will not functi
[% END # IF issues_count %]
</div> <!-- / .opac-user-checkouts -->
[% IF borrower.get_club_enrollments_count.size || borrower.get_enrollable_clubs(1).size %]
<div id="opac-user-clubs">
Loading...
</div>
[% END %]
[% IF ( OPACFinesTab ) %]
<!-- FINES BOX -->
[% IF BORROWER_INFO.amountoverfive %]
@ -893,6 +908,13 @@ Using this account is not recommended because some parts of Koha will not functi
[% END %]
$( ".suspend-until" ).datepicker({ minDate: 1 }); // Require that "until date" be in the future
if ( $('#opac-user-clubs').length ) {
$('#opac-user-clubs-tab-link').on('click', function() {
$('#opac-user-clubs').text(_("Loading..."));
$('#opac-user-clubs').load('/cgi-bin/koha/clubs/clubs-tab.pl?borrowernumber=[% borrowernumber %]');
});
}
});
//]]>
</script>

2
members/moremember.pl

@ -64,6 +64,7 @@ if ( C4::Context->preference('NorwegianPatronDBEnable') && C4::Context->preferen
use DateTime;
use Koha::DateUtils;
use Koha::Database;
use Koha::Patrons;
use Koha::Patron::Categories;
use Koha::Token;
@ -356,6 +357,7 @@ $template->param(
PatronsPerPage => C4::Context->preference("PatronsPerPage") || 20,
relatives_issues_count => $relatives_issues_count,
relatives_borrowernumbers => \@relatives,
borrower => Koha::Patrons->find( $borrowernumber ),
);
output_html_with_http_headers $input, $cookie, $template->output;

52
opac/clubs/clubs-tab.pl

@ -0,0 +1,52 @@
#!/usr/bin/perl
# Copyright 2013 ByWater Solutions
#
# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Koha is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Koha; if not, see <http://www.gnu.org/licenses>.
use Modern::Perl;
use CGI;
use C4::Auth;
use C4::Output;
use Koha::Patrons;
my $cgi = new CGI;
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
{
template_name => "clubs/clubs-tab.tt",
query => $cgi,
type => "opac",
authnotrequired => 0,
}
);
my $borrowernumber = $cgi->param('borrowernumber');
my $borrower = Koha::Patrons->find($borrowernumber);
my @enrollments = $borrower->get_club_enrollments();
my @clubs = $borrower->get_enrollable_clubs( my $opac = 1 );
$template->param(
enrollments => \@enrollments,
clubs => \@clubs,
borrower => $borrower,
);
output_html_with_http_headers( $cgi, $cookie, $template->output );

49
opac/clubs/enroll.pl

@ -0,0 +1,49 @@
#!/usr/bin/perl
# Copyright 2013 ByWater Solutions
#
# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Koha is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Koha; if not, see <http://www.gnu.org/licenses>.
use Modern::Perl;
use CGI;
use C4::Auth;
use C4::Output;
use Koha::Clubs;
my $cgi = new CGI;
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
{
template_name => "clubs/enroll.tt",
query => $cgi,
type => "opac",
authnotrequired => 0,
}
);
my $id = $cgi->param('id');
my $borrowernumber = $cgi->param('borrowernumber');
my $club = Koha::Clubs->find($id);
$template->param(
club => $club,
borrowernumber => $borrowernumber,
);
output_html_with_http_headers( $cgi, $cookie, $template->output );

47
opac/svc/club/cancel_enrollment

@ -0,0 +1,47 @@
#!/usr/bin/perl
# Copyright 2014 ByWater Solutions
#
# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version.
#
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with Koha; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
use Modern::Perl;
use CGI;
use JSON qw(to_json);
use C4::Auth qw(check_cookie_auth);
use Koha::Club::Enrollments;
my $cgi = new CGI;
my ( $auth_status, $sessionID ) =
check_cookie_auth( $cgi->cookie('CGISESSID') );
if ( $auth_status ne "ok" ) {
exit 0;
}
my $borrowernumber = C4::Context->userenv->{'number'};
my $id = $cgi->param('id');
my $enrollment = Koha::Club::Enrollments->find($id);
$enrollment->cancel();
binmode STDOUT, ':encoding(UTF-8)';
print $cgi->header( -type => 'text/plain', -charset => 'UTF-8' );
print to_json( { success => $enrollment ? 1 : 0 } );

77
opac/svc/club/enroll

@ -0,0 +1,77 @@
#!/usr/bin/perl
# Copyright 2014 ByWater Solutions
#
# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version.
#
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with Koha; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
use Modern::Perl;
use CGI;
use JSON qw(to_json);
use C4::Auth qw(check_cookie_auth);
use Koha::Club::Enrollment::Field;
use Koha::Club::Enrollment;
use Koha::Clubs;
my $cgi = new CGI;
my ( $auth_status, $sessionID ) =
check_cookie_auth( $cgi->cookie('CGISESSID') );
if ( $auth_status ne "ok" ) {
exit 0;
}
my $borrowernumber = C4::Context->userenv->{'number'};
my $id = $cgi->param('id');
my $enrollment;
if ( $borrowernumber && $id ) {
my $club = Koha::Clubs->find($id);
if ( $club->club_template()->is_enrollable_from_opac() ) {
$enrollment = Koha::Club::Enrollment->new()->set(
{
club_id => $club->id(),
borrowernumber => $borrowernumber,
date_enrolled => \'NOW()',
date_created => \'NOW()',
branchcode => C4::Context->userenv
? C4::Context->userenv->{'branch'}
: undef,
}
)->store();
my @enrollment_fields = $club->club_template()->club_template_enrollment_fields();
foreach my $e (@enrollment_fields) {
Koha::Club::Enrollment::Field->new()->set(
{
club_enrollment_id => $enrollment->id(),
club_template_enrollment_field_id => $e->id(),
value => $cgi->param( $e->id() ),
}
)->store();
}
}
}
binmode STDOUT, ':encoding(UTF-8)';
print $cgi->header( -type => 'text/plain', -charset => 'UTF-8' );
print to_json( { success => $enrollment ? 1 : 0 } );

46
svc/club/cancel_enrollment

@ -0,0 +1,46 @@
#!/usr/bin/perl
# Copyright 2014 ByWater Solutions
#
# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version.
#
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with Koha; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
use Modern::Perl;
use CGI;
use JSON qw(to_json);
use C4::Auth qw(check_cookie_auth);
use Koha::Club::Enrollments;
my $cgi = new CGI;
my ( $auth_status, $sessionID ) =
check_cookie_auth( $cgi->cookie('CGISESSID'), { clubs => 'enroll' } );
if ( $auth_status ne "ok" ) {
exit 0;
}
my $id = $cgi->param('id');
my $enrollment = Koha::Club::Enrollments->find($id);
$enrollment->cancel() if $enrollment;
binmode STDOUT, ':encoding(UTF-8)';
print $cgi->header( -type => 'text/plain', -charset => 'UTF-8' );
print to_json( { success => $enrollment ? 1 : 0 } );

48
svc/club/delete

@ -0,0 +1,48 @@
#!/usr/bin/perl
# Copyright 2014 ByWater Solutions
#
# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version.
#
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with Koha; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
use Modern::Perl;
use CGI;
use JSON qw(to_json);
use C4::Auth qw(check_cookie_auth);
use Koha::Clubs;
my $cgi = new CGI;
my ( $auth_status, $sessionID ) = check_cookie_auth( $cgi->cookie('CGISESSID'), { clubs => 'edit_clubs' } );
if ( $auth_status ne "ok" ) {
exit 0;
}
my $success = 0;
my $id = $cgi->param('id');
my $club = Koha::Clubs->find($id);
if ($club) {
$success = $club->delete();
}
binmode STDOUT, ':encoding(UTF-8)';
print $cgi->header( -type => 'text/plain', -charset => 'UTF-8' );
print to_json( { success => $success ? 1 : 0 } );

74
svc/club/enroll

@ -0,0 +1,74 @@
#!/usr/bin/perl
# Copyright 2014 ByWater Solutions
#
# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version.
#
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with Koha; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
use Modern::Perl;
use CGI;
use JSON qw(to_json);
use C4::Auth qw(check_cookie_auth);
use Koha::Club::Enrollment::Fields;
use Koha::Club::Enrollments;
use Koha::Clubs;
my $cgi = new CGI;
my ( $auth_status, $sessionID ) =
check_cookie_auth( $cgi->cookie('CGISESSID'), { clubs => 'enroll' } );
if ( $auth_status ne "ok" ) {
exit 0;
}
my $id = $cgi->param('id');
my $borrowernumber = $cgi->param('borrowernumber');
my $club = Koha::Clubs->find($id);
my $enrollment;
if ($club) {
$enrollment = Koha::Club::Enrollment->new(
{
club_id => $club->id(),
borrowernumber => $borrowernumber,
date_enrolled => \'NOW()',
date_created => \'NOW()',
branchcode => C4::Context->userenv ? C4::Context->userenv->{'branch'} : undef,
}
)->store();
if ($enrollment) {
my @enrollment_fields = $club->club_template()->club_template_enrollment_fields();
foreach my $e (@enrollment_fields) {
my $club_enrollment_field = Koha::Club::Enrollment::Field->new(
{
club_enrollment_id => $enrollment->id(),
club_template_enrollment_field_id => $e->id(),
value => $cgi->param( $e->id() ),
}
)->store();
}
}
}
binmode STDOUT, ':encoding(UTF-8)';
print $cgi->header( -type => 'text/plain', -charset => 'UTF-8' );
print to_json( { success => $enrollment ? 1 : 0 } );

49
svc/club/template/delete

@ -0,0 +1,49 @@
#!/usr/bin/perl
# Copyright 2014 ByWater Solutions
#
# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version.
#
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with Koha; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
use Modern::Perl;
use CGI;
use JSON qw(to_json);
use C4::Auth qw(check_cookie_auth);
use Koha::Club::Templates;
my $cgi = new CGI;
my ( $auth_status, $sessionID ) = check_cookie_auth( $cgi->cookie('CGISESSID'), { clubs => 'edit_templates' } );
if ( $auth_status ne "ok" ) {
exit 0;
}
my $success = 0;
my $id = $cgi->param('id');
my $club_template = Koha::Club::Templates->find($id);
if ($club_template) {
$success = $club_template->delete();
}
binmode STDOUT, ':encoding(UTF-8)';
print $cgi->header( -type => 'text/plain', -charset => 'UTF-8' );
print to_json( { success => $success ? 1 : 0 } );

221
t/db_dependent/Clubs.t

@ -0,0 +1,221 @@
#!/usr/bin/perl
# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Koha is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Koha; if not, see <http://www.gnu.org/licenses>.
use Modern::Perl;
use Test::More tests => 36;
use Test::Warn;
use C4::Context;
use Koha::Database;
use Koha::Patrons;
use t::lib::TestBuilder;
BEGIN {
use_ok('Koha::Club');
use_ok('Koha::Clubs');
use_ok('Koha::Club::Field');
use_ok('Koha::Club::Fields');
use_ok('Koha::Club::Template');
use_ok('Koha::Club::Templates');
use_ok('Koha::Club::Template::Field');
use_ok('Koha::Club::Template::Fields');
use_ok('Koha::Club::Enrollment::Field');
use_ok('Koha::Club::Enrollment::Fields');
use_ok('Koha::Club::Template::EnrollmentField');
use_ok('Koha::Club::Template::EnrollmentFields');
}
# Start transaction
my $database = Koha::Database->new();
my $schema = $database->schema();
my $dbh = C4::Context->dbh;
my $builder = t::lib::TestBuilder->new;
$schema->storage->txn_begin();
$dbh->do("DELETE FROM club_templates");
my $categorycode = $builder->build( { source => 'Category' } )->{categorycode};
my $branchcode = $builder->build( { source => 'Branch' } )->{branchcode};
my $patron = Koha::Patron->new(
{
surname => 'Test 1',
branchcode => $branchcode,
categorycode => $categorycode
}
);
$patron->store();
my $club_template = Koha::Club::Template->new(
{
name => "Test Club Template",
is_enrollable_from_opac => 0,
is_email_required => 0,
}
)->store();
is( ref($club_template), 'Koha::Club::Template', 'Club template created' );
# Add some template fields
my $club_template_field_1 = Koha::Club::Template::Field->new(
{
club_template_id => $club_template->id,
name => 'Test Club Template Field 1',
}
)->store();
is( ref($club_template_field_1),
'Koha::Club::Template::Field', 'Club template field 1 created' );
my $club_template_field_2 = Koha::Club::Template::Field->new(
{
club_template_id => $club_template->id,
name => 'Test Club Template Field 2',
}
)->store();
is( ref($club_template_field_2),
'Koha::Club::Template::Field', 'Club template field 2 created' );
is( $club_template->club_template_fields->count,
2, 'Club template has two fields' );
## Add some template enrollment fields
my $club_template_enrollment_field_1 =
Koha::Club::Template::EnrollmentField->new(
{
club_template_id => $club_template->id,
name => 'Test Club Template EnrollmentField 1',
}
)->store();
is(
ref($club_template_enrollment_field_1),
'Koha::Club::Template::EnrollmentField',
'Club template field 1 created'
);
my $club_template_enrollment_field_2 =
Koha::Club::Template::EnrollmentField->new(
{
club_template_id => $club_template->id,
name => 'Test Club Template EnrollmentField 2',
}
)->store();
is(
ref($club_template_enrollment_field_2),
'Koha::Club::Template::EnrollmentField',
'Club template field 2 created'
);
is( $club_template->club_template_enrollment_fields->count,
2, 'Club template has two enrollment fields' );
## Create a club based on this template
my $club = Koha::Club->new(
{
club_template_id => $club_template->id,
name => "Test Club",
branchcode => $branchcode,
}
)->store();
my $club_field_1 = Koha::Club::Field->new(
{
club_template_field_id => $club_template_field_1->id,
club_id => $club->id,
value => 'TEST',
}
)->store();
is( ref($club_field_1), 'Koha::Club::Field', 'Club field 1 created' );
is(
$club_field_1->club_template_field->id,
$club_template_field_1->id,
'Field 2 is linked to correct template field'
);
my $club_field_2 = Koha::Club::Field->new(
{
club_template_field_id => $club_template_field_2->id,
club_id => $club->id,
value => 'TEST',
}
)->store();
is( ref($club_field_2), 'Koha::Club::Field', 'Club field 2 created' );
is(
$club_field_2->club_template_field->id,
$club_template_field_2->id,
'Field 2 is linked to correct template field'
);
is( ref($club), 'Koha::Club', 'Club created' );
is( $club->club_template->id,
$club_template->id, 'Club is using correct template' );
is( $club->branch->id, $branchcode, 'Club is using correct branch' );
is( $club->club_fields->count, 2, 'Club has correct number of fields' );
is( Koha::Clubs->get_enrollable( { borrower => $patron } )->count,
1, 'Koha::Clubs->get_enrollable returns 1 enrollable club for patron' );
is( $patron->get_enrollable_clubs->count,
1, 'There is 1 enrollable club for patron' );
## Create an enrollment for this club
my $club_enrollment = Koha::Club::Enrollment->new(
{
club_id => $club->id,
borrowernumber => $patron->id,
branchcode => $branchcode,
}
)->store();
is( ref($club_enrollment), 'Koha::Club::Enrollment',
'Club enrollment created' );
my $club_enrollment_field_1 = Koha::Club::Enrollment::Field->new(
{
club_enrollment_id => $club_enrollment->id,
club_template_enrollment_field_id =>
$club_template_enrollment_field_1->id,
value => 'TEST',
}
)->store();
is(
ref($club_enrollment_field_1),
'Koha::Club::Enrollment::Field',
'Enrollment field 1 created'
);
my $club_enrollment_field_2 = Koha::Club::Enrollment::Field->new(
{
club_enrollment_id => $club_enrollment->id,
club_template_enrollment_field_id =>
$club_template_enrollment_field_2->id,
value => 'TEST',
}
)->store();
is(
ref($club_enrollment_field_2),
'Koha::Club::Enrollment::Field',
'Enrollment field 2 created'
);
is( $club_enrollment->club->id, $club->id, 'Got correct club for enrollment' );
is( Koha::Clubs->get_enrollable( { borrower => $patron } )->count,
0, 'Koha::Clubs->get_enrollable returns 0 enrollable clubs for patron' );
is( $patron->get_club_enrollments->count,
1, 'Got 1 club enrollment for patron' );
is( $patron->get_enrollable_clubs->count,
0, 'No more enrollable clubs for patron' );
$schema->storage->txn_rollback();
1;
Loading…
Cancel
Save