Track Conifer JavaScript circulation rules
authorDan Scott <dan@coffeecode.net>
Mon, 30 May 2011 02:18:04 +0000 (22:18 -0400)
committerDan Scott <dscott@laurentian.ca>
Sun, 7 Dec 2014 21:35:19 +0000 (16:35 -0500)
Signed-off-by: Dan Scott <dscott@laurentian.ca>
16 files changed:
Open-ILS/src/javascript/backend/circ/circ_duration.js [changed mode: 0644->0755]
Open-ILS/src/javascript/backend/circ/circ_duration_CRC.js [new symlink]
Open-ILS/src/javascript/backend/circ/circ_duration_HUNTINGTON.js [new symlink]
Open-ILS/src/javascript/backend/circ/circ_duration_MRC.js [new symlink]
Open-ILS/src/javascript/backend/circ/circ_duration_NOSME.js [new file with mode: 0644]
Open-ILS/src/javascript/backend/circ/circ_duration_NOSMW.js [new file with mode: 0644]
Open-ILS/src/javascript/backend/circ/circ_duration_OSM.js [new file with mode: 0644]
Open-ILS/src/javascript/backend/circ/circ_duration_OSTMA.js [new file with mode: 0644]
Open-ILS/src/javascript/backend/circ/circ_duration_OSUL.js [new file with mode: 0644]
Open-ILS/src/javascript/backend/circ/circ_duration_OWA.js [new file with mode: 0644]
Open-ILS/src/javascript/backend/circ/circ_duration_OWAL.js [new file with mode: 0644]
Open-ILS/src/javascript/backend/circ/circ_duration_SUDBURY.js [new symlink]
Open-ILS/src/javascript/backend/circ/circ_groups.js [changed mode: 0644->0755]
Open-ILS/src/javascript/backend/circ/circ_lib.js
Open-ILS/src/javascript/backend/circ/circ_permit_copy.js
Open-ILS/src/javascript/backend/circ/circ_permit_patron.js [changed mode: 0644->0755]

old mode 100644 (file)
new mode 100755 (executable)
index 6f6a3d4..bfcd1f8
@@ -4,10 +4,34 @@ load_lib('circ/circ_item_config.js');
 load_lib('JSON_v1.js');
 log_vars('circ_duration');
 
+/*
+var currentTime = new Date();
+var debugStamp = "circ" + (currentTime.getMonth() + 1) + "" +
+       "" + currentTime.getDate() + "" + currentTime.getFullYear() +
+       ": ";
+*/
+
+
+//log_info(debugStamp + "copy location identified as " + copy.circ_lib.shortname);
+
+try {   
+       /* load circ rules for specific institutions based on the library that owns the copy */
+       var circ_duration_institution_file = 'circ/circ_duration_' + copy.circ_lib.shortname + '.js';
+       log_info('loading ' + circ_duration_institution_file);
+       load_lib(circ_duration_institution_file);
+
+       // log_error(circ_duration_institution_file);
+
+       /* if an institution specific script was loaded, then stop */
+       if (result.durationRule) return;
+} catch (e) {
+       // fall through to system-wide defaults
+       log_info("error loading " + e);
+}
 
 /* treat pre-cat copies like vanilla books */
 if( isTrue(isPrecat) ) {
-       log_info("pre-cat copy getting duration defaults...");
+       //log_info("pre-cat copy getting duration defaults...");
        result.durationRule                     = 'default';
        result.recurringFinesRule       = 'default';
        result.maxFine                          = 'default'
@@ -26,24 +50,37 @@ var itemForm        = (marcXMLDoc) ? extractFixedField(marcXMLDoc,'Form') : "";
        ----------------------------------------------------------------------------- */
 if( config ) {
 
+       //log_info("config exists");
        log_debug("circ_duration found a config for the copy");
        result.durationRule                     = config.durationRule;
        result.recurringFinesRule       = config.recurringFinesRule;
        result.maxFine                      = config.maxFine;
 
 } else {
+       //log_info("falling back to default");
 
        result.durationRule = 'default';
        result.recurringFinesRule = 'default';
        result.maxFine = 'default';
 }
 
+if (patronProfile == 'Faculty') {
+       result.durationRule = '120_days_2_renew';
+}
+if (patronProfile == 'Graduate') {
+       result.durationRule = '120_days_2_renew';
+}
+if (patronProfile == 'Undergraduate') {
+       result.durationRule = '3_weeks_2_renew';
+}
+if (patronProfile == 'Staff members') {
+       result.durationRule = '3_weeks_2_renew';
+}
+if (patronProfile == 'Readers' || patronProfile == 'Alumni' || patronProfile == 'College Students' || patronProfile == 'High School Students') {
+       result.durationRule = '3_weeks_2_renew';
+}
 
 log_info('final duration results: ' + 
     result.durationRule + ' : ' + result.recurringFinesRule + ' : ' + result.maxFine );
 
 } go();
