[OPEN-ILS-GENERAL] Circulation And Holds "Rewrite"

Thomas Berezansky tsbere at mvlc.org
Mon Mar 12 13:20:37 EDT 2012


I would like to make a number of changes to circulation and holds, but  
have determined that they will interact with each other significantly  
code-wise. Thus I am planning to do them as one large project, rather  
than as smaller chunks that would be difficult to keep working with  
each other independently. Before I begin, however, I would like input  
on the plans I have so far.

Also, before anyone panics about some of the more significant changes  
listed here I would like to point out that there is no chance of this  
work making it into 2.2 at this time.

I highly recommend you read the HTML version of this email, if only  
for formatting purposes. You can find it at  
http://mvlcstaff.org/circ_holds_rewrite.html and it contains  
everything here except for this note to go look at it.

General Changes
---------------

Some of the changes I am looking to make apply equally to circulation  
and holds, and are the main reason I am changing circulation and holds  
at the same time.

Remove Legacy Script Support
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

At this point Legacy Circ Scripts are not recommended for use, and  
most groups appear to be trying to move away from them. In addition to  
that, I suspect that some of the things I am looking to change are  
being done to make INDB act, to the rest of the system, more like the  
legacy scripts do.

As a result of this, rather than attempt to tie any new features into  
the legacy script support, I would prefer to tear the legacy script  
support out entirely. This has additional side benefits as well, such  
as removing a source of confusion for new developers from the code base.

I am willing to work with people on reasonable lists of things that  
they can currently accomplish with scripts that INDB won't be able to  
handle, even if I don't see a significant need for the functionality  
myself.

Updated Editors
~~~~~~~~~~~~~~~

One of the biggest complaints, if not the biggest complaint, about the  
circ and hold matrices is the horrendous state of the editors. Thus I  
plan on re-writing them from scratch to hopefully be more useful.

Included in this would be a filtering interface and use of the  
server-side weighting values to order the fields as close to as the  
server will when applying them as possible. I also hope to put in  
"test" fields where patron and item barcodes can be input to determine  
what rules would apply.

Splitting "Grouped" Failure Reasons
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Currently a number of failure reasons share a single failure code. For  
example, right now you cannot distinguish a matrix rule saying no from  
the copy saying no from the copy location saying no for circulation or  
holds. That means you can't assign different override permissions for  
each failure reason, leaving them at all or nothing.

To my knowledge this is being done to make INDB look more like legacy  
scripts. See above for my thoughts on that.

I would like to split these "grouped" reasons into their individual  
codes, removing the old codes and exposing the INDB backend codes  
instead.

Custom Failure Codes
~~~~~~~~~~~~~~~~~~~~

In addition to splitting up the "Grouped" codes I feel it would be  
good to allow for custom failure codes, with descriptions, to be  
placed into the system. This would allow for Circ and Hold matrix rows  
that disallow the circulation or hold to return a code other than the  
current "the row said no" failure code. In addition, the Circulation  
Limit Sets feature would also get the ability to have these codes  
applied.

This would allow for staff to get descriptive reasons for why a  
circulation failed, rather than a simple "the rules said no" response.  
For example, you may have "Local Use Only" patrons that can't  
circulate items out of other libraries, or perhaps you want to  
indicate that an item isn't suitable for patrons flagged as juvenile.  
As an added benefit you would then be able to assign override  
permissions based on these failure codes, giving even more granular  
control over what can and cannot be overridden.

These failure codes would come from a global list of valid codes, one  
each for the circ and hold matrix (because some codes make no sense in  
one context, but others may be fine in both).

Relative Org Units
~~~~~~~~~~~~~~~~~~

One major limitation of the Circ and Hold matrix tables is that all  
org unit checks are done with absolute org units. In order to say, for  
example, "the user's home library is the item's circ library" you need  
one rule per home library.

I want to resolve that by adding relative org unit lookups. For a  
given org unit checking column you would be able to say "I want to  
match based on this specific org unit (current behavior) or an org  
unit defined by the user, item, or for holds the requestor".

My current plans are to support the following fields for the relative lookups:

