Bugzilla – Attachment 51378 Details for
Bug 6906
Show 'Borrower has previously issued $ITEM' alert on checkout
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Rebase on Master
0001-Bug-6906-show-Borrower-has-previously-issued.patch (text/plain), 36.44 KB, created by
Alex Sassmannshausen
on 2016-05-10 12:07:46 UTC
(
hide
)
Description:
Rebase on Master
Filename:
MIME Type:
Creator:
Alex Sassmannshausen
Created:
2016-05-10 12:07:46 UTC
Size:
36.44 KB
patch
obsolete
>From 1890929e5bf466208e99a2ccdbfaa4b348a28134 Mon Sep 17 00:00:00 2001 >From: Alex Sassmannshausen <alex.sassmannshausen@ptfs-europe.com> >Date: Fri, 11 Mar 2016 15:00:01 +0100 >Subject: [PATCH] Bug 6906 - show 'Borrower has previously issued... > >New feature: provide granular means to configure warnings about items >that have been issued to a particular borrower before, according to >their checkout history. > >- Global syspref ('CheckPrevCheckout'), set to 'hardno' by default, > allows users to enable this feature library wide. >- Per patron category pref allows libraries to create overrides per > category, falling back on the global setting by default. >- Per patron pref allows switching the functionality on at the level > of patron. Fall-back to category settings by default. > >* Koha/Patron (wantsCheckPrevCheckout, doCheckPrevCheckout): New > methods. >* C4/Circulation.pm (CanBookBeIssued): Introduce CheckPrevCheckout > check. >* admin/categories.pl: Pass along checkprevcheckout. >* koha-tmpl/intranet-tmpl/prog/en/modules/admin/categories.tt: Expose > CheckPrevCheckout per category setting. >* koha-tmpl/intranet-tmpl/prog/en/modules/preferences/patrons.pref: > Expose CheckPrevCheckout syspref. >* koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt: > Expose per patron CheckPrevCheckout preference. >* koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt: Expose > per patron CheckPrevCheckout preference. >* koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt: Add > 'CHECKPREVCHECKOUT' confirmation message. >* installer/data/mysql/kohastructure.sql: Modify structure of > 'categories', 'borrowers', 'oldborrowers'. >* installer/data/mysql/sysprefs.sql: Add 'CheckPrevCheckout'. >* installer/data/mysql/atomicupdate/checkPrevCheckout.sql: New file. >* t/db_dependent/Patron/CheckPrevCheckout.t: New file with unit tests. > >Test plan: >- Apply patch. >- Run updatedatabase. >- Regenerate Koha Schema files. >- Run the unit tests. >- Verify 'CheckPrevCheckout' is visible in Patrons sysprefs and can be > switched to 'hardyes', 'softyes', 'softno' and 'hardno'. > + Check out previously checked out items to a patron, checking the > message appears as expected. >- Verify no 'Check previous checkouts' setting appears on the borrower > category pages if the syspref is set to a 'hard' option. >- Verify 'Check previous checkouts' setting appears on the borrower > category pages and can be modified per borrower category. > + Issue previously issued items to a borrower, checking the message > appears as expected (This setting should override the default > setting if that is set to a 'soft' option). >- Verify no 'Check previous checkouts' setting appears on the individual > borrower pages if the syspref is set to a 'hard' option. >- Verify 'Check previous checkouts' setting appears on individual > borrower pages and can be modified. > + Issue previously issued items to a borrower, checking the message > appears as expected (This setting should override the category > setting and the default setting if the latter is set to a 'soft' > option). >--- > C4/Circulation.pm | 8 + > Koha/Patron.pm | 76 +++- > admin/categories.pl | 3 + > .../data/mysql/atomicupdate/checkPrevCheckout.sql | 15 + > installer/data/mysql/kohastructure.sql | 3 + > installer/data/mysql/sysprefs.sql | 1 + > .../prog/en/modules/admin/categories.tt | 53 +++ > .../prog/en/modules/admin/preferences/patrons.pref | 9 + > .../prog/en/modules/circ/circulation.tt | 4 + > .../prog/en/modules/members/memberentrygen.tt | 21 +- > .../prog/en/modules/members/moremember.tt | 11 + > t/db_dependent/Patron/CheckPrevCheckout.t | 447 +++++++++++++++++++++ > 12 files changed, 649 insertions(+), 2 deletions(-) > create mode 100644 installer/data/mysql/atomicupdate/checkPrevCheckout.sql > create mode 100644 t/db_dependent/Patron/CheckPrevCheckout.t > >diff --git a/C4/Circulation.pm b/C4/Circulation.pm >index 8d585a2..6e4c473 100644 >--- a/C4/Circulation.pm >+++ b/C4/Circulation.pm >@@ -941,6 +941,14 @@ sub CanBookBeIssued { > } > > # >+ # CHECKPREVCHECKOUT: CHECK IF ITEM HAS EVER BEEN LENT TO PATRON >+ # >+ my $patron = Koha::Patrons->find($borrower->{borrowernumber}); >+ my $wantsCheckPrevCheckout = $patron->wantsCheckPrevCheckout; >+ $needsconfirmation{PREVISSUE} = 1 >+ if ($wantsCheckPrevCheckout and $patron->doCheckPrevCheckout($item)); >+ >+ # > # ITEM CHECKING > # > if ( $item->{'notforloan'} ) >diff --git a/Koha/Patron.pm b/Koha/Patron.pm >index ac62594..aa38363 100644 >--- a/Koha/Patron.pm >+++ b/Koha/Patron.pm >@@ -1,6 +1,7 @@ > package Koha::Patron; > > # Copyright ByWater Solutions 2014 >+# Copyright PTFS Europe 2016 > # > # This file is part of Koha. > # >@@ -21,9 +22,13 @@ use Modern::Perl; > > use Carp; > >+use C4::Context; > use Koha::Database; >-use Koha::Patrons; >+use Koha::Issues; >+use Koha::OldIssues; >+use Koha::Patron::Categories; > use Koha::Patron::Images; >+use Koha::Patrons; > > use base qw(Koha::Object); > >@@ -95,6 +100,74 @@ sub siblings { > ); > } > >+=head3 wantsCheckPrevCheckout >+ >+ $wantsCheckPrevCheckout = $patron->wantsCheckPrevCheckout; >+ >+Return 1 if Koha needs to perform PrevIssue checking, else 0. >+ >+=cut >+ >+sub wantsCheckPrevCheckout { >+ my ( $self ) = @_; >+ my $syspref = C4::Context->preference("checkPrevCheckout"); >+ >+ # Simple cases >+ ## Hard syspref trumps all >+ return 1 if ($syspref eq 'hardyes'); >+ return 0 if ($syspref eq 'hardno'); >+ ## Now, patron pref trumps all >+ return 1 if ($self->checkprevcheckout eq 'yes'); >+ return 0 if ($self->checkprevcheckout eq 'no'); >+ >+ # More complex: patron inherits -> determine category preference >+ my $checkPrevCheckoutByCat = Koha::Patron::Categories >+ ->find($self->categorycode)->checkprevcheckout; >+ return 1 if ($checkPrevCheckoutByCat eq 'yes'); >+ return 0 if ($checkPrevCheckoutByCat eq 'no'); >+ >+ # Finally: category preference is inherit, default to 0 >+ if ($syspref eq 'softyes') { >+ return 1; >+ } else { >+ return 0; >+ } >+} >+ >+=head3 doCheckPrevCheckout >+ >+ $checkPrevCheckout = $patron->doCheckPrevCheckout($item); >+ >+Return 1 if the bib associated with $ITEM has previously been checked out to >+$PATRON, 0 otherwise. >+ >+=cut >+ >+sub doCheckPrevCheckout { >+ my ( $self, $item ) = @_; >+ >+ # Find all items for bib and extract item numbers. >+ my @items = Koha::Items->search({biblionumber => $item->{biblionumber}}); >+ my @item_nos; >+ foreach my $item (@items) { >+ push @item_nos, $item->itemnumber; >+ } >+ >+ # Create (old)issues search criteria >+ my $criteria = { >+ borrowernumber => $self->borrowernumber, >+ itemnumber => \@item_nos, >+ }; >+ >+ # Check current issues table >+ my $issues = Koha::Issues->search($criteria); >+ return 1 if $issues->count; # 0 || N >+ >+ # Check old issues table >+ my $old_issues = Koha::OldIssues->search($criteria); >+ return $old_issues->count; # 0 || N >+} >+ > =head3 type > > =cut >@@ -106,6 +179,7 @@ sub _type { > =head1 AUTHOR > > Kyle M Hall <kyle@bywatersolutions.com> >+Alex Sassmannshausen <alex.sassmannshausen@ptfs-europe.com> > > =cut > >diff --git a/admin/categories.pl b/admin/categories.pl >index 7d4e8d3..dfcbcb4 100755 >--- a/admin/categories.pl >+++ b/admin/categories.pl >@@ -90,6 +90,7 @@ elsif ( $op eq 'add_validate' ) { > my $overduenoticerequired = $input->param('overduenoticerequired'); > my $category_type = $input->param('category_type'); > my $BlockExpiredPatronOpacActions = $input->param('BlockExpiredPatronOpacActions'); >+ my $checkPrevCheckout = $input->param('checkprevcheckout'); > my $default_privacy = $input->param('default_privacy'); > my @branches = grep { $_ ne q{} } $input->multi_param('branches'); > >@@ -113,6 +114,7 @@ elsif ( $op eq 'add_validate' ) { > $category->overduenoticerequired($overduenoticerequired); > $category->category_type($category_type); > $category->BlockExpiredPatronOpacActions($BlockExpiredPatronOpacActions); >+ $category->checkprevcheckout($checkPrevCheckout); > $category->default_privacy($default_privacy); > eval { > $category->store; >@@ -138,6 +140,7 @@ elsif ( $op eq 'add_validate' ) { > overduenoticerequired => $overduenoticerequired, > category_type => $category_type, > BlockExpiredPatronOpacActions => $BlockExpiredPatronOpacActions, >+ checkprevcheckout => $checkPrevCheckout, > default_privacy => $default_privacy, > }); > eval { >diff --git a/installer/data/mysql/atomicupdate/checkPrevCheckout.sql b/installer/data/mysql/atomicupdate/checkPrevCheckout.sql >new file mode 100644 >index 0000000..a426c16 >--- /dev/null >+++ b/installer/data/mysql/atomicupdate/checkPrevCheckout.sql >@@ -0,0 +1,15 @@ >+INSERT INTO systempreferences (variable,value,options,explanation,type) >+VALUES('CheckPrevCheckout','hardno','hardyes|softyes|softno|hardno','By default, for every item checked out, should we warn if the patron has checked out that item in the past?','Choice'); >+ >+ALTER TABLE categories >+ADD COLUMN `checkprevcheckout` varchar(7) NOT NULL default 'inherit' >+AFTER `default_privacy`; >+ >+ALTER TABLE borrowers >+ADD COLUMN `checkprevcheckout` varchar(7) NOT NULL default 'inherit' >+AFTER `privacy_guarantor_checkouts`; >+ >+ALTER TABLE deletedborrowers >+ADD COLUMN `checkprevcheckout` varchar(7) NOT NULL default 'inherit' >+AFTER `privacy_guarantor_checkouts`; >+ >diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql >index 1d3b3d6..788c2d6 100644 >--- a/installer/data/mysql/kohastructure.sql >+++ b/installer/data/mysql/kohastructure.sql >@@ -266,6 +266,7 @@ CREATE TABLE `borrowers` ( -- this table includes information about your patrons > `sms_provider_id` int(11) DEFAULT NULL, -- the provider of the mobile phone number defined in smsalertnumber > `privacy` integer(11) DEFAULT '1' NOT NULL, -- patron/borrower's privacy settings related to their reading history > `privacy_guarantor_checkouts` tinyint(1) NOT NULL DEFAULT '0', -- controls if relatives can see this patron's checkouts >+ `checkprevcheckout` varchar(7) NOT NULL default 'inherit', -- produce a warning for this patron if this item has previously been checked out to this patron if 'yes', not if 'no', defer to category setting if 'inherit'. > UNIQUE KEY `cardnumber` (`cardnumber`), > PRIMARY KEY `borrowernumber` (`borrowernumber`), > KEY `categorycode` (`categorycode`), >@@ -504,6 +505,7 @@ CREATE TABLE `categories` ( -- this table shows information related to Koha patr > `category_type` varchar(1) NOT NULL default 'A', -- type of Koha patron (Adult, Child, Professional, Organizational, Statistical, Staff) > `BlockExpiredPatronOpacActions` tinyint(1) NOT NULL default '-1', -- wheither or not a patron of this category can renew books or place holds once their card has expired. 0 means they can, 1 means they cannot, -1 means use syspref BlockExpiredPatronOpacActions > `default_privacy` ENUM( 'default', 'never', 'forever' ) NOT NULL DEFAULT 'default', -- Default privacy setting for this patron category >+ `checkprevcheckout` varchar(7) NOT NULL default 'inherit', -- produce a warning for this patron category if this item has previously been checked out to this patron if 'yes', not if 'no', defer to syspref setting if 'inherit'. > PRIMARY KEY (`categorycode`), > UNIQUE KEY `categorycode` (`categorycode`) > ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; >@@ -920,6 +922,7 @@ CREATE TABLE `deletedborrowers` ( -- stores data related to the patrons/borrower > `sms_provider_id` int(11) DEFAULT NULL, -- the provider of the mobile phone number defined in smsalertnumber > `privacy` integer(11) DEFAULT '1' NOT NULL, -- patron/borrower's privacy settings related to their reading history KEY `borrowernumber` (`borrowernumber`), > `privacy_guarantor_checkouts` tinyint(1) NOT NULL DEFAULT '0', -- controls if relatives can see this patron's checkouts >+ `checkprevcheckout` varchar(7) NOT NULL default 'inherit', -- produce a warning for this patron if this item has previously been checked out to this patron if 'yes', not if 'no', defer to category setting if 'inherit'. > KEY borrowernumber (borrowernumber), > KEY `cardnumber` (`cardnumber`), > KEY `sms_provider_id` (`sms_provider_id`) >diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql >index d95754d..c21c6d3 100644 >--- a/installer/data/mysql/sysprefs.sql >+++ b/installer/data/mysql/sysprefs.sql >@@ -91,6 +91,7 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` > ('CatalogModuleRelink','0',NULL,'If OFF the linker will never replace the authids that are set in the cataloging module.','YesNo'), > ('CataloguingLog','1',NULL,'If ON, log edit/create/delete actions on bibliographic data. WARNING: this feature is very resource consuming.','YesNo'), > ('checkdigit','none','none|katipo','If ON, enable checks on patron cardnumber: none or \"Katipo\" style checks','Choice'), >+('CheckPrevCheckout','hardno','hardyes|softyes|softno|hardno','By default, for every item checked out, should we warn if the patron has borrowed that item in the past?','Choice'), > ('CircAutocompl','1',NULL,'If ON, autocompletion is enabled for the Circulation input','YesNo'), > ('CircAutoPrintQuickSlip','qslip',NULL,'Choose what should happen when an empty barcode field is submitted in circulation: Display a print quick slip window, Display a print slip window or Clear the screen.','Choice'), > ('CircControl','ItemHomeLibrary','PickupLibrary|PatronLibrary|ItemHomeLibrary','Specify the agency that controls the circulation and fines policy','Choice'), >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/categories.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/categories.tt >index aa2d3a2..af6cecd 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/categories.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/categories.tt >@@ -189,6 +189,28 @@ > Choose whether patrons of this category be blocked from public catalog actions such as renewing and placing holds when their cards have expired. > </span> > </li> >+ [% IF ( Koha.Preference('CheckPrevCheckout') == 'softyes' || Koha.Preference('CheckPrevCheckout') == 'softno' ) %] >+ <li><label for="checkprevcheckout">Check for previous checkouts: </label> >+ <select name="checkprevcheckout" id="checkprevcheckout"> >+ [% IF category.checkprevcheckout == 'yes' %] >+ <option value="yes" selected="selected">Yes and try to override system preferences</option> >+ <option value="no">No and try to override system preferences</option> >+ <option value="inherit">Inherit from system preferences</option> >+ [% ELSIF category.checkprevcheckout == 'no' %] >+ <option value="yes">Yes and try to override system preferences</option> >+ <option value="no" selected="selected">No and try to override system preferences</option> >+ <option value="inherit">Inherit from system preferences</option> >+ [% ELSE %] >+ <option value="yes">Yes and try to override system preferences</option> >+ <option value="no">No and try to override system preferences</option> >+ <option value="inherit" selected="selected">Inherit from system preferences</option> >+ [% END %] >+ </select> >+ <span> >+ Choose whether patrons of this category by default are reminded if they try to borrow an item they borrowed before. >+ </span> >+ </li> >+ [% END %] > <li> > <label for="default_privacy">Default privacy: </label> > <select id="default_privacy" name="default_privacy"> >@@ -261,6 +283,22 @@ > <tr><th scope="row">Receives overdue notices: </th><td>[% IF category. overduenoticerequired %]Yes[% ELSE %]No[% END %]</td></tr> > <tr><th scope="row">Lost items in staff client</th><td>[% IF category.hidelostitems %]Hidden by default[% ELSE %]Shown[% END %]</td></tr> > <tr><th scope="row">Hold fee: </th><td>[% category.reservefee | $Price %]</td></tr> >+ >+ [% IF ( Koha.Preference('CheckPrevCheckout') == 'softyes' || Koha.Preference('CheckPrevCheckout') == 'softno' ) %] >+ <tr> >+ <th scope="row">Check previous checkouts: </th> >+ <td> >+ [% SWITCH category.checkprevcheckout %] >+ [% CASE 'yes' %] >+ Yes >+ [% CASE 'no' %] >+ No >+ [% CASE 'inherit' %] >+ Inherit >+ [% END %] >+ </td> >+ </tr> >+ [% END %] > <tr> > <th scope="row">Default privacy: </th> > <td> >@@ -317,6 +355,9 @@ > <th scope="col">Messaging</th> > [% END %] > <th scope="col">Branches limitations</th> >+ [% IF ( Koha.Preference('CheckPrevCheckout') == 'softyes' || Koha.Preference('CheckPrevCheckout') == 'softno' ) %] >+ <th scope="col">Check previous checkout?</th> >+ [% END %] > <th scope="col">Default privacy</th> > <th scope="col"> </th> > <th scope="col"> </th> >@@ -394,6 +435,18 @@ > No limitation > [% END %] > </td> >+ [% IF ( Koha.Preference('CheckPrevCheckout') == 'softyes' || Koha.Preference('CheckPrevCheckout') == 'softno' ) %] >+ <td> >+ [% SWITCH category.checkprevcheckout %] >+ [% CASE 'yes' %] >+ Yes >+ [% CASE 'no' %] >+ No >+ [% CASE 'inherit' %] >+ Inherit >+ [% END %] >+ </td> >+ [% END %] > <td> > [% SWITCH category.default_privacy %] > [% CASE 'default' %] >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref >index f7b5706..40900ec 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref >@@ -44,6 +44,15 @@ Patrons: > class: multi > - (separate multiple choices with |) > - >+ - pref: CheckPrevCheckout >+ default: no >+ choices: >+ hardyes: "Do" >+ softyes: "Unless overridden, do" >+ softno: "Unless overridden, do not" >+ hardno: "Do not" >+ - " check borrower checkout history to see if the current item has been checked out before." >+ - > - pref: checkdigit > choices: > none: "Don't" >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt >index cd3fc35..638504c 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt >@@ -321,6 +321,10 @@ $(document).ready(function() { > <li>High demand item. Loan period shortened to [% HIGHHOLDS.duration %] days (due [% HIGHHOLDS.returndate %]). Check out anyway?</li> > [% END %] > >+[% IF PREVISSUE %] >+ <li>This item has previously been checked out to this patron. Check out anyway?</li> >+[% END %] >+ > [% IF BIBLIO_ALREADY_ISSUED %] > <li> > Patron has already checked out another item from this record. >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt >index aa1de3e..a5fa3f7 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt >@@ -604,7 +604,26 @@ $(document).ready(function() { > [% END %] > </li> > [% END %] >- </ol> >+ [% IF ( Koha.Preference('CheckPrevCheckout') == 'softyes' || Koha.Preference('CheckPrevCheckout') == 'softno' ) %] >+ <li><label for="checkprevcheckout">Check for previous checkouts: </label> >+ <select name="checkprevcheckout" id="checkprevcheckout"> >+ [% IF ( checkprevcheckout == 'yes' ) %] >+ <option value="yes" selected="selected">Yes if settings allow it</option> >+ <option value="no">No if settings allow it</option> >+ <option value="inherit">Inherit from settings</option> >+ [% ELSIF ( checkprevcheckout == 'no' ) %] >+ <option value="yes">Yes if settings allow it</option> >+ <option value="no" selected="selected">No if settings allow it</option> >+ <option value="inherit">Inherit from settings</option> >+ [% ELSE %] >+ <option value="yes">Yes if settings allow it</option> >+ <option value="no">No if settings allow it</option> >+ <option value="inherit" selected="selected">Inherit from settings</option> >+ [% END %] >+ </select> >+ </li> >+ [% END %] >+ </ol> > </fieldset> > [% UNLESS nodateenrolled && noopacnote && noborrowernotes %] > <fieldset class="rows" id="memberentry_subscription"> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt >index b775673..92231ca 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt >@@ -404,6 +404,17 @@ function validate1(date) { > <li><span class="label">Activate sync: </span>No</li> > [% END %] > [% END %] >+ [% IF ( Koha.Preference('CheckPrevCheckout') == 'softyes' || Koha.Preference('CheckPrevCheckout') == 'softno' ) %] >+ <li><span class="label">Check previous checkouts: </span> >+ [% IF ( checkprevcheckout == 'yes' ) %] >+ Yes >+ [% ELSIF ( checkprevcheckout == 'no' ) %] >+ No >+ [% ELSE %] >+ Inherited >+ [% END %] >+ </li> >+ [% END %] > </ol> > </div> > </div> >diff --git a/t/db_dependent/Patron/CheckPrevCheckout.t b/t/db_dependent/Patron/CheckPrevCheckout.t >new file mode 100644 >index 0000000..d76b96d0 >--- /dev/null >+++ b/t/db_dependent/Patron/CheckPrevCheckout.t >@@ -0,0 +1,447 @@ >+#!/usr/bin/perl >+use Modern::Perl; >+ >+use C4::Members; >+use C4::Circulation; >+use Koha::Database; >+use Koha::Patrons; >+use Koha::Patron; >+ >+use Test::More tests => 59; >+ >+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 $yesCatCode = $builder->build({ >+ source => 'Category', >+ value => { >+ categorycode => 'yesCat', >+ checkprevcheckout => 'yes', >+ }, >+}); >+ >+my $noCatCode = $builder->build({ >+ source => 'Category', >+ value => { >+ categorycode => 'noCat', >+ checkprevcheckout => 'no', >+ }, >+}); >+ >+my $inheritCatCode = $builder->build({ >+ source => 'Category', >+ value => { >+ categorycode => 'inheritCat', >+ checkprevcheckout => 'inherit', >+ }, >+}); >+ >+# Create context for some tests late on in the file. >+my $staff = $builder->build({source => 'Borrower'}); >+my @USERENV = ( >+ $staff->{borrowernumber}, 'test', 'MASTERTEST', 'firstname', 'CPL', >+ 'CPL', 'email@example.org' >+); >+C4::Context->_new_userenv('DUMMY_SESSION_ID'); >+C4::Context->set_userenv(@USERENV); >+BAIL_OUT("No userenv") unless C4::Context->userenv; >+ >+ >+# wantsCheckPrevCheckout >+ >+# We expect the following result matrix: >+# >+# (1/0 indicates the return value of WantsCheckPrevCheckout; i.e. 1 says we >+# should check whether the item was previously issued) >+# >+# | System Preference | hardyes | softyes | softno | hardno | >+# |-------------------+-----------------------------------+-----------------------------------+-----------------------------------+-----------------------------------| >+# | Category Setting | yes | no | inherit | yes | no | inherit | yes | no | inherit | yes | no | inherit | >+# |-------------------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------| >+# | Patron Setting | y | n | i | y | n | i | y | n | i | y | n | i | y | n | i | y | n | i | y | n | i | y | n | i | y | n | i | y | n | i | y | n | i | y | n | i | >+# |-------------------+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ >+# | Expected Result | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | >+ >+my $mappings = [ >+ { >+ syspref => 'hardyes', >+ categories => [ >+ { >+ setting => 'yes', >+ patrons => [ >+ {setting => 'yes', result => 1}, >+ {setting => 'no', result => 1}, >+ {setting => 'inherit', result => 1}, >+ ], >+ }, >+ { >+ setting => 'no', >+ patrons => [ >+ {setting => 'yes', result => 1}, >+ {setting => 'no', result => 1}, >+ {setting => 'inherit', result => 1}, >+ ], >+ }, >+ { >+ setting => 'inherit', >+ patrons => [ >+ {setting => 'yes', result => 1}, >+ {setting => 'no', result => 1}, >+ {setting => 'inherit', result => 1}, >+ ], >+ }, >+ ], >+ }, >+ { >+ syspref => 'softyes', >+ categories => [ >+ { >+ setting => 'yes', >+ patrons => [ >+ {setting => 'yes', result => 1}, >+ {setting => 'no', result => 0}, >+ {setting => 'inherit', result => 1}, >+ ], >+ }, >+ { >+ setting => 'no', >+ patrons => [ >+ {setting => 'yes', result => 1}, >+ {setting => 'no', result => 0}, >+ {setting => 'inherit', result => 0}, >+ ], >+ }, >+ { >+ setting => 'inherit', >+ patrons => [ >+ {setting => 'yes', result => 1}, >+ {setting => 'no', result => 0}, >+ {setting => 'inherit', result => 1}, >+ ], >+ }, >+ ], >+ }, >+ { >+ syspref => 'softno', >+ categories => [ >+ { >+ setting => 'yes', >+ patrons => [ >+ {setting => 'yes', result => 1}, >+ {setting => 'no', result => 0}, >+ {setting => 'inherit', result => 1}, >+ ], >+ }, >+ { >+ setting => 'no', >+ patrons => [ >+ {setting => 'yes', result => 1}, >+ {setting => 'no', result => 0}, >+ {setting => 'inherit', result => 0}, >+ ], >+ }, >+ { >+ setting => 'inherit', >+ patrons => [ >+ {setting => 'yes', result => 1}, >+ {setting => 'no', result => 0}, >+ {setting => 'inherit', result => 0}, >+ ], >+ }, >+ ], >+ }, >+ { >+ syspref => 'hardno', >+ categories => [ >+ { >+ setting => 'yes', >+ patrons => [ >+ {setting => 'yes', result => 0}, >+ {setting => 'no', result => 0}, >+ {setting => 'inherit', result => 0}, >+ ], >+ }, >+ { >+ setting => 'no', >+ patrons => [ >+ {setting => 'yes', result => 0}, >+ {setting => 'no', result => 0}, >+ {setting => 'inherit', result => 0}, >+ ], >+ }, >+ { >+ setting => 'inherit', >+ patrons => [ >+ {setting => 'yes', result => 0}, >+ {setting => 'no', result => 0}, >+ {setting => 'inherit', result => 0}, >+ ], >+ }, >+ ], >+ }, >+]; >+ >+map { >+ my $syspref = $_->{syspref}; >+ t::lib::Mocks::mock_preference('checkprevcheckout', $syspref); >+ map { >+ my $code = $_->{setting} . 'Cat'; >+ map { >+ my $kpatron = $builder->build({ >+ source => 'Borrower', >+ value => { >+ checkprevcheckout => $_->{setting}, >+ categorycode => $code, >+ }, >+ }); >+ my $patron = Koha::Patrons->find($kpatron->{borrowernumber}); >+ is( >+ $patron->wantsCheckPrevCheckout, $_->{result}, >+ "Predicate with syspref " . $syspref . ", cat " . $code >+ . ", patron " . $_->{setting} >+ ); >+ } @{$_->{patrons}}; >+ } @{$_->{categories}}; >+} @{$mappings}; >+ >+# doCheckPrevCheckout >+ >+# We want to test: >+# - DESCRIPTION [RETURNVALUE (0/1)] >+## PreIssue (sanity checks) >+# - Item, patron [0] >+# - Diff item, same bib, same patron [0] >+# - Diff item, diff bib, same patron [0] >+# - Same item, diff patron [0] >+# - Diff item, same bib, diff patron [0] >+# - Diff item, diff bib, diff patron [0] >+## PostIssue >+# - Same item, same patron [1] >+# - Diff item, same bib, same patron [1] >+# - Diff item, diff bib, same patron [0] >+# - Same item, diff patron [0] >+# - Diff item, same bib, diff patron [0] >+# - Diff item, diff bib, diff patron [0] >+## PostReturn >+# - Same item, same patron [1] >+# - Diff item, same bib, same patron [1] >+# - Diff item, diff bib, same patron [0] >+# - Same item, diff patron [0] >+# - Diff item, same bib, diff patron [0] >+# - Diff item, diff bib, diff patron [0] >+ >+# Requirements: >+# $patron, $different_patron, $items (same bib number), $different_item >+my $patron = $builder->build({source => 'Borrower'}); >+my $patron_d = $builder->build({source => 'Borrower'}); >+my $item_1 = $builder->build({source => 'Item'}); >+my $item_2 = $builder->build({ >+ source => 'Item', >+ value => { biblionumber => $item_1->{biblionumber} }, >+}); >+my $item_d = $builder->build({source => 'Item'}); >+ >+## Testing Sub >+sub test_it { >+ my ($mapping, $stage) = @_; >+ map { >+ my $patron = Koha::Patrons->find($_->{patron}->{borrowernumber}); >+ is( >+ $patron->doCheckPrevCheckout($_->{item}), >+ $_->{result}, $stage . ": " . $_->{msg} >+ ); >+ } @{$mapping}; >+}; >+ >+## Initial Mappings >+my $cpvmappings = [ >+ { >+ msg => "Item, patron [0]", >+ item => $item_1, >+ patron => $patron, >+ result => 0, >+ }, >+ { >+ msg => "Diff item, same bib, same patron [0]", >+ item => $item_2, >+ patron => $patron, >+ result => 0, >+ }, >+ { >+ msg => "Diff item, diff bib, same patron [0]", >+ item => $item_d, >+ patron => $patron, >+ result => 0, >+ }, >+ { >+ msg => "Same item, diff patron [0]", >+ item => $item_1, >+ patron => $patron_d, >+ result => 0, >+ }, >+ { >+ msg => "Diff item, same bib, diff patron [0]", >+ item => $item_2, >+ patron => $patron_d, >+ result => 0, >+ }, >+ { >+ msg => "Diff item, diff bib, diff patron [0]", >+ item => $item_d, >+ patron => $patron_d, >+ result => 0, >+ }, >+]; >+ >+test_it($cpvmappings, "PreIssue"); >+ >+# Issue item_1 to $patron: >+my $patron_get_mem = >+ GetMember(%{{borrowernumber => $patron->{borrowernumber}}}); >+BAIL_OUT("Issue failed") >+ unless AddIssue($patron_get_mem, $item_1->{barcode}); >+ >+# Then test: >+my $cpvPmappings = [ >+ { >+ msg => "Same item, same patron [1]", >+ item => $item_1, >+ patron => $patron, >+ result => 1, >+ }, >+ { >+ msg => "Diff item, same bib, same patron [1]", >+ item => $item_2, >+ patron => $patron, >+ result => 1, >+ }, >+ { >+ msg => "Diff item, diff bib, same patron [0]", >+ item => $item_d, >+ patron => $patron, >+ result => 0, >+ }, >+ { >+ msg => "Same item, diff patron [0]", >+ item => $item_1, >+ patron => $patron_d, >+ result => 0, >+ }, >+ { >+ msg => "Diff item, same bib, diff patron [0]", >+ item => $item_2, >+ patron => $patron_d, >+ result => 0, >+ }, >+ { >+ msg => "Diff item, diff bib, diff patron [0]", >+ item => $item_d, >+ patron => $patron_d, >+ result => 0, >+ }, >+]; >+ >+test_it($cpvPmappings, "PostIssue"); >+ >+# Return item_1 from patron: >+BAIL_OUT("Return Failed") unless AddReturn($item_1->{barcode}, $patron->{branchcode}); >+ >+# Then: >+test_it($cpvPmappings, "PostReturn"); >+ >+# Finally test C4::Circulation::CanBookBeIssued >+ >+# We have already tested ->wantsCheckPrevCheckout and ->doCheckPrevCheckout, >+# so all that remains to be tested is whetherthe different combinational >+# outcomes of the above return values in CanBookBeIssued result in the >+# approriate $needsconfirmation. >+ >+# We want to test: >+# - DESCRIPTION [RETURNVALUE (0/1)] >+# - patron, !wantsCheckPrevCheckout, !doCheckPrevCheckout >+# [!$issuingimpossible,!$needsconfirmation->{PREVISSUE}] >+# - patron, wantsCheckPrevCheckout, !doCheckPrevCheckout >+# [!$issuingimpossible,!$needsconfirmation->{PREVISSUE}] >+# - patron, !wantsCheckPrevCheckout, doCheckPrevCheckout >+# [!$issuingimpossible,!$needsconfirmation->{PREVISSUE}] >+# - patron, wantsCheckPrevCheckout, doCheckPrevCheckout >+# [!$issuingimpossible,$needsconfirmation->{PREVISSUE}] >+ >+# Needs: >+# - $patron_from_GetMember >+# - $item objects (one not issued, another prevIssued) >+# - $checkprevcheckout pref (first hardno, then hardyes) >+ >+# Our Patron >+my $CBBI_patron = $builder->build({source => 'Borrower'}); >+my $p_from_GetMember = >+ GetMember(%{{borrowernumber => $CBBI_patron->{borrowernumber}}}); >+# Our Items >+my $new_item = $builder->build({ >+ source => 'Item', >+ value => { >+ notforloan => 0, >+ withdrawn => 0, >+ itemlost => 0, >+ }, >+}); >+my $prev_item = $builder->build({ >+ source => 'Item', >+ value => { >+ notforloan => 0, >+ withdrawn => 0, >+ itemlost => 0, >+ }, >+}); >+# Second is Checked Out >+BAIL_OUT("CanBookBeIssued Issue failed") >+ unless AddIssue($p_from_GetMember, $prev_item->{barcode}); >+ >+# Mappings >+my $CBBI_mappings = [ >+ { >+ syspref => 'hardno', >+ item => $new_item, >+ result => undef, >+ msg => "patron, !wantsCheckPrevCheckout, !doCheckPrevCheckout" >+ >+ }, >+ { >+ syspref => 'hardyes', >+ item => $new_item, >+ result => undef, >+ msg => "patron, wantsCheckPrevCheckout, !doCheckPrevCheckout" >+ }, >+ { >+ syspref => 'hardno', >+ item => $prev_item, >+ result => undef, >+ msg => "patron, !wantsCheckPrevCheckout, doCheckPrevCheckout" >+ }, >+ { >+ syspref => 'hardyes', >+ item => $prev_item, >+ result => 1, >+ msg => "patron, wantsCheckPrevCheckout, doCheckPrevCheckout" >+ }, >+]; >+ >+# Tests >+map { >+ t::lib::Mocks::mock_preference('checkprevcheckout', $_->{syspref}); >+ my ( $issuingimpossible, $needsconfirmation ) = >+ C4::Circulation::CanBookBeIssued( >+ $p_from_GetMember, $_->{item}->{barcode} >+ ); >+ is($needsconfirmation->{PREVISSUE}, $_->{result}, $_->{msg}); >+} @{$CBBI_mappings}; >+ >+$schema->storage->txn_rollback; >+ >+1; >-- >2.7.4 >
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 6906
:
5531
|
5532
|
5533
|
27558
|
27606
|
30680
|
30681
|
50071
|
50127
|
50128
|
50243
|
50286
|
50323
|
51378
|
51393
|
52278
|
52279
|
52280
|
53104
|
53105
|
53136
|
53144
|
53145
|
53146
|
53147
|
53148