-
-
-
-
diff --git a/Open-ILS/src/javascript/backend/circ/circ_duration_CRC.js b/Open-ILS/src/javascript/backend/circ/circ_duration_CRC.js
new file mode 120000 (symlink)
index 0000000..e54bfe1
--- /dev/null
@@ -0,0 +1 @@
+circ_duration_OSUL.js
\ No newline at end of file
diff --git a/Open-ILS/src/javascript/backend/circ/circ_duration_HUNTINGTON.js b/Open-ILS/src/javascript/backend/circ/circ_duration_HUNTINGTON.js
new file mode 120000 (symlink)
index 0000000..e54bfe1
--- /dev/null
@@ -0,0 +1 @@
+circ_duration_OSUL.js
\ No newline at end of file
diff --git a/Open-ILS/src/javascript/backend/circ/circ_duration_MRC.js b/Open-ILS/src/javascript/backend/circ/circ_duration_MRC.js
new file mode 120000 (symlink)
index 0000000..e54bfe1
--- /dev/null
@@ -0,0 +1 @@
+circ_duration_OSUL.js
\ No newline at end of file
diff --git a/Open-ILS/src/javascript/backend/circ/circ_duration_NOSME.js b/Open-ILS/src/javascript/backend/circ/circ_duration_NOSME.js
new file mode 100644 (file)
index 0000000..08b3272
--- /dev/null
@@ -0,0 +1,16 @@
+/* grab the config from the config script */
+var config = getItemConfig();
+var itemForm    = (marcXMLDoc) ? extractFixedField(marcXMLDoc,'Form') : "";
+
+/* Set the defaults for books and equipment for most patron types */
+result.durationRule = '6_weeks_3_renew';
+result.recurringFinesRule = 'NOSM_daily';
+result.maxFine = 'NOSM_daily';
+
+if (copy.circ_modifier == 'RESERVE 4 HOUR') {
+        result.durationRule = '4_hours_3_renew';
+}
+
+if (copy.circ_modifier == 'RESERVE 1 DAY') {
+        result.durationRule = '1_day_3_renew';
+}
diff --git a/Open-ILS/src/javascript/backend/circ/circ_duration_NOSMW.js b/Open-ILS/src/javascript/backend/circ/circ_duration_NOSMW.js
new file mode 100644 (file)
index 0000000..08b3272
--- /dev/null
@@ -0,0 +1,16 @@
+/* grab the config from the config script */
+var config = getItemConfig();
+var itemForm    = (marcXMLDoc) ? extractFixedField(marcXMLDoc,'Form') : "";
+
+/* Set the defaults for books and equipment for most patron types */
+result.durationRule = '6_weeks_3_renew';
+result.recurringFinesRule = 'NOSM_daily';
+result.maxFine = 'NOSM_daily';
+
+if (copy.circ_modifier == 'RESERVE 4 HOUR') {
+        result.durationRule = '4_hours_3_renew';
+}
+
+if (copy.circ_modifier == 'RESERVE 1 DAY') {
+        result.durationRule = '1_day_3_renew';
+}
diff --git a/Open-ILS/src/javascript/backend/circ/circ_duration_OSM.js b/Open-ILS/src/javascript/backend/circ/circ_duration_OSM.js
new file mode 100644 (file)
index 0000000..08b3272
--- /dev/null
@@ -0,0 +1,16 @@
+/* grab the config from the config script */
+var config = getItemConfig();
+var itemForm    = (marcXMLDoc) ? extractFixedField(marcXMLDoc,'Form') : "";
+
+/* Set the defaults for books and equipment for most patron types */
+result.durationRule = '6_weeks_3_renew';
+result.recurringFinesRule = 'NOSM_daily';
+result.maxFine = 'NOSM_daily';
+
+if (copy.circ_modifier == 'RESERVE 4 HOUR') {
+        result.durationRule = '4_hours_3_renew';
+}
+
+if (copy.circ_modifier == 'RESERVE 1 DAY') {
+        result.durationRule = '1_day_3_renew';
+}
diff --git a/Open-ILS/src/javascript/backend/circ/circ_duration_OSTMA.js b/Open-ILS/src/javascript/backend/circ/circ_duration_OSTMA.js
new file mode 100644 (file)
index 0000000..7b9c26c
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+var currentTime = new Date();
+var debugStamp = "circ_duraction_test" + (currentTime.getMonth() + 1) + "" +
+        "" + currentTime.getDate() + "" + currentTime.getFullYear() +
+        ": ";
+*/
+
+log_info("here for OSTMA");
+
+/* grab the config from the config script */
+var config = getItemConfig();
+var itemForm    = (marcXMLDoc) ? extractFixedField(marcXMLDoc,'Form') : "";
+
+
+/* Set the defaults for books for most patron types */
+result.durationRule = '3_weeks_2_renew';                       
+result.recurringFinesRule = '50_cent_per_day';
+result.maxFine = '10_dollars';
+
+
+/*Set the exceptions for regular books*/
+/* FACULTY */
+if (patronProfile == 'Faculty'){
+       result.durationRule = '120_days_0_renew';               
+}
+
+/*Set exceptions for other materials*/
+
+/* AV MATERIALS */
+if (copy.circ_modifier == 'AUDIO' ||
+    copy.circ_modifier == 'VIDEO' ||
+    copy.circ_modifer == 'DVD VIDEO' ||
+    copy.location.name == 'ALGO-AV' &&
+    patronProfile == 'Faculty'
+    
+   ){
+
+       result.durationRule = '14_days_0_renew';                                        
+       result.recurringFinesRule = '2_dollars_per_day';
+       result.maxFine = '25_dollars';  
+}
+
+/* RESERVES */
+/* Reserve items - let's use regular expressions to save some pain */
+res_day_re = /^RESERVE (\d+) DAY$/;
+res_hour_re = /^RESERVE (\d+) HOUR$/;
+res_day_match = res_day_re.exec(copy.circ_modifier);
+res_hour_match = res_hour_re.exec(copy.circ_modifier);
+if (res_day_match) {
+       result.durationRule = res_day_match[1] + '_days_0_renew';
+       result.recurringFinesRule = '2_dollars_per_day';
+       result.maxFine = '15_dollars';
+} else if (res_hour_match) {
+       result.durationRule = res_hour_match[1] + '_hours_0_renew';
+       result.recurringFinesRule = '50_cent_per_hour';
+       result.maxFine = '15_dollars';
+}
+
+
+
+
+
+
+
diff --git a/Open-ILS/src/javascript/backend/circ/circ_duration_OSUL.js b/Open-ILS/src/javascript/backend/circ/circ_duration_OSUL.js
new file mode 100644 (file)
index 0000000..4e8d281
--- /dev/null
@@ -0,0 +1,63 @@
+/* grab the config from the config script */
+var config = getItemConfig();
+var itemForm    = (marcXMLDoc) ? extractFixedField(marcXMLDoc,'Form') : "";
+
+/* Set the defaults for books for most patron types */
+result.durationRule = '3_weeks_3_renew';
+result.recurringFinesRule = 'OSUL_daily';
+result.maxFine = 'OSUL_daily';
+
+if (patronProfile == 'Faculty' || 
+    patronProfile == 'Graduate') {
+       result.durationRule = '120_days_1_renew';
+}
+
+/* Distance education laptops */
+if (copy.circ_modifier == 'COMPUTER LONG') {
+        result.durationRule = 'OSUL_computer_long';
+        result.recurringFinesRule = 'OSUL_computer';
+        result.maxFine = 'overdue_equip_max';
+}
+
+/* Short term laptops */
+if (copy.circ_modifier == 'COMPUTER SHORT') {
+        result.durationRule = '4_hours_0_renew';
+        result.recurringFinesRule = 'OSUL_computer';
+        result.maxFine = 'overdue_equip_max';
+}
+
+/* Study room keys */
+if (copy.circ_modifier == 'KEYS') {
+        result.durationRule = '3_hours_1_renew';
+        result.recurringFinesRule = 'OSUL_hourly';
+       result.maxFine = 'OSUL_hourly';
+}
+
+/* Reserve items - let's use regular expressions to save some pain */
+res_day_re = /^RESERVE (\d+) DAY$/;
+res_hour_re = /^RESERVE (\d+) HOUR$/;
+res_day_match = res_day_re.exec(copy.circ_modifier);
+res_hour_match = res_hour_re.exec(copy.circ_modifier);
+if (res_day_match) {
+       result.durationRule = res_day_match[1] + '_days_0_renew';
+       result.recurringFinesRule = 'OSUL_reserves_daily';
+       result.maxFine = 'OSUL_reserves';
+} else if (res_hour_match) {
+       result.durationRule = res_hour_match[1] + '_hours_0_renew';
+       result.recurringFinesRule = 'OSUL_hourly';
+       result.maxFine = 'OSUL_reserves';
+}
+
+/* RACER books */
+if (copy.circ_modifier == 'PEB-LIVRE') {
+        result.durationRule = '14_days_0_renew';
+        result.recurringFinesRule = '1_dollar_per_day';
+       result.maxFine = 'INFINITY_AND_BEYOND';
+}
+
+/* VIDEO recordings */
+if (copy.circ_modifier == 'VIDEO') {
+        result.durationRule = '3_days_0_renew';
+        result.recurringFinesRule = '1_dollar_per_day';
+       result.maxFine = 'OSUL_reserves';
+}
diff --git a/Open-ILS/src/javascript/backend/circ/circ_duration_OWA.js b/Open-ILS/src/javascript/backend/circ/circ_duration_OWA.js
new file mode 100644 (file)
index 0000000..883e833
--- /dev/null
@@ -0,0 +1,99 @@
+// circ duration rules for Windsor Leddy (OWA)
+
+/* we use a date based identifier to pick up values in the log */
+/*
+var currentTime = new Date();
+var debugStamp = "circ" + (currentTime.getMonth() + 1) + "" +
+        "" + currentTime.getDate() + "" + currentTime.getFullYear() +
+        ": ";
+*/
+
+/* set item type defaults - if the either the patron group or the circ modifier
+   is missing or invalid, these settings will be used */
+
+// do these first two have any significance for us?
+result.SIPMediaType = '001';
+result.magneticMedia = 'f';
+
+/* if result.durationRule is not modified for a patron group, set default
+ * this value will be used for all circ overrides! */
+result.durationRule = 'non_circ';
+
+// for fines, set the most common value here
+result.recurringFinesRule = 'OWA_daily';
+result.maxFine = 'OWA_normal';
+
+/* adjust rules by patron group and circ modifier */
+
+log_info('patronProfile is ' + patronProfile + ' - modifier ' + copy.circ_modifier);
+
+if (isValidPatron(patronProfile)) {
+    var temp_array = patronProfile.split(" ");
+    var profileFirst = temp_array[0];
+    
+    switch(copy.circ_modifier) {
+        case 'CD MUSIC':
+            result.durationRule = 'OWA_audiovisual';
+            break;
+        case 'CIRC':
+            result.durationRule = 'OWA_' + profileFirst;
+            break;
+        case 'CIRC SHORT':
+            result.durationRule = 'OWA_short';
+            result.recurringFinesRule = 'OWA_daily_short';
+            result.maxFine = 'OWA_short';
+            break;
+        case 'CRC MEDIA':
+            result.durationRule = 'OWA_sevenday';
+            break;
+        case 'CRC SPEC':
+            result.durationRule = 'OWA_' + profileFirst;
+            break;
+        case 'CRC TEXT':
+            result.durationRule = 'OWA_' + profileFirst;
+            break;
+        case 'DOC':
+            result.durationRule = 'OWA_' + profileFirst;
+            break;
+        case 'DVD VIDEO':
+            result.durationRule = 'OWA_audiovisual';
+            break;
+        case 'MEDIA':
+            result.durationRule = 'OWA_' + profileFirst;
+            break;
+        case 'MFORM':
+            result.durationRule = 'OWA_' + profileFirst;
+            break;
+        case 'REF':
+            result.durationRule = 'OWA_sevenday';
+            break;
+        case 'RSV1':
+            result.durationRule = 'OWA_rsv_oneday';
+            result.recurringFinesRule = 'OWA_daily_rsv';
+            result.maxFine = 'OWA_rsv';
+            break;
+        case 'RSV2':
+            result.durationRule = 'OWA_rsv_twohour';
+            result.recurringFinesRule = 'OWA_hourly_rsv';
+            result.maxFine = 'OWA_rsv';
+            break;
+        case 'RSV3':
+            result.durationRule = 'OWA_rsv_threeday';
+            result.recurringFinesRule = 'OWA_daily_rsv';
+            result.maxFine = 'OWA_rsv';
+            break;
+        case 'RSV7':
+            result.durationRule = 'OWA_rsv_sevenday';
+            result.recurringFinesRule = 'OWA_daily_rsv';
+            result.maxFine = 'OWA_rsv';
+            break;
+        case 'SER':
+            result.durationRule = 'OWA_serials';
+            result.recurringFinesRule = 'OWA_daily_serials';
+            break;
+        case 'THESIS':
+            result.durationRule = 'OWA_' + profileFirst;
+            break;
+    }
+}
+log_info("circ0814 - results: " + result.durationRule);
diff --git a/Open-ILS/src/javascript/backend/circ/circ_duration_OWAL.js b/Open-ILS/src/javascript/backend/circ/circ_duration_OWAL.js
new file mode 100644 (file)
index 0000000..50a0d50
--- /dev/null
@@ -0,0 +1,80 @@
+// circ duration rules for Windsor Law (OWAL)
+
+/* we use a date based identifier to pick up values in the log */
+/*
+var currentTime = new Date();
+var debugStamp = "circ" + (currentTime.getMonth() + 1) + "" +
+        "" + currentTime.getDate() + "" + currentTime.getFullYear() +
+        ": ";
+*/
+
+/* set item type defaults - if the either the patron group or the circ modifier
+ * is missing or invalid, these settings will be used */
+
+// do these first two have any significance for us?
+result.SIPMediaType = '001';
+result.magneticMedia = 'f';
+
+/* if result.durationRule is not modified for a patron group, set default
+ * this value will be used for all circ overrides! */
+result.durationRule = 'non_circ';
+
+// for fines, set the most common value here
+result.recurringFinesRule = 'OWAL_daily';
+result.maxFine = 'OWAL_normal';
+
+/* adjust rules by patron group and circ modifier */
+
+log_info('patronProfile is ' + patronProfile + ' - modifier ' + copy.circ_modifier);
+
+if (isValidPatron(patronProfile)) {
+    var temp_array = patronProfile.split(" ");
+    var profileFirst = temp_array[0];
+
+    if ((patronProfile == 'Readers' || patronProfile == 'Alumni' || patronProfile == 'College Students' || patronProfile == 'High School Students') && patron.home_ou.shortname != 'OWAL') {
+        // use override value - Non-Law Readers can borrow nothing
+    } else if ((patronProfile == 'Readers' || patronProfile == 'Alumni' || patronProfile == 'College Students' || patronProfile == 'High School Students') && copy.circ_modifier == 'LAW_MONO') {
+        result.durationRule = 'OWAL_' + profileFirst;  // Law Readers can only borrow LAW_MONO items
+    } else {
+        switch(copy.circ_modifier) {
+            case 'LAW MONO':
+                result.durationRule = 'OWAL_' + profileFirst;
+                break;
+            case 'LAW NOCIRC':
+                // use override value
+                break;
+            case 'LAW RES1D':
+                result.durationRule = 'OWAL_rsv_oneday';
+                result.recurringFinesRule = 'OWAL_hourly';
+                break;
+            case 'LAW RES3D':
+                result.durationRule = 'OWAL_rsv_threeday';
+                result.recurringFinesRule = 'OWAL_hourly';
+                break;
+            case 'LAW RES3H':
+                result.durationRule = 'OWAL_rsv_threehour';
+                result.recurringFinesRule = 'OWAL_hourly';
+                break;
+            case 'LAW RES5H':
+                result.durationRule = 'OWAL_rsv_fivehour';
+                result.recurringFinesRule = 'OWAL_hourly';
+                break;
+            case 'LAW SERIAL':
+                // Faculty exceptions handled below
+                break;
+        }
+    }
+    //exceptions for Faculty
+    if (patronProfile == "Faculty") {
+        if (copy.circ_modifier == 'LAW SERIAL') {
+            result.durationRule = 'OWAL_Faculty_serials';       // all Faculty can borrow serials
+        }
+        if (patron.home_ou.shortname == 'OWAL') {
+            result.recurringFinesRule = 'free';                // Law Faculty pay no fines
+            if (copy.circ_modifier.slice(0, 7) == 'LAW RES') { 
+                result.durationRule = 'OWAL_rsv_threeday';      // Law Faculty get all reserve items for three days
+            }
+        }
+    }
+}
+log_info("circ0814 - results: " + result.durationRule);
diff --git a/Open-ILS/src/javascript/backend/circ/circ_duration_SUDBURY.js b/Open-ILS/src/javascript/backend/circ/circ_duration_SUDBURY.js
new file mode 120000 (symlink)
index 0000000..e54bfe1
--- /dev/null
@@ -0,0 +1 @@
+circ_duration_OSUL.js
\ No newline at end of file
old mode 100644 (file)
new mode 100755 (executable)
index 036d56e..93c78d4
@@ -15,7 +15,56 @@ var GROUP_CONFIG = {
        'Patron' : {
                maxItemsOut         : 50,
                fineThreshold       : 10,
-               overdueThreshold    : 10,
+               overdueThreshold    : 100,
                maxHolds            : -1
        },
+       'Faculty' : {
+               maxItemsOut         : 60,
+               fineThreshold       : 10,
+               overdueThreshold    : 100,
+               maxHolds            : -1
+       },
+       'Graduate' : {
+               maxItemsOut         : 60,
+               fineThreshold       : 10,
+               overdueThreshold    : 100,
+               maxHolds            : -1
+       },
+       'Undergraduate' : {
+               maxItemsOut         : 30,
+               fineThreshold       : 10,
+               overdueThreshold    : 100,
+               maxHolds            : -1
+       },
+       'Staff members' : {
+               maxItemsOut         : 30,
+               fineThreshold       : 10,
+               overdueThreshold    : 100,
+               maxHolds            : -1
+       },
+       'Readers' : {
+               maxItemsOut         : 15,
+               fineThreshold       : 10,
+               overdueThreshold    : 100,
+               maxHolds            : -1
+       },
+       'Alumni' : {
+               maxItemsOut         : 15,
+               fineThreshold       : 10,
+               overdueThreshold    : 100,
+               maxHolds            : -1
+       },
+       'College Students' : {
+               maxItemsOut         : 15,
+               fineThreshold       : 10,
+               overdueThreshold    : 100,
+               maxHolds            : -1
+       },
+       'High School Students' : {
+               maxItemsOut         : 15,
+               fineThreshold       : 10,
+               overdueThreshold    : 100,
+               maxHolds            : -1
+       },
+
 }