* User's home library
* Item's circ library
* Item's owning library
* Requestor's home library (for holds only)

I plan on putting these checks into a table to allow for some  
customization, specifically to allow for depth modification. That  
would allow you to check against, for example, the system the user's  
home library is in instead of just the specific branch.

Importance/Manual Ordering
~~~~~~~~~~~~~~~~~~~~~~~~~~

Right now the weights system for the circ and hold matrices allows for  
a lot of flexibility from system to system, but it is possible for  
multiple rules to come out with the same weight value. At this point  
the final tiebreaker is the rule ID, with the lower rule always coming  
first.

This works out great for ensuring predictable results, but there are  
reasons to want finer control over things. Thus I propose adding an  
"Importance" field, hooked into the weights system. The higher the  
value the more important the rule is. A negative value would make the  
rule less important. Sufficiently large values could even push a  
specific rule higher up in the list as an override for when normal  
weighting decisions aren't sufficient.

By hooking it into the weights system there is the added benefit of  
being able to make it the most important field, thus allowing for  
manual ordering of rules for those that want the ultimate level of  
control over what rules come first.

Comments/Notes Field
~~~~~~~~~~~~~~~~~~~~

Intended to be seen only on the rule editing screen this field would  
provide an area to store information about the rule for later review.  
It could be as simple as who last edited the rule or as complicated as  
the full reasoning behind the rule's existence.

Or, as I suspect will be the most common case, it could be left blank.


Circ Matrix Specific Changes
----------------------------

I feel that circulation rule checks can benefit from a couple of  
additional features that don't apply to holds, mainly because most  
hold checks are in batch on multiple potential copies.

Thus, the following features are intended specifically for the circ  
matrix, and I don't currently plan on implementing them for holds.

Context Field
~~~~~~~~~~~~~

At the moment a circulation happens at a specific location in the org  
tree, but there are times where that isn't quite granular enough. For  
example, you may want to prevent checkouts of things in security cases  
at selfchecks that don't support opening those cases. Or perhaps you  
want to disallow OPAC renewals of some items, without disallowing all  
renewals of them.

This is where a Context field would come in, similar to the Context  
Org Unit that the circ matrix already has. This would be a string,  
similar to circ modifiers. An example set of defaults I am planning:

* staffclient - Would be used for checkouts done by staff in the staff client.
* sip2 - Would be used for checkouts done via SIP2, say using  
selfchecks. I plan on making this changeable via the SIP2  
configuration, to allow differentiation between different kinds of  
clients.
* opac - For OPAC renewals, primarily.
* selfcheck - For the Evergreen selfcheck interface.

Failure Scopes
~~~~~~~~~~~~~~

Right now pretty much all overrides are checked based on the  
workstation, but in a single install covering a number of systems you  
may not want to grant overrides that broadly. I want to further extend  
the granularity permitted by the split and custom failure codes by  
allowing the addition of a failure scope to them.

The scope would allow an org unit to be specified as the point you  
need permission to override at. This org unit could be an absolute org  
unit or a relative one. In addition I am thinking that a default  
(relative) org unit should be permitted for some codes, such as the  
various circulate flags that otherwise aren't generated by matrix  
rules directly.

This would allow for saying things like "You can override the copy  
level circulate flag for your copies, but not for another library's  
copies" and "You can checkout your copies to someone else's Local Use  
Only patron, but not a third party's copies" without having to rely on  
broad override permissions and staff attentiveness.


Holds Specific Changes
----------------------

Similar to how some things only make sense for circulation, other  
things only make sense for holds.

Fallthrough in Hold Matrix
~~~~~~~~~~~~~~~~~~~~~~~~~~

Existing options in the hold matrix coupled with some of the additions  
here make fallthrough in the hold matrix a good idea. Thus I plan on  
implementing fallthrough, which will allow for "result" fields to be  
set on more generic rules. For example, "max holds" could be set once  
at the top of the org tree and have an effect on all rules.

Capture at circ lib only
~~~~~~~~~~~~~~~~~~~~~~~~

