Bugzilla – Attachment 55326 Details for
Bug 5670
Housebound Readers Module
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 5670: Housebound Readers Module
Bug-5670-Housebound-Readers-Module.patch (text/plain), 60.73 KB, created by
Chris Cormack
on 2016-09-08 08:47:24 UTC
(
hide
)
Description:
Bug 5670: Housebound Readers Module
Filename:
MIME Type:
Creator:
Chris Cormack
Created:
2016-09-08 08:47:24 UTC
Size:
60.73 KB
patch
obsolete
>From 71dd122e02bc61ce0be3e14e4f87ace30b944e1a Mon Sep 17 00:00:00 2001 >From: "A. Sassmannshausen" <alex.sassmannshausen@ptfs-europe.com> >Date: Fri, 4 Apr 2014 09:55:07 +0000 >Subject: [PATCH] Bug 5670: Housebound Readers Module > >New module to handle management of circulation to Housebound readers. > >- Ability to create housebound profiles & scheduled visits for patrons. >- Ability to record users as Deliverers or Choosers (or both), using > extended patron attributes. >- Ability to link choosers and deliverers to individual delivery runs. >- 'Delivery Frequencies' are customizable through authorised > values ('HSBND_FREQ'). > >* koha-tmpl/intranet-tmpl/prog/en/includes/circ-menu.inc: add > Housebound menu if appropriate. >* Koha/Patron.pm (housebound_profile): New method. >* Koha/Patrons.pm (housebound_choosers, housebound_deliverers): New > methods. >* Koha/Patron/HouseboundProfile.pm: New File. >* Koha/Patron/HouseboundProfiles.pm: New File. >* Koha/Patron/HouseboundVisits.pm: New File. >* Koha/Patron/HouseboundVisit.pm: New File. >* koha-tmpl/intranet-tmpl/prog/en/modules/members/housebound.tt: New file. >* members/housebound.pl: New file. >* installer/data/mysql/kohastructure.sql: Add housebound_* tables. >* installer/data/mysql/sysprefs.sql: Add HouseboundModule syspref. >* koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref: > Add HouseboundModule syspref. >* installer/data/mysql/atomicupdate/housebound_tables.sql: New file. >* t/db_dependent/Patron/Borrower_Housebound.t: New file. >* t/db_dependent/Patron/Borrower_HouseboundProfiles.t: New file. >* t/db_dependent/Patron/Borrower_HouseboundVisits.t: New file. > >Test plan: >- Apply patch. >- Run atomic update script. >- Run Unit Tests (t/db_dependent/Patron/Housebound*) >- Optionally, add additional authorised values to 'HSBND_FREQ'. >- Switch on 'HouseboundModule' syspref. >- Ensure 'ExtendedPatronAttributes syspref is on. >- On patron pages, when editing, add some to the Housebound deliverer > and chooser groups by setting their extended attributes. >- On a patron page, the Housebound menu should now be present. > - create housebound profile > + ensure Frequency values seem pulled from 'HSBND_FREQ'. > - create 'housebound visits' (deliveries) > + ensure chooser/deliverer lists are populated with patrons that > have the Chooser or Deliverer Attribute type. > - edit visits. > - delete visits. >- Switch off 'HouseboundModule' > - the Housebound menu should disappear > >Signed-off-by: Chris Cormack <chrisc@catalyst.net.nz> >--- > Koha/Patron.pm | 13 + > Koha/Patron/HouseboundProfile.pm | 72 ++++ > Koha/Patron/HouseboundProfiles.pm | 61 +++ > Koha/Patron/HouseboundVisit.pm | 83 ++++ > Koha/Patron/HouseboundVisits.pm | 102 +++++ > Koha/Patrons.pm | 32 ++ > .../data/mysql/atomicupdate/housebound_tables.sql | 52 +++ > installer/data/mysql/en/mandatory/auth_values.sql | 4 + > .../data/mysql/en/mandatory/patron_attributes.sql | 4 + > .../data/mysql/en/mandatory/patron_attributes.txt | 2 + > installer/data/mysql/kohastructure.sql | 48 +++ > installer/data/mysql/sysprefs.sql | 1 + > .../intranet-tmpl/prog/en/includes/circ-menu.inc | 3 + > .../en/modules/admin/preferences/circulation.pref | 7 + > .../prog/en/modules/members/housebound.tt | 434 +++++++++++++++++++++ > members/housebound.pl | 150 +++++++ > t/db_dependent/Patron/Borrower_Housebound.t | 75 ++++ > .../Patron/Borrower_HouseboundProfiles.t | 75 ++++ > t/db_dependent/Patron/Borrower_HouseboundVisits.t | 92 +++++ > 19 files changed, 1310 insertions(+) > create mode 100644 Koha/Patron/HouseboundProfile.pm > create mode 100644 Koha/Patron/HouseboundProfiles.pm > create mode 100644 Koha/Patron/HouseboundVisit.pm > create mode 100644 Koha/Patron/HouseboundVisits.pm > create mode 100644 installer/data/mysql/atomicupdate/housebound_tables.sql > create mode 100644 installer/data/mysql/en/mandatory/patron_attributes.sql > create mode 100644 installer/data/mysql/en/mandatory/patron_attributes.txt > create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/members/housebound.tt > create mode 100755 members/housebound.pl > create mode 100755 t/db_dependent/Patron/Borrower_Housebound.t > create mode 100644 t/db_dependent/Patron/Borrower_HouseboundProfiles.t > create mode 100644 t/db_dependent/Patron/Borrower_HouseboundVisits.t > >diff --git a/Koha/Patron.pm b/Koha/Patron.pm >index 42b066b..ec61703 100644 >--- a/Koha/Patron.pm >+++ b/Koha/Patron.pm >@@ -29,6 +29,7 @@ use Koha::DateUtils; > use Koha::Issues; > use Koha::OldIssues; > use Koha::Patron::Categories; >+use Koha::Patron::HouseboundProfiles; > use Koha::Patron::Images; > use Koha::Patrons; > >@@ -76,6 +77,18 @@ sub guarantees { > return Koha::Patrons->search( { guarantorid => $self->borrowernumber } ); > } > >+=head3 housebound_profile >+ >+Returns the HouseboundProfile associated with this patron. >+ >+=cut >+ >+sub housebound_profile { >+ my ( $self ) = @_; >+ >+ return Koha::Patron::HouseboundProfiles->find($self->borrowernumber); >+} >+ > =head3 siblings > > Returns the siblings of this patron. >diff --git a/Koha/Patron/HouseboundProfile.pm b/Koha/Patron/HouseboundProfile.pm >new file mode 100644 >index 0000000..5ce87f8 >--- /dev/null >+++ b/Koha/Patron/HouseboundProfile.pm >@@ -0,0 +1,72 @@ >+package Koha::Patron::HouseboundProfile; >+ >+# 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 Koha::Database; >+use Koha::Patron::HouseboundVisits; >+ >+use base qw(Koha::Object); >+ >+=head1 NAME >+ >+Koha::Patron::HouseboundProfile - Koha Patron HouseboundProfile Object class >+ >+=head1 SYNOPSIS >+ >+HouseboundProfile class used primarily by members/housebound.pl. >+ >+=head1 DESCRIPTION >+ >+Standard Koha::Objects definitions, and additional methods. >+ >+=head1 API >+ >+=head2 Class Methods >+ >+=cut >+ >+=head3 housebound_visits >+ >+ my $visits = Koha::Patron::HouseboundProfile->housebound_visits; >+ >+Returns an arrayref of all visits associated this houseboundProfile. >+ >+=cut >+ >+sub housebound_visits { >+ my ( $self ) = @_; >+ my @visits = Koha::Patron::HouseboundVisits >+ ->special_search({ borrowernumber => $self->borrowernumber }); >+ return \@visits; >+} >+ >+=head3 _type >+ >+=cut >+ >+sub _type { >+ return 'HouseboundProfile'; >+} >+ >+1; >+ >+=head1 AUTHOR >+ >+Alex Sassmannshausen <alex.sassmannshausen@ptfs-europe.com> >+ >+=cut >diff --git a/Koha/Patron/HouseboundProfiles.pm b/Koha/Patron/HouseboundProfiles.pm >new file mode 100644 >index 0000000..65cc771 >--- /dev/null >+++ b/Koha/Patron/HouseboundProfiles.pm >@@ -0,0 +1,61 @@ >+package Koha::Patron::HouseboundProfiles; >+ >+# 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 Koha::Database; >+use Koha::Patron::HouseboundProfile; >+ >+use base qw(Koha::Objects); >+ >+=head1 NAME >+ >+Koha::Patron::HouseboundProfiles - Koha Patron HouseboundProfiles Object class >+ >+=head1 SYNOPSIS >+ >+HouseboundProfiles class used primarily by members/housebound.pl. >+ >+=head1 DESCRIPTION >+ >+Standard Koha::Objects definitions, and additional methods. >+ >+=head1 API >+ >+=head2 Class Methods >+ >+=cut >+ >+=head3 _type >+ >+=cut >+ >+sub _type { >+ return 'HouseboundProfile'; >+} >+ >+sub object_class { >+ return 'Koha::Patron::HouseboundProfile'; >+} >+ >+1; >+ >+=head1 AUTHOR >+ >+Alex Sassmannshausen <alex.sassmannshausen@ptfs-europe.com> >+ >+=cut >diff --git a/Koha/Patron/HouseboundVisit.pm b/Koha/Patron/HouseboundVisit.pm >new file mode 100644 >index 0000000..a7dc0c6 >--- /dev/null >+++ b/Koha/Patron/HouseboundVisit.pm >@@ -0,0 +1,83 @@ >+package Koha::Patron::HouseboundVisit; >+ >+# 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 Koha::Database; >+ >+use base qw(Koha::Object); >+ >+=head1 NAME >+ >+Koha::Patron::HouseboundVisit - Koha Patron HouseboundVisit Object class >+ >+=head1 SYNOPSIS >+ >+HouseboundVisit class used primarily by members/housebound.pl. >+ >+=head1 DESCRIPTION >+ >+Standard Koha::Objects definitions, and additional methods. >+ >+=head1 API >+ >+=head2 Class Methods >+ >+=cut >+ >+=head3 chooser >+ >+ my $chooser = Koha::Patron::HouseboundVisit->chooser; >+ >+Returns the prefetched chooser for this visit. >+ >+=cut >+ >+sub chooser { >+ my ( $self ) = @_; >+ return $self->_result->chooser_brwnumber; >+} >+ >+=head3 deliverer >+ >+ my $deliverer = Koha::Patron::HouseboundVisit->deliverer; >+ >+Returns the prefetched deliverer for this visit. >+ >+=cut >+ >+sub deliverer { >+ my ( $self ) = @_; >+ return $self->_result->deliverer_brwnumber; >+ >+} >+ >+=head3 _type >+ >+=cut >+ >+sub _type { >+ return 'HouseboundVisit'; >+} >+ >+1; >+ >+=head1 AUTHOR >+ >+Alex Sassmannshausen <alex.sassmannshausen@ptfs-europe.com> >+ >+=cut >diff --git a/Koha/Patron/HouseboundVisits.pm b/Koha/Patron/HouseboundVisits.pm >new file mode 100644 >index 0000000..5a31f60 >--- /dev/null >+++ b/Koha/Patron/HouseboundVisits.pm >@@ -0,0 +1,102 @@ >+package Koha::Patron::HouseboundVisits; >+ >+# 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 Koha::Database; >+use Koha::Patron::HouseboundVisit; >+ >+use base qw(Koha::Objects); >+ >+=head1 NAME >+ >+Koha::Patron::HouseboundVisits - Koha Patron HouseboundVisits Object class >+ >+=head1 SYNOPSIS >+ >+HouseboundVisits class used primarily by members/housebound.pl. >+ >+=head1 DESCRIPTION >+ >+Standard Koha::Objects definitions, and additional methods. >+ >+=head1 API >+ >+=head2 Class Methods >+ >+=cut >+ >+=head3 special_search; >+ >+ my @houseboundVisits = Koha::HouseboundVisits->special_search($params, $attributes); >+ >+Perform a search for housebound visits. This method overrides standard search >+to prefetch deliverers and choosers as we always need them anyway. >+ >+If $attributes contains a prefetch entry, we defer to it, otherwise we add the >+prefetch attribute and also augment $params with explicit 'me.' prefixes. >+ >+This is intended to make search behave as most people would expect it to >+behave. >+ >+Should the user want to do complicated searches involving joins, without >+specifying their own prefetch, the naive 'me.' augmentation will break in >+hilarious ways. In this case the user should supply their own prefetch >+clause. >+ >+=cut >+ >+sub special_search { >+ my ( $self, $params, $attributes ) = @_; >+ unless (exists $attributes->{prefetch}) { >+ # No explicit prefetch has been passed in -> automatic optimisation. >+ $attributes->{prefetch} = [ >+ 'chooser_brwnumber', 'deliverer_brwnumber' >+ ]; >+ # So we must ensure our $params use the 'me.' prefix. >+ my $oldparams = $params; >+ $params = {}; >+ while (my ($k, $v) = each %{$oldparams}) { >+ if ($k =~ /^me\..*/) { >+ $params->{$k} = $v; >+ } else { >+ $params->{"me." . $k} = $v; >+ } >+ } >+ } >+ $self->SUPER::search($params, $attributes); >+} >+ >+=head3 _type >+ >+=cut >+ >+sub _type { >+ return 'HouseboundVisit'; >+} >+ >+sub object_class { >+ return 'Koha::Patron::HouseboundVisit'; >+} >+ >+1; >+ >+=head1 AUTHOR >+ >+Alex Sassmannshausen <alex.sassmannshausen@ptfs-europe.com> >+ >+=cut >diff --git a/Koha/Patrons.pm b/Koha/Patrons.pm >index e001b84..384a25c 100644 >--- a/Koha/Patrons.pm >+++ b/Koha/Patrons.pm >@@ -37,6 +37,38 @@ Koha::Patron - Koha Patron Object class > > =cut > >+=head3 housebound_choosers >+ >+Returns all Patrons which are Housebound choosers. >+ >+=cut >+ >+sub housebound_choosers { >+ my ( $self ) = @_; >+ my $cho = $self->_resultset->search >+ ->search_related('borrower_attributes', { >+ code => 'HSBND', >+ attribute => 'CHO', >+ })->search_related('borrowernumber'); >+ return Koha::Patrons->_new_from_dbic($cho); >+} >+ >+=head3 housebound_deliverers >+ >+Returns all Patrons which are Housebound deliverers. >+ >+=cut >+ >+sub housebound_deliverers { >+ my ( $self ) = @_; >+ my $del = $self->_resultset->search >+ ->search_related('borrower_attributes', { >+ code => 'HSBND', >+ attribute => 'DEL', >+ })->search_related('borrowernumber'); >+ return Koha::Patrons->_new_from_dbic($del); >+} >+ > =head3 type > > =cut >diff --git a/installer/data/mysql/atomicupdate/housebound_tables.sql b/installer/data/mysql/atomicupdate/housebound_tables.sql >new file mode 100644 >index 0000000..3219ade >--- /dev/null >+++ b/installer/data/mysql/atomicupdate/housebound_tables.sql >@@ -0,0 +1,52 @@ >+CREATE TABLE IF NOT EXISTS `housebound_profile` ( >+ `borrowernumber` int(11) NOT NULL, -- Number of the borrower associated with this profile. >+ `day` text NOT NULL, -- The preferred day of the week for delivery. >+ `frequency` text NOT NULL, -- The Authorised_Value definining the pattern for delivery. >+ `fav_itemtypes` text default NULL, -- Free text describing preferred itemtypes. >+ `fav_subjects` text default NULL, -- Free text describing preferred subjects. >+ `fav_authors` text default NULL, -- Free text describing preferred authors. >+ `referral` text default NULL, -- Free text indicating how the borrower was added to the service. >+ `notes` text default NULL, -- Free text for additional notes. >+ PRIMARY KEY (`borrowernumber`), >+ CONSTRAINT `housebound_profile_bnfk` >+ FOREIGN KEY (`borrowernumber`) >+ REFERENCES `borrowers` (`borrowernumber`) >+ ON UPDATE CASCADE ON DELETE CASCADE >+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; >+ >+CREATE TABLE IF NOT EXISTS `housebound_visit` ( >+ `id` int(11) NOT NULL auto_increment, -- ID of the visit. >+ `borrowernumber` int(11) NOT NULL, -- Number of the borrower, & the profile, linked to this visit. >+ `appointment_date` date default NULL, -- Date of visit. >+ `day_segment` varchar(10), -- Rough time frame: 'morning', 'afternoon' 'evening' >+ `chooser_brwnumber` int(11) default NULL, -- Number of the borrower to choose items for delivery. >+ `deliverer_brwnumber` int(11) default NULL, -- Number of the borrower to deliver items. >+ PRIMARY KEY (`id`), >+ CONSTRAINT `houseboundvisit_bnfk` >+ FOREIGN KEY (`borrowernumber`) >+ REFERENCES `housebound_profile` (`borrowernumber`) >+ ON UPDATE CASCADE ON DELETE CASCADE, >+ CONSTRAINT `houseboundvisit_bnfk_1` >+ FOREIGN KEY (`chooser_brwnumber`) >+ REFERENCES `borrowers` (`borrowernumber`) >+ ON UPDATE CASCADE ON DELETE CASCADE, >+ CONSTRAINT `houseboundvisit_bnfk_2` >+ FOREIGN KEY (`deliverer_brwnumber`) >+ REFERENCES `borrowers` (`borrowernumber`) >+ ON UPDATE CASCADE ON DELETE CASCADE >+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; >+ >+INSERT IGNORE INTO systempreferences >+ (variable,value,options,explanation,type) VALUES >+ ('HouseboundModule',0,'', >+ 'If ON, enable housebound module functionality.','YesNo'); >+ >+INSERT IGNORE INTO authorised_values (category, authorised_value, lib) VALUES >+ ('HSBND_FREQ','EW','Every week'), >+ ('HSBND_ROLE','CHO','Chooser'), >+ ('HSBND_ROLE','DEL','Deliverer'); >+ >+INSERT IGNORE INTO borrower_attribute_types >+ (code, description, repeatable, opac_display, staff_searchable, >+ authorised_value_category, display_checkout) values >+ ('HSBND', 'Housebound role', 1, 1, 1, 'HSBND_ROLE', 1); >diff --git a/installer/data/mysql/en/mandatory/auth_values.sql b/installer/data/mysql/en/mandatory/auth_values.sql >index d7fb280..511b096 100644 >--- a/installer/data/mysql/en/mandatory/auth_values.sql >+++ b/installer/data/mysql/en/mandatory/auth_values.sql >@@ -1,2 +1,6 @@ > INSERT INTO authorised_values (category,authorised_value,lib,lib_opac) VALUES ('YES_NO','0','No','No'); > INSERT INTO authorised_values (category,authorised_value,lib,lib_opac) VALUES ('YES_NO','1','Yes','Yes'); >+INSERT INTO authorised_values (category, authorised_value, lib) VALUES >+ ('HSBND_FREQ','EW','Every week'), >+ ('HSBND_ROLE','CHO','Chooser'), >+ ('HSBND_ROLE','DEL','Deliverer'); >diff --git a/installer/data/mysql/en/mandatory/patron_attributes.sql b/installer/data/mysql/en/mandatory/patron_attributes.sql >new file mode 100644 >index 0000000..89845ad >--- /dev/null >+++ b/installer/data/mysql/en/mandatory/patron_attributes.sql >@@ -0,0 +1,4 @@ >+INSERT INTO borrower_attribute_types >+ (code, description, repeatable, opac_display, staff_searchable, >+ authorised_value_category, display_checkout) values >+ ('HSBND', 'Housebound role', 1, 1, 1, 'HSBND_ROLE', 1); >diff --git a/installer/data/mysql/en/mandatory/patron_attributes.txt b/installer/data/mysql/en/mandatory/patron_attributes.txt >new file mode 100644 >index 0000000..c2d0d4f >--- /dev/null >+++ b/installer/data/mysql/en/mandatory/patron_attributes.txt >@@ -0,0 +1,2 @@ >+Default Koha system extended patron attributes: >+* HSBND - Allow assignment of different housebound roles for volunteers >diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql >index 10bee02..04ec4be 100644 >--- a/installer/data/mysql/kohastructure.sql >+++ b/installer/data/mysql/kohastructure.sql >@@ -3793,6 +3793,54 @@ CREATE TABLE `hold_fill_targets` ( > REFERENCES `branches` (`branchcode`) ON DELETE CASCADE ON UPDATE CASCADE > ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; > >+-- >+-- Table structure for table `housebound_profile` >+-- >+ >+DROP TABLE IF EXISTS `housebound_profile`; >+CREATE TABLE `housebound_profile` ( >+ `borrowernumber` int(11) NOT NULL, -- Number of the borrower associated with this profile. >+ `day` text NOT NULL, -- The preferred day of the week for delivery. >+ `frequency` text NOT NULL, -- The Authorised_Value definining the pattern for delivery. >+ `fav_itemtypes` text default NULL, -- Free text describing preferred itemtypes. >+ `fav_subjects` text default NULL, -- Free text describing preferred subjects. >+ `fav_authors` text default NULL, -- Free text describing preferred authors. >+ `referral` text default NULL, -- Free text indicating how the borrower was added to the service. >+ `notes` text default NULL, -- Free text for additional notes. >+ PRIMARY KEY (`borrowernumber`), >+ CONSTRAINT `housebound_profile_bnfk` >+ FOREIGN KEY (`borrowernumber`) >+ REFERENCES `borrowers` (`borrowernumber`) >+ ON UPDATE CASCADE ON DELETE CASCADE >+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; >+ >+-- >+-- Table structure for table `housebound_visit` >+-- >+ >+DROP TABLE IF EXISTS `housebound_visit`; >+CREATE TABLE `housebound_visit` ( >+ `id` int(11) NOT NULL auto_increment, -- ID of the visit. >+ `borrowernumber` int(11) NOT NULL, -- Number of the borrower, & the profile, linked to this visit. >+ `appointment_date` date default NULL, -- Date of visit. >+ `day_segment` varchar(10), -- Rough time frame: 'morning', 'afternoon' 'evening' >+ `chooser_brwnumber` int(11) default NULL, -- Number of the borrower to choose items for delivery. >+ `deliverer_brwnumber` int(11) default NULL, -- Number of the borrower to deliver items. >+ PRIMARY KEY (`id`), >+ CONSTRAINT `houseboundvisit_bnfk` >+ FOREIGN KEY (`borrowernumber`) >+ REFERENCES `housebound_profile` (`borrowernumber`) >+ ON UPDATE CASCADE ON DELETE CASCADE, >+ CONSTRAINT `houseboundvisit_bnfk_1` >+ FOREIGN KEY (`chooser_brwnumber`) >+ REFERENCES `borrowers` (`borrowernumber`) >+ ON UPDATE CASCADE ON DELETE CASCADE, >+ CONSTRAINT `houseboundvisit_bnfk_2` >+ FOREIGN KEY (`deliverer_brwnumber`) >+ REFERENCES `borrowers` (`borrowernumber`) >+ ON UPDATE CASCADE ON DELETE CASCADE >+) 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 */; >diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql >index ac6f852..5ab7c3b 100644 >--- a/installer/data/mysql/sysprefs.sql >+++ b/installer/data/mysql/sysprefs.sql >@@ -172,6 +172,7 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` > ('HoldsQueueSkipClosed', '0', NULL, 'If enabled, any libraries that are closed when the holds queue is built will be ignored for the purpose of filling holds.', 'YesNo'), > ('HoldsToPullStartDate','2',NULL,'Set the default start date for the Holds to pull list to this many days ago','Integer'), > ('HomeOrHoldingBranch','holdingbranch','holdingbranch|homebranch','Used by Circulation to determine which branch of an item to check with independent branches on, and by search to determine which branch to choose for availability ','Choice'), >+('HouseboundModule',0,'','If ON, enable housebound module functionality.','YesNo'), > ('HTML5MediaEnabled','not','not|opac|staff|both','Show a tab with a HTML5 media player for files catalogued in field 856','Choice'), > ('HTML5MediaExtensions','webm|ogg|ogv|oga|vtt','','Media file extensions','free'), > ('HTML5MediaYouTube',0,'Embed|Don\'t embed','YouTube links as videos','YesNo'), >diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/circ-menu.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/circ-menu.inc >index a423844..951b5df 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/includes/circ-menu.inc >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/circ-menu.inc >@@ -105,5 +105,8 @@ > [% IF CAN_user_borrowers && useDischarge %] > [% IF dischargeview %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/discharge.pl?borrowernumber=[% borrowernumber %]">Discharges</a></li> > [% END %] >+ [% IF Koha.Preference('HouseboundModule') %] >+ [% IF houseboundview %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/housebound.pl?borrowernumber=[% borrowernumber %]">Housebound</a></li> >+ [% END %] > </ul></div> > [% END %] >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref >index a3ce0b3..5de44f6 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref >@@ -763,3 +763,10 @@ Circulation: > - "Patron categories allowed to checkout in a batch" > - pref: BatchCheckoutsValidCategories > - "(list of patron categories separated with a pipe '|')" >+ Housebound module: >+ - >+ - pref: HouseboundModule >+ choices: >+ yes: Enable >+ no: Disable >+ - "housebound module" >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/members/housebound.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/members/housebound.tt >new file mode 100644 >index 0000000..d48af41 >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/members/housebound.tt >@@ -0,0 +1,434 @@ >+[% USE Koha %] >+[% USE KohaDates %] >+[% USE AuthorisedValues %] >+[% borrowernumber = patron.borrowernumber %] >+[% branchname = branch.branchname %] >+[% categoryname = category.description %] >+[% categorycode = category.categorycode %] >+[% category_type = category.category_type %] >+[% firstname = patron.firstname %] >+[% surname = patron.surname %] >+[% othernames = patron.othernames %] >+[% invert_name = 0 %] >+[% INCLUDE 'doc-head-open.inc' %] >+<title>Koha › Housebound › Details for [% INCLUDE 'patron-title.inc' %]</title> >+[% INCLUDE 'doc-head-close.inc' %] >+[% INCLUDE 'calendar.inc' %] >+<script type="text/javascript"> >+//<![CDATA[ >+$(document).ready(function() { >+ $("#date").datepicker({ minDate: 0, dateFormat: "yy-mm-dd" }); >+}); >+//]]> >+</script> >+ >+</head> >+<body> >+[% INCLUDE 'header.inc' %] >+[% INCLUDE 'patron-search.inc' %] >+ >+<div id="breadcrumbs"> >+ <a href="/cgi-bin/koha/mainpage.pl">Home</a> >+› <a href="/cgi-bin/koha/members/members-home.pl">Patrons</a> >+› Details for [% INCLUDE 'patron-title.inc' %] >+</div> >+ >+<div id="doc3" class="yui-t2"> >+ <div id="bd"> >+ <div id="yui-main"> >+ <div class="yui-b"> >+ >+ [% UNLESS ( unknowuser ) %] >+ [% INCLUDE 'members-toolbar.inc' %] >+ [% END %] >+ >+ <div class="yui-g"> >+ >+ <!-- Title --> >+ <h3>Housebound details for [% patron.title %] [% patron.firstname %] [% patron.surname %] ([% patron.cardnumber %])</h3> >+ <div class="yui-u first"> >+ >+ <!-- Create or edit housebound_profile --> >+ [% IF ( method == 'update_or_create' ) %] >+ <h4>Manage housebound profile</h4> >+ <form id="editform" method="post" name="editform" >+ action="/cgi-bin/koha/members/housebound.pl"> >+ <input type="hidden" name="borrowernumber" value="[% borrowernumber %]" /> >+ [% IF ( housebound_profile ) %] >+ <input type="hidden" name="method" value="updateconfirm" /> >+ [% ELSE %] >+ <input type="hidden" name="method" value="createconfirm" /> >+ [% END %] >+ <fieldset id="houseboundentry" class="rows"> >+ <legend>Housebound details</legend> >+ <ol> >+ <li> >+ <label for="day">Delivery day:</label> >+ <select id="day" name="day" required="required"> >+ <option value="">Select a day</option> >+ [% IF ( housebound_profile ) %] >+ [% IF ( housebound_profile.day == 'any' ) %] >+ <option value="any" selected='selected'>Any</option> >+ [% ELSE %] >+ <option value="any">Any</option> >+ [% END %] >+ [% IF ( housebound_profile.day == 'monday' ) %] >+ <option value="monday" selected='selected'>Monday</option> >+ [% ELSE %] >+ <option value="monday">Monday</option> >+ [% END %] >+ [% IF ( housebound_profile.day == 'tuesday' ) %] >+ <option value="tuesday" selected='selected'>Tuesday</option> >+ [% ELSE %] >+ <option value="tuesday">Tuesday</option> >+ [% END %] >+ [% IF ( housebound_profile.day == 'wednesday' ) %] >+ <option value="wednesday" selected='selected'>Wednesday</option> >+ [% ELSE %] >+ <option value="wednesday">Wednesday</option> >+ [% END %] >+ [% IF ( housebound_profile.day == 'thursday' ) %] >+ <option value="thursday" selected='selected'>Thursday</option> >+ [% ELSE %] >+ <option value="thursday">Thursday</option> >+ [% END %] >+ [% IF ( housebound_profile.day == 'friday' ) %] >+ <option value="friday" selected='selected'>Friday</option> >+ [% ELSE %] >+ <option value="friday">Friday</option> >+ [% END %] >+ [% IF ( housebound_profile.day == 'saturday' ) %] >+ <option value="saturday" selected='selected'>Saturday</option> >+ [% ELSE %] >+ <option value="saturday">Saturday</option> >+ [% END %] >+ [% IF ( housebound_profile.day == 'sunday' ) %] >+ <option value="sunday" selected='selected'>Sunday</option> >+ [% ELSE %] >+ <option value="sunday">Sunday</option> >+ [% END %] >+ [% ELSE %] >+ <option value="any">Any</option> >+ <option value="monday">Monday</option> >+ <option value="tuesday">Tuesday</option> >+ <option value="wednesday">Wednesday</option> >+ <option value="thursday">Thursday</option> >+ <option value="friday">Friday</option> >+ <option value="saturday">Saturday</option> >+ <option value="sunday">Sunday</option> >+ [% END %] >+ </select> >+ </li> >+ <li> >+ <label for="frequency">Frequency:</label> >+ <select id="frequency" name="frequency" required="required"> >+ <option value="">Select a frequency</option> >+ [% FOREACH frequency IN AuthorisedValues.GetAuthValueDropbox('HSBND_FREQ') %] >+ [% IF housebound_profile.frequency == frequency.value %] >+ <option value="[% frequency.value %]" selected="selected">[% frequency.label %]</option> >+ [% ELSE %] >+ <option value="[% frequency.value %]">[% frequency.label %]</option> >+ [% END %] >+ [% END %] >+ </select> >+ </li> >+ <li> >+ <label for="fav_itemtypes">Preferred materials:</label> >+ [% IF ( housebound_profile ) %] >+ <input id="fav_itemtypes" type="text" size="50" name="fav_itemtypes" >+ value="[% housebound_profile.fav_itemtypes %]"> >+ [% ELSE %] >+ <input id="fav_itemtypes" type="text" value="" size="50" name="fav_itemtypes"> >+ [% END %] >+ </li> >+ <li> >+ <label for="fav_subjects">Subjects:</label> >+ [% IF ( housebound_profile ) %] >+ <input id="fav_subjects" type="text" size="50" name="fav_subjects" >+ value="[% housebound_profile.fav_subjects %]"> >+ [% ELSE %] >+ <input id="fav_subjects" type="text" value="" size="50" name="fav_subjects"> >+ [% END %] >+ </li> >+ <li> >+ <label for="fav_authors">Authors:</label> >+ [% IF ( housebound_profile ) %] >+ <input id="fav_authors" type="text" size="50" name="fav_authors" >+ value="[% housebound_profile.fav_authors %]"> >+ [% ELSE %] >+ <input id="fav_authors" type="text" value="" size="50" name="fav_authors"> >+ [% END %] >+ </li> >+ <li> >+ <label for="referral">Referral:</label> >+ [% IF ( housebound_profile ) %] >+ <input id="referral" type="text" size="50" name="referral" >+ value="[% housebound_profile.referral %]"> >+ [% ELSE %] >+ <input id="referral" type="text" value="" size="50" name="referral"> >+ [% END %] >+ </li> >+ <li> >+ <label for="notes">Notes:</label> >+ [% IF ( housebound_profile ) %] >+ <input id="notes" type="text" size="50" name="notes" >+ value="[% housebound_profile.notes %]"> >+ [% ELSE %] >+ <input id="notes" type="text" value="" size="50" name="notes"> >+ [% END %] >+ </li> >+ </ol> >+ </fieldset> >+ <fieldset class="action"> >+ <input type="submit" value="Save changes" name="save" >+ onclick="console.log('Must validate form');" /> >+ <a class="cancel" >+ href="/cgi-bin/koha/members/housebound.pl?borrowernumber=[% borrowernumber %]"> >+ Cancel >+ </a> >+ </fieldset> >+ </form> >+ >+ <!-- Create or edit housebound_visit --> >+ [% ELSIF ( method == 'visit_update_or_create' ) %] >+ <h4>Manage housebound deliveries</h4> >+ <form name="form" id="instance_form" method="post" >+ action="/cgi-bin/koha/members/housebound.pl"> >+ [% IF ( visit ) %] >+ <input type="hidden" name="method" value="editvisitconfirm" /> >+ <input type="hidden" name="visit_id" value="[% visit.id %]" /> >+ [% ELSE %] >+ <input type="hidden" name="method" value="addvisitconfirm" /> >+ [% END %] >+ <input type="hidden" name="borrowernumber" value="[% borrowernumber %]" /> >+ <fieldset class="rows" id="instance"> >+ <legend>Delivery details</legend> >+ <ol> >+ <li> >+ <label for="date">Date: </label> >+ [% IF ( visit ) %] >+ <input type="text" id="date" name="date" size="20" >+ value="[% visit.appointment_date %]" >+ required="required"/> >+ [% ELSE %] >+ <input type="text" id="date" name="date" size="20" >+ value="" required="required"/> >+ [% END %] >+ </li> >+ <li> >+ <label for="segment">Time:</label> >+ <select id="segment" name="segment" required="required"> >+ <option value="">Select a time</option> >+ [% IF ( visit ) %] >+ [% IF ( visit.day_segment == 'morning' ) %] >+ <option value="morning" selected="selected"> >+ Morning >+ </option> >+ [% ELSE %] >+ <option value="morning">Morning</option> >+ [% END %] >+ [% IF ( visit.day_segment == 'afternoon' ) %] >+ <option value="afternoon" selected="selected"> >+ Afternoon >+ </option> >+ [% ELSE %] >+ <option value="afternoon">Afternoon</option> >+ [% END %] >+ [% IF ( visit.day_segment == 'evening' ) %] >+ <option value="evening" selected="selected"> >+ Evening >+ </option> >+ [% ELSE %] >+ <option value="evening">Evening</option> >+ [% END %] >+ [% ELSE %] >+ <option value="morning">Morning</option> >+ <option value="afternoon">Afternoon</option> >+ <option value="evening">Evening</option> >+ [% END %] >+ </select> >+ </li> >+ <li> >+ <label for="chooser">Chooser:</label> >+ <select id="chooser" name="chooser" required="required"> >+ <option value="">Select a chooser</option> >+ [% IF ( visit ) %] >+ [% FOREACH chooser IN choosers %] >+ [% IF ( visit.chooser_brwnumber == chooser.borrowernumber ) %] >+ <option value="[% chooser.borrowernumber %]" selected="selected"> >+ [% INCLUDE 'patron-title.inc' borrowernumber = chooser.borrowernumber category_type = chooser.category_type firstname = chooser.firstname surname = chooser.surname othernames = chooser.othernames cardnumber = chooser.cardnumber invert_name = 0 %] >+ </option> >+ [% ELSE %] >+ <option value="[% chooser.borrowernumber %]"> >+ [% INCLUDE 'patron-title.inc' borrowernumber = chooser.borrowernumber category_type = chooser.category_type firstname = chooser.firstname surname = chooser.surname othernames = chooser.othernames cardnumber = chooser.cardnumber invert_name = 0 %] >+ </option> >+ [% END %] >+ [% END %] >+ [% ELSE %] >+ [% FOREACH chooser IN choosers %] >+ <option value="[% chooser.borrowernumber %]"> >+ [% INCLUDE 'patron-title.inc' borrowernumber = chooser.borrowernumber category_type = chooser.category_type firstname = chooser.firstname surname = chooser.surname othernames = chooser.othernames cardnumber = chooser.cardnumber invert_name = 0 %] >+ </option> >+ [% END %] >+ [% END %] >+ </select> >+ </li> >+ <li> >+ <label for="deliverer">Deliverer:</label> >+ <select id="deliverer" name="deliverer" required="required"> >+ <option value="">Select a deliverer</option> >+ [% IF ( visit ) %] >+ [% FOREACH deliverer IN deliverers %] >+ [% IF ( visit.deliverer_brwnumber == deliverer.borrowernumber ) %] >+ <option value="[% deliverer.borrowernumber %]" selected="selected"> >+ [% INCLUDE 'patron-title.inc' borrowernumber = deliverer.borrowernumber category_type = deliverer.category_type firstname = deliverer.firstname surname = deliverer.surname othernames = deliverer.othernames cardnumber = deliverer.cardnumber invert_name = 0 %] >+ </option> >+ [% ELSE %] >+ <option value="[% deliverer.borrowernumber %]"> >+ [% INCLUDE 'patron-title.inc' borrowernumber = deliverer.borrowernumber category_type = deliverer.category_type firstname = deliverer.firstname surname = deliverer.surname othernames = deliverer.othernames cardnumber = deliverer.cardnumber invert_name = 0 %] >+ </option> >+ [% END %] >+ [% END %] >+ [% ELSE %] >+ [% FOREACH deliverer IN deliverers %] >+ <option value="[% deliverer.borrowernumber %]"> >+ [% INCLUDE 'patron-title.inc' borrowernumber = deliverer.borrowernumber category_type = deliverer.category_type firstname = deliverer.firstname surname = deliverer.surname othernames = deliverer.othernames cardnumber = deliverer.cardnumber invert_name = 0 %] >+ </option> >+ [% END %] >+ [% END %] >+ </select> >+ </li> >+ </ol> >+ </fieldset> >+ <fieldset class="action"> >+ <input type="submit" value="Save" name="save" >+ onclick="console.log('Must validate form');" /> >+ <a class="cancel" >+ href="/cgi-bin/koha/members/housebound.pl?borrowernumber=[% borrowernumber %]"> >+ Cancel >+ </a> >+ </fieldset> >+ </form> >+ >+ <!-- Display a housebound_profile --> >+ [% ELSIF ( housebound_profile ) %] >+ <div> >+ <ul class="toolbar"> >+ <li> >+ <span class="yui-button yui-link-button first-child"> >+ <a href="/cgi-bin/koha/members/housebound.pl?borrowernumber=[% borrowernumber %]&method=update_or_create"> >+ Edit >+ </a> >+ </span> >+ </li> >+ </ul> >+ </div> >+ <div class="rows"> >+ <ol> >+ <li> >+ <span class="label">Delivery day:</span> >+ [% hpd = housebound_profile.day %] >+ [% IF hpd == 'any' %] >+ Any >+ [% ELSIF hpd == 'monday' %] >+ Monday >+ [% ELSIF hpd == 'tuesday' %] >+ Tuesday >+ [% ELSIF hpd == 'wednesday' %] >+ Wednesday >+ [% ELSIF hpd == 'thursday' %] >+ Thursday >+ [% ELSIF hpd == 'friday' %] >+ Friday >+ [% ELSIF hpd == 'saturday' %] >+ Saturday >+ [% ELSIF hpd == 'sunday' %] >+ Sunday >+ [% END %] >+ </li> >+ <li> >+ <span class="label">Frequency:</span> >+ [% AuthorisedValues.GetByCode( 'HSBND_FREQ', housebound_profile.frequency, 0 ) || housebound_profile.frequency %] >+ </li> >+ <li> >+ <span class="label">Material:</span> >+ [% housebound_profile.fav_itemtypes %] >+ </li> >+ <li> >+ <span class="label">Subjects:</span> >+ [% housebound_profile.fav_subjects %] >+ </li> >+ <li> >+ <span class="label">Authors:</span> >+ [% housebound_profile.fav_authors %] >+ </li> >+ <li> >+ <span class="label">Referral:</span> >+ [% housebound_profile.referral %] >+ </li> >+ <li> >+ <span class="label">Notes:</span> >+ [% housebound_profile.notes %] >+ </li> >+ </ol> >+ </div> >+ <div> >+ <h4>Deliveries</h4> >+ <div> >+ <ul class="toolbar"> >+ <li> >+ <span class="yui-button yui-link-button first-child"> >+ <a href="/cgi-bin/koha/members/housebound.pl?method=visit_update_or_create&borrowernumber=[% borrowernumber %]"> >+ Add a new delivery >+ </a> >+ </span> >+ </li> >+ </ul> >+ </div> >+ [% housebound_visits = housebound_profile.housebound_visits %] >+ [% IF housebound_visits.size > 0 %] >+ <table border="0" width="100%" cellpadding="3" cellspacing="0"> >+ <tr> >+ <th>ID</th><th>Date</th><th>Chooser</th><th>Deliverer</th><th>Actions</th> >+ </tr> >+ [% FOREACH entry IN housebound_visits %] >+ <tr> >+ <td>[% entry.id %]</td> >+ <td>[% entry.appointment_date %] ([% entry.day_segment %])</td> >+ <td> >+ <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% entry.chooser.borrowernumber %]"> >+ [% INCLUDE 'patron-title.inc' borrowernumber = entry.chooser.borrowernumber category_type = entry.chooser.category_type firstname = entry.chooser.firstname surname = entry.chooser.surname othernames = entry.chooser.othernames cardnumber = entry.chooser.cardnumber invert_name = 0 %] >+ </a> >+ </td> >+ <td> >+ <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% entry.deliverer.borrowernumber %]"> >+ [% INCLUDE 'patron-title.inc' borrowernumber = entry.deliverer.borrowernumber category_type = entry.deliverer.category_type firstname = entry.deliverer.firstname surname = entry.deliverer.surname othernames = entry.deliverer.othernames cardnumber = entry.deliverer.cardnumber invert_name = 0 %] >+ </a> >+ </td> >+ <td align="center"> >+ <a href="/cgi-bin/koha/members/housebound.pl?method=visit_update_or_create&visit_id=[% entry.id %]&borrowernumber=[% borrowernumber %]"> >+ Edit >+ </a> >+ | >+ <a href="/cgi-bin/koha/members/housebound.pl?method=visit_delete&visit_id=[% entry.id %]&borrowernumber=[% borrowernumber %]"> >+ Delete >+ </a> >+ </td> >+ </tr> >+ [% END %] >+ </table> >+ [% END %] >+ </div> >+ >+ [% END %] >+ >+ </div> <!-- End yui-u first --> >+ </div> <!-- End yui-g --> >+ </div> >+ </div >+ </div> >+ <div class="yui-b"> >+ [% INCLUDE 'circ-menu.inc' %] >+ </div> >+</div> >+[% INCLUDE 'intranet-bottom.inc' %] >diff --git a/members/housebound.pl b/members/housebound.pl >new file mode 100755 >index 0000000..f5ced86 >--- /dev/null >+++ b/members/housebound.pl >@@ -0,0 +1,150 @@ >+#!/usr/bin/perl >+ >+# Copyright 2016 PTFS-Europe Ltd >+# >+# 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. >+ >+=head1 housebound.pl >+ >+ Script to handle housebound management for patrons. This single script >+ handles display, creation, deletion and management of profiles and visits. >+ >+=cut >+ >+use Modern::Perl; >+use CGI; >+use C4::Auth; >+use C4::Output; >+use Koha::Libraries; >+use Koha::Patrons; >+use Koha::Patron::Categories; >+use Koha::Patron::HouseboundProfile; >+use Koha::Patron::HouseboundVisit; >+use Koha::Patron::HouseboundVisits; >+ >+my $input = CGI->new; >+ >+my ( $template, $loggedinuser, $cookie ) = get_template_and_user( >+ { >+ template_name => 'members/housebound.tt', >+ query => $input, >+ type => 'intranet', >+ authnotrequired => 0, >+ flagsrequired => { borrowers => 1 }, >+ } >+); >+ >+my $patron = Koha::Patrons->new->find($input->param('borrowernumber')); >+my $method = $input->param('method') // q{}; >+my $visit_id = $input->param('visit_id') // q{}; >+my $branch = Koha::Libraries->new->find($patron->branchcode); >+my $category = Koha::Patron::Categories->new->find($patron->categorycode); >+my $houseboundprofile = $patron->housebound_profile; >+ >+my ( $houseboundvisits, $deliverers, $choosers ); >+my ( $houseboundvisit, $deliverer, $chooser ); >+ >+if ( $method eq 'updateconfirm' ) { >+ # We have received the input from the profile edit form. We must save the >+ # changes, and return to simple display. >+ $houseboundprofile->set({ >+ day => $input->param('day') // q{}, >+ frequency => $input->param('frequency') // q{}, >+ fav_itemtypes => $input->param('fav_itemtypes') // q{}, >+ fav_subjects => $input->param('fav_subjects') // q{}, >+ fav_authors => $input->param('fav_authors') // q{}, >+ referral => $input->param('referral') // q{}, >+ notes => $input->param('notes') // q{}, >+ }); >+ die("Unable to store edited profile") >+ unless ( $houseboundprofile->store ); >+ $method = undef; >+} elsif ( $method eq 'createconfirm' ) { >+ # We have received the input necessary to create a new profile. We must >+ # save it, and return to simple display. >+ $houseboundprofile = Koha::Patron::HouseboundProfile->new({ >+ borrowernumber => $patron->borrowernumber, >+ day => $input->param('day') // q{}, >+ frequency => $input->param('frequency') // q{}, >+ fav_itemtypes => $input->param('fav_itemtypes') // q{}, >+ fav_subjects => $input->param('fav_subjects') // q{}, >+ fav_authors => $input->param('fav_authors') // q{}, >+ referral => $input->param('referral') // q{}, >+ notes => $input->param('notes') // q{}, >+ }); >+ die("Unable to store new profile") >+ unless ( $houseboundprofile->store ); >+ $method = undef; >+} elsif ( $method eq 'visit_update_or_create' ) { >+ # We want to edit, edit a visit, so we must pass its details. >+ $deliverers = Koha::Patrons->new->housebound_deliverers; >+ $choosers = Koha::Patrons->new->housebound_choosers; >+ $houseboundvisit = Koha::Patron::HouseboundVisits->find($visit_id) >+ if ( $visit_id ); >+} elsif ( $method eq 'visit_delete' ) { >+ # We want ot delete a specific visit. >+ my $visit = Koha::Patron::HouseboundVisits->find($visit_id); >+ die("Unable to delete visit") unless ( $visit->delete ); >+ $method = undef; >+} elsif ( $method eq 'editvisitconfirm' ) { >+ # We have received input for editing a visit. We must store and return to >+ # simple display. >+ my $visit = Koha::Patron::HouseboundVisits->find($visit_id); >+ $visit->set({ >+ borrowernumber => $input->param('borrowernumber') // q{}, >+ appointment_date => $input->param('date') // q{}, >+ day_segment => $input->param('segment') // q{}, >+ chooser_brwnumber => $input->param('chooser') // q{}, >+ deliverer_brwnumber => $input->param('deliverer') // q{}, >+ }); >+ die("Unable to store edited visit") unless ( $visit->store ); >+ $method = undef; >+} elsif ( $method eq 'addvisitconfirm' ) { >+ # We have received input for creating a visit. We must store and return >+ # to simple display. >+ my $visit = Koha::Patron::HouseboundVisit->new({ >+ borrowernumber => $input->param('borrowernumber') // q{}, >+ appointment_date => $input->param('date') // q{}, >+ day_segment => $input->param('segment') // q{}, >+ chooser_brwnumber => $input->param('chooser') // q{}, >+ deliverer_brwnumber => $input->param('deliverer') // q{}, >+ }); >+ die("Unable to store new visit") unless ( $visit->store ); >+ $method = undef; >+} >+ >+# We don't have any profile information, so we must display a creation form. >+$method = 'update_or_create' if ( !$houseboundprofile ); >+ >+$template->param( >+ patron => $patron, >+ housebound_profile => $houseboundprofile, >+ visit => $houseboundvisit, >+ branch => $branch, >+ category => $category, >+ method => $method, >+ choosers => $choosers, >+ deliverers => $deliverers, >+ houseboundview => 'on', >+); >+ >+output_html_with_http_headers $input, $cookie, $template->output; >+ >+=head1 AUTHOR >+ >+Alex Sassmannshausen <alex.sassmannshausen@ptfs-europe.com> >+ >+=cut >diff --git a/t/db_dependent/Patron/Borrower_Housebound.t b/t/db_dependent/Patron/Borrower_Housebound.t >new file mode 100755 >index 0000000..320dd61 >--- /dev/null >+++ b/t/db_dependent/Patron/Borrower_Housebound.t >@@ -0,0 +1,75 @@ >+#!/usr/bin/perl >+use Modern::Perl; >+ >+use C4::Members; >+use C4::Circulation; >+use Koha::Database; >+use Koha::Patrons; >+ >+use Test::More tests => 6; >+ >+use_ok('Koha::Patron'); >+ >+use t::lib::TestBuilder; >+use t::lib::Mocks; >+ >+my $schema = Koha::Database->new->schema; >+$schema->storage->txn_begin; >+ >+my $builder = t::lib::TestBuilder->new; >+ >+my $patron = $builder->build({ source => 'Borrower' }); >+my $profile = $builder->build({ >+ source => 'HouseboundProfile', >+ value => { >+ borrowernumber => $patron->{borrowernumber}, >+ }, >+}); >+ >+# Test housebound_profile >+is( >+ Koha::Patrons->find($patron->{borrowernumber}) >+ ->housebound_profile->frequency, >+ $profile->{frequency}, >+ "Fetch housebound_profile." >+); >+ >+# patron_choosers and patron_deliverers Tests >+ >+# Current Patron Chooser / Deliverer count >+my $orig_del_count = Koha::Patrons->housebound_deliverers->count; >+my $orig_cho_count = Koha::Patrons->housebound_choosers->count; >+ >+# We add one, just in case the above is 0, so we're guaranteed one of each. >+my $patron_chooser = $builder->build({ source => 'Borrower' }); >+$builder->build({ >+ source => 'BorrowerAttribute', >+ value => { >+ borrowernumber => $patron_chooser->{borrowernumber}, >+ code => 'HSBND', >+ attribute => 'CHO', >+ password => undef, >+ }, >+}); >+ >+my $patron_deliverer = $builder->build({ source => 'Borrower' }); >+$builder->build({ >+ source => 'BorrowerAttribute', >+ value => { >+ borrowernumber => $patron_deliverer->{borrowernumber}, >+ code => 'HSBND', >+ attribute => 'DEL', >+ password => undef, >+ }, >+}); >+ >+# Test housebound_choosers >+is(Koha::Patrons->housebound_choosers->count, $orig_cho_count + 1, "Correct count of choosers."); >+is(Koha::Patrons->housebound_deliverers->count, $orig_del_count + 1, "Correct count of deliverers"); >+ >+isa_ok(Koha::Patrons->housebound_choosers->next, "Koha::Patron"); >+isa_ok(Koha::Patrons->housebound_deliverers->next, "Koha::Patron"); >+ >+$schema->storage->txn_rollback; >+ >+1; >diff --git a/t/db_dependent/Patron/Borrower_HouseboundProfiles.t b/t/db_dependent/Patron/Borrower_HouseboundProfiles.t >new file mode 100644 >index 0000000..05d6392 >--- /dev/null >+++ b/t/db_dependent/Patron/Borrower_HouseboundProfiles.t >@@ -0,0 +1,75 @@ >+#!/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 => 3; >+ >+use Koha::Database; >+use Koha::Patron::HouseboundProfiles; >+ >+use t::lib::TestBuilder; >+ >+my $schema = Koha::Database->new->schema; >+$schema->storage->txn_begin; >+ >+my $builder = t::lib::TestBuilder->new; >+ >+# Profile Tests >+ >+my $profile = $builder->build({ source => 'HouseboundProfile' }); >+ >+is( >+ Koha::Patron::HouseboundProfiles >+ ->find($profile->{borrowernumber})->borrowernumber, >+ $profile->{borrowernumber}, >+ "Find created profile." >+); >+ >+my @profiles = Koha::Patron::HouseboundProfiles >+ ->search({ day => $profile->{day} }); >+my $found_profile = shift @profiles; >+is( >+ $found_profile->borrowernumber, >+ $profile->{borrowernumber}, >+ "Search for created profile." >+); >+ >+# ->housebound_profile Tests >+ >+my $visit1 = $builder->build({ >+ source => 'HouseboundVisit', >+ value => { >+ borrowernumber => $profile->{borrowernumber}, >+ }, >+}); >+my $visit2 = $builder->build({ >+ source => 'HouseboundVisit', >+ value => { >+ borrowernumber => $profile->{borrowernumber}, >+ }, >+}); >+ >+is( >+ scalar @{$found_profile->housebound_visits}, >+ 2, >+ "Fetch housebound_visits." >+); >+ >+$schema->storage->txn_rollback; >+ >+1; >diff --git a/t/db_dependent/Patron/Borrower_HouseboundVisits.t b/t/db_dependent/Patron/Borrower_HouseboundVisits.t >new file mode 100644 >index 0000000..bec556c >--- /dev/null >+++ b/t/db_dependent/Patron/Borrower_HouseboundVisits.t >@@ -0,0 +1,92 @@ >+#!/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 => 8; >+ >+use Koha::Database; >+use Koha::Patron::HouseboundVisits; >+use Koha::Patron::HouseboundVisit; >+ >+use t::lib::TestBuilder; >+ >+my $schema = Koha::Database->new->schema; >+$schema->storage->txn_begin; >+ >+my $builder = t::lib::TestBuilder->new; >+ >+########### Test HouseboundVisits >+ >+my $visit = $builder->build({ source => 'HouseboundVisit' }); >+ >+is( >+ Koha::Patron::HouseboundVisits >+ ->find($visit->{id})->id, >+ $visit->{id}, >+ "Find created visit." >+); >+ >+# Using our Prefetching search >+ >+# Does it work implicitly? >+my @visits = Koha::Patron::HouseboundVisits >+ ->special_search({ borrowernumber => $visit->{borrowernumber} }); >+my $found_visit = shift @visits; >+is( >+ $found_visit->borrowernumber, >+ $visit->{borrowernumber}, >+ "Search for created visit." >+); >+ >+# Does it work Explicitly? >+@visits = Koha::Patron::HouseboundVisits >+ ->special_search({ 'me.borrowernumber' => $visit->{borrowernumber} }); >+$found_visit = shift @visits; >+is( >+ $found_visit->borrowernumber, >+ $visit->{borrowernumber}, >+ "Search for created visit." >+); >+ >+# Does it work without prefetcing? >+@visits = Koha::Patron::HouseboundVisits >+ ->special_search({ borrowernumber => $visit->{borrowernumber} }, { prefetch => [] }); >+$found_visit = shift @visits; >+is( >+ $found_visit->borrowernumber, >+ $visit->{borrowernumber}, >+ "Search for created visit." >+); >+ >+########### Test HouseboundVisit >+ >+my $result = Koha::Patron::HouseboundVisits->find($visit->{id}); >+ >+is( $result->deliverer->borrowernumber, $visit->{deliverer_brwnumber} ); >+ >+is( $result->chooser->borrowernumber, $visit->{chooser_brwnumber} ); >+ >+TODO: { >+ local $TODO = "We want our results here to be Koha::Patron objects, but they by default return DBIC Schema objects. The currently accepted solution to this (use the _from_dbic method), is defined for Koha::Objects, but not for Koha::Object. We do not resolve this issue here"; >+ isa_ok( $result->deliverer, "Koha::Patron"); >+ isa_ok( $result->chooser, "Koha::Patron"); >+} >+ >+$schema->storage->txn_rollback; >+ >+1; >-- >2.9.3
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 5670
:
3038
|
22162
|
22163
|
22164
|
22165
|
26816
|
27288
|
50930
|
51377
|
51875
|
54384
|
54385
|
55326
|
55334
|
55335
|
55336
|
55734
|
55735
|
55736
|
55737
|
55738
|
55739
|
55865
|
55866
|
55867
|
55890
|
55891
|
56298
|
56299
|
56300
|
56301
|
56302
|
56308
|
56337
|
56341
|
56346
|
56347
|
56348
|
56349
|
56350
|
56351
|
56352
|
56353
|
56354
|
56355
|
56356
|
56357
|
56358
|
56359
|
56360
|
56361
|
56362
|
56363
|
56364
|
56365
|
56366
|
56367
|
56368
|
56369
|
56580
|
56581
|
56582
|
56583
|
56584
|
56585
|
56586
|
56587
|
56588
|
56589
|
56590
|
56591
|
56592
|
56593
|
56594
|
56595
|
56596
|
56597
|
56598
|
56599
|
56600
|
56601
|
56602
|
56603
|
56604
|
56605
|
56606