index 64923ed..61b65d7 100644 (file)
@@ -312,3 +312,15 @@ function debugGroupConfig(name, foundName, config) {
 }
 
 
+/* custom functions for Windsor libraries */
+
+function isValidPatron(patronProfile) {
+    var valid_patrons = ['Faculty', 'Graduate', 'Undergraduate', 'Staff members', 'Readers', 'Alumni', 'College Students', 'High School Students'];
+    for (var i = 0; i < valid_patrons.length; i++) {
+        if (valid_patrons[i] == patronProfile) {
+            return true;
+        }
+    }
+    return false;
+}
+
index 053d9b7..8f93442 100644 (file)
@@ -5,9 +5,143 @@ load_lib('circ/circ_lib.js');
 load_lib('JSON_v1.js');
 log_vars('circ_permit_copy');
 
+var lusys = ['LUSYS', 'CRC', 'HUNTINGTON', 'LDCR', 'MRC', 'OSUL', 'MEDIACEN', 'SUDBURY'];
+var hearstsys = ['HEARSTSYS', 'HEARST', 'KAP', 'TIMMINS'];
+var nosmsys = ['OSM', 'NOSME', 'NOSMW'];
+var winsys = ['OWA', 'OWAL'];
+var algsys = ['OSTMA']; /* looks silly but we do plan to add one or two branches during the winter term */
 
