moved the PINES-specific circ rules over to the Evergreen tree
authorerickson <erickson@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Mon, 12 Mar 2007 00:20:19 +0000 (00:20 +0000)
committererickson <erickson@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Mon, 12 Mar 2007 00:20:19 +0000 (00:20 +0000)
git-svn-id: svn://svn.open-ils.org/ILS/trunk@7054 dcc99617-32d9-48b4-a31d-7c20da2025e4

Evergreen/Makefile
Evergreen/src/javascript/backend/circ/circ_duration.js [new file with mode: 0644]
Evergreen/src/javascript/backend/circ/circ_groups.js [new file with mode: 0644]
Evergreen/src/javascript/backend/circ/circ_item_config.js [new file with mode: 0644]
Evergreen/src/javascript/backend/circ/circ_permit_copy.js [new file with mode: 0644]
Evergreen/src/javascript/backend/circ/circ_permit_hold.js [new file with mode: 0644]
Evergreen/src/javascript/backend/circ/circ_permit_patron.js [new file with mode: 0644]
Evergreen/src/javascript/backend/circ/circ_permit_renew.js [new file with mode: 0644]

index 2d32fa7..e326d71 100644 (file)
@@ -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 (file)
index 0000000..9c38922
--- /dev/null
@@ -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 (file)
index 0000000..6fc2bf1
--- /dev/null
@@ -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 (file)
index 0000000..87207f0
--- /dev/null
@@ -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 (file)
index 0000000..edb48ac
--- /dev/null
@@ -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 (file)
index 0000000..41e3374
--- /dev/null
@@ -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 (file)
index 0000000..8b8cd43
--- /dev/null
@@ -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 (file)
index 0000000..7f61d92
--- /dev/null
@@ -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();