Record the date a copy first became "active" after creation in active_date.
Offer Org Unit setting for using the active date for age hold protection.
Any copy without an active_date, with age hold protect using it, will be
protected until it has an active date. Regardless of create_date.
Circ/Hold matrix can match on item age based on active_date.
Active is defined as entering a status with copy_active set to true. By default:
Available
Checked out
Reshelving
On holds shelf
ILL
Reserves
On reservation shelf
Signed-off-by: Thomas Berezansky <tsbere@mvlc.org>
Signed-off-by: Bill Erickson <berick@esilibrary.com>
<field reporter:label="MARC Form" name="marc_form" oils_persist:primitive="string" reporter:datatype="float"/>
<field reporter:label="Videorecording Format" name="marc_vr_format" oils_persist:primitive="string" reporter:datatype="float"/>
<field reporter:label="Reference?" name="ref_flag" reporter:datatype="float"/>
+ <field reporter:label="Item Age <" name="item_age" reporter:datatype="float"/>
</fields>
<links/>
<permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
<field reporter:label="Reference?" name="ref_flag" reporter:datatype="float"/>
<field reporter:label="User Age: Lower Bound" name="usr_age_lower_bound" reporter:datatype="float"/>
<field reporter:label="User Age: Upper Bound" name="usr_age_upper_bound" reporter:datatype="float"/>
+ <field reporter:label="Item Age <" name="item_age" reporter:datatype="float"/>
</fields>
<links/>
<permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
<field reporter:label="MARC Bib Level" name="marc_bib_level" oils_persist:primitive="string" reporter:datatype="link"/>
<field reporter:label="Videorecording Format" name="marc_vr_format" oils_persist:primitive="string" reporter:datatype="link"/>
<field reporter:label="Reference?" name="ref_flag" reporter:datatype="bool"/>
+ <field reporter:label="Item Age <" name="item_age" reporter:datatype="text"/>
<field reporter:label="Holdable?" name="holdable" reporter:datatype="bool"/>
<field reporter:label="Range is from Owning Lib?" name="distance_is_from_owner" reporter:datatype="bool"/>
<field reporter:label="Transit Range" name="transit_range" reporter:datatype="link"/>
<field reporter:label="Juvenile?" name="juvenile_flag" reporter:datatype="bool"/>
<field reporter:label="User Age: Lower Bound" name="usr_age_lower_bound" reporter:datatype="text"/>
<field reporter:label="User Age: Upper Bound" name="usr_age_upper_bound" reporter:datatype="text"/>
+ <field reporter:label="Item Age <" name="item_age" reporter:datatype="text"/>
<field reporter:label="Circulate?" name="circulate" reporter:datatype="bool"/>
<field reporter:label="Duration Rule" name="duration_rule" reporter:datatype="link"/>
<field reporter:label="Recurring Fine Rule" name="recurring_fine_rule" reporter:datatype="link"/>
<field name="id" reporter:selector="name" reporter:datatype="id"/>
<field name="name" reporter:datatype="text" oils_persist:i18n="true"/>
<field name="opac_visible" reporter:datatype="bool"/>
+ <field name="copy_active" reporter:datatype="bool"/>
</fields>
<links/>
<permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
<field reporter:label="Can Circulate" name="circulate" reporter:datatype="bool"/>
<field reporter:label="Copy Number on Volume" name="copy_number" reporter:datatype="text"/>
<field reporter:label="Creation Date/Time" name="create_date" reporter:datatype="timestamp"/>
+ <field reporter:label="Active Date/Time" name="active_date" reporter:datatype="timestamp"/>
<field reporter:label="Creating User" name="creator" reporter:datatype="link"/>
<field reporter:label="Is Deleted" name="deleted" reporter:datatype="bool"/>
<field reporter:label="Dummy ISBN" name="dummy_isbn" reporter:datatype="text"/>
<field reporter:label="Can Circulate" name="circulate" reporter:datatype="bool"/>
<field reporter:label="Copy Number on Volume" name="copy_number" reporter:datatype="text"/>
<field reporter:label="Creation Date/Time" name="create_date" reporter:datatype="timestamp"/>
+ <field reporter:label="Active Date/Time" name="active_date" reporter:datatype="timestamp"/>
<field reporter:label="Creating User" name="creator" reporter:datatype="link"/>
<field reporter:label="Is Deleted" name="deleted" reporter:datatype="bool"/>
<field reporter:label="Dummy ISBN" name="dummy_isbn" reporter:datatype="text"/>
fine_level circulate deposit price ref opac_visible
circ_as_type circ_modifier deposit_amount location mint_condition
holdable dummy_title dummy_author deleted alert_message
- age_protect floating cost status_changed_time/ );
+ age_protect floating cost status_changed_time active_date/ );
#-------------------------------------------------------------------------------
package asset::copy_part_map;
use base qw/config/;
__PACKAGE__->table('config_copy_status');
__PACKAGE__->columns(Primary => 'id');
-__PACKAGE__->columns(Essential => qw/name holdable opac_visible/);
+__PACKAGE__->columns(Essential => qw/name holdable opac_visible copy_active/);
#-------------------------------------------------------------------------------
package config::net_access_level;
fine_level circulate deposit price ref opac_visible dummy_isbn
circ_as_type circ_modifier deposit_amount location mint_condition
holdable dummy_title dummy_author deleted alert_message
- age_protect floating summary_contents detailed_contents/ );
+ age_protect floating summary_contents detailed_contents active_date/ );
#-------------------------------------------------------------------------------
package serial::record_entry;
{ order_by => 'age' }
);
- # Now, now many seconds old is this copy
- my $create_date = DateTime::Format::ISO8601
- ->new
- ->parse_datetime( OpenSRF::Utils::cleanse_ISO8601($copy->create_date) )
- ->epoch;
-
- my $age = time - $create_date;
+ my $age_protect_date = $copy->create_date;
+ $age_protect_date = $copy->active_date if($U->ou_ancestor_setting_value($copy->circ_lib, 'circ.holds.age_protect.active_date'));
+
+ my $age = 0;
+ my $age_protect_parsed;
+ if($age_protect_date) {
+ # Now, now many seconds old is this copy
+ $age_protect_parsed = DateTime::Format::ISO8601
+ ->new
+ ->parse_datetime( OpenSRF::Utils::cleanse_ISO8601($age_protect_date) )
+ ->epoch;
+ $age = time - $age_protect_parsed;
+ }
for my $protection ( @$protection_list ) {
# How many seconds old does the copy have to be to escape age protection
my $interval = OpenSRF::Utils::interval_to_seconds($protection->age);
- $logger->info("age_protect interval=$interval, create_date=$create_date, age=$age");
+ $logger->info("age_protect interval=$interval, age_protect_date=$age_protect_parsed, age=$age");
if( $interval > $age ) {
# if age of the item is less than the protection interval,
id SERIAL PRIMARY KEY,
name TEXT NOT NULL UNIQUE,
holdable BOOL NOT NULL DEFAULT FALSE,
- opac_visible BOOL NOT NULL DEFAULT FALSE
+ opac_visible BOOL NOT NULL DEFAULT FALSE,
+ copy_active BOOL NOT NULL DEFAULT FALSE
);
COMMENT ON TABLE config.copy_status IS $$
Copy Statuses
floating BOOL NOT NULL DEFAULT FALSE,
dummy_isbn TEXT,
status_changed_time TIMESTAMP WITH TIME ZONE,
+ active_date TIMESTAMP WITH TIME ZONE,
mint_condition BOOL NOT NULL DEFAULT TRUE,
cost NUMERIC(8,2)
);
BEGIN
IF NEW.status <> OLD.status THEN
NEW.status_changed_time := now();
+ IF NEW.active_date IS NULL AND NEW.status IN (SELECT id FROM config.copy_status WHERE copy_active = true) THEN
+ NEW.active_date := now();
+ END IF;
+ END IF;
+ RETURN NEW;
+END;
+$$ LANGUAGE plpgsql;
+
+-- Need to check on initial create. Fast adds, manual edit of status at create, etc.
+CREATE OR REPLACE FUNCTION asset.acp_created()
+RETURNS TRIGGER AS $$
+BEGIN
+ IF NEW.active_date IS NULL AND NEW.status IN (SELECT id FROM config.copy_status WHERE copy_active = true) THEN
+ NEW.active_date := now();
+ END IF;
+ IF NEW.status_changed_time IS NULL THEN
+ NEW.status_changed_time := now();
END IF;
RETURN NEW;
END;
BEFORE UPDATE ON asset.copy
FOR EACH ROW EXECUTE PROCEDURE asset.acp_status_changed();
+CREATE TRIGGER acp_created_trig
+ BEFORE INSERT ON asset.copy
+ FOR EACH ROW EXECUTE PROCEDURE asset.acp_created();
+
CREATE TABLE asset.stat_cat_sip_fields (
field CHAR(2) PRIMARY KEY,
name TEXT NOT NULL,
juvenile_flag NUMERIC(6,2) NOT NULL,
is_renewal NUMERIC(6,2) NOT NULL,
usr_age_lower_bound NUMERIC(6,2) NOT NULL,
- usr_age_upper_bound NUMERIC(6,2) NOT NULL
+ usr_age_upper_bound NUMERIC(6,2) NOT NULL,
+ item_age NUMERIC(6,2) NOT NULL
);
-- Hold Matrix Weights
marc_bib_level NUMERIC(6,2) NOT NULL,
marc_vr_format NUMERIC(6,2) NOT NULL,
juvenile_flag NUMERIC(6,2) NOT NULL,
- ref_flag NUMERIC(6,2) NOT NULL
+ ref_flag NUMERIC(6,2) NOT NULL,
+ item_age NUMERIC(6,2) NOT NULL
);
-- Linking between weights and org units
is_renewal BOOL,
usr_age_lower_bound INTERVAL,
usr_age_upper_bound INTERVAL,
+ item_age INTERVAL,
-- "Result" Fields
circulate BOOL, -- Hard "can't circ" flag requiring an override
duration_rule INT REFERENCES config.rule_circ_duration (id) DEFERRABLE INITIALLY DEFERRED,
);
-- Nulls don't count for a constraint match, so we have to coalesce them into something that does.
-CREATE UNIQUE INDEX ccmm_once_per_paramset ON config.circ_matrix_matchpoint (org_unit, grp, COALESCE(circ_modifier, ''), COALESCE(marc_type, ''), COALESCE(marc_form, ''), COALESCE(marc_bib_level,''), COALESCE(marc_vr_format, ''), COALESCE(copy_circ_lib::TEXT, ''), COALESCE(copy_owning_lib::TEXT, ''), COALESCE(user_home_ou::TEXT, ''), COALESCE(ref_flag::TEXT, ''), COALESCE(juvenile_flag::TEXT, ''), COALESCE(is_renewal::TEXT, ''), COALESCE(usr_age_lower_bound::TEXT, ''), COALESCE(usr_age_upper_bound::TEXT, '')) WHERE active;
+CREATE UNIQUE INDEX ccmm_once_per_paramset ON config.circ_matrix_matchpoint (org_unit, grp, COALESCE(circ_modifier, ''), COALESCE(marc_type, ''), COALESCE(marc_form, ''), COALESCE(marc_bib_level,''), COALESCE(marc_vr_format, ''), COALESCE(copy_circ_lib::TEXT, ''), COALESCE(copy_owning_lib::TEXT, ''), COALESCE(user_home_ou::TEXT, ''), COALESCE(ref_flag::TEXT, ''), COALESCE(juvenile_flag::TEXT, ''), COALESCE(is_renewal::TEXT, ''), COALESCE(usr_age_lower_bound::TEXT, ''), COALESCE(usr_age_upper_bound::TEXT, ''), COALESCE(item_age::TEXT, '')) WHERE active;
-- Tests for max items out by circ_modifier
CREATE TABLE config.circ_matrix_circ_mod_test (
matchpoint config.circ_matrix_matchpoint%ROWTYPE;
weights config.circ_matrix_weights%ROWTYPE;
user_age INTERVAL;
+ my_item_age INTERVAL;
denominator NUMERIC(6,2);
row_list INT[];
result action.found_circ_matrix_matchpoint;
SELECT INTO user_age age(user_object.dob);
END IF;
+ -- Ditto
+ IF item_object.active_date IS NOT NULL THEN
+ SELECT INTO my_item_age age(item_object.active_date);
+ END IF;
+
-- Grab the closest set circ weight setting.
SELECT INTO weights cw.*
FROM config.weight_assoc wa
weights.is_renewal := 7.0;
weights.usr_age_lower_bound := 0.0;
weights.usr_age_upper_bound := 0.0;
+ weights.item_age := 0.0;
END IF;
-- Determine the max (expected) depth (+1) of the org tree and max depth of the permisson tree
AND (m.marc_bib_level IS NULL OR m.marc_bib_level = rec_descriptor.bib_level)
AND (m.marc_vr_format IS NULL OR m.marc_vr_format = rec_descriptor.vr_format)
AND (m.ref_flag IS NULL OR m.ref_flag = item_object.ref)
+ AND (m.item_age IS NULL OR (my_item_age IS NOT NULL AND m.item_age > my_item_age))
ORDER BY
-- Permission Groups
CASE WHEN upgad.distance IS NOT NULL THEN 2^(2*weights.grp - (upgad.distance/denominator)) ELSE 0.0 END +
CASE WHEN m.marc_type IS NOT NULL THEN 4^weights.marc_type ELSE 0.0 END +
CASE WHEN m.marc_form IS NOT NULL THEN 4^weights.marc_form ELSE 0.0 END +
CASE WHEN m.marc_vr_format IS NOT NULL THEN 4^weights.marc_vr_format ELSE 0.0 END +
- CASE WHEN m.ref_flag IS NOT NULL THEN 4^weights.ref_flag ELSE 0.0 END DESC,
+ CASE WHEN m.ref_flag IS NOT NULL THEN 4^weights.ref_flag ELSE 0.0 END +
+ -- Item age has a slight adjustment to weight based on value.
+ -- This should ensure that a shorter age limit comes first when all else is equal.
+ -- NOTE: This assumes that intervals will normally be in days.
+ CASE WHEN m.item_age IS NOT NULL THEN 4^weights.item_age - 1 + 86400/EXTRACT(EPOCH FROM m.item_age) ELSE 0.0 END DESC,
-- Final sort on id, so that if two rules have the same sorting in the previous sort they have a defined order
-- This prevents "we changed the table order by updating a rule, and we started getting different results"
m.id LOOP
marc_vr_format TEXT,
juvenile_flag BOOL,
ref_flag BOOL,
+ item_age INTERVAL,
-- "Result" Fields
holdable BOOL NOT NULL DEFAULT TRUE, -- Hard "can't hold" flag requiring an override
distance_is_from_owner BOOL NOT NULL DEFAULT FALSE, -- How to calculate transit_range. True means owning lib, false means copy circ lib
);
-- Nulls don't count for a constraint match, so we have to coalesce them into something that does.
-CREATE UNIQUE INDEX chmm_once_per_paramset ON config.hold_matrix_matchpoint (COALESCE(user_home_ou::TEXT, ''), COALESCE(request_ou::TEXT, ''), COALESCE(pickup_ou::TEXT, ''), COALESCE(item_owning_ou::TEXT, ''), COALESCE(item_circ_ou::TEXT, ''), COALESCE(usr_grp::TEXT, ''), COALESCE(requestor_grp::TEXT, ''), COALESCE(circ_modifier, ''), COALESCE(marc_type, ''), COALESCE(marc_form, ''), COALESCE(marc_bib_level, ''), COALESCE(marc_vr_format, ''), COALESCE(juvenile_flag::TEXT, ''), COALESCE(ref_flag::TEXT, '')) WHERE active;
+CREATE UNIQUE INDEX chmm_once_per_paramset ON config.hold_matrix_matchpoint (COALESCE(user_home_ou::TEXT, ''), COALESCE(request_ou::TEXT, ''), COALESCE(pickup_ou::TEXT, ''), COALESCE(item_owning_ou::TEXT, ''), COALESCE(item_circ_ou::TEXT, ''), COALESCE(usr_grp::TEXT, ''), COALESCE(requestor_grp::TEXT, ''), COALESCE(circ_modifier, ''), COALESCE(marc_type, ''), COALESCE(marc_form, ''), COALESCE(marc_bib_level, ''), COALESCE(marc_vr_format, ''), COALESCE(juvenile_flag::TEXT, ''), COALESCE(ref_flag::TEXT, ''), COALESCE(item_age::TEXT, '')) WHERE active;
CREATE OR REPLACE FUNCTION action.find_hold_matrix_matchpoint(pickup_ou integer, request_ou integer, match_item bigint, match_user integer, match_requestor integer)
RETURNS integer AS
user_object actor.usr%ROWTYPE;
item_object asset.copy%ROWTYPE;
item_cn_object asset.call_number%ROWTYPE;
+ my_item_age INTERVAL;
rec_descriptor metabib.rec_descriptor%ROWTYPE;
matchpoint config.hold_matrix_matchpoint%ROWTYPE;
weights config.hold_matrix_weights%ROWTYPE;
SELECT INTO item_cn_object * FROM asset.call_number WHERE id = item_object.call_number;
SELECT INTO rec_descriptor * FROM metabib.rec_descriptor WHERE record = item_cn_object.record;
+ IF item_object.active_date IS NOT NULL THEN
+ SELECT INTO my_item_age age(item_object.active_date);
+ END IF;
+
-- The item's owner should probably be the one determining if the item is holdable
-- How to decide that is debatable. Decided to default to the circ library (where the item lives)
-- This flag will allow for setting it to the owning library (where the call number "lives")
SELECT INTO weights hw.*
FROM config.weight_assoc wa
JOIN config.hold_matrix_weights hw ON (hw.id = wa.hold_weights)
- JOIN actor.org_unit_ancestors_distance( cn_object.owning_lib ) d ON (wa.org_unit = d.id)
+ JOIN actor.org_unit_ancestors_distance( item_cn_object.owning_lib ) d ON (wa.org_unit = d.id)
WHERE active
ORDER BY d.distance
LIMIT 1;
weights.marc_vr_format := 1.0;
weights.juvenile_flag := 4.0;
weights.ref_flag := 0.0;
+ weights.item_age := 0.0;
END IF;
-- Determine the max (expected) depth (+1) of the org tree and max depth of the permisson tree
AND (m.marc_bib_level IS NULL OR m.marc_bib_level = rec_descriptor.bib_level)
AND (m.marc_vr_format IS NULL OR m.marc_vr_format = rec_descriptor.vr_format)
AND (m.ref_flag IS NULL OR m.ref_flag = item_object.ref)
+ AND (m.item_age IS NULL OR (my_item_age IS NOT NULL AND m.item_age > my_item_age))
ORDER BY
-- Permission Groups
CASE WHEN rpgad.distance IS NOT NULL THEN 2^(2*weights.requestor_grp - (rpgad.distance/denominator)) ELSE 0.0 END +
CASE WHEN m.marc_type IS NOT NULL THEN 4^weights.marc_type ELSE 0.0 END +
CASE WHEN m.marc_form IS NOT NULL THEN 4^weights.marc_form ELSE 0.0 END +
CASE WHEN m.marc_vr_format IS NOT NULL THEN 4^weights.marc_vr_format ELSE 0.0 END +
- CASE WHEN m.ref_flag IS NOT NULL THEN 4^weights.ref_flag ELSE 0.0 END DESC,
+ CASE WHEN m.ref_flag IS NOT NULL THEN 4^weights.ref_flag ELSE 0.0 END +
+ -- Item age has a slight adjustment to weight based on value.
+ -- This should ensure that a shorter age limit comes first when all else is equal.
+ -- NOTE: This assumes that intervals will normally be in days.
+ CASE WHEN m.item_age IS NOT NULL THEN 4^weights.item_age - 86400/EXTRACT(EPOCH FROM m.item_age) ELSE 0.0 END DESC,
-- Final sort on id, so that if two rules have the same sorting in the previous sort they have a defined order
-- This prevents "we changed the table order by updating a rule, and we started getting different results"
m.id;
ou_skip actor.org_unit_setting%ROWTYPE;
result action.matrix_test_result;
hold_test config.hold_matrix_matchpoint%ROWTYPE;
+ use_active_date TEXT;
+ age_protect_date TIMESTAMP WITH TIME ZONE;
hold_count INT;
hold_transit_prox INT;
frozen_hold_count INT;
IF item_object.age_protect IS NOT NULL THEN
SELECT INTO age_protect_object * FROM config.rule_age_hold_protect WHERE id = item_object.age_protect;
-
- IF item_object.create_date + age_protect_object.age > NOW() THEN
+ IF hold_test.distance_is_from_owner THEN
+ SELECT INTO use_active_date value FROM actor.org_unit_ancestor_setting('circ.holds.age_protect.active_date', item_cn_object.owning_lib);
+ ELSE
+ SELECT INTO use_active_date value FROM actor.org_unit_ancestor_setting('circ.holds.age_protect.active_date', item_object.circ_lib);
+ END IF;
+ IF use_active_date = 'true' THEN
+ age_protect_date := COALESCE(item_object.active_date, NOW());
+ ELSE
+ age_protect_date := item_object.create_date;
+ END IF;
+ IF age_protect_date + age_protect_object.age > NOW() THEN
IF hold_test.distance_is_from_owner THEN
SELECT INTO item_cn_object * FROM asset.call_number WHERE id = item_object.call_number;
SELECT INTO hold_transit_prox prox FROM actor.org_unit_proximity WHERE from_org = item_cn_object.owning_lib AND to_org = pickup_ou;
BEFORE UPDATE ON serial.unit
FOR EACH ROW EXECUTE PROCEDURE asset.acp_status_changed();
+-- ditto
+CREATE TRIGGER sunit_created_trig
+ BEFORE INSERT ON serial.unit
+ FOR EACH ROW EXECUTE PROCEDURE asset.acp_created();
+
CREATE TABLE serial.item (
id SERIAL PRIMARY KEY,
creator INT NOT NULL
(2, oils_i18n_gettext(2, '6month', 'crahp', 'name'), '6 months', 2);
SELECT SETVAL('config.rule_age_hold_protect_id_seq'::TEXT, 100);
-INSERT INTO config.copy_status (id,name,holdable,opac_visible) VALUES (0,oils_i18n_gettext(0, 'Available', 'ccs', 'name'),'t','t');
-INSERT INTO config.copy_status (id,name,holdable,opac_visible) VALUES (1,oils_i18n_gettext(1, 'Checked out', 'ccs', 'name'),'t','t');
+INSERT INTO config.copy_status (id,name,holdable,opac_visible,copy_active) VALUES (0,oils_i18n_gettext(0, 'Available', 'ccs', 'name'),'t','t','t');
+INSERT INTO config.copy_status (id,name,holdable,opac_visible,copy_active) VALUES (1,oils_i18n_gettext(1, 'Checked out', 'ccs', 'name'),'t','t','t');
INSERT INTO config.copy_status (id,name) VALUES (2,oils_i18n_gettext(2, 'Bindery', 'ccs', 'name'));
INSERT INTO config.copy_status (id,name) VALUES (3,oils_i18n_gettext(3, 'Lost', 'ccs', 'name'));
INSERT INTO config.copy_status (id,name) VALUES (4,oils_i18n_gettext(4, 'Missing', 'ccs', 'name'));
INSERT INTO config.copy_status (id,name,holdable,opac_visible) VALUES (5,oils_i18n_gettext(5, 'In process', 'ccs', 'name'),'t','t');
INSERT INTO config.copy_status (id,name,holdable,opac_visible) VALUES (6,oils_i18n_gettext(6, 'In transit', 'ccs', 'name'),'t','t');
-INSERT INTO config.copy_status (id,name,holdable,opac_visible) VALUES (7,oils_i18n_gettext(7, 'Reshelving', 'ccs', 'name'),'t','t');
-INSERT INTO config.copy_status (id,name,holdable,opac_visible) VALUES (8,oils_i18n_gettext(8, 'On holds shelf', 'ccs', 'name'),'t','t');
+INSERT INTO config.copy_status (id,name,holdable,opac_visible,copy_active) VALUES (7,oils_i18n_gettext(7, 'Reshelving', 'ccs', 'name'),'t','t','t');
+INSERT INTO config.copy_status (id,name,holdable,opac_visible,copy_active) VALUES (8,oils_i18n_gettext(8, 'On holds shelf', 'ccs', 'name'),'t','t','t');
INSERT INTO config.copy_status (id,name,holdable,opac_visible) VALUES (9,oils_i18n_gettext(9, 'On order', 'ccs', 'name'),'t','t');
-INSERT INTO config.copy_status (id,name) VALUES (10,oils_i18n_gettext(10, 'ILL', 'ccs', 'name'));
+INSERT INTO config.copy_status (id,name,copy_active) VALUES (10,oils_i18n_gettext(10, 'ILL', 'ccs', 'name'),'t');
INSERT INTO config.copy_status (id,name) VALUES (11,oils_i18n_gettext(11, 'Cataloging', 'ccs', 'name'));
-INSERT INTO config.copy_status (id,name,opac_visible) VALUES (12,oils_i18n_gettext(12, 'Reserves', 'ccs', 'name'),'t');
+INSERT INTO config.copy_status (id,name,opac_visible,copy_active) VALUES (12,oils_i18n_gettext(12, 'Reserves', 'ccs', 'name'),'t','t');
INSERT INTO config.copy_status (id,name) VALUES (13,oils_i18n_gettext(13, 'Discard/Weed', 'ccs', 'name'));
INSERT INTO config.copy_status (id,name) VALUES (14,oils_i18n_gettext(14, 'Damaged', 'ccs', 'name'));
-INSERT INTO config.copy_status (id,name) VALUES (15,oils_i18n_gettext(15, 'On reservation shelf', 'ccs', 'name'));
+INSERT INTO config.copy_status (id,name,copy_active) VALUES (15,oils_i18n_gettext(15, 'On reservation shelf', 'ccs', 'name'),'t');
SELECT SETVAL('config.copy_status_id_seq'::TEXT, 100);
-- circ matrix
INSERT INTO config.circ_matrix_matchpoint (org_unit,grp,circulate,duration_rule,recurring_fine_rule,max_fine_rule) VALUES (1,1,true,11,1,1);
-INSERT INTO config.circ_matrix_weights(name, org_unit, grp, circ_modifier, marc_type, marc_form, marc_bib_level, marc_vr_format, copy_circ_lib, copy_owning_lib, user_home_ou, ref_flag, juvenile_flag, is_renewal, usr_age_upper_bound, usr_age_lower_bound) VALUES
- ('Default', 10.0, 11.0, 5.0, 4.0, 3.0, 2.0, 2.0, 8.0, 8.0, 8.0, 1.0, 6.0, 7.0, 0.0, 0.0),
- ('Org_Unit_First', 11.0, 10.0, 5.0, 4.0, 3.0, 2.0, 2.0, 8.0, 8.0, 8.0, 1.0, 6.0, 7.0, 0.0, 0.0),
- ('Item_Owner_First', 8.0, 8.0, 5.0, 4.0, 3.0, 2.0, 2.0, 10.0, 11.0, 8.0, 1.0, 6.0, 7.0, 0.0, 0.0),
- ('All_Equal', 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
+INSERT INTO config.circ_matrix_weights(name, org_unit, grp, circ_modifier, marc_type, marc_form, marc_bib_level, marc_vr_format, copy_circ_lib, copy_owning_lib, user_home_ou, ref_flag, juvenile_flag, is_renewal, usr_age_upper_bound, usr_age_lower_bound, item_age) VALUES
+ ('Default', 10.0, 11.0, 5.0, 4.0, 3.0, 2.0, 2.0, 8.0, 8.0, 8.0, 1.0, 6.0, 7.0, 0.0, 0.0, 0.0),
+ ('Org_Unit_First', 11.0, 10.0, 5.0, 4.0, 3.0, 2.0, 2.0, 8.0, 8.0, 8.0, 1.0, 6.0, 7.0, 0.0, 0.0, 0.0),
+ ('Item_Owner_First', 8.0, 8.0, 5.0, 4.0, 3.0, 2.0, 2.0, 10.0, 11.0, 8.0, 1.0, 6.0, 7.0, 0.0, 0.0, 0.0),
+ ('All_Equal', 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
-- hold matrix - 110.hold_matrix.sql:
INSERT INTO config.hold_matrix_matchpoint (requestor_grp) VALUES (1);
-INSERT INTO config.hold_matrix_weights(name, user_home_ou, request_ou, pickup_ou, item_owning_ou, item_circ_ou, usr_grp, requestor_grp, circ_modifier, marc_type, marc_form, marc_bib_level, marc_vr_format, juvenile_flag, ref_flag) VALUES
- ('Default', 5.0, 5.0, 5.0, 5.0, 5.0, 7.0, 8.0, 4.0, 3.0, 2.0, 1.0, 1.0, 4.0, 0.0),
- ('Item_Owner_First', 5.0, 5.0, 5.0, 8.0, 7.0, 5.0, 5.0, 4.0, 3.0, 2.0, 1.0, 1.0, 4.0, 0.0),
- ('User_Before_Requestor', 5.0, 5.0, 5.0, 5.0, 5.0, 8.0, 7.0, 4.0, 3.0, 2.0, 1.0, 1.0, 4.0, 0.0),
- ('All_Equal', 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
+INSERT INTO config.hold_matrix_weights(name, user_home_ou, request_ou, pickup_ou, item_owning_ou, item_circ_ou, usr_grp, requestor_grp, circ_modifier, marc_type, marc_form, marc_bib_level, marc_vr_format, juvenile_flag, ref_flag, item_age) VALUES
+ ('Default', 5.0, 5.0, 5.0, 5.0, 5.0, 7.0, 8.0, 4.0, 3.0, 2.0, 1.0, 1.0, 4.0, 0.0, 0.0),
+ ('Item_Owner_First', 5.0, 5.0, 5.0, 8.0, 7.0, 5.0, 5.0, 4.0, 3.0, 2.0, 1.0, 1.0, 4.0, 0.0, 0.0),
+ ('User_Before_Requestor', 5.0, 5.0, 5.0, 5.0, 5.0, 8.0, 7.0, 4.0, 3.0, 2.0, 1.0, 1.0, 4.0, 0.0, 0.0),
+ ('All_Equal', 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
-- dynamic weight associations
INSERT INTO config.weight_assoc(active, org_unit, circ_weights, hold_weights) VALUES
oils_i18n_gettext('circ.holds.min_estimated_wait_interval', 'When predicting the amount of time a patron will be waiting for a hold to be fulfilled, this is the minimum estimated length of time to assume an item will be checked out. Examples: "2 weeks", "5 days"', 'coust', 'description'),
'interval'),
+( 'circ.holds.age_protect.active_date',
+ oils_i18n_gettext('circ.holds.age_protect.active_date', 'Holds: Use Active Date for Age Protection', 'coust', 'label'),
+ oils_i18n_gettext('circ.holds.age_protect.active_date', 'When calculating age protection rules use the active date instead of the creation date.', 'coust', 'description'),
+ 'bool'),
+
( 'circ.selfcheck.patron_login_timeout',
oils_i18n_gettext('circ.selfcheck.patron_login_timeout', 'Selfcheck: Patron Login Timeout (in seconds)', 'coust', 'label'),
oils_i18n_gettext('circ.selfcheck.patron_login_timeout', 'Number of seconds of inactivity before the patron is logged out of the selfcheck interface', 'coust', 'description'),
if (attr == 'opac_visible' && typeof n != 'string')
this.setValue(item, 'opac_visible', n ? 't' : 'f');
+ if (attr == 'copy_active' && typeof n != 'string')
+ this.setValue(item, 'copy_active', n ? 't' : 'f');
};
dojo.addOnUnload( function (event) {
return false;
}
}
+ },
+ { name : ccs_strings.COPY_ACTIVE,
+ field : "copy_active",
+ editor : dojox.grid.editors.bool,
+ get : function (row) {
+ var r = window.status_data_model.getRow(row);
+ if (r) {
+ var h = r.copy_active;
+ if (h == 't' || h === true) return true;
+ return false;
+ }
+ }
}
]
]
"CONFIRM_EXIT_PGT": "There are unsaved modified permission maps. Click OK to save these changes, or Cancel to abandon them.",
"CONFIRM_EXIT_PPL": "There are unsaved modified permissions. Click OK to save these changes, or Cancel to abandon them.",
"CONFIRM_UNSAVED_CHANGES": "There are unsaved changes to one or more organization types. Click OK to save these changes, or Cancel to abandon them.",
+ "COPY_ACTIVE": "Sets copy active",
"ERROR_CALLING_METHOD_AOUT": "Problem calling method to create child organization type",
"ERROR_CALLING_METHOD_CAM": "Problem calling method to create new ${0}",
"ERROR_CALLING_METHOD_CCS": "Problem calling method to create new copy status",
<!ENTITY staff.browse_list.circulate "Circulate">
<!ENTITY staff.browse_list.copy_number "Copy Number">
<!ENTITY staff.browse_list.create_date "Creation Date">
+<!ENTITY staff.browse_list.active_date "Active Date">
<!ENTITY staff.browse_list.creator "Creator">
<!ENTITY staff.browse_list.deposit "Deposit">
<!ENTITY staff.browse_list.deposit_amount "Deposit Amount">
<!ENTITY staff.cat.copy_summary.created.label "Created:">
<!ENTITY staff.cat.copy_summary.edited.label "Edited:">
<!ENTITY staff.cat.copy_summary.age_protect.label "Age Protect:">
+<!ENTITY staff.cat.copy_summary.active_date.label "Active Date:">
<!ENTITY staff.cat.copy_summary.total_circs.label "Total Circulations:">
<!ENTITY staff.cat.copy_summary.alternate_view.label "Alternate View">
<!ENTITY staff.cat.copy_summary.alternate_view.accesskey "">
<!ENTITY staff.circ.alternate_copy_summary.Copy_Location.label "Copy Location">
<!ENTITY staff.circ.alternate_copy_summary.Renewal_Type.label "Renewal Type">
<!ENTITY staff.circ.alternate_copy_summary.Date_Created.label "Date Created">
+<!ENTITY staff.circ.alternate_copy_summary.Date_Active.label "Date Active">
<!ENTITY staff.circ.alternate_copy_summary.Status_Changed_Time.label "Status Changed">
<!ENTITY staff.circ.alternate_copy_summary.Due_Date.label "Due Date">
<!ENTITY staff.circ.alternate_copy_summary.Edition.label "Edition">
<!ENTITY rdetail.cn.location "Location">
<!ENTITY rdetail.cn.hold.age "Age Hold Protection">
<!ENTITY rdetail.cn.genesis "Create Date">
+<!ENTITY rdetail.cn.active "Active Date">
<!ENTITY rdetail.cn.holdable "Holdable">
<!ENTITY rdetail.cn.due "Due Date">
<!ENTITY rdetail.cn.more "more info...">
<td>&rdetail.cn.location;</td>
<td name='age_protect_label' class='hide_me'>&rdetail.cn.hold.age;</td>
<td name='create_date_label' class='hide_me'>&rdetail.cn.genesis;</td>
+ <td name='active_date_label' class='hide_me'>&rdetail.cn.active;</td>
<td name='holdable_label' class='hide_me'>&rdetail.cn.holdable;</td>
<td name='due_date_label' class='hide_me'>&rdetail.cn.due;</td>
</tr>
<td name='location'> </td>
<td name='age_protect_value' class='hide_me'>&rdetail.cn.disabled;</td>
<td name='create_date_value' class='hide_me'> </td>
+ <td name='active_date_value' class='hide_me'> </td>
<td name='copy_holdable_td' class='hide_me'>
<span name='copy_is_holdable'> </span>
/* unhide before we unhide/clone the parent */
unHideMe($n(templateRow, 'age_protect_label'));
unHideMe($n(templateRow, 'create_date_label'));
+ unHideMe($n(templateRow, 'active_date_label'));
unHideMe($n(templateRow, 'holdable_label'));
}
/* unhide before we unhide/clone the parent */
unHideMe($n(copyrow, 'age_protect_value'));
unHideMe($n(copyrow, 'create_date_value'));
+ unHideMe($n(copyrow, 'active_date_value'));
unHideMe($n(copyrow, 'copy_holdable_td'));
}
cd = cd.replace(/T.*/, '');
$n(row, 'create_date_value').appendChild(text(cd));
+ var ad = copy.active_date();
+ if(ad) {
+ ad = ad.replace(/T.*/, '');
+ $n(row, 'active_date_value').appendChild(text(ad));
+ }
+
var yes = $('rdetail.yes').innerHTML;
var no = $('rdetail.no').innerHTML;
<td name='copy_part_label' class='hide_me'>&rdetail.cn.part;</td>
<td name='age_protect_label' class='hide_me'>&rdetail.cn.hold.age;</td>
<td name='create_date_label' class='hide_me'>&rdetail.cn.genesis;</td>
+ <td name='active_date_label' class='hide_me'>&rdetail.cn.active;</td>
<td name='holdable_label' class='hide_me'>&rdetail.cn.holdable;</td>
<td name='due_date_label' class='hide_me'>&rdetail.cn.due;</td>
</tr>
<td name='copy_part' class='hide_me'> </td>
<td name='age_protect_value' class='hide_me'>&rdetail.cn.disabled;</td>
<td name='create_date_value' class='hide_me'> </td>
+ <td name='active_date_value' class='hide_me'> </td>
<td name='copy_holdable_td' class='hide_me'>
<span name='copy_is_holdable'> </span>
<table jsId="cmGrid"
style="height: 600px;"
dojoType="openils.widget.AutoGrid"
- fieldOrder="['id', 'active', 'grp', 'org_unit', 'copy_circ_lib', 'copy_owning_lib', 'user_home_ou', 'is_renewal', 'juvenile_flag', 'circ_modifier', 'marc_type', 'marc_form', 'marc_bib_level', 'marc_vr_format', 'ref_flag', 'usr_age_lower_bound', 'usr_age_upper_bound', 'circulate', 'duration_rule', 'renewals', 'hard_due_date', 'recurring_fine_rule', 'grace_period', 'max_fine_rule', 'available_copy_hold_ratio', 'total_copy_hold_ratio', 'script_test']"
+ fieldOrder="['id', 'active', 'grp', 'org_unit', 'copy_circ_lib', 'copy_owning_lib', 'user_home_ou', 'is_renewal', 'juvenile_flag', 'circ_modifier', 'marc_type', 'marc_form', 'marc_bib_level', 'marc_vr_format', 'ref_flag', 'usr_age_lower_bound', 'usr_age_upper_bound', 'item_age', 'circulate', 'duration_rule', 'renewals', 'hard_due_date', 'recurring_fine_rule', 'grace_period', 'max_fine_rule', 'available_copy_hold_ratio', 'total_copy_hold_ratio', 'script_test']"
defaultCellWidth='"auto"'
query="{id: '*'}"
fmClass='ccmm'
}
],
[
+ $('catStrings').getString('staff.cat.copy_editor.field.active_date.label'),
+ {
+ render: 'util.date.formatted_date( fm.active_date(), "%F");',
+ }
+ ],
+ [
$('catStrings').getString('staff.cat.copy_editor.field.creator.label'),
{
render: 'fm.creator();',
set("floating", '');
set("copy_number", '');
set("copy_create_date", '');
+ set("copy_active_date", '');
set("status_changed_time", '');
set("copy_creator", '');
set("deleted", '');
set("floating", get_localized_bool( details.copy.floating() ));
set("copy_number", details.copy.copy_number());
set("copy_create_date", util.date.formatted_date( details.copy.create_date(), '%{localized}' ));
+ set("copy_active_date", util.date.formatted_date( details.copy.active_date(), '%{localized}' ));
set("status_changed_time", util.date.formatted_date( details.copy.status_changed_time(), '%{localized}' ));
set("copy_creator", details.copy.creator());
set("deleted", details.copy.deleted());
<textbox name="checkout_workstation" readonly="true" context="clipboard"/>
</row>
<row>
- <label value="&staff.circ.alternate_copy_summary.Status_Changed_Time.label;" />
- <textbox name="status_changed_time" readonly="true" context="clipboard"/>
+ <label value="&staff.circ.alternate_copy_summary.Date_Active.label;" />
+ <textbox name="copy_active_date" readonly="true" context="clipboard"/>
<label value="&staff.circ.alternate_copy_summary.Fine_Level.label;" />
<textbox name="fine_level" readonly="true" context="clipboard"/>
<label value="&staff.circ.alternate_copy_summary.Total_Circs___Prev_Year.label;" />
<textbox name="duration_rule" readonly="true" context="clipboard"/>
</row>
<row>
- <label value="&staff.circ.alternate_copy_summary.Copy_ID.label;" />
- <textbox name="copy_id" readonly="true" context="clipboard"/>
+ <label value="&staff.circ.alternate_copy_summary.Status_Changed_Time.label;" />
+ <textbox name="status_changed_time" readonly="true" context="clipboard"/>
<label value="&staff.circ.alternate_copy_summary.Reference.label;" />
<textbox name="ref" readonly="true" context="clipboard"/>
<!--
<textbox name="recurring_fine_rule" readonly="true" context="clipboard"/>
</row>
<row>
- <label value="&staff.circ.alternate_copy_summary.TCN.label;" />
- <textbox name="tcn" readonly="true" context="clipboard"/>
+ <label value="&staff.circ.alternate_copy_summary.Copy_ID.label;" />
+ <textbox name="copy_id" readonly="true" context="clipboard"/>
<label value="&staff.circ.alternate_copy_summary.OPAC_Visible.label;" />
<textbox name="opac_visible" readonly="true" context="clipboard"/>
<label value="&staff.circ.alternate_copy_summary.Remaining_Renewals.label;" />
<textbox name="max_fine_rule" readonly="true" context="clipboard"/>
</row>
<row>
- <label value="&staff.circ.alternate_copy_summary.Floating.label;" />
- <textbox name="floating" readonly="true" context="clipboard"/>
+ <label value="&staff.circ.alternate_copy_summary.TCN.label;" />
+ <textbox name="tcn" readonly="true" context="clipboard"/>
<label value="&staff.circ.alternate_copy_summary.Holdable.label;" />
<textbox name="holdable" readonly="true" context="clipboard"/>
<spacer /><spacer />
<textbox name="checkin_time" readonly="true" context="clipboard"/>
</row>
<row>
- <spacer /><spacer />
+ <label value="&staff.circ.alternate_copy_summary.Floating.label;" />
+ <textbox name="floating" readonly="true" context="clipboard"/>
<label value="&staff.circ.alternate_copy_summary.Circulate.label;" />
<textbox name="circulate" readonly="true" context="clipboard"/>
<!--
staff.cat.copy_editor.field.last_editor.label=Last Editor
staff.cat.copy_editor.field.barcode.label=Barcode
staff.cat.copy_editor.field.creation_date.label=Creation Date
+staff.cat.copy_editor.field.active_date.label=Active Date
staff.cat.copy_editor.field.last_edit_date.label=Last Edit Date
staff.cat.copy_editor.field.location.label=Location/Collection
staff.cat.copy_editor.field.circulation_library.label=Circulation Library