-if( ! isTrue(copy.circulate) || !isTrue(copy.location.circulate) ) 
+/* In theory, isOrgDescendent would work - but it isn't, for some reason */
+if (patron.home_ou.id != copy.circ_lib.id) {
+        /* Laurentian campus patrons can borrow from one another */
+        if (isOrgDescendent('LUSYS', patron.home_ou.id) && isOrgDescendent('LUSYS', copy.circ_lib.id)) {
+                // go in peace
+        } else if (isAMember(patron.home_ou.shortname, lusys) && (
+                       isAMember(copy.circ_lib.shortname, lusys) || isAMember(copy.circ_lib.shortname, nosmsys) 
+               ))
+       {
+                // No problemo
+        } else if (isOrgDescendent('HEARSTSYS', patron.home_ou.id) && isOrgDescendent('LUSYS', copy.circ_lib.id)) {
+                // go in peace
+        } else if (isAMember(patron.home_ou.shortname, hearstsys) && isAMember(copy.circ_lib.shortname, hearstsys)) {
+                // No problemo
+        } else if (isAMember(patron.home_ou.shortname, winsys) && isAMember(copy.circ_lib.shortname, winsys)) {
+                // No problemo
+        } else if (isOrgDescendent('OSM', patron.home_ou.id) && isOrgDescendent('OSM', copy.circ_lib.id)) {
+                // go in peace
+        } else if (isAMember(patron.home_ou.shortname, nosmsys) && (
+                       isAMember(copy.circ_lib.shortname, lusys) || isAMember(copy.circ_lib.shortname, nosmsys) 
+               ))
+       {
+                // No problemo
+        } else {
+                result.events.push('CIRC_EXCEEDS_COPY_RANGE');
+        }
+}
+
+if( ! isTrue(copy.circulate) || 
+       !isTrue(copy.location.circulate) ||
+       (copy.circ_lib.shortname == 'OSUL' && copy.circ_modifier == 'DEPOSIT') ||
+       (copy.circ_lib.shortname == 'OSUL' && copy.circ_modifier == 'DOCUMENTS') ||
+       (copy.circ_lib.shortname == 'OSUL' && copy.circ_modifier == 'PERIODICAL') ||
+       (copy.circ_lib.shortname == 'OSUL' && copy.circ_modifier == 'REFERENCE')
+) {
        result.events.push('COPY_CIRC_NOT_ALLOWED');
+}
+
+// set permissions for Windsor Leddy
+if (copy.circ_lib.shortname == 'OWA') {
+
+       if (isValidPatron(patronProfile)) {
+  
+               // permit circulations for the following circ modifiers to all patrons
+               var circ_allow_list = ['CIRC', 'CRC MEDIA', 'CRC SPEC', 'CRC TEXT', 'DOC', 'DVD VIDEO', 'MEDIA', 'MFORM', 'REF', 'THESIS'];
+
+               // add permissions for patron groups who are not external borrowers
+               if (patronProfile == 'Faculty' || patronProfile == 'Graduate' || patronProfile == 'Undergraduate' || patronProfile == 'Staff members') {
+                       circ_allow_list = circ_allow_list.concat('CIRC SHORT', 'RSV1', 'RSV2', 'RSV3', 'RSV7');
+               }
+
+               // faculty, grads, and staff can borrow serials
+               if (patronProfile == 'Faculty' || patronProfile == 'Graduate'|| patronProfile == 'Staff members') {
+                       circ_allow_list = circ_allow_list.concat('SER');
+               }
+
+               // faculty and staff can also borrow music CDs
+               if (patronProfile == 'Faculty' || patronProfile == 'Staff members') {
+                       circ_allow_list = circ_allow_list.concat('CD MUSIC');
+               }
+
+               if ( ! testCircAllow(circ_allow_list) ) {
+                       result.events.push('COPY_CIRC_NOT_ALLOWED');
+               }
+
+       } else {
+               result.events.push('COPY_CIRC_NOT_ALLOWED'); // would prefer this to push a "Check Patron Profile" message
+       }
+} // end permissions for Windsor Leddy
+
+// set permissions for Windsor Law
+if (copy.circ_lib.shortname == 'OWAL') {
+
+       if (isValidPatron(patronProfile)) {
+
+               // only Law external borrowers can borrow Law items
+               if ((patronProfile == 'Readers' || patronProfile == 'Alumni' || patronProfile == 'College Students' || patronProfile == 'High School Students') && patron.home_ou.shortname != 'OWAL') {
+                       result.events.push('COPY_CIRC_NOT_ALLOWED');
+               }
+
+               // permit circulations for the following circ modifiers to all patrons not excluded above
+               var circ_allow_list = ['LAW MONO'];
+
+               // add permissions for patron groups who are not external borrowers
+               if (patronProfile == 'Faculty' || patronProfile == 'Graduate' || patronProfile == 'Undergraduate' || patronProfile == 'Staff members') {
+                       circ_allow_list = circ_allow_list.concat('LAW RES1D', 'LAW RES3D', 'LAW RES3H', 'LAW RES5H');
+               }
+
+               // faculty can borrow non-circulating items and serials
+               if (patronProfile == 'Faculty') {
+                       circ_allow_list = circ_allow_list.concat('LAW NOCIRC', 'LAW SERIAL');
+               }
+
+               if ( ! testCircAllow(circ_allow_list) ) {
+                       result.events.push('COPY_CIRC_NOT_ALLOWED');
+               }
+
+       } else {
+               result.events.push('COPY_CIRC_NOT_ALLOWED'); // would prefer this to push a "Check Patron Profile" message
+       }
+} // end permissions for Windsor Law
+
+/*******************************
+   PERMIT FOR ALGOMA
+********************************/
+
+if (copy.circ_lib.shortname == 'OSTMA') {
+
+       if (isValidPatron(patronProfile)) {
+
+               if (copy.location.name == 'ALGO-REF' ||
+                   copy.location.name == 'ALGO-PER' ||
+                   copy.location.name == 'ALGO-SHWK' ||        
+                    copy.location.name == 'ALGO-DOC' 
+                  )
+               {
+                       result.events.push('COPY_CIRC_NOT_ALLOWED');
+               }
+        } 
+
+
+       if (patronProfile != 'Faculty' && copy.location.name == 'ALGO-AV') {
+               result.events.push('COPY_CIRC_NOT_ALLOWED');            
+       }
+
+}
+
+
+/*******************************
+   END -- PERMIT FOR ALGOMA
+********************************/
 
 
 if( ! isTrue(isRenewal) ) {
@@ -17,8 +151,25 @@ if( ! isTrue(isRenewal) ) {
        } 
 }
 