This is intended for a very specific situation, but may have uses  
elsewhere. The goal is to prevent items being captured for out of  
system ILL from capturing at locations other than their circ library.  
This would allow for staff to double check items and would help  
prevent "remote" transits that may need elevated permissions to abort.

HOLD_EXISTS Checks
~~~~~~~~~~~~~~~~~~

Right now the HOLD_EXISTS failure code is only checked when actually  
placing the hold. If you have had a different override applied earlier  
in the process it may be missed entirely.

I want to run this check earlier in the process, to allow for a more  
complete picture of why a hold wasn't, or shouldn't, be placed.

Failure Reasons
~~~~~~~~~~~~~~~

Currently the hold placement process can only tell what the last  
failure code was. I want to change that, to provide a more complete  
view of why a hold wasn't placed. That will require bubbling the  
failure codes up from the backend. Once they reach the UI layer they  
can then be parsed to provide more descriptive reasons, for staff and  
patrons, as to why a hold couldn't be placed.

Stalling Start
~~~~~~~~~~~~~~

Currently stalling doesn't take into account when a hold was  
suspended, or re-activated. That means that a hold can "eat up" the  
entire stalling period by being frozen.

The goal here is to add a new field to holds that is reset when the  
hold is placed or re-activated. That field would then be used for  
stalling calculations, allowing for stalling periods to occur on a  
hold that spent weeks suspended.

Age Protection
~~~~~~~~~~~~~~

Currently age protection in INDB rules is a copy level one rule check,  
but is remarkably inflexible. The addition of custom failure codes  
will permit a hold rule to pretend to be age protection, but without a  
couple of additional fields on the hold matrix that may not be enough.

Thus, I want to add two more fields to the hold matrix for age  
protection purposes. The first is a match field for the age protection  
rule in use, to allow matching of copies that use specific age  
protection rules. This would allow, for example, the addition of a  
second age protection check on top of the normal one for a second  
range, so a rule that limits to the branch could then be extended to  
include the system for an extra period of time.

The second field I want to add is a result field to allow a rule to  
skip the normal age protection checks. Set globally you would be  
moving age protection checks 100% into the hold matrix rules, but  
there are other use cases as well. For example, a special user group  
that gets to ignore age protection for some reason.

Default Part
~~~~~~~~~~~~

When cataloging records that will later have parts it is likely that  
you won't know what those parts will be ahead of time. If you have "On  
Order" records, though, patrons may place holds on those records.

Once the copies are given parts there may no longer be any copies that  
can fill the holds placed when things were "On Order", which may leave  
a lot of extra holds that will not fill around.

This would be an optional flag on parts, limit one part per bib  
flagged as such. If set then copies without a part would be treated as  
though they had this part for part holds, and holds without a part  
would consider this part as valid for filling the hold.

Subparts
~~~~~~~~

Currently a copy can have a single part assigned to them. This can be  
a problem when a patron wants, say, a single DVD from a box set, but  
the box set is broken up in multiple ways. The patron has the option  
of picking one part that covers the DVD they want and waiting for that  
hold to fill or placing one hold for each part that contains the DVD  
they want and possibly getting them all at once.

This would solve that problem by creating an optional list of  
"Subparts" for each part. If set then the part would fill holds for  
the part itself or subparts thereof.

For example, if you have a "Disc 1-3" part you could have subparts of  
"Disc 1", "Disc 2", "Disc 3", "Disc 1-2", and "Disc 2-3". The "Disc  
1-2" part may be defined as having "Disc 1" and "Disc 2" as subparts,  
and the same for "Disc 2-3" with "Disc 2" and "Disc 3". A patron  
placing a hold on "Disc 2" would then be able to get a copy flagged as  
"Disc 2" directly, or a copy that is flagged as "Disc 1-3", "Disc  
1-2", or "Disc 2-3" to fill their hold.

A secondary checkbox, only visible when subparts are in use, could  
allow for patrons to indicate whether they want any part that can fill  
the request or only the specific part they are selecting.

Thomas Berezansky
Merrimack Valley Library Consortium






More information about the Open-ils-general mailing list