From 285678b7332e7abe9ca2da94f95e7be0716546cc Mon Sep 17 00:00:00 2001 From: Nick Clemens Date: Fri, 8 Jan 2016 19:41:52 +0000 Subject: [PATCH] Bug 14576 - Allow arbitrary automatic update of location on checkin This patch adds a new syspref "UpdateItemLocationOnCheckin" which accepts pairs of shelving locations. On check-in the items location is compared ot the location on the left and, if it matches, is updated to the location on the left. This preference replaces ReturnToShelvingCart and InProcessingToShelvingCart preferences. The update statement should insert values that replciate these functions. Note existing functionality of all items in PROC location being returned to permanent_location is preserved by default. Also, any items issued from CART location will be returned to their permanent location on issue (if it differs) Special values for this pref are: _ALL_ - used on left side only to affect all items _BLANK_ - used on either side to match on/set to blank (actual blanks will work, but this is an easier to read option) _PERM_ - used on right side only to return items to permanent location Test Plan: 1) Apply this patch 2) Run updatedatabase.pl 3) Set the new system preference UpdateitemLocationOnCheckin to the following (assuming sample data): NEW: FIC FIC: GEN 4) Create an item, set its location to NEW 5) Check in the item, note its location is now FIC 6) Check in the item again, note its location is now GEN 7) Check in the item again, note its location remains GEN 8) Test using _ALL_, _BLANK_ and _PERM_ for updates 9) Try entering various incorrect syntax in the pref and note you are warned Sponsored by: Arcadia Public Library (http://library.ci.arcadia.ca.us/) Middletown Township Public Library (http://www.mtpl.org/) Signed-off-by: Cathi Wiggins Signed-off-by: Megan Wianecki --- C4/Circulation.pm | 48 +++++++++++++++------- circ/returns.pl | 3 ++ ...576-add_UpdateItemLocationOnCheckin_syspref.sql | 5 +++ installer/data/mysql/sysprefs.sql | 1 + .../en/modules/admin/preferences/circulation.pref | 27 ++++++------ .../intranet-tmpl/prog/en/modules/circ/returns.tt | 29 +++++++++++++ .../intranet-tmpl/prog/js/pages/preferences.js | 19 +++++++++ 7 files changed, 105 insertions(+), 27 deletions(-) create mode 100644 installer/data/mysql/atomicupdate/bug_14576-add_UpdateItemLocationOnCheckin_syspref.sql diff --git a/C4/Circulation.pm b/C4/Circulation.pm index 50e6c10..6dc2878 100644 --- a/C4/Circulation.pm +++ b/C4/Circulation.pm @@ -1427,7 +1427,8 @@ sub AddIssue { } ); - if ( C4::Context->preference('ReturnToShelvingCart') ) { ## ReturnToShelvingCart is on, anything issued should be taken off the cart. + if ( $item->{'location'} eq 'CART' && $item->{'permanent_location'} ne 'CART' ) { + ## Item was moved to cart via UpdateItemLocationOnCheckin, anything issued should be taken off the cart. CartToShelf( $item->{'itemnumber'} ); } $item->{'issues'}++; @@ -1924,17 +1925,6 @@ sub AddReturn { my $item = GetItem($itemnumber) or die "GetItem($itemnumber) failed"; - if ( $item->{'location'} eq 'PROC' ) { - if ( C4::Context->preference("InProcessingToShelvingCart") ) { - $item->{'location'} = 'CART'; - } - else { - $item->{location} = $item->{permanent_location}; - } - - ModItem( $item, $item->{'biblionumber'}, $item->{'itemnumber'} ); - } - # full item data, but no borrowernumber or checkout info (no issue) # we know GetItem should work because GetItemnumberFromBarcode worked my $hbr = GetBranchItemRule($item->{'homebranch'}, $item->{'itype'})->{'returnbranch'} || "homebranch"; @@ -1944,6 +1934,37 @@ sub AddReturn { my $borrowernumber = $borrower->{'borrowernumber'} || undef; # we don't know if we had a borrower or not + my $yaml = C4::Context->preference('UpdateItemLocationOnCheckin'); + if ($yaml) { + $yaml = "$yaml\n\n"; # YAML is strict on ending \n. Surplus does not hurt + my $rules; + eval { $rules = YAML::Load($yaml); }; + if ($@) { + warn "Unable to parse UpdateItemLocationOnCheckin syspref : $@"; + } + else { + if (defined $rules->{_ALL_}) { + if ($rules->{_ALL_} eq '_PERM_') { $rules->{_ALL_} = $item->{permanent_location}; } + if ($rules->{_ALL_} eq '_BLANK_') { $rules->{_ALL_} = ''; } + if ( $item->{location} ne $rules->{_ALL_}) { + $messages->{'ItemLocationUpdated'} = { from => $item->{location}, to => $rules->{_ALL_} }; + ModItem( { location => $rules->{_ALL_} }, undef, $itemnumber ); + } + } + else { + foreach my $key ( keys %$rules ) { + if ( $rules->{$key} eq '_PERM_' ) { $rules->{$key} = $item->{permanent_location}; } + if ( $rules->{$key} eq '_BLANK_') { $rules->{$key} = '' ;} + if ( ($item->{location} eq $key && $item->{location} ne $rules->{$key}) || ($key eq '_BLANK_' && $item->{location} eq '' && $rules->{$key} ne '') ) { + $messages->{'ItemLocationUpdated'} = { from => $item->{location}, to => $rules->{$key} }; + ModItem( { location => $rules->{$key} }, undef, $itemnumber ); + last; + } + } + } + } + } + my $yaml = C4::Context->preference('UpdateNotForLoanStatusOnCheckin'); if ($yaml) { $yaml = "$yaml\n\n"; # YAML is anal on ending \n. Surplus does not hurt @@ -2095,15 +2116,12 @@ sub AddReturn { ); $sth->execute( $item->{'itemnumber'} ); # if we have a reservation with valid transfer, we can set it's status to 'W' - ShelfToCart( $item->{'itemnumber'} ) if ( C4::Context->preference("ReturnToShelvingCart") ); C4::Reserves::ModReserveStatus($item->{'itemnumber'}, 'W'); } else { $messages->{'WrongTransfer'} = $tobranch; $messages->{'WrongTransferItem'} = $item->{'itemnumber'}; } $validTransfert = 1; - } else { - ShelfToCart( $item->{'itemnumber'} ) if ( C4::Context->preference("ReturnToShelvingCart") ); } # fix up the accounts..... diff --git a/circ/returns.pl b/circ/returns.pl index 3804543..845a69c 100755 --- a/circ/returns.pl +++ b/circ/returns.pl @@ -539,6 +539,9 @@ foreach my $code ( keys %$messages ) { elsif ( $code eq 'ForeverDebarred' ) { $err{foreverdebarred} = $messages->{'ForeverDebarred'}; } + elsif ( $code eq 'ItemLocationUpdated' ) { + $err{ItemLocationUpdated} = $messages->{ItemLocationUpdated}; + } elsif ( $code eq 'NotForLoanStatusUpdated' ) { $err{NotForLoanStatusUpdated} = $messages->{NotForLoanStatusUpdated}; } diff --git a/installer/data/mysql/atomicupdate/bug_14576-add_UpdateItemLocationOnCheckin_syspref.sql b/installer/data/mysql/atomicupdate/bug_14576-add_UpdateItemLocationOnCheckin_syspref.sql new file mode 100644 index 0000000..bd39d20 --- /dev/null +++ b/installer/data/mysql/atomicupdate/bug_14576-add_UpdateItemLocationOnCheckin_syspref.sql @@ -0,0 +1,5 @@ +INSERT IGNORE INTO systempreferences (variable,value,options,explanation,type) VALUES('UpdateItemLocationOnCheckin', 'PROC: _PERM_\n', 'NULL', 'This a list of value pairs. When an item is checked in, if the location value on the left matches the items location value t will be updated to the right-hand value. E.g. ''PROC: FIC'' will cause an item that was set to ''Book Cart'' to now be in the ''Fiction'' shelving location. Note that PROC and CART are special values, for these locations only can location and permanent_location differ. In all other cases an update will affect both. Items in the CART location will be returned to their permanent location on checkout. You can also use the special term _BLANK_ on either side of a pair to update/remove items with no locaiton assigned. You can use the special term _ALL_ on the left side to affect all items and the special term _PERM_ on the right side to return items to their permanent location', 'Free'); +UPDATE systempreferences s1, (SELECT IF(value,'PROC: CART\n','') AS p2c FROM systempreferences WHERE variable='InProcessingToShelvingCart') s2 SET s1.value= CONCAT(s2.p2c, REPLACE(s1.value,'PROC: _PERM_\n','') ) WHERE s1.variable='UpdateItemLocationOnCheckin' AND s1.value NOT LIKE '%PROC: CART%'; +DELETE FROM systempreferences WHERE variable='InProcessingToShelvingCart'; +UPDATE systempreferences s1, (SELECT IF(value,'_ALL_: CART\n','') AS rtc FROM systempreferences WHERE variable='ReturnToShelvingCart') s2 SET s1.value= CONCAT(s2.rtc,s1.value) WHERE s1.variable='UpdateItemLocationOnCheckin' AND s1.value NOT LIKE '%_ALL_: CART%'; +DELETE FROM systempreferences WHERE variable='ReturnToShelvingCart'; diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql index 2b95c99..09f9e5d 100644 --- a/installer/data/mysql/sysprefs.sql +++ b/installer/data/mysql/sysprefs.sql @@ -500,6 +500,7 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` ('UNIMARCAuthorsFacetsSeparator',', ',NULL,'UNIMARC authors facets separator','short'), ('UNIMARCField100Language','fre',NULL,'UNIMARC field 100 default language','short'), ('UniqueItemFields','barcode','','Space-separated list of fields that should be unique (used in acquisition module for item creation). Fields must be valid SQL column names of items table','Free'), +('UpdateItemLocationOnCheckin', '', 'NULL', 'This is a list of value pairs. When an item is checked in, if the location value on the left matches the items location value it will be updated to the right-hand value. E.g. ''PROC: FIC'' will cause an item that was set to ''Book Cart'' to now be in the ''Fiction'' shelving location. Note that PROC and CART are special values, for these locations only can location and permanent_location differ. In all other cases an update will affect both. Items in the CART location will be returned to their permanent location on checkout. You can also use the special term _BLANK_ on either side of a pair to update/remove items with no locaiton assigned. You can use the special term _ALL_ on the left side to affect all items and the special term _PERM_ on the right side to return items to their permanent location', 'Free'), ('UpdateNotForLoanStatusOnCheckin', '', 'NULL', 'This is a list of value pairs. When an item is checked in, if the not for loan value on the left matches the items not for loan value it will be updated to the right-hand value. E.g. ''-1: 0'' will cause an item that was set to ''Ordered'' to now be available for loan. Each pair of values should be on a separate line.', 'Free'), ('UpdateTotalIssuesOnCirc','0',NULL,'Whether to update the totalissues field in the biblio on each circ.','YesNo'), ('uppercasesurnames','0',NULL,'If ON, surnames are converted to upper case in patron entry form','YesNo'), 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 9a37608..883535f 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 @@ -181,18 +181,6 @@ Circulation: no: "Don't allow" - staff to manually override and check out items to patrons who have more than noissuescharge in fines. - - - pref: InProcessingToShelvingCart - choices: - yes: Move - no: "Don't move" - - items that have the location PROC to the location CART when they are checked in. - - - - pref: ReturnToShelvingCart - choices: - yes: Move - no: "Don't move" - - all items to the location CART when they are checked in. - - - pref: AutomaticItemReturn choices: yes: Do @@ -441,6 +429,21 @@ Circulation: - calculate and update overdue charges when an item is returned. -
NOTE If you are doing hourly loans then you should have this on. - + - pref: UpdateItemLocationOnCheckin + type: textarea + class: code + - This is is a list of value pairs, the first value is followed immediately by colon space then the second value i.e.:
+ - "PROC: FIC" + -
When an item is checked in, if the location value on the left matches the items location value + - "it will be updated to the right-hand value.
E.g. ''PROC: FIC'' will cause an item that was set to ''Book Cart'' to now be in the ''Fiction'' shelving location." + -
Note that PROC and CART are special values, for these locations only can location and permanent_location differ. In all other cases an update will affect both. + -
Items in the CART location will be returned to their permanent location on checkout + -
You can use the special term _BLANK_ on either side of a pair to update/remove items with no location assigned + -
You can use the special term _ALL_ on the left side to affect all items + - and the special term _PERM_ on the right side to return items to their permanent location + -
**Use of an _ALL_ rule will override/ignore any other values** + -
Each pair of values should be on a separate line. + - - pref: UpdateNotForLoanStatusOnCheckin type: textarea class: code diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/returns.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/returns.tt index 0c4180c..b357d09 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/returns.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/returns.tt @@ -478,6 +478,35 @@ $(document).ready(function () { [% END %]

[% END %] + [% IF ( errmsgloo.ItemLocationUpdated ) %] +

+ Item shelving location updated + from + [% IF errmsgloo.ItemLocationUpdated.from %] + [% IF errmsgloo.ItemLocationUpdated.from == '' %] + empty + [% ELSIF AuthorisedValues.GetByCode( 'LOC', errmsgloo.ItemLocationUpdated.from ) == '' %] + [% errmsgloo.ItemLocationUpdated.from %] (No description available) + [% ELSE %] + [% AuthorisedValues.GetByCode( 'LOC', errmsgloo.ItemLocationUpdated.from ) %] + [% END %] + [% ELSE %] + "Blank" + [% END %] + to + [% IF errmsgloo.ItemLocationUpdated.to %] + [% IF errmsgloo.ItemLocationUpdated.to == '' %] + empty + [% ELSIF AuthorisedValues.GetByCode( 'LOC', errmsgloo.ItemLocationUpdated.to ) == '' %] + [% errmsgloo.ItemLocationUpdated.to %] (Not an authorized value) + [% ELSE %] + [% AuthorisedValues.GetByCode( 'LOC', errmsgloo.ItemLocationUpdated.to ) %] + [% END %] + [% ELSE %] + "Blank" + [% END %] +

+ [% END %] [% IF ( errmsgloo.badbarcode ) %]

No item with barcode: [% errmsgloo.msg %]

[% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/js/pages/preferences.js b/koha-tmpl/intranet-tmpl/prog/js/pages/preferences.js index 70365cd..4db6750 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/pages/preferences.js +++ b/koha-tmpl/intranet-tmpl/prog/js/pages/preferences.js @@ -137,4 +137,23 @@ $( document ).ready( function () { if ( search_jumped ) { document.location.hash = "jumped"; } + + $("#pref_UpdateItemLocationOnCheckin").change(function(){ + var the_text = $(this).val(); + var alert_text = ''; + if ( the_text.indexOf('_ALL_:') != -1 ) alert_text= _("Note: _ALL_ value will override all other values") + '\n'; + var split_text =the_text.split("\n"); + var alert_issues = ''; + var issue_count = 0; + var reg_check = /.*:\s.*/; + for (var i=0; i < split_text.length; i++){ + if ( !split_text[i].match(reg_check) && split_text[i].length ) { + alert_issues+=split_text[i]+"\n"; + issue_count++; + } + } + if (issue_count) alert_text += "\n"+_("The following values are not formatted correctly:")+"\n"+alert_issues; + if ( alert_text.length ) alert(alert_text); + }); + } ); -- 2.1.4