+}
+
+function isAMember(shortname, group) {
+       for (var i = 0; i < group.length; i++) {
+               if (group[i] == shortname) {
+                       return true;
+               }
+       }
+       return false;
+}
 
-       
-} go();
+function testCircAllow(circ_allow_list) {
+       for (var i = 0; i < circ_allow_list.length; i++) {
+               if (circ_allow_list[i] == copy.circ_modifier) {
+                       return true;
+               }
+       }
+       return false;
+}
 
+go();
 
old mode 100644 (file)
new mode 100755 (executable)
index 9549688..1afc66e
@@ -20,6 +20,25 @@ if( config ) {
             result.events.push('PATRON_EXCEEDS_CHECKOUT_COUNT');
         }
     }
+
+    limit = config.fineThreshold;
+    /* but Laurentian suspends loan privileges immediately */
+    if (copy.circ_lib == 103) {
+       limit = 0.01;
+    }
+    if (patronFines >= limit) {
+        result.events.push('PATRON_EXCEEDS_FINES');
+    }
+
+    limit = config.overdueThreshold;
+    /* but Laurentian suspends loan privileges immediately */
+    if (copy.circ_lib == 103) {
+       limit = 1;
+    }
+    if (patronOverdueCount >= limit) {
+        result.events.push('PATRON_EXCEEDS_OVERDUE_COUNT');
+    }
+
     
 } else {