From 94aa4f60f9d60f85cb6bd7e49d776055026ade5c Mon Sep 17 00:00:00 2001 From: erickson Date: Mon, 12 Mar 2007 00:20:19 +0000 Subject: [PATCH] moved the PINES-specific circ rules over to the Evergreen tree git-svn-id: svn://svn.open-ils.org/ILS/trunk@7054 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- Evergreen/Makefile | 2 +- .../javascript/backend/circ/circ_duration.js | 83 +++ .../javascript/backend/circ/circ_groups.js | 114 ++++ .../backend/circ/circ_item_config.js | 487 ++++++++++++++++++ .../backend/circ/circ_permit_copy.js | 30 ++ .../backend/circ/circ_permit_hold.js | 106 ++++ .../backend/circ/circ_permit_patron.js | 36 ++ .../backend/circ/circ_permit_renew.js | 15 + 8 files changed, 872 insertions(+), 1 deletion(-) create mode 100644 Evergreen/src/javascript/backend/circ/circ_duration.js create mode 100644 Evergreen/src/javascript/backend/circ/circ_groups.js create mode 100644 Evergreen/src/javascript/backend/circ/circ_item_config.js create mode 100644 Evergreen/src/javascript/backend/circ/circ_permit_copy.js create mode 100644 Evergreen/src/javascript/backend/circ/circ_permit_hold.js create mode 100644 Evergreen/src/javascript/backend/circ/circ_permit_patron.js create mode 100644 Evergreen/src/javascript/backend/circ/circ_permit_renew.js diff --git a/Evergreen/Makefile b/Evergreen/Makefile index 2d32fa7703..e326d715e3 100644 --- a/Evergreen/Makefile +++ b/Evergreen/Makefile @@ -34,7 +34,7 @@ perl-install: circ-install: @echo $@ mkdir -p $(CIRCRULESDIR) - cp circ_rules/*.rules $(CIRCRULESDIR)/ + cp src/javascript/backend/circ/*.js $(CIRCRULESDIR) iplist-install: @echo $@ diff --git a/Evergreen/src/javascript/backend/circ/circ_duration.js b/Evergreen/src/javascript/backend/circ/circ_duration.js new file mode 100644 index 0000000000..9c3892249a --- /dev/null +++ b/Evergreen/src/javascript/backend/circ/circ_duration.js @@ -0,0 +1,83 @@ +function go(){ + +load_lib('circ/circ_item_config.js'); +log_vars('circ_duration'); + + +/* treat pre-cat copies like vanilla books */ +if( isTrue(isPrecat) ) { + log_info("pre-cat copy getting duration defaults..."); + result.durationRule = '14_days_2_renew'; + result.recurringFinesRule = '10_cent_per_day'; + result.maxFine = 'overdue_mid'; + checkDurationExceptions(); + return; +} + + +/* grab the config from the config script */ +var config = getItemConfig(); +var itemForm = (marcXMLDoc) ? extractFixedField(marcXMLDoc,'Form') : ""; + + +/* ----------------------------------------------------------------------------- + Now set the rule values based on the config. If there is no configured info + on this copy, fall back on defaults. + ----------------------------------------------------------------------------- */ +if( config ) { + + log_debug("circ_duration found a config for the copy"); + result.durationRule = config.durationRule; + result.recurringFinesRule = config.recurringFinesRule; + result.maxFine = config.maxFine; + +} else { + + result.durationRule = '14_days_2_renew'; + result.recurringFinesRule = "10_cent_per_day"; + result.maxFine = "overdue_mid"; +} + + + +/* ----------------------------------------------------------------------------- + Add custom rules here. + ----------------------------------------------------------------------------- */ + +var circMod = (copy.circ_modifier) ? copy.circ_modifier.toLowerCase() : ''; + +if( isOrgDescendent('STATELIB', copy.circ_lib.id) ) { + if( circMod == 'book' ) + result.durationRule = '35_days_1_renew'; + if(isTrue(copy.ref)) + result.durationRule = '14_days_2_renew'; + +} else if( isOrgDescendent('NCLS', copy.circ_lib.id) && ( circMod == 'dvd' || circMod == 'video' ) ) + result.recurringFinesRule = '10_cent_per_day'; + + +checkDurationExceptions(); + +log_info('final duration results: ' + result.durationRule + ' : ' + result.recurringFinesRule + ' : ' + result.maxFine ); + +} go(); + + + +function checkDurationExceptions() { + log_debug("Checking duration rule exceptions for profile "+patronProfile); + + if( isGroupDescendant('Staff', patronProfile) || + isGroupDescendant('Trustee', patronProfile) || + isGroupDescendant('Outreach', patronProfile) ) { + + result.recurringFinesRule = "staff"; + result.maxFine = "staff"; + } + + if( isGroupDescendant('Outreach', patronProfile) ) { + log_info("Outreach user found, setting duration to 2 months"); + result.durationRule = '2_months_2_renew'; + } +} + diff --git a/Evergreen/src/javascript/backend/circ/circ_groups.js b/Evergreen/src/javascript/backend/circ/circ_groups.js new file mode 100644 index 0000000000..6fc2bf1149 --- /dev/null +++ b/Evergreen/src/javascript/backend/circ/circ_groups.js @@ -0,0 +1,114 @@ +/* --------------------------------------------------------------------- + Set up the limits for the various profiles (aka permission groups). + Values of -1 mean there is no limit + + maxItemsOut - the maximum number of items the user can have out + fineThreshold - the fine threshold. + overdueThreshold - the overdue items threshold. + maxHolds - The maximum number of holds the user can have + + A user exceeds the fineThreshold and/or overdueThreshold if they are + equal to or exceed the threshold + --------------------------------------------------------------------- */ + +var GROUP_CONFIG = { + + 'Patron' : { + maxItemsOut : 50, + fineThreshold : 10, + overdueThreshold : 10, + maxHolds : -1 + }, + + 'Class' : { + maxItemsOut : 50, + fineThreshold : 10, + overdueThreshold : 10, + maxHolds : 15 + }, + + 'Friend' : { + maxItemsOut : 50, + fineThreshold : 10, + overdueThreshold : 10, + maxHolds : -1 + }, + + 'NonResident' : { + maxItemsOut : 50, + fineThreshold : 10, + overdueThreshold : 10, + maxHolds : -1 + }, + + 'OutOfState' : { + maxItemsOut : 50, + fineThreshold : 10, + overdueThreshold : 10, + maxHolds : -1 + }, + + 'Outreach' : { + maxItemsOut : -1, + fineThreshold : -1, + overdueThreshold : -1, + maxHolds : 15 + }, + + + 'Restricted' : { + maxItemsOut : 2, + fineThreshold : 0.01, + overdueThreshold : 1, + maxHolds : 5 + }, + + 'Temp' : { + maxItemsOut : 5, + fineThreshold : .01, + overdueThreshold : 1, + maxHolds : 5 + }, + + 'TempRes6' : { + maxItemsOut : 50, + fineThreshold : 10, + overdueThreshold : 10, + maxHolds : -1 + }, + + 'tempRes12' : { + maxItemsOut : 50, + fineThreshold : 10, + overdueThreshold : 10, + maxHolds : -1 + }, + + 'Trustee' : { + maxItemsOut : 50, + fineThreshold : 10, + overdueThreshold : 10, + maxHolds : 10 + }, + + + 'Vendor' : { + maxItemsOut : 0, + fineThreshold : 0.01, + overdueThreshold : 1, + maxHolds : 0 + }, + + 'Staff' : { + maxItemsOut : 50, + fineThreshold : -1, + overdueThreshold : -1, + maxHolds : -1 + }, + +}; + + + + + diff --git a/Evergreen/src/javascript/backend/circ/circ_item_config.js b/Evergreen/src/javascript/backend/circ/circ_item_config.js new file mode 100644 index 0000000000..87207f06b6 --- /dev/null +++ b/Evergreen/src/javascript/backend/circ/circ_item_config.js @@ -0,0 +1,487 @@ +load_lib('circ/circ_lib.js'); +log_debug('loading circ_item_config.js ...'); + + +/* SIP media types +000 Other +001 Book +002 Magazine +003 Bound journal +004 Audio tape +005 Video tape +006 CD/CDROM +007 Diskette +008 Book with diskette +009 Book with CD +010 Book with audio tape +*/ + +/* ----------------------------------------------------------------------------- + Configure the duration rules for the various item types and circ modifiers + + MARC Fixed Field info: + http://www.oclc.org/bibformats/en/fixedfield/ + + ----------------------------------------------------------------------------- */ + +var MARC_ITEM_TYPE_MAP = { + + a : { /* Language material [Books] */ + SIPMediaType : '001', + magneticMedia : 'f', + durationRule : '14_days_2_renew', + recurringFinesRule : '10_cent_per_day', + maxFine : 'overdue_mid' + }, + + t : { /* Manuscript language material [Books] */ + SIPMediaType : '001', + magneticMedia : 'f', + durationRule : '14_days_2_renew', + recurringFinesRule : '10_cent_per_day', + maxFine : 'overdue_mid' + }, + + g : { /* Projected medium [Videos, etc.] */ + SIPMediaType : '005', + magneticMedia : 'f', + durationRule : '7_days_0_renew', + recurringFinesRule : '10_cent_per_day', + maxFine : 'overdue_mid' + }, + + k : { /* Two-dimensional nonprojectable graphic [Card, charts, etc.] */ + SIPMediaType : '001', + magneticMedia : 'f', + durationRule : '3_month_0_renew', + recurringFinesRule : '10_cent_per_day', + maxFine : 'overdue_mid' + }, + + r : { /* Three-dimensional artifact or naturally occurring object [Models, games, etc.] */ + SIPMediaType : '001', + magneticMedia : 'f', + durationRule : '14_days_2_renew', + recurringFinesRule : '10_cent_per_day', + maxFine : 'overdue_mid' + }, + + o : { /* Kit [Mixture of item types] */ + SIPMediaType : '001', + magneticMedia : 'f', + durationRule : '14_days_2_renew', + recurringFinesRule : '10_cent_per_day', + maxFine : 'overdue_mid' + }, + + p : { /* Mixed materials [Mixture of item types] */ + SIPMediaType : '001', + magneticMedia : 'f', + durationRule : '14_days_2_renew', + recurringFinesRule : '10_cent_per_day', + maxFine : 'overdue_mid' + }, + + e : { /* Cartographic material [Map] */ + SIPMediaType : '001', + magneticMedia : 'f', + durationRule : '7_days_2_renew', + recurringFinesRule : '50_cent_per_day', + maxFine : 'overdue_mid' + }, + + f : { /* Manuscript cartographic material [Map] */ + SIPMediaType : '001', + magneticMedia : 'f', + durationRule : '3_days_1_renew', + recurringFinesRule : '50_cent_per_day', + maxFine : 'overdue_mid' + }, + + c : { /* Notated music [Printed music] */ + SIPMediaType : '001', + magneticMedia : 'f', + durationRule : '14_days_2_renew', + recurringFinesRule : '10_cent_per_day', + maxFine : 'overdue_mid' + }, + + d : { /* Manuscript notated music [Printed music] */ + SIPMediaType : '001', + magneticMedia : 'f', + durationRule : '14_days_2_renew', + recurringFinesRule : '10_cent_per_day', + maxFine : 'overdue_mid' + }, + + i : { /* Nonmusical sound recording [Audiobooks, sound effects, etc.] */ + SIPMediaType : '001', + magneticMedia : 'f', + durationRule : '14_days_2_renew', + recurringFinesRule : '10_cent_per_day', + maxFine : 'overdue_mid' + }, + + j : { /* Musical sound recording [Music] */ + SIPMediaType : '001', + magneticMedia : 'f', + durationRule : '14_days_2_renew', + recurringFinesRule : '10_cent_per_day', + maxFine : 'overdue_mid' + }, + + m : { /* Computer file */ + SIPMediaType : '001', + magneticMedia : 'f', + durationRule : '14_days_2_renew', + recurringFinesRule : '10_cent_per_day', + maxFine : 'overdue_mid' + } +} + + +var CIRC_MOD_MAP = { + + 'art' : { + SIPMediaType : '000', + magneticMedia : 'f', + durationRule : '3_month_1_renew', + recurringFinesRule : '10_cent_per_day', + maxFine : 'overdue_mid' + }, + + 'atlas' : { + SIPMediaType : '000', + magneticMedia : 'f', + durationRule : '7_days_2_renew', + recurringFinesRule : '50_cent_per_day', + maxFine : 'overdue_mid' + }, + + 'audiobook' : { + SIPMediaType : '004', + magneticMedia : 'f', + durationRule : '14_days_2_renew', + recurringFinesRule : '10_cent_per_day', + maxFine : 'overdue_mid' + }, + + 'av' : { + SIPMediaType : '005', + magneticMedia : 'f', + durationRule : '7_days_2_renew', + recurringFinesRule : '50_cent_per_day', + maxFine : 'overdue_mid' + }, + + 'new-av' : { + SIPMediaType : '005', + magneticMedia : 'f', + durationRule : '3_days_1_renew', + recurringFinesRule : '50_cent_per_day', + maxFine : 'overdue_mid' + }, + + 'bestseller' : { + SIPMediaType : '001', + magneticMedia : 'f', + durationRule : '7_days_2_renew', + recurringFinesRule : '50_cent_per_day', + maxFine : 'overdue_mid' + }, + + 'bestsellernh' : { + SIPMediaType : '001', + magneticMedia : 'f', + durationRule : '7_days_2_renew', + recurringFinesRule : '50_cent_per_day', + maxFine : 'overdue_mid' + }, + + 'book' : { + SIPMediaType : '001', + magneticMedia : 'f', + durationRule : '14_days_2_renew', + recurringFinesRule : '10_cent_per_day', + maxFine : 'overdue_mid' + }, + + 'cd' : { + SIPMediaType : '006', + magneticMedia : 'f', + durationRule : '14_days_2_renew', + recurringFinesRule : '10_cent_per_day', + maxFine : 'overdue_mid' + }, + + 'dvd' : { + SIPMediaType : '006', + magneticMedia : 'f', + durationRule : '7_days_0_renew', + recurringFinesRule : '50_cent_per_day', + maxFine : 'overdue_mid' + }, + + 'dvd-long' : { + SIPMediaType : '006', + magneticMedia : 'f', + durationRule : '14_days_2_renew', + recurringFinesRule : '10_cent_per_day', + maxFine : 'overdue_mid' + }, + + 'e-book' : { + SIPMediaType : '001', + magneticMedia : 'f', + durationRule : '3_days_1_renew', + recurringFinesRule : '50_cent_per_day', + maxFine : 'overdue_mid' + }, + + 'equipment' : { + SIPMediaType : '000', + magneticMedia : 'f', + durationRule : '1_day_0_renew', /* make me 1 day, 0 renewal when possible */ + recurringFinesRule : '50_cent_per_day', + maxFine : 'overdue_mid' + }, + + 'equip-long' : { + SIPMediaType : '000', + magneticMedia : 'f', + durationRule : '3_days_1_renew', + recurringFinesRule : '50_cent_per_day', + maxFine : 'overdue_mid' + }, + + 'filmstrip' : { + SIPMediaType : '000', + magneticMedia : 'f', + durationRule : '14_days_2_renew', + recurringFinesRule : '10_cent_per_day', + maxFine : 'overdue_mid' + }, + + 'kit' : { + SIPMediaType : '000', + magneticMedia : 'f', + durationRule : '14_days_2_renew', + recurringFinesRule : '10_cent_per_day', + maxFine : 'overdue_mid' + }, + + 'magazine' : { + SIPMediaType : '002', + magneticMedia : 'f', + durationRule : '14_days_2_renew', + recurringFinesRule : '10_cent_per_day', + maxFine : 'overdue_mid' + }, + + 'map' : { + SIPMediaType : '000', + magneticMedia : 'f', + durationRule : '3_days_1_renew', + recurringFinesRule : '50_cent_per_day', + maxFine : 'overdue_mid' + }, + + 'microform' : { + SIPMediaType : '000', + magneticMedia : 'f', + durationRule : '14_days_2_renew', + recurringFinesRule : '10_cent_per_day', + maxFine : 'overdue_mid' + }, + + 'music' : { + SIPMediaType : '004', + magneticMedia : 'f', + durationRule : '14_days_2_renew', + recurringFinesRule : '10_cent_per_day', + maxFine : 'overdue_mid' + }, + + 'record' : { + SIPMediaType : '000', + magneticMedia : 'f', + durationRule : '14_days_2_renew', + recurringFinesRule : '10_cent_per_day', + maxFine : 'overdue_mid' + }, + + 'software' : { + SIPMediaType : '006', + magneticMedia : 'f', + durationRule : '7_days_2_renew', + recurringFinesRule : '10_cent_per_day', + maxFine : 'overdue_mid' + }, + + 'softwrlong' : { + SIPMediaType : '006', + magneticMedia : 'f', + durationRule : '14_days_2_renew', + recurringFinesRule : '10_cent_per_day', + maxFine : 'overdue_mid' + }, + + 'talking book' : { + SIPMediaType : '006', + magneticMedia : 'f', + durationRule : 'unlimited', + }, + + 'toy' : { + SIPMediaType : '000', + magneticMedia : 'f', + durationRule : '14_days_2_renew', + recurringFinesRule : '10_cent_per_day', + maxFine : 'overdue_mid' + }, + + 'video' : { + SIPMediaType : '005', + magneticMedia : 'f', + durationRule : '7_days_0_renew', + recurringFinesRule : '50_cent_per_day', + maxFine : 'overdue_mid' + }, + + 'video-long' : { + SIPMediaType : '005', + magneticMedia : 'f', + durationRule : '14_days_2_renew', + recurringFinesRule : '10_cent_per_day', + maxFine : 'overdue_mid' + }, + + 'facbestslr' : { + SIPMediaType : '001', + magneticMedia : 'f', + durationRule : '7_days_2_renew', + recurringFinesRule : '10_cent_per_day', + maxFine : 'overdue_mid' + }, + +} + + +/* Set up rules for legacy types */ +CIRC_MOD_MAP['DEPOSIT'] = CIRC_MOD_MAP['book']; +CIRC_MOD_MAP['E-AUDIO'] = CIRC_MOD_MAP['book']; +CIRC_MOD_MAP['FACNEWBK'] = CIRC_MOD_MAP['book']; +CIRC_MOD_MAP['MAG-CIRC'] = CIRC_MOD_MAP['book']; +CIRC_MOD_MAP['MAG-NOCIRC'] = CIRC_MOD_MAP['book']; +CIRC_MOD_MAP['NEW-BOOK'] = CIRC_MOD_MAP['book']; +CIRC_MOD_MAP['NEWSPAPER'] = CIRC_MOD_MAP['book']; +CIRC_MOD_MAP['OUTREACH'] = CIRC_MOD_MAP['book']; +CIRC_MOD_MAP['PAMPHLET'] = CIRC_MOD_MAP['book']; +CIRC_MOD_MAP['PAPERBACK'] = CIRC_MOD_MAP['book']; +CIRC_MOD_MAP['RESERVE'] = CIRC_MOD_MAP['book']; +CIRC_MOD_MAP['STATE-BOOK'] = { + SIPMediaType : '001', + magneticMedia : 'f', + durationRule : '35_days_1_renew', + recurringFinesRule : "10_cent_per_day", + maxFine : "overdue_mid" +}; +CIRC_MOD_MAP['STATE-MFRM'] = { + SIPMediaType : '001', + magneticMedia : 'f', + durationRule : '14_days_2_renew', + recurringFinesRule : "10_cent_per_day", + maxFine : "overdue_mid" +}; + + + + +/* this will set defaults even if no one asked for them */ +log_debug("Calling getItemConfig() to force defaults.."); +getItemConfig(); +log_debug("getItemConfig() set magneticMedia to "+result.magneticMedia); + + +function getItemConfig() { + + /* ----------------------------------------------------------------------------------- + If a circ_modifier is defined on the copy and we have config info for the + provided circ_modifier, use that config. Otherwise fall back on the MARC item type + ----------------------------------------------------------------------------------- */ + var marcType = getMARCItemType(); + var itemForm = (marcXMLDoc) ? extractFixedField(marcXMLDoc,'Form') : ""; + //var circMod = (copy.circ_modifier) ? copy.circ_modifier.toLowerCase() : ''; + var circMod = copy.circ_modifier; + + var config = null; + + if( circMod ) { + config = CIRC_MOD_MAP[circMod]; + if(!config) + config = CIRC_MOD_MAP[circMod.toLowerCase()] + if(config) + log_info("a circ_mod config exists for the copy with mod: " + circMod); + } + + if(!config) { + /* otherwise, fall back on the MARC item type */ + if( circMod ) + log_info("no circ_mod config found for " +circMod+", falling back to MARC"); + config = MARC_ITEM_TYPE_MAP[marcType]; + } + + /* if no config could be found, default to 'book' */ + if(!config) { + log_warn("item_config found no circ_mod OR MARC config, defaulting to 'book'"); + config = CIRC_MOD_MAP['book']; + } + + config.maxFine = setMaxFineByCircLocation(); + + /* go ahead and set some default result + data (which may be overidden) */ + for( var i in config ) { + log_debug("item_config setting result defaults: "+i+" = " +config[i]); + result[i] = config[i]; + } + + return config; +} + + +function setMaxFineByCircLocation() { + var max_libs = [ 'ARL', 'DTRL', 'SJRLS' ]; + var mid_libs = [ 'CHRL', 'ECGR', 'FRRLS', 'HCLS', 'OCRL', 'OHOOP', 'OKRL', 'PMRLS', 'PPL', 'STRL' ]; + + var cl = (volume && volume.id != -1) ? volume.owning_lib : currentLocation.id; + var max_fine = null; + + for( var i = 0; i < max_libs.length; i++ ) { + var org = max_libs[i]; + if( isOrgDescendent(org, cl) ) { + log_debug("found max-fine ancestor org "+org); + max_fine = 'overdue_max'; + break; + } + } + + if(!max_fine) { + for( var i = 0; i < mid_libs.length; i++ ) { + var org = mid_libs[i]; + if( isOrgDescendent(org, cl) ) { + log_debug("found mid-fine ancestor org "+org); + max_fine = 'overdue_mid'; + break; + } + } + } + + if(!max_fine) max_fine = 'overdue_min'; + + log_info("setMaxFineByCircLocation() set max_fine to "+ max_fine); + + return max_fine; +} + + diff --git a/Evergreen/src/javascript/backend/circ/circ_permit_copy.js b/Evergreen/src/javascript/backend/circ/circ_permit_copy.js new file mode 100644 index 0000000000..edb48accf4 --- /dev/null +++ b/Evergreen/src/javascript/backend/circ/circ_permit_copy.js @@ -0,0 +1,30 @@ +function go() { + +/* load the lib script */ +load_lib('circ/circ_lib.js'); +log_vars('circ_permit_copy'); + + +if( ! isTrue(copy.circulate) ) + result.events.push('COPY_CIRC_NOT_ALLOWED'); + + +if( ! isOrgDescendent( 'STATELIB', copy.circ_lib.id ) ) { + if( isTrue(copy.ref) ) + result.events.push('COPY_IS_REFERENCE'); +} + + + +if( ! isTrue(isRenewal) ) { + if(copyStatus != 'Available' && + copyStatus != 'On holds shelf' && copyStatus != 'Reshelving' ) { + result.events.push('COPY_NOT_AVAILABLE'); + } +} + + + +} go(); + + diff --git a/Evergreen/src/javascript/backend/circ/circ_permit_hold.js b/Evergreen/src/javascript/backend/circ/circ_permit_hold.js new file mode 100644 index 0000000000..41e3374a72 --- /dev/null +++ b/Evergreen/src/javascript/backend/circ/circ_permit_hold.js @@ -0,0 +1,106 @@ +function go() { + +load_lib('circ/circ_lib.js'); +log_vars('circ_permit_hold'); + + +/* is a staff member placing this hold? */ +var isStaffHold = isGroupDescendant('Staff', patronProfile); + + +/* non-staff members are allowed 50 open holds at most */ +if( ! isStaffHold ) { + var count = userHoldCount(patron.id); + log_info("patron has " + count + " open holds"); + if( count >= 50 ) + result.events.push('MAX_HOLDS'); +} + + +if( isTrue(patron.barred) ) + result.events.push('PATRON_BARRED'); + +if( isTrue(copy.ref) ) + result.events.push('ITEM_NOT_HOLDABLE'); + +if( !isTrue(copy.circulate) ) + result.events.push('ITEM_NOT_HOLDABLE'); + +/* all STATELIB items are holdable regardless of type */ +if( isOrgDescendent('STATELIB', copy.circ_lib.id) ) return; + + +var mod = (copy.circ_modifier) ? copy.circ_modifier.toLowerCase() : ""; +var marcItemType = getMARCItemType(); + + +log_info("circ-modifier = "+mod); +log_info("marc-type = "+marcItemType); + + +if( mod == 'bestsellernh' ) + result.events.push('ITEM_NOT_HOLDABLE'); + + +if( ( marcItemType == 'g' || + marcItemType == 'i' || + marcItemType == 'j' || + mod == 'softwrlong' || + mod == 'music' || + mod == 'audiobook' || + mod == 'av' || + mod == 'new-av' || + mod == 'cd' || + mod == 'kit' || + mod == 'dvd' || + mod == 'deposit' || + mod == 'atlas' || + mod == 'magazine' || + mod == 'equipment' || + mod == 'equip-long' || + mod == 'microform' || + mod == 'record' || + isTrue(copy.deposit) || + mod == 'video-long' || + mod == 'video' ) ) { + + + log_info("this is a range-protected item..."); + + if( ! hasCommonAncestor( volume.owning_lib, holdPickupLib, 1 ) ) { + + /* we don't want these items to transit to the pickup lib */ + result.events.push('ITEM_NOT_HOLDABLE'); + log_info("pickup_lib is not in the owning_lib's region...NOT OK"); + + } else { /* pickup lib is in the owning region */ + + if( isStaffHold && hasCommonAncestor( volume.owning_lib, holdRequestLib.id, 1) ) { + + /* staff in the region can place holds for patrons outside the region with local pickup lib */ + log_info("local, staff-placed hold is allowed with local pickup_lib...OK"); + + } else { + + if( hasCommonAncestor( volume.owning_lib, patron.home_ou.id, 1 ) ) { + + /* patrons can hold the item if they are registered + in the region and pickup lib is local */ + log_info("patron's home_ou is in the owning region...OK"); + + } else { + + log_info("patron's home_ou lies outside the owning region...NOT OK"); + result.events.push('ITEM_NOT_HOLDABLE'); + } + } + } +} + + + + +} go(); + + + diff --git a/Evergreen/src/javascript/backend/circ/circ_permit_patron.js b/Evergreen/src/javascript/backend/circ/circ_permit_patron.js new file mode 100644 index 0000000000..8b8cd43246 --- /dev/null +++ b/Evergreen/src/javascript/backend/circ/circ_permit_patron.js @@ -0,0 +1,36 @@ +function go() { + +/* load the script library */ +load_lib('circ/circ_lib.js'); +log_vars('circ_permit_patron'); + + + +if( isTrue(patron.barred) ) + result.events.push('PATRON_BARRED'); + + +/* --------------------------------------------------------------------- + Check the items out count + --------------------------------------------------------------------- */ +var config = findGroupConfig(patronProfile); +if( config ) { + + var limit = config.maxItemsOut; + if( limit >= 0 ) { + /* Patrons are allowed to renew regardless + of how many items they have checked out */ + log_info('patron items out = ' + patronItemsOut +' limit = ' + limit); + if( !isTrue(isRenewal) && patronItemsOut >= limit ) { + result.events.push('PATRON_EXCEEDS_CHECKOUT_COUNT'); + } + } + +} else { + log_warn("** profile has no configured information: " + patronProfile); +} + + +} go(); + + diff --git a/Evergreen/src/javascript/backend/circ/circ_permit_renew.js b/Evergreen/src/javascript/backend/circ/circ_permit_renew.js new file mode 100644 index 0000000000..7f61d923d3 --- /dev/null +++ b/Evergreen/src/javascript/backend/circ/circ_permit_renew.js @@ -0,0 +1,15 @@ +function go() { + +/* load the lib script */ +load_lib('circ/circ_lib.js'); +log_vars('circ_permit_renew'); + +log_info("permit_renew searching for potential holds for copy " + copy.barcode) +var hold = copy.fetchBestHold(); +if( hold ) { + log_info("hold found for renewal item, checking hold->usr.."); + if( hold && hold.usr != patron.id ) + return result.events.push('COPY_NEEDED_FOR_HOLD'); +} + +} go(); -- 2.43.2