Koha How-To

Changing Circulation Rules Midstream

Recent events have dramatically increased the time we spend looking at changes to circulation and fines rules and talking to our partners about how those changes will impact existing checkouts. With that in mind, I wanted to give you a quick tour of how Koha stores and uses data related to circulation.

The first thing to bear in mind here is that Koha generally prefers to check data as needed rather than store data in multiple places. In circulation, that means we record the bare minimum about each checkout and use that to find the other data we need as we need it. That can lead to some confusion when things change between checkout and checkin, but it also allows us a lot of flexibility should we need to change things on the fly.

The easiest way to see what Koha remembers for each checkout is to grab an entry from the issues table:

  • issue_id: 1
  • borrowernumber: 19
  • itemnumber: 1
  • date_due: 2020-04-13 23:59:00
  • branchcode: CPL
  • returndate: NULL
  • lastreneweddate: NULL
  • renewals: 0
  • auto_renew: 0
  • auto_renew_error: NULL
  • timestamp: 2020-04-08 12:57:56
  • issuedate: 2020-04-08 12:57:56
  • onsite_checkout: 0
  • note: NULL
  • notedate: NULL
  • noteseen: NULL

This is a checkout I just performed on my test system. Those 16 fields show all the functional data Koha stores about this checkout (there’s statistical data about this checkout written elsewhere, but it’s not used for actual processing). If it’s not recorded here, it’s figured out in the moment as needed. Most notable in their absence are item type, patron category, and anything about the specifics of the rule used for this checkout. We have all the pieces we need to find those things, but Koha re-finds them each time it needs to.

At checkout

When you scan an item barcode into the checkout box, Koha zips through a lot of data to figure out what to do. Figuring out which circ rule to use starts with the system preference CircControl.

If we’re setting up different circ rules for different branches, then we need to tell Koha how to decide which to use. Imagine you have a patron from Branch A who put a hold on an item from Branch B and set it for pickup at Branch C - those could be three totally different sets of rules! So CircControl lets us decide whether we want to use the circ rules for the patron’s library, the item’s library, or the library at which the checkout is happening. If CircControl is set to the item’s library, then you have one more question to answer in the system preference HomeOrHoldingBranch.

Every item has a home branch (where it lives) and a holding branch (where it is right now), so Koha needs to know which one of those to use.

Once the branch question has been settled, it’s time to pick a specific circ rule. That means finding an item type and a patron category, which is just a couple of easy searches based on the itemnumber and borrowernumber we already have. With those, Koha finds a circ rule and, assuming the checkout is allowed, writes some stuff into the issues table.

We store the itemnumber, the borrowernumber, and the branchcode for the branch at which the checkout happened so we can find the circ rule again as neeed, but we don’t store anything about the rule itself. We store the issuedate and the datedue, but not anything about how the latter was calculated or what might happen when we get to or past that datedue.

There’s a bit of an outlier here, though. That’s the auto_renew field. At the moment of checkout, Koha checks whether the rule it’s using says yes or no for auto-renewal and records that here (1 for yes, 0 for no). That determines this checkout’s auto-renewal behavior for the rest of its life, even if the rule later changes. Auto-renew behavior can also be set manually at checkout using the Automatic Renewal checkbox in the checkout screen. Checking this box records a 1 in issues.auto_renew, setting this checkout to auto-renew, regardless of the circ rule used.

After checkout

Given that we store only the bare minimum of information about a checkout, much of the process I outlined above gets repeated many times in the course of a checkout’s life. For example, each time the fines cronjob runs it uses the system preferences mentioned above to pick which branch’s rules to follow and then uses the itemnumber and borrowernumber recorded in the issues table to figure out the item type and patron category to use to pick a specific rule. That means that any changes to those system preferences, edits to the item or patron, or changes to the rule between checkout and a run of the fines cron will change what the fines cron does.

For a more specific example, suppose a library does not charge their staff any late fines. A staff member has a book that is 3 weeks overdue but has been charged no fines, based on the circ rules for staff members. But then the staff member retires and their patron category is changed from staff to patron. The next morning, when the fines cron runs, it sees a patron with a book that is 3 weeks and 1 day overdue and assesses an overdue fine for that whole period. The fines process has no concept of the history of this checkout, it just uses the facts as they exist in that moment to calculate what the fines should be.

Changes to system preferences, item types, or patron categories are relatively rare, but changes to circ rules are both more common. Fines and renewals are both subject to changes to circ rules while an item is checked out. The following aspects of your circ rules are checked each time the fines cron runs or an item is renewed:

  • Fines: fine amount, fine charging interval, when to charge, fine grace period, overdue fines cap, cap fine at replacement price
  • Renewal: renewals allowed, renewal period, no renewal before, no automatic renewal after

Any changes to those fields in your circ rules will apply to any future interactions with existing checkouts. Additionally, any changes to your items, patrons, or CircControl and HomeOrHolding system preferences could change which rule is used, even if the rules themselves stay the same.

Automatic renewal

Once again, automatic renewal works a little bit differently. As noted above, the part of your circ rule that determines whether or not a given item will auto-renew is consulted at checkout and the decision made at that time persists throughout the checkout period. More specifically, this decision is whether or not the auto-renew cron should look at this checkout when it runs. However, once the cron has decided to look at a given checkout, it uses the other parts of your circ rule (renewals allowed, renewal period, no renewal before, and no automatic renewal after) to decide whether or not the item can be renewed that day and, if so, how long it should renew for. So changing the Automatic Renewal yes/no rule will not change the behavior of existing checkouts, but changing the other renewal-related parts of your circ rule will.

One caveat here, though: Koha just added a new feature that allows patrons to opt out of auto-renewal. You can see details of how this is set up in Jessie's recent post about auto-renewal. This new feature doesn't change how your circ rules work or what gets recorded in the issues table. At time of checkout, Koha still looks at the circ rules to decide whether to put a 1 or a 0 in issues.auto_renew. This new feature adds another check to the auto-renew cron. Now the cron will only look at checkouts where issues.auto_renew=1 and the patron has not opted out of auto-renew. Whenever a patron changes their auto-renew opt out setting, that change applies to all of their existing checkouts and will apply to the next run of the auto-renew cron.

At checkin

If you have the system preference CalculateFinesOnReturn set to “Do,” then Koha checks your circ rules one last time when an item gets checked in.

If you’ve changed your circulation rules since this item was checked out (or even since the last time the fines cron ran), the final fine for this item will be calculated using the circ rules as they exist at the moment of checkin. Similarly, if the item or patron have changed such that they should follow a different rule than the one used at checkout, their final fine will be calculated using that new rule.