======INDB Circulation (DRAFT)====== WARNING: This has not been updated for various changes in 2.2+. =====Tables===== ====config.circ_matrix_matchpoint==== The circ matrix matchpoint table could be seen as being split into several sections. Over time features are added, and thus a version for when the column was added is included. To start with, every row has an id and whether or not it is active: ^ Column Name ^ Column Description ^ Requires Version ^ | id | Matchpoint ID | 1.6+ | | active | Is matchpoint active? | 1.6+ | Then there are the "match values". With the exception of grp and org_unit, every one of these can be null to indicate that they don't matter. The most basic rule thus only sets grp and org_unit. ^ Column Name ^ Column Description ^ Requires Version ^ | grp | User Permission Group the matchpoint applies to (primary only)| 1.6+ | | org_unit | Org Unit, owning and applied to | 1.6+ | | copy_owning_lib | Owning Library of the call number | 2.0+ | | copy_circ_lib | Copy Circulation Library | 2.0+ | | usr_home_ou | User Home Library | 2.1+ | | is_renewal | Is this circ a renewal? | 1.6+ | | juvenile_flag | Is the user flagged as juvenile? | 1.6+ | | circ_modifier | Copy Circulation Modifier | 1.6+ | | marc_type | Copy circ as type if set, otherwise rec descriptor item type | 1.6+ | | marc_form | rec descriptor item form | 1.6+ | | marc_vr_format | rec descriptor videorecording format | 1.6+ | | ref_flag | Copy reference flag | 1.6+ | | usr_age_lower_bound | User minimum age based on DOB | 1.6+ | | usr_age_upper_bound | User maximum age based on DOB | 1.6+ | Then there are the "result values" that determine the circ parameters and if the circ is allowed. Pre-2.1 only the script test, hold ratio, and hard due date values could be set to null. In 2.1+ they can all be set to null for fallthrough purposes (though script_test does not fall through). ^ Column Name ^ Column Description ^ Requires Version ^ | circulate | Is the item allowed to circulate | 1.6+ | | duration_rule | The id of the rule to use from config.rule_circ_duration | 1.6+ | | recurring_fine_rule | The id of the rule to use from config.rule_recurring_fine | 1.6+ | | max_fine_rule | The id of the rule to use from config.rule_max_fine | 1.6+ | | hard_due_date | The id of the rule to use from config.hard_due_date | 1.6.2+ | | renewals | Override for max renewals | 2.1+ | | grace | Override for grace period | 2.1+ | | total_copy_hold_ratio | If there are holds, and ratio of copies to holds is less than this, deny circulation | 2.0+ | | available_copy_hold_ratio | If there are holds, and the ratio of available copies to holds is less than this, deny circulation | 2.0+ | | script_test | Currently unused(?) | 1.6+ | ====config.circ_matrix_circ_mod_test==== The circ matrix circ mod test table is used to limit checkouts by circ modifier or circ modifier set. It has so far remained unchanged since 1.6. ^ Column Name ^ Column Description ^ | id | Circ Mod Test ID | | matchpoint | Linked matchpoint from config.circ_matrix_matchpoint | | items_out | Max number of items out for this test | ====config.circ_matrix_circ_mod_test_map==== The circ matrix circ mod test map table links circulation modifier values to the test table ^ Column Name ^ Column Description ^ | id | Circ Mod Test Map ID | | circ_mod_test | Linked circ mod test from config.circ_matrix_circ_mod_test | | circ_mod | The Circulation Modifier from config.circ_modifier.code | =====Circulation Rules/Allowed Check===== Lookups are done by way of a call to action.item_user_circ_test or action.item_user_renew_test. Each of these takes three parameters: - The Context OU, where the circulation is occuring, as an integer - The item to be circulated's database ID - The database ID of the user the circulation is for They then call a second variant of action.item_user_circ_test. This one takes a fourth parameter for "is a renewal", which is only set to true in the action.item_user_renew_test variant. No other information is passed in, and all decisions must then be made with those few pieces of information or information that can be gathered by using them. action.item_user_circ_test returns a set of data: ^ Field ^ Description ^ Requires Version ^ | success | True if circulation should go through, false if there is a failure | 1.6+ | | matchpoint | The ID of the most specific matchpoint found. This will be the only matchpoint pre-2.1. | 1.6+ | | fail_part | String identifying why success was false | 1.6+ | | duration_rule | The ID of the duration rule matched | 2.1+ | | recurring_fine_rule | The ID of the recurring fine rule matched | 2.1+ | | max_fine_rule | The ID of the max fine rule matched | 2.1+ | | hard_due_date | The ID of the hard due date rule matched | 2.1+ | | renewals | The renewals override (if any) | 2.1+ | | grace | The grace period override (if any) | 2.1+ | | buildrows | Ordered array of rows used to generate the above | 2.1+ | If success is true only one row should be returned. If success is false one or more rows may be returned, depending on the number of failure points. Pre-2.1 the sole returned matchpoint is then loaded with fleshing to obtain results, 2.1+ loads the various pieces returned instead. fail_part can be one of the following: ^ fail_part ^ Description ^ Requires Version | | A Standing Penalty Name | The user has an active standing penalty preventing circulation | 1.6+ | | actor.usr.barred | The user is barred | 1.6+ | | asset.copy.circulate | The copy is set to not circulate | 1.6+ | | asset.copy.status | The copy is in the wrong status | 1.6+ | | asset.copy_location.circulate | The copy's location is set to not circulate | 1.6+ | | config.circ_matrix_circ_mod_test | The user has too many items out matching the circ mod rules | 1.6+ | | config.circ_matrix_test.available_copy_hold_ratio | The available copy count to hold count ratio is too small | 2.0+ | | config.circ_matrix_test.circulate | The returned matchpoint has the circulate flag set to false | 1.6+ | | config.circ_matrix_test.total_copy_hold_ratio | The total copy count to hold count ratio is too small | 2.0+ | | no_item | The item was not found - Bails out | 1.6+ | | no_matchpoint | No matchpoint was found | 1.6+ | | no_user | The user was not found - Bails out | 1.6+ | =====Matchpoint Lookup===== The matchpoint used for the circulation rules above is located, or built, by action.find_circ_matrix_matchpoint. This function takes the context ou, the item's database ID, the user's database ID, and a boolean stating if the circulation is a renewal. It then searches the config.circ_matrix_matchpoint table for a corresponding matchpoint (or matchpoints) to return back to action.item_user_circ_test. With the exception of the user's permission group and the context org unit all of the "match values" can be set to null to indicate that the rule isn't limited to something matching them. This means it is a good idea to always have at least one rule set to the top of the user permission tree and the top of the organizational unit tree with no other match values set that defines the overall defaults for in the event no other rule matches. ====Pre-2.1==== Pre-2.1 the various match values are weighted in a somewhat strict fashion: - User's Permission Group (grp) - Used as the outermost check, the matchpoint finding "walks" up the user permission group tree starting at the permission group in the user's profile - Context OU (org_unit) - Used as the second check, by increasing proximity (0 is exact match and is first, parent is 1, parent of parent is 2, etc) - Weighted values - In Descending order of weight added up from the following: - copy_owning_lib - 256/(proximity + 1) - exact match will be weight 256, parent will be weight 128, parent of parent will be weight 85.3, etc - copy_circ_lib - 256/(proximity + 1) - exact match will be weight 256, parent will be weight 128, parent of parent will be weight 85.3, etc - is_renewal: 128 if set - juvenile_flag: 64 if set - circ_modifier: 32 if set - marc_type: 16 if set - marc_form: 8 if set - marc_vr_format: 4 if set - ref_flag: 2 if set - usr_age_lower_bound: 0.5 if set - usr_age_upper_bound: 0.5 if set ====2.1+==== By default the same general calculation is done in 2.1+ as in Pre-2.1, but with the addition of the user_home_ou field being treated like the copy owning and circ libraries. However, 2.1 includes Dynamic Weighting, which allows for the values used to vary by the value of the Context OU (org_unit). This also allows for the grp and org_unit fields to be less important than other fields for ordering purposes. In addition, in the event of a tie, 2.1+ does a final sort on the rule ID number, to ensure consistent sorting. =====Rule Migration===== ====To 2.0==== Migrating from 1.6 to 2.0 is a matter of doing nothing. All previous rules should function exactly as they did before, and you can begin to take advantage of the new fields available in 2.0. ====To 2.1+==== Migrating from Pre-2.1 to 2.1+ may result in different results in some cases due to the addition of fallthrough. While all your Pre-2.1 rules will include the circulate, duration_rule, recurring_fine_rule, and max_fine_rule values they may not contain hard_due_date, total_copy_hold_ratio, and available_copy_hold_ratio. If you are using these values in your Pre-2.1 rules at all then fallthrough may cause them to be applied where you do not want them to be. There are two quick solutions to this problem: - For total_copy_hold_ratio and available_copy_hold_ratio you can set them to 0 for all matchpoints they are not set in. A value of 0 effectively disables them. - For hard_due_date you can create a dummy hard due date value (Such as "None") with a date in the past (such as 1970-1-31). Hard due dates in the past return to using the duration rule.