[open-ils-commits] [GIT] Evergreen ILS branch master updated. 6227dcdcd4cf3be18579b9239857c8c3f3ae0e11
Evergreen Git
git at git.evergreen-ils.org
Wed Jul 6 15:29:18 EDT 2011
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Evergreen ILS".
The branch, master has been updated
via 6227dcdcd4cf3be18579b9239857c8c3f3ae0e11 (commit)
via 2fc6c995cd469353f494e336b8db3b677aa3d25e (commit)
via 11218af3531a20925b6a9fdc5aa0eb97777f15a7 (commit)
via aa2579147103fef0d17f249336c088d041b5b403 (commit)
via 05df9c099d497a017a03f37f5116750691d01087 (commit)
via 53ed31174c82d971e931682d80c54e77b07c15f8 (commit)
via 70ea48192396caf3051673162cc06a423d065e02 (commit)
via 55b5194b26062cef811f5fde9487d4b64158bcb5 (commit)
via b79724aa8ad7ea1783b8f100e19effa493b39b34 (commit)
via a513654859fd4eeb188097355a34074406a85479 (commit)
via 19ab89718293f1ae761a0237cea47ecbfda76f9c (commit)
via 4c0d9bcacb0cb29c2a2c33032fed8392299353b5 (commit)
via 669d12b7b58da33fa889fc0faa8b1ea40f4733d8 (commit)
via 0612489eb8d325b30c4fa1bf7afa961cd9c45979 (commit)
via bae1ec5dd89662529127eab766ba100afe53c618 (commit)
via 3b250d8c958b209e0739eda15bb58b1456e2ff5a (commit)
via a56d95c3218ed1a4c78434430df3206e752c1a54 (commit)
via 205675af130077e3fe74325983f22c68d74267a9 (commit)
via 780e59e5baa189e7c7fa01c41378cd51cbbfb834 (commit)
via f2218fa2015df835718d4bba856c3365e84333f3 (commit)
via f18a260e1f75c090e1a1567173c53d82fd651fb2 (commit)
via 05c990e3c61a140b5036ea1b55f3274cd5cb04a4 (commit)
via 70f893c2d049f17ae7ff35d86c2f48cae01e1503 (commit)
via 12029c8f696863957ddbbdb784c4dda0a8e94f56 (commit)
via 7f913b210b523d68dd4bb7395b37dd5f824e1e22 (commit)
via 0cf7d27b68cba7d10942db2ee8d8ae3ff8fc17ec (commit)
via 10c443b05e002ba1cf3c917c228b77e312f35c59 (commit)
via e9c64425a8df9e91c9f14051e87138edd5d84aeb (commit)
via c094b362e18e9fed3551c2c2fa9375dbb0627789 (commit)
via 40a118a3ddf858ad88f5696406b6b3abac9dcc0f (commit)
via 98d5a7532ec67ce24c385648ba4cc8a24fdefb26 (commit)
via a65d906c7591a7c1d6312d3772b44272f61627b2 (commit)
via bd61d29819665315ba2f8ac2de9e162e864dabd0 (commit)
via 6e2fb189b6c199f0ec08662352803044b228abe7 (commit)
via 78366c9c9a039c722fd5b1187a6a9d431f3a61e0 (commit)
via 93aef19351dcb1538c9a4ddf2d5bfcbd37284015 (commit)
via 6162208b18d9351870770648d70e68575d7d68a2 (commit)
via eb4fbe43bb76aefc210bb92137996474887da0bf (commit)
via 9cc978be2ed4741410ce4d95913f4cf53cb93ba7 (commit)
via 72522570c89283573ebf914a604c12c016761208 (commit)
via 0853fdbf76f0ceadc77be39c7a5961dde409d756 (commit)
via 97f5bf78b56c673678404eec7c8961e49316cb35 (commit)
via d49ebdc0a9995bfcf7829cd3f5e0b0c2a88509cb (commit)
via 43e5b25daf7eecea247aebaf76fd2e2c722ab5af (commit)
via f9ef894ebd6d76f1a85c67d82473c6af31ad4ac3 (commit)
via 57692a847e30c2a95c568f2b15ed0cc6669a392c (commit)
via e4f5a23f414a1afe91a758e563bed1112d0bc9d6 (commit)
via 0f725603bf94f71bf71de57f9c9e8c42f445cc0c (commit)
via 6baadbc2fcd5baf128d6ad7768726addae1d9a2b (commit)
via 64e04af74bc1d40a168dd6e4244b0769cfafcb44 (commit)
via 207dd51b5dae6f5c4f88f576f79d6736b16ef559 (commit)
via ff796bd6fc1ae0744a7f7efc73a0bdb11b9975e8 (commit)
via 130a5dcf1f0c8bdc79dc617873e20033dc433311 (commit)
via 815e3e2f48614f1cead864d4151f188c62a88d95 (commit)
via da3a453442050482a419deff91d3dc92fdbf132a (commit)
via 9e9c1c3b6ab1c85e803f7611a38cfd4a9113e027 (commit)
via aa4fbb88b33a5b8f55295605caecf4841cfbb05a (commit)
via 5a13cc0b51f5d5a96a125beac16bf587c6189701 (commit)
via b212468779aa74dd719cb9ac614919c749927260 (commit)
via 45cf5cbebb15792d0439346d857e0a85aee7200d (commit)
via 1395a488c2db041cffc9558d48c2beaef276845a (commit)
via 054ac72165d347166553d3b0987d1442c194ee2d (commit)
via d856654f61afd4c674440c2d2b068336c3d5dfbd (commit)
via 76699369880f251fa0aae5f936642e53cb658a92 (commit)
via 9af9f804e7e272845b0dce09d98c1f88f0097670 (commit)
via 5c858d48ef21bb7ed74697b209120faf88c5fcef (commit)
via c3201eb4258ce9f1317910417ea6d3b810354727 (commit)
via 8c40a2e78e76a495bd3d77abdf565ac1175c89c0 (commit)
via b27b7881d3c3c776bca73b78e02149b3a9459f4c (commit)
via 8c223ecec89a5e097f13d788e9db016544f761e9 (commit)
via 065b545d3e1ad5ab06205ce8205d49b7dc632610 (commit)
via b81fd284cb7e600c6f4011741f9d7f91618cab12 (commit)
via f1170755a54cfeb7f55d394989ebbb5c14d9cc85 (commit)
via ce07a23e829a7271fc4b11af72117b8c14837ad3 (commit)
via d2127cf97568f02c8b7cf40e8d981b677455f619 (commit)
via 0d784d89f00fd350181e6559a9c94bca039210c8 (commit)
via a978e74d8303bf39bdcd081c2f77bb5289d1159d (commit)
via 0aec475a117564063a98a4e0219b35946eb393db (commit)
via 90047c17588fa07bb6cabca1ec14f290198d8883 (commit)
via a8f7f42453896dc97af0d51729a1a04ea7b3e900 (commit)
via 7e245cb05b5978b19c7f7f5236cff93906e11718 (commit)
via 41432f29df97e0ca44a7ac4dc7163f8ce7900803 (commit)
via ff2ab6bfd10050306dbbb65e1134703433b6b46a (commit)
via 19bb47e04e1de3764fc1e3b93be7589bae0d0e14 (commit)
via f44258e7f54013e6c64f1aeeb617f4b7f016a696 (commit)
via d50e03f75c2fa5635e715dcaa8f057f577a508f1 (commit)
via e14a3f4e11bc91d6cc0100209be4e2147f559301 (commit)
via 7cca21c8c126e98a64ec8677d2981d4a472ca26a (commit)
via 3585f727e20b8d986e1983213fb6b6677ae169ab (commit)
via e1a271d2525911e5c1cdcbb4bb495b6295acb5df (commit)
via 06e1fa2563792748dcebdabbd0a32efa11d559b4 (commit)
via b61162301e6c81b2be3b0def8438535d2fb4c28b (commit)
via 2620862d7ebafed7a86c26c682a01dcc2d11f705 (commit)
via d5c786e515791eaf53992dac8a6bd11520a661d6 (commit)
via 1aaf8a040116c614eb014fd2582e6bbc702b5e92 (commit)
via ca861020320e5a412114655eba10efe120a668a7 (commit)
via 4de86d2c97b9117db2808681d091f85c79279373 (commit)
via b2f78352b012820c1bbf4a6caa49d2380d9a3145 (commit)
via c7b99f8d90aa0b3a2be4fc609bfa83e5da261431 (commit)
via 813ac365b8ebf1e4d2e4434002ab248a0160833e (commit)
via a02e77558027149e5a8d405daba583baa394c796 (commit)
via a2a99fc7368401e56c0ff331b39f800ff320ca60 (commit)
via 8aa208b2796b05c74d2a4efa126b71514448e4fc (commit)
via 091e82590d2d7b63fa4e882cbc9681b470ba97e2 (commit)
via c9ee753591520129794452347403801545894caf (commit)
via a050890c67f43f989810bcb76695ff4f13eea938 (commit)
via bae118889863f9fa37fbafd195c5d8ed86404f11 (commit)
via fe0c574d0fd474cf1145786ed959ceb4df840874 (commit)
via 3a406e5cb384a22ade99069a69cec8d9091073c6 (commit)
via 9e82b590abbc53e2e2059067028a25e4c25dbef2 (commit)
via c78f3ec233c08fa7a3526621f06ea1521a47074c (commit)
via e04c57f1234925ba9acd681e2d944060a843975a (commit)
via 128554e383bafb7f9ac7b0edd3ec17ebb3ff90e0 (commit)
via 5e0b24e22043d49b2b87eb7157df1b97e7713b91 (commit)
via 6c32ca2e574f57e2eb57bc29c75b3ff506651a9e (commit)
via 18f70edb704e984ff70b7182d4795f5e28ef4168 (commit)
via 752e696bba75275c8e6330ff8fe7444318b9e21f (commit)
via 55bd5e663a1a7d3e611d124fea3aee68f54daeba (commit)
via 6795405f13dead5dff39cf884fa727c01d6f4636 (commit)
via b1854026fc611c259a66b5c537af6018be981d15 (commit)
via 13041c7e9aabd1f8067ad51efaa2b92b74c2f319 (commit)
via e0114f18272c347795c21ac59e9c1e4520e2de65 (commit)
via efba3908ce39499b007161f1c25b0d5de42e10fa (commit)
via 934603b401b6db47f65e3d706283f291cef8d96f (commit)
via efa9520b2133321b1649c92eda5db29d1d6d8ec5 (commit)
via 57b7f22475b6b3cdbe3514546c82eb5b2947041c (commit)
via 66144a226706c2ee8cccbcf2c5248f3c4aed404c (commit)
from b17e3b14d28839739764ce4c29bd3bec01f0fc3c (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 6227dcdcd4cf3be18579b9239857c8c3f3ae0e11
Merge: b17e3b1 2fc6c99
Author: Bill Erickson <berick at esilibrary.com>
Date: Wed Jul 6 15:21:58 2011 -0400
Vandelay matching, quality, error reporting, and queue export additions
* Configuration of direct MARC field comparisons of incoming record to existing records
* Support for nested boolean MARC comparison expressions: e.g. 100a and (020a or 024a)
* Support for field-level match scores to create an overall per-record match score
* Support for best match merge/overlay
* Support for field-level quality metrics to determine overall record quality
* Support for enforcing a minimum quality ratio on import to prevent import of lower quality records
* Support for capturing and reporting record and item import failures.
* Support for exporting record queues and items as print, CSV, and email
* Various small display fixes and cleanup
Signed-off-by: Bill Erickson <berick at esilibrary.com>
commit 2fc6c995cd469353f494e336b8db3b677aa3d25e
Author: Bill Erickson <berick at esilibrary.com>
Date: Wed Jul 6 15:18:48 2011 -0400
Stamped DB version
Signed-off-by: Bill Erickson <berick at esilibrary.com>
diff --git a/Open-ILS/src/sql/Pg/002.schema.config.sql b/Open-ILS/src/sql/Pg/002.schema.config.sql
index d9ad349..6276a29 100644
--- a/Open-ILS/src/sql/Pg/002.schema.config.sql
+++ b/Open-ILS/src/sql/Pg/002.schema.config.sql
@@ -86,7 +86,7 @@ CREATE TRIGGER no_overlapping_deps
BEFORE INSERT OR UPDATE ON config.db_patch_dependencies
FOR EACH ROW EXECUTE PROCEDURE evergreen.array_overlap_check ('deprecates');
-INSERT INTO config.upgrade_log (version, applied_to) VALUES ('0571', :eg_version); -- miker
+INSERT INTO config.upgrade_log (version, applied_to) VALUES ('0572', :eg_version); -- berick
CREATE TABLE config.bib_source (
id SERIAL PRIMARY KEY,
diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.vandelay-record-matching-and-quality.sql b/Open-ILS/src/sql/Pg/upgrade/0572.schema.vandelay-record-matching-and-quality.sql
similarity index 99%
rename from Open-ILS/src/sql/Pg/upgrade/XXXX.vandelay-record-matching-and-quality.sql
rename to Open-ILS/src/sql/Pg/upgrade/0572.schema.vandelay-record-matching-and-quality.sql
index 34a0b90..3b986b0 100644
--- a/Open-ILS/src/sql/Pg/upgrade/XXXX.vandelay-record-matching-and-quality.sql
+++ b/Open-ILS/src/sql/Pg/upgrade/0572.schema.vandelay-record-matching-and-quality.sql
@@ -1,12 +1,10 @@
--- Evergreen DB patch XXXX.vandelay-record-matching-and-quality.sql
---
--- FIXME: insert description of change, if needed
+-- Evergreen DB patch 0572.vandelay-record-matching-and-quality.sql
--
BEGIN;
-- check whether patch can be applied
---SELECT evergreen.upgrade_deps_block_check('XXXX', :eg_version);
+SELECT evergreen.upgrade_deps_block_check('0572', :eg_version);
CREATE OR REPLACE FUNCTION evergreen.array_remove_item_by_value(inp ANYARRAY, el ANYELEMENT) RETURNS anyarray AS $$ SELECT ARRAY_ACCUM(x.e) FROM UNNEST( $1 ) x(e) WHERE x.e <> $2; $$ LANGUAGE SQL;
commit 11218af3531a20925b6a9fdc5aa0eb97777f15a7
Author: Bill Erickson <berick at squeeze.localnet>
Date: Wed Jul 6 12:52:04 2011 -0400
Seed data and schema cleanup for merge
* Updated A/T event-def ID in seed data to match master
* Move schema elements into the correct order in the baseline files (mike)
Signed-off-by: Mike Rylander <mrylander at gmail.com>
Signed-off-by: Bill Erickson <berick at esilibrary.com>
diff --git a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
index 56edddd..8095e3b 100644
--- a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
+++ b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
@@ -153,7 +153,7 @@ CREATE TABLE vandelay.import_item (
definition BIGINT NOT NULL REFERENCES vandelay.import_item_attr_definition (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
import_error TEXT REFERENCES vandelay.import_error (code) ON DELETE SET NULL ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
error_detail TEXT,
- imported_as BIGINT REFERENCES asset.copy (id) DEFERRABLE INITIALLY DEFERRED,
+ imported_as BIGINT,
import_time TIMESTAMP WITH TIME ZONE,
owning_lib INT,
circ_lib INT,
@@ -1423,269 +1423,6 @@ CREATE OR REPLACE FUNCTION vandelay.auto_overlay_bib_queue ( queue_id BIGINT ) R
SELECT * FROM vandelay.auto_overlay_bib_queue( $1, NULL );
$$ LANGUAGE SQL;
-CREATE OR REPLACE FUNCTION vandelay.ingest_items ( import_id BIGINT, attr_def_id BIGINT ) RETURNS SETOF vandelay.import_item AS $$
-DECLARE
-
- owning_lib TEXT;
- circ_lib TEXT;
- call_number TEXT;
- copy_number TEXT;
- status TEXT;
- location TEXT;
- circulate TEXT;
- deposit TEXT;
- deposit_amount TEXT;
- ref TEXT;
- holdable TEXT;
- price TEXT;
- barcode TEXT;
- circ_modifier TEXT;
- circ_as_type TEXT;
- alert_message TEXT;
- opac_visible TEXT;
- pub_note TEXT;
- priv_note TEXT;
-
- attr_def RECORD;
- tmp_attr_set RECORD;
- attr_set vandelay.import_item%ROWTYPE;
-
- xpath TEXT;
-
-BEGIN
-
- SELECT * INTO attr_def FROM vandelay.import_item_attr_definition WHERE id = attr_def_id;
-
- IF FOUND THEN
-
- attr_set.definition := attr_def.id;
-
- -- Build the combined XPath
-
- owning_lib :=
- CASE
- WHEN attr_def.owning_lib IS NULL THEN 'null()'
- WHEN LENGTH( attr_def.owning_lib ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.owning_lib || '"]'
- ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.owning_lib
- END;
-
- circ_lib :=
- CASE
- WHEN attr_def.circ_lib IS NULL THEN 'null()'
- WHEN LENGTH( attr_def.circ_lib ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.circ_lib || '"]'
- ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.circ_lib
- END;
-
- call_number :=
- CASE
- WHEN attr_def.call_number IS NULL THEN 'null()'
- WHEN LENGTH( attr_def.call_number ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.call_number || '"]'
- ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.call_number
- END;
-
- copy_number :=
- CASE
- WHEN attr_def.copy_number IS NULL THEN 'null()'
- WHEN LENGTH( attr_def.copy_number ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.copy_number || '"]'
- ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.copy_number
- END;
-
- status :=
- CASE
- WHEN attr_def.status IS NULL THEN 'null()'
- WHEN LENGTH( attr_def.status ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.status || '"]'
- ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.status
- END;
-
- location :=
- CASE
- WHEN attr_def.location IS NULL THEN 'null()'
- WHEN LENGTH( attr_def.location ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.location || '"]'
- ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.location
- END;
-
- circulate :=
- CASE
- WHEN attr_def.circulate IS NULL THEN 'null()'
- WHEN LENGTH( attr_def.circulate ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.circulate || '"]'
- ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.circulate
- END;
-
- deposit :=
- CASE
- WHEN attr_def.deposit IS NULL THEN 'null()'
- WHEN LENGTH( attr_def.deposit ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.deposit || '"]'
- ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.deposit
- END;
-
- deposit_amount :=
- CASE
- WHEN attr_def.deposit_amount IS NULL THEN 'null()'
- WHEN LENGTH( attr_def.deposit_amount ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.deposit_amount || '"]'
- ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.deposit_amount
- END;
-
- ref :=
- CASE
- WHEN attr_def.ref IS NULL THEN 'null()'
- WHEN LENGTH( attr_def.ref ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.ref || '"]'
- ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.ref
- END;
-
- holdable :=
- CASE
- WHEN attr_def.holdable IS NULL THEN 'null()'
- WHEN LENGTH( attr_def.holdable ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.holdable || '"]'
- ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.holdable
- END;
-
- price :=
- CASE
- WHEN attr_def.price IS NULL THEN 'null()'
- WHEN LENGTH( attr_def.price ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.price || '"]'
- ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.price
- END;
-
- barcode :=
- CASE
- WHEN attr_def.barcode IS NULL THEN 'null()'
- WHEN LENGTH( attr_def.barcode ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.barcode || '"]'
- ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.barcode
- END;
-
- circ_modifier :=
- CASE
- WHEN attr_def.circ_modifier IS NULL THEN 'null()'
- WHEN LENGTH( attr_def.circ_modifier ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.circ_modifier || '"]'
- ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.circ_modifier
- END;
-
- circ_as_type :=
- CASE
- WHEN attr_def.circ_as_type IS NULL THEN 'null()'
- WHEN LENGTH( attr_def.circ_as_type ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.circ_as_type || '"]'
- ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.circ_as_type
- END;
-
- alert_message :=
- CASE
- WHEN attr_def.alert_message IS NULL THEN 'null()'
- WHEN LENGTH( attr_def.alert_message ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.alert_message || '"]'
- ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.alert_message
- END;
-
- opac_visible :=
- CASE
- WHEN attr_def.opac_visible IS NULL THEN 'null()'
- WHEN LENGTH( attr_def.opac_visible ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.opac_visible || '"]'
- ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.opac_visible
- END;
-
- pub_note :=
- CASE
- WHEN attr_def.pub_note IS NULL THEN 'null()'
- WHEN LENGTH( attr_def.pub_note ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.pub_note || '"]'
- ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.pub_note
- END;
- priv_note :=
- CASE
- WHEN attr_def.priv_note IS NULL THEN 'null()'
- WHEN LENGTH( attr_def.priv_note ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.priv_note || '"]'
- ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.priv_note
- END;
-
-
- xpath :=
- owning_lib || '|' ||
- circ_lib || '|' ||
- call_number || '|' ||
- copy_number || '|' ||
- status || '|' ||
- location || '|' ||
- circulate || '|' ||
- deposit || '|' ||
- deposit_amount || '|' ||
- ref || '|' ||
- holdable || '|' ||
- price || '|' ||
- barcode || '|' ||
- circ_modifier || '|' ||
- circ_as_type || '|' ||
- alert_message || '|' ||
- pub_note || '|' ||
- priv_note || '|' ||
- opac_visible;
-
- -- RAISE NOTICE 'XPath: %', xpath;
-
- FOR tmp_attr_set IN
- SELECT *
- FROM oils_xpath_table( 'id', 'marc', 'vandelay.queued_bib_record', xpath, 'id = ' || import_id )
- AS t( id INT, ol TEXT, clib TEXT, cn TEXT, cnum TEXT, cs TEXT, cl TEXT, circ TEXT,
- dep TEXT, dep_amount TEXT, r TEXT, hold TEXT, pr TEXT, bc TEXT, circ_mod TEXT,
- circ_as TEXT, amessage TEXT, note TEXT, pnote TEXT, opac_vis TEXT )
- LOOP
-
- tmp_attr_set.pr = REGEXP_REPLACE(tmp_attr_set.pr, E'[^0-9\\.]', '', 'g');
- tmp_attr_set.dep_amount = REGEXP_REPLACE(tmp_attr_set.dep_amount, E'[^0-9\\.]', '', 'g');
-
- tmp_attr_set.pr := NULLIF( tmp_attr_set.pr, '' );
- tmp_attr_set.dep_amount := NULLIF( tmp_attr_set.dep_amount, '' );
-
- SELECT id INTO attr_set.owning_lib FROM actor.org_unit WHERE shortname = UPPER(tmp_attr_set.ol); -- INT
- SELECT id INTO attr_set.circ_lib FROM actor.org_unit WHERE shortname = UPPER(tmp_attr_set.clib); -- INT
- SELECT id INTO attr_set.status FROM config.copy_status WHERE LOWER(name) = LOWER(tmp_attr_set.cs); -- INT
-
- SELECT id INTO attr_set.location
- FROM asset.copy_location
- WHERE LOWER(name) = LOWER(tmp_attr_set.cl)
- AND asset.copy_location.owning_lib = COALESCE(attr_set.owning_lib, attr_set.circ_lib); -- INT
-
- attr_set.circulate :=
- LOWER( SUBSTRING( tmp_attr_set.circ, 1, 1)) IN ('t','y','1')
- OR LOWER(tmp_attr_set.circ) = 'circulating'; -- BOOL
-
- attr_set.deposit :=
- LOWER( SUBSTRING( tmp_attr_set.dep, 1, 1 ) ) IN ('t','y','1')
- OR LOWER(tmp_attr_set.dep) = 'deposit'; -- BOOL
-
- attr_set.holdable :=
- LOWER( SUBSTRING( tmp_attr_set.hold, 1, 1 ) ) IN ('t','y','1')
- OR LOWER(tmp_attr_set.hold) = 'holdable'; -- BOOL
-
- attr_set.opac_visible :=
- LOWER( SUBSTRING( tmp_attr_set.opac_vis, 1, 1 ) ) IN ('t','y','1')
- OR LOWER(tmp_attr_set.opac_vis) = 'visible'; -- BOOL
-
- attr_set.ref :=
- LOWER( SUBSTRING( tmp_attr_set.r, 1, 1 ) ) IN ('t','y','1')
- OR LOWER(tmp_attr_set.r) = 'reference'; -- BOOL
-
- attr_set.copy_number := tmp_attr_set.cnum::INT; -- INT,
- attr_set.deposit_amount := tmp_attr_set.dep_amount::NUMERIC(6,2); -- NUMERIC(6,2),
- attr_set.price := tmp_attr_set.pr::NUMERIC(8,2); -- NUMERIC(8,2),
-
- attr_set.call_number := tmp_attr_set.cn; -- TEXT
- attr_set.barcode := tmp_attr_set.bc; -- TEXT,
- attr_set.circ_modifier := tmp_attr_set.circ_mod; -- TEXT,
- attr_set.circ_as_type := tmp_attr_set.circ_as; -- TEXT,
- attr_set.alert_message := tmp_attr_set.amessage; -- TEXT,
- attr_set.pub_note := tmp_attr_set.note; -- TEXT,
- attr_set.priv_note := tmp_attr_set.pnote; -- TEXT,
- attr_set.alert_message := tmp_attr_set.amessage; -- TEXT,
-
- RETURN NEXT attr_set;
-
- END LOOP;
-
- END IF;
-
- RETURN;
-
-END;
-$$ LANGUAGE PLPGSQL;
-
-
CREATE OR REPLACE FUNCTION vandelay.ingest_bib_marc ( ) RETURNS TRIGGER AS $$
DECLARE
value TEXT;
@@ -1709,70 +1446,6 @@ BEGIN
END;
$$ LANGUAGE PLPGSQL;
-CREATE OR REPLACE FUNCTION vandelay.ingest_bib_items ( ) RETURNS TRIGGER AS $func$
-DECLARE
- attr_def BIGINT;
- item_data vandelay.import_item%ROWTYPE;
-BEGIN
-
- IF TG_OP IN ('INSERT','UPDATE') AND NEW.imported_as IS NOT NULL THEN
- RETURN NEW;
- END IF;
-
- SELECT item_attr_def INTO attr_def FROM vandelay.bib_queue WHERE id = NEW.queue;
-
- FOR item_data IN SELECT * FROM vandelay.ingest_items( NEW.id::BIGINT, attr_def ) LOOP
- INSERT INTO vandelay.import_item (
- record,
- definition,
- owning_lib,
- circ_lib,
- call_number,
- copy_number,
- status,
- location,
- circulate,
- deposit,
- deposit_amount,
- ref,
- holdable,
- price,
- barcode,
- circ_modifier,
- circ_as_type,
- alert_message,
- pub_note,
- priv_note,
- opac_visible
- ) VALUES (
- NEW.id,
- item_data.definition,
- item_data.owning_lib,
- item_data.circ_lib,
- item_data.call_number,
- item_data.copy_number,
- item_data.status,
- item_data.location,
- item_data.circulate,
- item_data.deposit,
- item_data.deposit_amount,
- item_data.ref,
- item_data.holdable,
- item_data.price,
- item_data.barcode,
- item_data.circ_modifier,
- item_data.circ_as_type,
- item_data.alert_message,
- item_data.pub_note,
- item_data.priv_note,
- item_data.opac_visible
- );
- END LOOP;
-
- RETURN NULL;
-END;
-$func$ LANGUAGE PLPGSQL;
-
CREATE OR REPLACE FUNCTION vandelay.match_bib_record ( ) RETURNS TRIGGER AS $func$
DECLARE
attr RECORD;
@@ -1877,10 +1550,6 @@ CREATE TRIGGER ingest_bib_trigger
AFTER INSERT OR UPDATE ON vandelay.queued_bib_record
FOR EACH ROW EXECUTE PROCEDURE vandelay.ingest_bib_marc();
-CREATE TRIGGER ingest_item_trigger
- AFTER INSERT OR UPDATE ON vandelay.queued_bib_record
- FOR EACH ROW EXECUTE PROCEDURE vandelay.ingest_bib_items();
-
CREATE TRIGGER zz_match_bibs_trigger
BEFORE INSERT OR UPDATE ON vandelay.queued_bib_record
FOR EACH ROW EXECUTE PROCEDURE vandelay.match_bib_record();
diff --git a/Open-ILS/src/sql/Pg/030.schema.metabib.sql b/Open-ILS/src/sql/Pg/030.schema.metabib.sql
index 9f00d0c..b70fae4 100644
--- a/Open-ILS/src/sql/Pg/030.schema.metabib.sql
+++ b/Open-ILS/src/sql/Pg/030.schema.metabib.sql
@@ -595,7 +595,7 @@ CREATE OR REPLACE FUNCTION biblio.marc21_extract_fixed_field( rid BIGINT, ff TEX
SELECT * FROM vandelay.marc21_extract_fixed_field( (SELECT marc FROM biblio.record_entry WHERE id = $1), $2 );
$func$ LANGUAGE SQL;
-CREATE TYPE biblio.record_ff_map AS (record BIGINT, ff_name TEXT, ff_value TEXT);
+-- CREATE TYPE biblio.record_ff_map AS (record BIGINT, ff_name TEXT, ff_value TEXT);
CREATE OR REPLACE FUNCTION vandelay.marc21_extract_all_fixed_fields( marc TEXT ) RETURNS SETOF biblio.record_ff_map AS $func$
DECLARE
tag_data TEXT;
diff --git a/Open-ILS/src/sql/Pg/800.fkeys.sql b/Open-ILS/src/sql/Pg/800.fkeys.sql
index d0ee887..ad05dd7 100644
--- a/Open-ILS/src/sql/Pg/800.fkeys.sql
+++ b/Open-ILS/src/sql/Pg/800.fkeys.sql
@@ -82,6 +82,8 @@ ALTER TABLE serial.unit ADD CONSTRAINT serial_unit_call_number_fkey FOREIGN KEY
ALTER TABLE serial.unit ADD CONSTRAINT serial_unit_creator_fkey FOREIGN KEY (creator) REFERENCES actor.usr (id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED;
ALTER TABLE serial.unit ADD CONSTRAINT serial_unit_editor_fkey FOREIGN KEY (editor) REFERENCES actor.usr (id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED;
+ALTER TABLE vandelay.import_item ADD CONSTRAINT imported_as_fkey FOREIGN KEY (imported_as) REFERENCES asset.copy (id) DEFERRABLE INITIALLY DEFERRED;
+
ALTER TABLE asset.copy_note ADD CONSTRAINT asset_copy_note_copy_fkey FOREIGN KEY (owning_copy) REFERENCES asset.copy (id) DEFERRABLE INITIALLY DEFERRED;
ALTER TABLE asset.copy_note ADD CONSTRAINT asset_copy_note_creator_fkey FOREIGN KEY (creator) REFERENCES actor.usr (id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED;
diff --git a/Open-ILS/src/sql/Pg/950.data.seed-values.sql b/Open-ILS/src/sql/Pg/950.data.seed-values.sql
index fe7618d..c7372ed 100644
--- a/Open-ILS/src/sql/Pg/950.data.seed-values.sql
+++ b/Open-ILS/src/sql/Pg/950.data.seed-values.sql
@@ -8816,13 +8816,7 @@ INSERT INTO config.org_unit_setting_type ( name, label, description, datatype )
),
'bool'
);
-INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'general.unknown', oils_i18n_gettext('general.unknown', 'Import or Overlay failed', 'vie', 'description') );
-INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'import.item.duplicate.barcode', oils_i18n_gettext('import.item.duplicate.barcode', 'Import failed due to barcode collision', 'vie', 'description') );
-INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'import.duplicate.sysid', oils_i18n_gettext('import.duplicate.sysid', 'Import failed due to system id collision', 'vie', 'description') );
-INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'overlay.missing.sysid', oils_i18n_gettext('overlay.missing.sysid', 'Overlay failed due to missing system id', 'vie', 'description') );
-INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'import.auth.duplicate.acn', oils_i18n_gettext('import.auth.duplicate.acn', 'Import failed due to Accession Number collision', 'vie', 'description') );
-INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'import.xml.malformed', oils_i18n_gettext('import.xml.malformed', 'Malformed record cause Import failure', 'vie', 'description') );
-INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'overlay.xml.malformed', oils_i18n_gettext('overlay.xml.malformed', 'Malformed record cause Overlay failure', 'vie', 'description') );
+
----------------------------------------------------------------
-- Seed data for queued record/item exports
----------------------------------------------------------------
@@ -8940,7 +8934,7 @@ INSERT INTO action_trigger.event_definition (
granularity,
template
) VALUES (
- 38,
+ 39,
TRUE,
1,
'Print Output for Queued Bib Records',
@@ -8982,8 +8976,8 @@ $$
;
INSERT INTO action_trigger.environment ( event_def, path) VALUES (
- 38, 'attributes')
- ,( 38, 'queue')
+ 39, 'attributes')
+ ,( 39, 'queue')
;
INSERT INTO action_trigger.event_definition (
@@ -8998,7 +8992,7 @@ INSERT INTO action_trigger.event_definition (
granularity,
template
) VALUES (
- 39,
+ 40,
TRUE,
1,
'CSV Output for Queued Bib Records',
@@ -9017,8 +9011,8 @@ $$
;
INSERT INTO action_trigger.environment ( event_def, path) VALUES (
- 39, 'attributes')
- ,( 39, 'queue')
+ 40, 'attributes')
+ ,( 40, 'queue')
;
INSERT INTO action_trigger.event_definition (
@@ -9033,7 +9027,7 @@ INSERT INTO action_trigger.event_definition (
granularity,
template
) VALUES (
- 40,
+ 41,
TRUE,
1,
'Email Output for Queued Bib Records',
@@ -9079,9 +9073,9 @@ $$
;
INSERT INTO action_trigger.environment ( event_def, path) VALUES (
- 40, 'attributes')
- ,( 40, 'queue')
- ,( 40, 'queue.owner')
+ 41, 'attributes')
+ ,( 41, 'queue')
+ ,( 41, 'queue.owner')
;
INSERT INTO action_trigger.event_definition (
@@ -9096,7 +9090,7 @@ INSERT INTO action_trigger.event_definition (
granularity,
template
) VALUES (
- 41,
+ 42,
TRUE,
1,
'Print Output for Queued Authority Records',
@@ -9124,8 +9118,8 @@ $$
;
INSERT INTO action_trigger.environment ( event_def, path) VALUES (
- 41, 'attributes')
- ,( 41, 'queue')
+ 42, 'attributes')
+ ,( 42, 'queue')
;
INSERT INTO action_trigger.event_definition (
@@ -9140,7 +9134,7 @@ INSERT INTO action_trigger.event_definition (
granularity,
template
) VALUES (
- 42,
+ 43,
TRUE,
1,
'CSV Output for Queued Authority Records',
@@ -9159,8 +9153,8 @@ $$
;
INSERT INTO action_trigger.environment ( event_def, path) VALUES (
- 42, 'attributes')
- ,( 42, 'queue')
+ 43, 'attributes')
+ ,( 43, 'queue')
;
INSERT INTO action_trigger.event_definition (
@@ -9175,7 +9169,7 @@ INSERT INTO action_trigger.event_definition (
granularity,
template
) VALUES (
- 43,
+ 44,
TRUE,
1,
'Email Output for Queued Authority Records',
@@ -9207,9 +9201,9 @@ $$
;
INSERT INTO action_trigger.environment ( event_def, path) VALUES (
- 43, 'attributes')
- ,( 43, 'queue')
- ,( 43, 'queue.owner')
+ 44, 'attributes')
+ ,( 44, 'queue')
+ ,( 44, 'queue.owner')
;
INSERT INTO action_trigger.event_definition (
@@ -9224,7 +9218,7 @@ INSERT INTO action_trigger.event_definition (
granularity,
template
) VALUES (
- 44,
+ 45,
TRUE,
1,
'Print Output for Import Items from Queued Bib Records',
@@ -9276,10 +9270,10 @@ $$
;
INSERT INTO action_trigger.environment ( event_def, path) VALUES (
- 44, 'record')
- ,( 44, 'record.attributes')
- ,( 44, 'record.queue')
- ,( 44, 'record.queue.owner')
+ 45, 'record')
+ ,( 45, 'record.attributes')
+ ,( 45, 'record.queue')
+ ,( 45, 'record.queue.owner')
;
INSERT INTO action_trigger.event_definition (
@@ -9294,7 +9288,7 @@ INSERT INTO action_trigger.event_definition (
granularity,
template
) VALUES (
- 45,
+ 46,
TRUE,
1,
'CSV Output for Import Items from Queued Bib Records',
@@ -9313,10 +9307,10 @@ $$
;
INSERT INTO action_trigger.environment ( event_def, path) VALUES (
- 45, 'record')
- ,( 45, 'record.attributes')
- ,( 45, 'record.queue')
- ,( 45, 'record.queue.owner')
+ 46, 'record')
+ ,( 46, 'record.attributes')
+ ,( 46, 'record.queue')
+ ,( 46, 'record.queue.owner')
;
INSERT INTO action_trigger.event_definition (
@@ -9331,7 +9325,7 @@ INSERT INTO action_trigger.event_definition (
granularity,
template
) VALUES (
- 46,
+ 47,
TRUE,
1,
'Email Output for Import Items from Queued Bib Records',
@@ -9386,10 +9380,10 @@ $$
;
INSERT INTO action_trigger.environment ( event_def, path) VALUES (
- 46, 'record')
- ,( 46, 'record.attributes')
- ,( 46, 'record.queue')
- ,( 46, 'record.queue.owner')
+ 47, 'record')
+ ,( 47, 'record.attributes')
+ ,( 47, 'record.queue')
+ ,( 47, 'record.queue.owner')
;
diff --git a/Open-ILS/src/sql/Pg/999.functions.global.sql b/Open-ILS/src/sql/Pg/999.functions.global.sql
index 0152417..0faeea6 100644
--- a/Open-ILS/src/sql/Pg/999.functions.global.sql
+++ b/Open-ILS/src/sql/Pg/999.functions.global.sql
@@ -1457,3 +1457,334 @@ BEGIN
RETURN config.interval_to_seconds( interval_string::INTERVAL );
END;
$$ LANGUAGE plpgsql;
+
+CREATE OR REPLACE FUNCTION vandelay.ingest_items ( import_id BIGINT, attr_def_id BIGINT ) RETURNS SETOF vandelay.import_item AS $$
+DECLARE
+
+ owning_lib TEXT;
+ circ_lib TEXT;
+ call_number TEXT;
+ copy_number TEXT;
+ status TEXT;
+ location TEXT;
+ circulate TEXT;
+ deposit TEXT;
+ deposit_amount TEXT;
+ ref TEXT;
+ holdable TEXT;
+ price TEXT;
+ barcode TEXT;
+ circ_modifier TEXT;
+ circ_as_type TEXT;
+ alert_message TEXT;
+ opac_visible TEXT;
+ pub_note TEXT;
+ priv_note TEXT;
+
+ attr_def RECORD;
+ tmp_attr_set RECORD;
+ attr_set vandelay.import_item%ROWTYPE;
+
+ xpath TEXT;
+
+BEGIN
+
+ SELECT * INTO attr_def FROM vandelay.import_item_attr_definition WHERE id = attr_def_id;
+
+ IF FOUND THEN
+
+ attr_set.definition := attr_def.id;
+
+ -- Build the combined XPath
+
+ owning_lib :=
+ CASE
+ WHEN attr_def.owning_lib IS NULL THEN 'null()'
+ WHEN LENGTH( attr_def.owning_lib ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.owning_lib || '"]'
+ ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.owning_lib
+ END;
+
+ circ_lib :=
+ CASE
+ WHEN attr_def.circ_lib IS NULL THEN 'null()'
+ WHEN LENGTH( attr_def.circ_lib ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.circ_lib || '"]'
+ ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.circ_lib
+ END;
+
+ call_number :=
+ CASE
+ WHEN attr_def.call_number IS NULL THEN 'null()'
+ WHEN LENGTH( attr_def.call_number ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.call_number || '"]'
+ ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.call_number
+ END;
+
+ copy_number :=
+ CASE
+ WHEN attr_def.copy_number IS NULL THEN 'null()'
+ WHEN LENGTH( attr_def.copy_number ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.copy_number || '"]'
+ ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.copy_number
+ END;
+
+ status :=
+ CASE
+ WHEN attr_def.status IS NULL THEN 'null()'
+ WHEN LENGTH( attr_def.status ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.status || '"]'
+ ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.status
+ END;
+
+ location :=
+ CASE
+ WHEN attr_def.location IS NULL THEN 'null()'
+ WHEN LENGTH( attr_def.location ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.location || '"]'
+ ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.location
+ END;
+
+ circulate :=
+ CASE
+ WHEN attr_def.circulate IS NULL THEN 'null()'
+ WHEN LENGTH( attr_def.circulate ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.circulate || '"]'
+ ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.circulate
+ END;
+
+ deposit :=
+ CASE
+ WHEN attr_def.deposit IS NULL THEN 'null()'
+ WHEN LENGTH( attr_def.deposit ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.deposit || '"]'
+ ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.deposit
+ END;
+
+ deposit_amount :=
+ CASE
+ WHEN attr_def.deposit_amount IS NULL THEN 'null()'
+ WHEN LENGTH( attr_def.deposit_amount ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.deposit_amount || '"]'
+ ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.deposit_amount
+ END;
+
+ ref :=
+ CASE
+ WHEN attr_def.ref IS NULL THEN 'null()'
+ WHEN LENGTH( attr_def.ref ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.ref || '"]'
+ ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.ref
+ END;
+
+ holdable :=
+ CASE
+ WHEN attr_def.holdable IS NULL THEN 'null()'
+ WHEN LENGTH( attr_def.holdable ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.holdable || '"]'
+ ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.holdable
+ END;
+
+ price :=
+ CASE
+ WHEN attr_def.price IS NULL THEN 'null()'
+ WHEN LENGTH( attr_def.price ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.price || '"]'
+ ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.price
+ END;
+
+ barcode :=
+ CASE
+ WHEN attr_def.barcode IS NULL THEN 'null()'
+ WHEN LENGTH( attr_def.barcode ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.barcode || '"]'
+ ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.barcode
+ END;
+
+ circ_modifier :=
+ CASE
+ WHEN attr_def.circ_modifier IS NULL THEN 'null()'
+ WHEN LENGTH( attr_def.circ_modifier ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.circ_modifier || '"]'
+ ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.circ_modifier
+ END;
+
+ circ_as_type :=
+ CASE
+ WHEN attr_def.circ_as_type IS NULL THEN 'null()'
+ WHEN LENGTH( attr_def.circ_as_type ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.circ_as_type || '"]'
+ ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.circ_as_type
+ END;
+
+ alert_message :=
+ CASE
+ WHEN attr_def.alert_message IS NULL THEN 'null()'
+ WHEN LENGTH( attr_def.alert_message ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.alert_message || '"]'
+ ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.alert_message
+ END;
+
+ opac_visible :=
+ CASE
+ WHEN attr_def.opac_visible IS NULL THEN 'null()'
+ WHEN LENGTH( attr_def.opac_visible ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.opac_visible || '"]'
+ ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.opac_visible
+ END;
+
+ pub_note :=
+ CASE
+ WHEN attr_def.pub_note IS NULL THEN 'null()'
+ WHEN LENGTH( attr_def.pub_note ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.pub_note || '"]'
+ ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.pub_note
+ END;
+ priv_note :=
+ CASE
+ WHEN attr_def.priv_note IS NULL THEN 'null()'
+ WHEN LENGTH( attr_def.priv_note ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.priv_note || '"]'
+ ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.priv_note
+ END;
+
+
+ xpath :=
+ owning_lib || '|' ||
+ circ_lib || '|' ||
+ call_number || '|' ||
+ copy_number || '|' ||
+ status || '|' ||
+ location || '|' ||
+ circulate || '|' ||
+ deposit || '|' ||
+ deposit_amount || '|' ||
+ ref || '|' ||
+ holdable || '|' ||
+ price || '|' ||
+ barcode || '|' ||
+ circ_modifier || '|' ||
+ circ_as_type || '|' ||
+ alert_message || '|' ||
+ pub_note || '|' ||
+ priv_note || '|' ||
+ opac_visible;
+
+ -- RAISE NOTICE 'XPath: %', xpath;
+
+ FOR tmp_attr_set IN
+ SELECT *
+ FROM oils_xpath_table( 'id', 'marc', 'vandelay.queued_bib_record', xpath, 'id = ' || import_id )
+ AS t( id INT, ol TEXT, clib TEXT, cn TEXT, cnum TEXT, cs TEXT, cl TEXT, circ TEXT,
+ dep TEXT, dep_amount TEXT, r TEXT, hold TEXT, pr TEXT, bc TEXT, circ_mod TEXT,
+ circ_as TEXT, amessage TEXT, note TEXT, pnote TEXT, opac_vis TEXT )
+ LOOP
+
+ tmp_attr_set.pr = REGEXP_REPLACE(tmp_attr_set.pr, E'[^0-9\\.]', '', 'g');
+ tmp_attr_set.dep_amount = REGEXP_REPLACE(tmp_attr_set.dep_amount, E'[^0-9\\.]', '', 'g');
+
+ tmp_attr_set.pr := NULLIF( tmp_attr_set.pr, '' );
+ tmp_attr_set.dep_amount := NULLIF( tmp_attr_set.dep_amount, '' );
+
+ SELECT id INTO attr_set.owning_lib FROM actor.org_unit WHERE shortname = UPPER(tmp_attr_set.ol); -- INT
+ SELECT id INTO attr_set.circ_lib FROM actor.org_unit WHERE shortname = UPPER(tmp_attr_set.clib); -- INT
+ SELECT id INTO attr_set.status FROM config.copy_status WHERE LOWER(name) = LOWER(tmp_attr_set.cs); -- INT
+
+ SELECT id INTO attr_set.location
+ FROM asset.copy_location
+ WHERE LOWER(name) = LOWER(tmp_attr_set.cl)
+ AND asset.copy_location.owning_lib = COALESCE(attr_set.owning_lib, attr_set.circ_lib); -- INT
+
+ attr_set.circulate :=
+ LOWER( SUBSTRING( tmp_attr_set.circ, 1, 1)) IN ('t','y','1')
+ OR LOWER(tmp_attr_set.circ) = 'circulating'; -- BOOL
+
+ attr_set.deposit :=
+ LOWER( SUBSTRING( tmp_attr_set.dep, 1, 1 ) ) IN ('t','y','1')
+ OR LOWER(tmp_attr_set.dep) = 'deposit'; -- BOOL
+
+ attr_set.holdable :=
+ LOWER( SUBSTRING( tmp_attr_set.hold, 1, 1 ) ) IN ('t','y','1')
+ OR LOWER(tmp_attr_set.hold) = 'holdable'; -- BOOL
+
+ attr_set.opac_visible :=
+ LOWER( SUBSTRING( tmp_attr_set.opac_vis, 1, 1 ) ) IN ('t','y','1')
+ OR LOWER(tmp_attr_set.opac_vis) = 'visible'; -- BOOL
+
+ attr_set.ref :=
+ LOWER( SUBSTRING( tmp_attr_set.r, 1, 1 ) ) IN ('t','y','1')
+ OR LOWER(tmp_attr_set.r) = 'reference'; -- BOOL
+
+ attr_set.copy_number := tmp_attr_set.cnum::INT; -- INT,
+ attr_set.deposit_amount := tmp_attr_set.dep_amount::NUMERIC(6,2); -- NUMERIC(6,2),
+ attr_set.price := tmp_attr_set.pr::NUMERIC(8,2); -- NUMERIC(8,2),
+
+ attr_set.call_number := tmp_attr_set.cn; -- TEXT
+ attr_set.barcode := tmp_attr_set.bc; -- TEXT,
+ attr_set.circ_modifier := tmp_attr_set.circ_mod; -- TEXT,
+ attr_set.circ_as_type := tmp_attr_set.circ_as; -- TEXT,
+ attr_set.alert_message := tmp_attr_set.amessage; -- TEXT,
+ attr_set.pub_note := tmp_attr_set.note; -- TEXT,
+ attr_set.priv_note := tmp_attr_set.pnote; -- TEXT,
+ attr_set.alert_message := tmp_attr_set.amessage; -- TEXT,
+
+ RETURN NEXT attr_set;
+
+ END LOOP;
+
+ END IF;
+
+ RETURN;
+
+END;
+$$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION vandelay.ingest_bib_items ( ) RETURNS TRIGGER AS $func$
+DECLARE
+ attr_def BIGINT;
+ item_data vandelay.import_item%ROWTYPE;
+BEGIN
+
+ IF TG_OP IN ('INSERT','UPDATE') AND NEW.imported_as IS NOT NULL THEN
+ RETURN NEW;
+ END IF;
+
+ SELECT item_attr_def INTO attr_def FROM vandelay.bib_queue WHERE id = NEW.queue;
+
+ FOR item_data IN SELECT * FROM vandelay.ingest_items( NEW.id::BIGINT, attr_def ) LOOP
+ INSERT INTO vandelay.import_item (
+ record,
+ definition,
+ owning_lib,
+ circ_lib,
+ call_number,
+ copy_number,
+ status,
+ location,
+ circulate,
+ deposit,
+ deposit_amount,
+ ref,
+ holdable,
+ price,
+ barcode,
+ circ_modifier,
+ circ_as_type,
+ alert_message,
+ pub_note,
+ priv_note,
+ opac_visible
+ ) VALUES (
+ NEW.id,
+ item_data.definition,
+ item_data.owning_lib,
+ item_data.circ_lib,
+ item_data.call_number,
+ item_data.copy_number,
+ item_data.status,
+ item_data.location,
+ item_data.circulate,
+ item_data.deposit,
+ item_data.deposit_amount,
+ item_data.ref,
+ item_data.holdable,
+ item_data.price,
+ item_data.barcode,
+ item_data.circ_modifier,
+ item_data.circ_as_type,
+ item_data.alert_message,
+ item_data.pub_note,
+ item_data.priv_note,
+ item_data.opac_visible
+ );
+ END LOOP;
+
+ RETURN NULL;
+END;
+$func$ LANGUAGE PLPGSQL;
+
+CREATE TRIGGER ingest_item_trigger
+ AFTER INSERT OR UPDATE ON vandelay.queued_bib_record
+ FOR EACH ROW EXECUTE PROCEDURE vandelay.ingest_bib_items();
+
diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.vandelay-record-matching-and-quality.sql b/Open-ILS/src/sql/Pg/upgrade/XXXX.vandelay-record-matching-and-quality.sql
index 5093d5f..34a0b90 100644
--- a/Open-ILS/src/sql/Pg/upgrade/XXXX.vandelay-record-matching-and-quality.sql
+++ b/Open-ILS/src/sql/Pg/upgrade/XXXX.vandelay-record-matching-and-quality.sql
@@ -1140,7 +1140,7 @@ INSERT INTO action_trigger.event_definition (
granularity,
template
) VALUES (
- 38,
+ 39,
TRUE,
1,
'Print Output for Queued Bib Records',
@@ -1182,8 +1182,8 @@ $$
;
INSERT INTO action_trigger.environment ( event_def, path) VALUES (
- 38, 'attributes')
- ,( 38, 'queue')
+ 39, 'attributes')
+ ,( 39, 'queue')
;
INSERT INTO action_trigger.event_definition (
@@ -1198,7 +1198,7 @@ INSERT INTO action_trigger.event_definition (
granularity,
template
) VALUES (
- 39,
+ 40,
TRUE,
1,
'CSV Output for Queued Bib Records',
@@ -1217,8 +1217,8 @@ $$
;
INSERT INTO action_trigger.environment ( event_def, path) VALUES (
- 39, 'attributes')
- ,( 39, 'queue')
+ 40, 'attributes')
+ ,( 40, 'queue')
;
INSERT INTO action_trigger.event_definition (
@@ -1233,7 +1233,7 @@ INSERT INTO action_trigger.event_definition (
granularity,
template
) VALUES (
- 40,
+ 41,
TRUE,
1,
'Email Output for Queued Bib Records',
@@ -1279,9 +1279,9 @@ $$
;
INSERT INTO action_trigger.environment ( event_def, path) VALUES (
- 40, 'attributes')
- ,( 40, 'queue')
- ,( 40, 'queue.owner')
+ 41, 'attributes')
+ ,( 41, 'queue')
+ ,( 41, 'queue.owner')
;
INSERT INTO action_trigger.event_definition (
@@ -1296,7 +1296,7 @@ INSERT INTO action_trigger.event_definition (
granularity,
template
) VALUES (
- 41,
+ 42,
TRUE,
1,
'Print Output for Queued Authority Records',
@@ -1324,8 +1324,8 @@ $$
;
INSERT INTO action_trigger.environment ( event_def, path) VALUES (
- 41, 'attributes')
- ,( 41, 'queue')
+ 42, 'attributes')
+ ,( 42, 'queue')
;
INSERT INTO action_trigger.event_definition (
@@ -1340,7 +1340,7 @@ INSERT INTO action_trigger.event_definition (
granularity,
template
) VALUES (
- 42,
+ 43,
TRUE,
1,
'CSV Output for Queued Authority Records',
@@ -1359,8 +1359,8 @@ $$
;
INSERT INTO action_trigger.environment ( event_def, path) VALUES (
- 42, 'attributes')
- ,( 42, 'queue')
+ 43, 'attributes')
+ ,( 43, 'queue')
;
INSERT INTO action_trigger.event_definition (
@@ -1375,7 +1375,7 @@ INSERT INTO action_trigger.event_definition (
granularity,
template
) VALUES (
- 43,
+ 44,
TRUE,
1,
'Email Output for Queued Authority Records',
@@ -1407,9 +1407,9 @@ $$
;
INSERT INTO action_trigger.environment ( event_def, path) VALUES (
- 43, 'attributes')
- ,( 43, 'queue')
- ,( 43, 'queue.owner')
+ 44, 'attributes')
+ ,( 44, 'queue')
+ ,( 44, 'queue.owner')
;
INSERT INTO action_trigger.event_definition (
@@ -1424,7 +1424,7 @@ INSERT INTO action_trigger.event_definition (
granularity,
template
) VALUES (
- 44,
+ 45,
TRUE,
1,
'Print Output for Import Items from Queued Bib Records',
@@ -1476,10 +1476,10 @@ $$
;
INSERT INTO action_trigger.environment ( event_def, path) VALUES (
- 44, 'record')
- ,( 44, 'record.attributes')
- ,( 44, 'record.queue')
- ,( 44, 'record.queue.owner')
+ 45, 'record')
+ ,( 45, 'record.attributes')
+ ,( 45, 'record.queue')
+ ,( 45, 'record.queue.owner')
;
INSERT INTO action_trigger.event_definition (
@@ -1494,7 +1494,7 @@ INSERT INTO action_trigger.event_definition (
granularity,
template
) VALUES (
- 45,
+ 46,
TRUE,
1,
'CSV Output for Import Items from Queued Bib Records',
@@ -1513,10 +1513,10 @@ $$
;
INSERT INTO action_trigger.environment ( event_def, path) VALUES (
- 45, 'record')
- ,( 45, 'record.attributes')
- ,( 45, 'record.queue')
- ,( 45, 'record.queue.owner')
+ 46, 'record')
+ ,( 46, 'record.attributes')
+ ,( 46, 'record.queue')
+ ,( 46, 'record.queue.owner')
;
INSERT INTO action_trigger.event_definition (
@@ -1531,7 +1531,7 @@ INSERT INTO action_trigger.event_definition (
granularity,
template
) VALUES (
- 46,
+ 47,
TRUE,
1,
'Email Output for Import Items from Queued Bib Records',
@@ -1586,10 +1586,10 @@ $$
;
INSERT INTO action_trigger.environment ( event_def, path) VALUES (
- 46, 'record')
- ,( 46, 'record.attributes')
- ,( 46, 'record.queue')
- ,( 46, 'record.queue.owner')
+ 47, 'record')
+ ,( 47, 'record.attributes')
+ ,( 47, 'record.queue')
+ ,( 47, 'record.queue.owner')
;
commit aa2579147103fef0d17f249336c088d041b5b403
Author: Bill Erickson <berick at esilibrary.com>
Date: Tue May 31 15:24:09 2011 -0400
Logic error fixes in Vandelay
* When counting import failures, also count records that have no import
items attached
* Fixed problem w/ not setting import time/as on newly imported records
Signed-off-by: Bill Erickson <berick at esilibrary.com>
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
index b3e516b..c2811d1 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
@@ -489,7 +489,7 @@ sub retrieve_queued_records {
if($$options{with_import_error}) {
- $query->{from} = {$class => {vii => {type => 'right'}}};
+ $query->{from} = {$class => {vii => {type => 'left'}}};
$query->{where}->{'-or'} = [
{'+vqbr' => {import_error => {'!=' => undef}}},
{'+vii' => {import_error => {'!=' => undef}}}
@@ -1121,6 +1121,7 @@ sub import_record_list_impl {
$logger->info("vl: successfully imported new $type record");
$rec->imported_as($record->id);
+ $imported = 1;
}
}
}
commit 05df9c099d497a017a03f37f5116750691d01087
Author: Bill Erickson <berick at esilibrary.com>
Date: Tue May 31 12:16:16 2011 -0400
Repaired typo on schema and upgrade SQL
ARRAY_ACUM is not a defined function. Per Dan Scott, replaced with
ARRAY_AGG instead of the correctly spelled ARRAY_ACCUM, since we'll be
using that function in place of ARRAY_ACCUM going forward.
Thanks, Dan.
Minor syntax/cleanup repairs
Remove tmp seed data file. T'was replaced with upgrade script
Signed-off-by: Bill Erickson <berick at esilibrary.com>
diff --git a/Open-ILS/src/sql/Pg/002.schema.config.sql b/Open-ILS/src/sql/Pg/002.schema.config.sql
index 80b7a65..d9ad349 100644
--- a/Open-ILS/src/sql/Pg/002.schema.config.sql
+++ b/Open-ILS/src/sql/Pg/002.schema.config.sql
@@ -882,8 +882,8 @@ Upgrade script % can not be applied:
deprecated by %
superseded by %',
my_db_patch,
- deprecates,
- supersedes,
+ ARRAY_AGG(evergreen.upgrade_list_applied_deprecates(my_db_patch)),
+ ARRAY_AGG(evergreen.upgrade_list_applied_supersedes(my_db_patch)),
evergreen.upgrade_list_applied_deprecated(my_db_patch),
evergreen.upgrade_list_applied_superseded(my_db_patch);
END IF;
diff --git a/Open-ILS/src/sql/Pg/upgrade/0526.schema.upgrade-dep-tracking.sql b/Open-ILS/src/sql/Pg/upgrade/0526.schema.upgrade-dep-tracking.sql
index 86b381d..16ff50d 100644
--- a/Open-ILS/src/sql/Pg/upgrade/0526.schema.upgrade-dep-tracking.sql
+++ b/Open-ILS/src/sql/Pg/upgrade/0526.schema.upgrade-dep-tracking.sql
@@ -101,8 +101,8 @@ Upgrade script % can not be applied:
deprecated by %
superseded by %',
my_db_patch,
- deprecates,
- supersedes,
+ ARRAY_AGG(evergreen.upgrade_list_applied_deprecates(my_db_patch)),
+ ARRAY_AGG(evergreen.upgrade_list_applied_supersedes(my_db_patch)),
evergreen.upgrade_list_applied_deprecated(my_db_patch),
evergreen.upgrade_list_applied_superseded(my_db_patch);
END IF;
diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.vandelay-record-matching-and-quality.sql b/Open-ILS/src/sql/Pg/upgrade/XXXX.vandelay-record-matching-and-quality.sql
index 56154df..5093d5f 100644
--- a/Open-ILS/src/sql/Pg/upgrade/XXXX.vandelay-record-matching-and-quality.sql
+++ b/Open-ILS/src/sql/Pg/upgrade/XXXX.vandelay-record-matching-and-quality.sql
@@ -6,7 +6,7 @@ BEGIN;
-- check whether patch can be applied
-SELECT evergreen.upgrade_deps_block_check('XXXX', :eg_version);
+--SELECT evergreen.upgrade_deps_block_check('XXXX', :eg_version);
CREATE OR REPLACE FUNCTION evergreen.array_remove_item_by_value(inp ANYARRAY, el ANYELEMENT) RETURNS anyarray AS $$ SELECT ARRAY_ACCUM(x.e) FROM UNNEST( $1 ) x(e) WHERE x.e <> $2; $$ LANGUAGE SQL;
@@ -53,7 +53,7 @@ CREATE UNIQUE INDEX vmsq_def_once_per_set ON vandelay.match_set_quality (match_s
-- ALTER TABLEs...
ALTER TABLE vandelay.queue ADD COLUMN match_set INT REFERENCES vandelay.match_set (id) ON UPDATE CASCADE ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED;
-ALTER TABLE vandelay.queue_record ADD COLUMN quality INT NOT NULL DEFAULT 0;
+ALTER TABLE vandelay.queued_record ADD COLUMN quality INT NOT NULL DEFAULT 0;
ALTER TABLE vandelay.bib_attr_definition DROP COLUMN ident;
CREATE TABLE vandelay.import_error (
@@ -144,7 +144,6 @@ BEGIN
END;
$func$ LANGUAGE PLPGSQL;
-CREATE TYPE biblio.record_ff_map AS (record BIGINT, ff_name TEXT, ff_value TEXT);
CREATE OR REPLACE FUNCTION vandelay.marc21_extract_all_fixed_fields( marc TEXT ) RETURNS SETOF biblio.record_ff_map AS $func$
DECLARE
tag_data TEXT;
@@ -180,7 +179,6 @@ BEGIN
END;
$func$ LANGUAGE PLPGSQL;
-CREATE TYPE biblio.marc21_physical_characteristics AS ( id INT, record BIGINT, ptype TEXT, subfield INT, value INT );
CREATE OR REPLACE FUNCTION vandelay.marc21_physical_characteristics( marc TEXT) RETURNS SETOF biblio.marc21_physical_characteristics AS $func$
DECLARE
rowid INT := 0;
diff --git a/Open-ILS/src/sql/Pg/upgrade/renumber_me.sql b/Open-ILS/src/sql/Pg/upgrade/renumber_me.sql
deleted file mode 100644
index 5396747..0000000
--- a/Open-ILS/src/sql/Pg/upgrade/renumber_me.sql
+++ /dev/null
@@ -1,572 +0,0 @@
-BEGIN;
-
-INSERT INTO config.upgrade_log (version) VALUES ('test'); -- phasefx
-
-INSERT INTO action_trigger.hook (key,core_type,description,passive) VALUES (
- 'vandelay.queued_bib_record.print',
- 'vqbr',
- oils_i18n_gettext(
- 'vandelay.queued_bib_record.print',
- 'Print output has been requested for records in an Importer Bib Queue.',
- 'ath',
- 'description'
- ),
- FALSE
- )
- ,(
- 'vandelay.queued_bib_record.csv',
- 'vqbr',
- oils_i18n_gettext(
- 'vandelay.queued_bib_record.csv',
- 'CSV output has been requested for records in an Importer Bib Queue.',
- 'ath',
- 'description'
- ),
- FALSE
- )
- ,(
- 'vandelay.queued_bib_record.email',
- 'vqbr',
- oils_i18n_gettext(
- 'vandelay.queued_bib_record.email',
- 'An email has been requested for records in an Importer Bib Queue.',
- 'ath',
- 'description'
- ),
- FALSE
- )
- ,(
- 'vandelay.queued_auth_record.print',
- 'vqar',
- oils_i18n_gettext(
- 'vandelay.queued_auth_record.print',
- 'Print output has been requested for records in an Importer Authority Queue.',
- 'ath',
- 'description'
- ),
- FALSE
- )
- ,(
- 'vandelay.queued_auth_record.csv',
- 'vqar',
- oils_i18n_gettext(
- 'vandelay.queued_auth_record.csv',
- 'CSV output has been requested for records in an Importer Authority Queue.',
- 'ath',
- 'description'
- ),
- FALSE
- )
- ,(
- 'vandelay.queued_auth_record.email',
- 'vqar',
- oils_i18n_gettext(
- 'vandelay.queued_auth_record.email',
- 'An email has been requested for records in an Importer Authority Queue.',
- 'ath',
- 'description'
- ),
- FALSE
- )
- ,(
- 'vandelay.import_items.print',
- 'vii',
- oils_i18n_gettext(
- 'vandelay.import_items.print',
- 'Print output has been requested for Import Items from records in an Importer Bib Queue.',
- 'ath',
- 'description'
- ),
- FALSE
- )
- ,(
- 'vandelay.import_items.csv',
- 'vii',
- oils_i18n_gettext(
- 'vandelay.import_items.csv',
- 'CSV output has been requested for Import Items from records in an Importer Bib Queue.',
- 'ath',
- 'description'
- ),
- FALSE
- )
- ,(
- 'vandelay.import_items.email',
- 'vii',
- oils_i18n_gettext(
- 'vandelay.import_items.email',
- 'An email has been requested for Import Items from records in an Importer Bib Queue.',
- 'ath',
- 'description'
- ),
- FALSE
- )
-;
-
-INSERT INTO action_trigger.event_definition (
- id,
- active,
- owner,
- name,
- hook,
- validator,
- reactor,
- group_field,
- granularity,
- template
- ) VALUES (
- 38,
- TRUE,
- 1,
- 'Print Output for Queued Bib Records',
- 'vandelay.queued_bib_record.print',
- 'NOOP_True',
- 'ProcessTemplate',
- 'queue.owner',
- 'print-on-demand',
-$$
-[%- USE date -%]
-<pre>
-Queue ID: [% target.0.queue.id %]
-Queue Name: [% target.0.queue.name %]
-Queue Type: [% target.0.queue.queue_type %]
-Complete? [% target.0.queue.complete %]
-
- [% FOR vqbr IN target %]
-=-=-=
- Title of work | [% helpers.get_queued_bib_attr('title',vqbr.attributes) %]
- Author of work | [% helpers.get_queued_bib_attr('author',vqbr.attributes) %]
- Language of work | [% helpers.get_queued_bib_attr('language',vqbr.attributes) %]
- Pagination | [% helpers.get_queued_bib_attr('pagination',vqbr.attributes) %]
- ISBN | [% helpers.get_queued_bib_attr('isbn',vqbr.attributes) %]
- ISSN | [% helpers.get_queued_bib_attr('issn',vqbr.attributes) %]
- Price | [% helpers.get_queued_bib_attr('price',vqbr.attributes) %]
- Accession Number | [% helpers.get_queued_bib_attr('rec_identifier',vqbr.attributes) %]
- TCN Value | [% helpers.get_queued_bib_attr('eg_tcn',vqbr.attributes) %]
- TCN Source | [% helpers.get_queued_bib_attr('eg_tcn_source',vqbr.attributes) %]
- Internal ID | [% helpers.get_queued_bib_attr('eg_identifier',vqbr.attributes) %]
- Publisher | [% helpers.get_queued_bib_attr('publisher',vqbr.attributes) %]
- Publication Date | [% helpers.get_queued_bib_attr('pubdate',vqbr.attributes) %]
- Edition | [% helpers.get_queued_bib_attr('edition',vqbr.attributes) %]
- Item Barcode | [% helpers.get_queued_bib_attr('item_barcode',vqbr.attributes) %]
-
- [% END %]
-</pre>
-$$
- )
-;
-
-INSERT INTO action_trigger.environment ( event_def, path) VALUES (
- 38, 'attributes')
- ,( 38, 'queue')
-;
-
-INSERT INTO action_trigger.event_definition (
- id,
- active,
- owner,
- name,
- hook,
- validator,
- reactor,
- group_field,
- granularity,
- template
- ) VALUES (
- 39,
- TRUE,
- 1,
- 'CSV Output for Queued Bib Records',
- 'vandelay.queued_bib_record.csv',
- 'NOOP_True',
- 'ProcessTemplate',
- 'queue.owner',
- 'print-on-demand',
-$$
-[%- USE date -%]
-"Title of work","Author of work","Language of work","Pagination","ISBN","ISSN","Price","Accession Number","TCN Value","TCN Source","Internal ID","Publisher","Publication Date","Edition","Item Barcode"
-[% FOR vqbr IN target %]"[% helpers.get_queued_bib_attr('title',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('author',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('language',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('pagination',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('isbn',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('issn',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('price',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('rec_identifier',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('eg_tcn',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('eg_tcn_source',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('eg_identifier',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_att
r('publisher',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('pubdate',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('edition',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('item_barcode',vqbr.attributes) | replace('"', '""') %]"
-[% END %]
-$$
- )
-;
-
-INSERT INTO action_trigger.environment ( event_def, path) VALUES (
- 39, 'attributes')
- ,( 39, 'queue')
-;
-
-INSERT INTO action_trigger.event_definition (
- id,
- active,
- owner,
- name,
- hook,
- validator,
- reactor,
- group_field,
- granularity,
- template
- ) VALUES (
- 40,
- TRUE,
- 1,
- 'Email Output for Queued Bib Records',
- 'vandelay.queued_bib_record.email',
- 'NOOP_True',
- 'SendEmail',
- 'queue.owner',
- NULL,
-$$
-[%- USE date -%]
-[%- SET user = target.0.queue.owner -%]
-To: [%- params.recipient_email || user.email || 'root at localhost' %]
-From: [%- params.sender_email || default_sender %]
-Subject: Bibs from Import Queue
-
-Queue ID: [% target.0.queue.id %]
-Queue Name: [% target.0.queue.name %]
-Queue Type: [% target.0.queue.queue_type %]
-Complete? [% target.0.queue.complete %]
-
- [% FOR vqbr IN target %]
-=-=-=
- Title of work | [% helpers.get_queued_bib_attr('title',vqbr.attributes) %]
- Author of work | [% helpers.get_queued_bib_attr('author',vqbr.attributes) %]
- Language of work | [% helpers.get_queued_bib_attr('language',vqbr.attributes) %]
- Pagination | [% helpers.get_queued_bib_attr('pagination',vqbr.attributes) %]
- ISBN | [% helpers.get_queued_bib_attr('isbn',vqbr.attributes) %]
- ISSN | [% helpers.get_queued_bib_attr('issn',vqbr.attributes) %]
- Price | [% helpers.get_queued_bib_attr('price',vqbr.attributes) %]
- Accession Number | [% helpers.get_queued_bib_attr('rec_identifier',vqbr.attributes) %]
- TCN Value | [% helpers.get_queued_bib_attr('eg_tcn',vqbr.attributes) %]
- TCN Source | [% helpers.get_queued_bib_attr('eg_tcn_source',vqbr.attributes) %]
- Internal ID | [% helpers.get_queued_bib_attr('eg_identifier',vqbr.attributes) %]
- Publisher | [% helpers.get_queued_bib_attr('publisher',vqbr.attributes) %]
- Publication Date | [% helpers.get_queued_bib_attr('pubdate',vqbr.attributes) %]
- Edition | [% helpers.get_queued_bib_attr('edition',vqbr.attributes) %]
- Item Barcode | [% helpers.get_queued_bib_attr('item_barcode',vqbr.attributes) %]
-
- [% END %]
-
-$$
- )
-;
-
-INSERT INTO action_trigger.environment ( event_def, path) VALUES (
- 40, 'attributes')
- ,( 40, 'queue')
- ,( 40, 'queue.owner')
-;
-
-INSERT INTO action_trigger.event_definition (
- id,
- active,
- owner,
- name,
- hook,
- validator,
- reactor,
- group_field,
- granularity,
- template
- ) VALUES (
- 41,
- TRUE,
- 1,
- 'Print Output for Queued Authority Records',
- 'vandelay.queued_auth_record.print',
- 'NOOP_True',
- 'ProcessTemplate',
- 'queue.owner',
- 'print-on-demand',
-$$
-[%- USE date -%]
-<pre>
-Queue ID: [% target.0.queue.id %]
-Queue Name: [% target.0.queue.name %]
-Queue Type: [% target.0.queue.queue_type %]
-Complete? [% target.0.queue.complete %]
-
- [% FOR vqar IN target %]
-=-=-=
- Record Identifier | [% helpers.get_queued_auth_attr('rec_identifier',vqar.attributes) %]
-
- [% END %]
-</pre>
-$$
- )
-;
-
-INSERT INTO action_trigger.environment ( event_def, path) VALUES (
- 41, 'attributes')
- ,( 41, 'queue')
-;
-
-INSERT INTO action_trigger.event_definition (
- id,
- active,
- owner,
- name,
- hook,
- validator,
- reactor,
- group_field,
- granularity,
- template
- ) VALUES (
- 42,
- TRUE,
- 1,
- 'CSV Output for Queued Authority Records',
- 'vandelay.queued_auth_record.csv',
- 'NOOP_True',
- 'ProcessTemplate',
- 'queue.owner',
- 'print-on-demand',
-$$
-[%- USE date -%]
-"Record Identifier"
-[% FOR vqar IN target %]"[% helpers.get_queued_auth_attr('rec_identifier',vqar.attributes) | replace('"', '""') %]"
-[% END %]
-$$
- )
-;
-
-INSERT INTO action_trigger.environment ( event_def, path) VALUES (
- 42, 'attributes')
- ,( 42, 'queue')
-;
-
-INSERT INTO action_trigger.event_definition (
- id,
- active,
- owner,
- name,
- hook,
- validator,
- reactor,
- group_field,
- granularity,
- template
- ) VALUES (
- 43,
- TRUE,
- 1,
- 'Email Output for Queued Authority Records',
- 'vandelay.queued_auth_record.email',
- 'NOOP_True',
- 'SendEmail',
- 'queue.owner',
- NULL,
-$$
-[%- USE date -%]
-[%- SET user = target.0.queue.owner -%]
-To: [%- params.recipient_email || user.email || 'root at localhost' %]
-From: [%- params.sender_email || default_sender %]
-Subject: Authorities from Import Queue
-
-Queue ID: [% target.0.queue.id %]
-Queue Name: [% target.0.queue.name %]
-Queue Type: [% target.0.queue.queue_type %]
-Complete? [% target.0.queue.complete %]
-
- [% FOR vqar IN target %]
-=-=-=
- Record Identifier | [% helpers.get_queued_auth_attr('rec_identifier',vqar.attributes) %]
-
- [% END %]
-
-$$
- )
-;
-
-INSERT INTO action_trigger.environment ( event_def, path) VALUES (
- 43, 'attributes')
- ,( 43, 'queue')
- ,( 43, 'queue.owner')
-;
-
-INSERT INTO action_trigger.event_definition (
- id,
- active,
- owner,
- name,
- hook,
- validator,
- reactor,
- group_field,
- granularity,
- template
- ) VALUES (
- 44,
- TRUE,
- 1,
- 'Print Output for Import Items from Queued Bib Records',
- 'vandelay.import_items.print',
- 'NOOP_True',
- 'ProcessTemplate',
- 'record.queue.owner',
- 'print-on-demand',
-$$
-[%- USE date -%]
-<pre>
-Queue ID: [% target.0.record.queue.id %]
-Queue Name: [% target.0.record.queue.name %]
-Queue Type: [% target.0.record.queue.queue_type %]
-Complete? [% target.0.record.queue.complete %]
-
- [% FOR vii IN target %]
-=-=-=
- Import Item ID | [% vii.id %]
- Title of work | [% helpers.get_queued_bib_attr('title',vii.record.attributes) %]
- ISBN | [% helpers.get_queued_bib_attr('isbn',vii.record.attributes) %]
- Attribute Definition | [% vii.definition %]
- Import Error | [% vii.import_error %]
- Import Error Detail | [% vii.error_detail %]
- Owning Library | [% vii.owning_lib %]
- Circulating Library | [% vii.circ_lib %]
- Call Number | [% vii.call_number %]
- Copy Number | [% vii.copy_number %]
- Status | [% vii.status.name %]
- Shelving Location | [% vii.location.name %]
- Circulate | [% vii.circulate %]
- Deposit | [% vii.deposit %]
- Deposit Amount | [% vii.deposit_amount %]
- Reference | [% vii.ref %]
- Holdable | [% vii.holdable %]
- Price | [% vii.price %]
- Barcode | [% vii.barcode %]
- Circulation Modifier | [% vii.circ_modifier %]
- Circulate As MARC Type | [% vii.circ_as_type %]
- Alert Message | [% vii.alert_message %]
- Public Note | [% vii.pub_note %]
- Private Note | [% vii.priv_note %]
- OPAC Visible | [% vii.opac_visible %]
-
- [% END %]
-</pre>
-$$
- )
-;
-
-INSERT INTO action_trigger.environment ( event_def, path) VALUES (
- 44, 'record')
- ,( 44, 'record.attributes')
- ,( 44, 'record.queue')
- ,( 44, 'record.queue.owner')
-;
-
-INSERT INTO action_trigger.event_definition (
- id,
- active,
- owner,
- name,
- hook,
- validator,
- reactor,
- group_field,
- granularity,
- template
- ) VALUES (
- 45,
- TRUE,
- 1,
- 'CSV Output for Import Items from Queued Bib Records',
- 'vandelay.import_items.csv',
- 'NOOP_True',
- 'ProcessTemplate',
- 'record.queue.owner',
- 'print-on-demand',
-$$
-[%- USE date -%]
-"Import Item ID","Title of work","ISBN","Attribute Definition","Import Error","Import Error Detail","Owning Library","Circulating Library","Call Number","Copy Number","Status","Shelving Location","Circulate","Deposit","Deposit Amount","Reference","Holdable","Price","Barcode","Circulation Modifier","Circulate As MARC Type","Alert Message","Public Note","Private Note","OPAC Visible"
-[% FOR vii IN target %]"[% vii.id | replace('"', '""') %]","[% helpers.get_queued_bib_attr('title',vii.record.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('isbn',vii.record.attributes) | replace('"', '""') %]","[% vii.definition | replace('"', '""') %]","[% vii.import_error | replace('"', '""') %]","[% vii.error_detail | replace('"', '""') %]","[% vii.owning_lib | replace('"', '""') %]","[% vii.circ_lib | replace('"', '""') %]","[% vii.call_number | replace('"', '""') %]","[% vii.copy_number | replace('"', '""') %]","[% vii.status.name | replace('"', '""') %]","[% vii.location.name | replace('"', '""') %]","[% vii.circulate | replace('"', '""') %]","[% vii.deposit | replace('"', '""') %]","[% vii.deposit_amount | replace('"', '""') %]","[% vii.ref | replace('"', '""') %]","[% vii.holdable | replace('"', '""') %]","[% vii.price | replace('"', '""') %]","[% vii.barcode | replace('"', '""') %]","[% vii.circ_modifier | replace('"', '""') %]","[% vii.circ_
as_type | replace('"', '""') %]","[% vii.alert_message | replace('"', '""') %]","[% vii.pub_note | replace('"', '""') %]","[% vii.priv_note | replace('"', '""') %]","[% vii.opac_visible | replace('"', '""') %]"
-[% END %]
-$$
- )
-;
-
-INSERT INTO action_trigger.environment ( event_def, path) VALUES (
- 45, 'record')
- ,( 45, 'record.attributes')
- ,( 45, 'record.queue')
- ,( 45, 'record.queue.owner')
-;
-
-INSERT INTO action_trigger.event_definition (
- id,
- active,
- owner,
- name,
- hook,
- validator,
- reactor,
- group_field,
- granularity,
- template
- ) VALUES (
- 46,
- TRUE,
- 1,
- 'Email Output for Import Items from Queued Bib Records',
- 'vandelay.import_items.email',
- 'NOOP_True',
- 'SendEmail',
- 'record.queue.owner',
- NULL,
-$$
-[%- USE date -%]
-[%- SET user = target.0.record.queue.owner -%]
-To: [%- params.recipient_email || user.email || 'root at localhost' %]
-From: [%- params.sender_email || default_sender %]
-Subject: Import Items from Import Queue
-
-Queue ID: [% target.0.record.queue.id %]
-Queue Name: [% target.0.record.queue.name %]
-Queue Type: [% target.0.record.queue.queue_type %]
-Complete? [% target.0.record.queue.complete %]
-
- [% FOR vii IN target %]
-=-=-=
- Import Item ID | [% vii.id %]
- Title of work | [% helpers.get_queued_bib_attr('title',vii.record.attributes) %]
- ISBN | [% helpers.get_queued_bib_attr('isbn',vii.record.attributes) %]
- Attribute Definition | [% vii.definition %]
- Import Error | [% vii.import_error %]
- Import Error Detail | [% vii.error_detail %]
- Owning Library | [% vii.owning_lib %]
- Circulating Library | [% vii.circ_lib %]
- Call Number | [% vii.call_number %]
- Copy Number | [% vii.copy_number %]
- Status | [% vii.status.name %]
- Shelving Location | [% vii.location.name %]
- Circulate | [% vii.circulate %]
- Deposit | [% vii.deposit %]
- Deposit Amount | [% vii.deposit_amount %]
- Reference | [% vii.ref %]
- Holdable | [% vii.holdable %]
- Price | [% vii.price %]
- Barcode | [% vii.barcode %]
- Circulation Modifier | [% vii.circ_modifier %]
- Circulate As MARC Type | [% vii.circ_as_type %]
- Alert Message | [% vii.alert_message %]
- Public Note | [% vii.pub_note %]
- Private Note | [% vii.priv_note %]
- OPAC Visible | [% vii.opac_visible %]
-
- [% END %]
-$$
- )
-;
-
-INSERT INTO action_trigger.environment ( event_def, path) VALUES (
- 46, 'record')
- ,( 46, 'record.attributes')
- ,( 46, 'record.queue')
- ,( 46, 'record.queue.owner')
-;
-
-COMMIT;
-
--- BEGIN; DELETE FROM action_trigger.event WHERE event_def IN (38,39,40,41,42,43,44,45,46); DELETE FROM action_trigger.environment WHERE event_def IN (38,39,40,41,42,43,44,45,46); DELETE FROM action_trigger.event_definition WHERE id IN (38,39,40,41,42,43,44,45,46); DELETE FROM action_trigger.hook WHERE key IN ('vandelay.queued_bib_record.print','vandelay.queued_bib_record.csv','vandelay.queued_bib_record.email','vandelay.queued_auth_record.print','vandelay.queued_auth_record.csv','vandelay.queued_auth_record.email','vandelay.import_items.print','vandelay.import_items.csv','vandelay.import_items.email'); DELETE FROM action_trigger.event_output WHERE id IN ((SELECT template_output FROM action_trigger.event WHERE event_def IN (38,39,40,41,42,43,44,45,46))UNION(SELECT error_output FROM action_trigger.event WHERE event_def IN (38,39,40,41,42,43,44,45,46))); DELETE FROM config.upgrade_log WHERE version = 'test'; COMMIT;
commit 53ed31174c82d971e931682d80c54e77b07c15f8
Author: Mike Rylander <mrylander at gmail.com>
Date: Thu May 26 16:23:18 2011 -0400
Correct regression that was held over due to massive moving of functions
upgrade script cleanup
Signed-off-by: Mike Rylander <mrylander at gmail.com>
diff --git a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
index 9a5c3ef..56edddd 100644
--- a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
+++ b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
@@ -440,9 +440,10 @@ BEGIN
attr_value := oils_xpath_string(attr_def.xpath, transformed_xml, COALESCE(attr_def.joiner,' '), ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]]);
ELSIF attr_def.phys_char_sf IS NOT NULL THEN -- a named Physical Characteristic, see config.marc21_physical_characteristic_*_map
- SELECT value::TEXT INTO attr_value
- FROM vandelay.marc21_physical_characteristics(xml)
- WHERE subfield = attr_def.phys_char_sf
+ SELECT m.value::TEXT INTO attr_value
+ FROM vandelay.marc21_physical_characteristics(xml) v
+ JOIN config.marc21_physical_characteristic_value_map m ON (m.id = v.value)
+ WHERE v.subfield = attr_def.phys_char_sf
LIMIT 1; -- Just in case ...
END IF;
diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.vandelay-record-matching-and-quality.sql b/Open-ILS/src/sql/Pg/upgrade/XXXX.vandelay-record-matching-and-quality.sql
index fd0c694..56154df 100644
--- a/Open-ILS/src/sql/Pg/upgrade/XXXX.vandelay-record-matching-and-quality.sql
+++ b/Open-ILS/src/sql/Pg/upgrade/XXXX.vandelay-record-matching-and-quality.sql
@@ -52,47 +52,32 @@ CREATE UNIQUE INDEX vmsq_def_once_per_set ON vandelay.match_set_quality (match_s
-- ALTER TABLEs...
+ALTER TABLE vandelay.queue ADD COLUMN match_set INT REFERENCES vandelay.match_set (id) ON UPDATE CASCADE ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED;
+ALTER TABLE vandelay.queue_record ADD COLUMN quality INT NOT NULL DEFAULT 0;
+ALTER TABLE vandelay.bib_attr_definition DROP COLUMN ident;
- match_set INT REFERENCES vandelay.match_set (id) ON UPDATE CASCADE ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED,
-@@ -18,7 +60,8 @@ CREATE TABLE vandelay.queued_record (
-- marc TEXT NOT NULL
- marc TEXT NOT NULL,
- quality INT NOT NULL DEFAULT 0
-@@ -31,8 +74,7 @@ CREATE TABLE vandelay.bib_attr_definition (
-- remove TEXT NOT NULL DEFAULT '',
-- ident BOOL NOT NULL DEFAULT FALSE
- remove TEXT NOT NULL DEFAULT ''
-@@ -67,6 +109,11 @@ CREATE TABLE vandelay.import_item_attr_definition (
CREATE TABLE vandelay.import_error (
code TEXT PRIMARY KEY,
description TEXT NOT NULL -- i18n
);
-@@ -75,9 +122,11 @@ CREATE TABLE vandelay.bib_queue (
-- queue INT NOT NULL REFERENCES vandelay.bib_queue (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
-- bib_source INT REFERENCES config.bib_source (id) DEFERRABLE INITIALLY DEFERRED,
-- imported_as BIGINT REFERENCES biblio.record_entry (id) DEFERRABLE INITIALLY DEFERRED
- queue INT NOT NULL REFERENCES vandelay.bib_queue (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
- bib_source INT REFERENCES config.bib_source (id) DEFERRABLE INITIALLY DEFERRED,
- imported_as BIGINT REFERENCES biblio.record_entry (id) DEFERRABLE INITIALLY DEFERRED,
- import_error TEXT REFERENCES vandelay.import_error (code) ON DELETE SET NULL ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
- error_detail TEXT
-@@ -92,17 +141,20 @@ CREATE INDEX queued_bib_record_attr_record_idx ON vandelay.queued_bib_record_att
-- field_type TEXT NOT NULL CHECK (field_type in ('isbn','tcn_value','id')),
-- matched_attr INT REFERENCES vandelay.queued_bib_record_attr (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
-- eg_record BIGINT REFERENCES biblio.record_entry (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED
- eg_record BIGINT REFERENCES biblio.record_entry (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
- quality INT NOT NULL DEFAULT 1,
- match_score INT NOT NULL DEFAULT 0
---- DROP TABLE vandelay.import_item CASCADE;
- import_error TEXT REFERENCES vandelay.import_error (code) ON DELETE SET NULL ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
- error_detail TEXT,
- imported_as BIGINT REFERENCES asset.copy (id) DEFERRABLE INITIALLY DEFERRED,
- import_time TIMESTAMP WITH TIME ZONE,
-@@ -139,10 +191,592 @@ CREATE TABLE vandelay.merge_profile (
- lwm_ratio NUMERIC,
+ALTER TABLE vandelay.queued_bib_record
+ ADD COLUMN import_error TEXT REFERENCES vandelay.import_error (code) ON DELETE SET NULL ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
+ ADD COLUMN error_detail TEXT;
+ALTER TABLE vandelay.bib_match
+ DROP COLUMN field_type,
+ DROP COLUMN matched_attr,
+ ADD COLUMN quality INT NOT NULL DEFAULT 1,
+ ADD COLUMN match_score INT NOT NULL DEFAULT 0;
+ALTER TABLE vandelay.import_item
+ ADD COLUMN import_error TEXT REFERENCES vandelay.import_error (code) ON DELETE SET NULL ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
+ ADD COLUMN error_detail TEXT,
+ ADD COLUMN imported_as BIGINT REFERENCES asset.copy (id) DEFERRABLE INITIALLY DEFERRED,
+ ADD COLUMN import_time TIMESTAMP WITH TIME ZONE;
+
+ALTER TABLE vandelay.merge_profile ADD COLUMN lwm_ratio NUMERIC;
CREATE OR REPLACE FUNCTION vandelay.marc21_record_type( marc TEXT ) RETURNS config.marc21_rec_type_map AS $func$
DECLARE
@@ -355,9 +340,10 @@ BEGIN
attr_value := oils_xpath_string(attr_def.xpath, transformed_xml, COALESCE(attr_def.joiner,' '), ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]]);
ELSIF attr_def.phys_char_sf IS NOT NULL THEN -- a named Physical Characteristic, see config.marc21_physical_characteristic_*_map
- SELECT value::TEXT INTO attr_value
- FROM vandelay.marc21_physical_characteristics(xml)
- WHERE subfield = attr_def.phys_char_sf
+ SELECT m.value::TEXT INTO attr_value
+ FROM vandelay.marc21_physical_characteristics(xml) v
+ JOIN config.marc21_physical_characteristic_value_map m ON (m.id = v.value)
+ WHERE v.subfield = attr_def.phys_char_sf
LIMIT 1; -- Just in case ...
END IF;
@@ -929,39 +915,56 @@ BEGIN
END;
$$ LANGUAGE PLPGSQL;
-
-- ALTER TABLEs...
--
--CREATE OR REPLACE FUNCTION vandelay.cleanup_bib_marc ( ) RETURNS TRIGGER AS $$
--BEGIN
-@@ -1200,7 +1818,7 @@ CREATE TRIGGER ingest_item_trigger
-- AFTER INSERT OR UPDATE ON vandelay.queued_bib_record
+DROP TRIGGER zz_match_bibs_trigger ON vandelay.queued_bib_record;
+CREATE TRIGGER zz_match_bibs_trigger
BEFORE INSERT OR UPDATE ON vandelay.queued_bib_record
-@@ -1211,8 +1829,7 @@ CREATE TABLE vandelay.authority_attr_definition (
-- remove TEXT NOT NULL DEFAULT '',
-- ident BOOL NOT NULL DEFAULT FALSE
- remove TEXT NOT NULL DEFAULT ''
-@@ -1223,7 +1840,9 @@ ALTER TABLE vandelay.authority_queue ADD PRIMARY KEY (id);
-- imported_as INT REFERENCES authority.record_entry (id) DEFERRABLE INITIALLY DEFERRED
- imported_as INT REFERENCES authority.record_entry (id) DEFERRABLE INITIALLY DEFERRED,
- import_error TEXT REFERENCES vandelay.import_error (code) ON DELETE SET NULL ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
- error_detail TEXT
-@@ -1238,9 +1857,9 @@ CREATE INDEX queued_authority_record_attr_record_idx ON vandelay.queued_authorit
-- matched_attr INT REFERENCES vandelay.queued_authority_record_attr (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
-- eg_record BIGINT REFERENCES authority.record_entry (id) DEFERRABLE INITIALLY DEFERRED
- eg_record BIGINT REFERENCES authority.record_entry (id) DEFERRABLE INITIALLY DEFERRED,
- quality INT NOT NULL DEFAULT 0
-@@ -1249,6 +1868,10 @@ DECLARE
+ FOR EACH ROW EXECUTE PROCEDURE vandelay.match_bib_record();
+
+CREATE OR REPLACE FUNCTION vandelay.ingest_authority_marc ( ) RETURNS TRIGGER AS $$
+DECLARE
+ value TEXT;
+ atype TEXT;
+ adef RECORD;
+BEGIN
IF TG_OP IN ('INSERT','UPDATE') AND NEW.imported_as IS NOT NULL THEN
RETURN NEW;
END IF;
-@@ -1264,6 +1887,10 @@ $$ LANGUAGE PLPGSQL;
+ FOR adef IN SELECT * FROM vandelay.authority_attr_definition LOOP
+
+ SELECT extract_marc_field('vandelay.queued_authority_record', id, adef.xpath, adef.remove) INTO value FROM vandelay.queued_authority_record WHERE id = NEW.id;
+ IF (value IS NOT NULL AND value <> '') THEN
+ INSERT INTO vandelay.queued_authority_record_attr (record, field, attr_value) VALUES (NEW.id, adef.id, value);
+ END IF;
+
+ END LOOP;
+
+ RETURN NULL;
+END;
+$$ LANGUAGE PLPGSQL;
+
+ALTER TABLE vandelay.authority_attr_definition DROP COLUMN ident;
+ALTER TABLE vandelay.queued_authority_record
+ ADD COLUMN import_error TEXT REFERENCES vandelay.import_error (code) ON DELETE SET NULL ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
+ ADD COLUMN error_detail TEXT;
+
+ALTER TABLE vandelay.authority_match DROP COLUMN matched_attr;
+
+CREATE OR REPLACE FUNCTION vandelay.cleanup_authority_marc ( ) RETURNS TRIGGER AS $$
+BEGIN
IF TG_OP IN ('INSERT','UPDATE') AND NEW.imported_as IS NOT NULL THEN
RETURN NEW;
END IF;
-@@ -372,6 +372,27 @@ CREATE OR REPLACE FUNCTION biblio.extract_metabib_field_entry ( BIGINT ) RETURNS
+
+ DELETE FROM vandelay.queued_authority_record_attr WHERE record = OLD.id;
+ IF TG_OP = 'UPDATE' THEN
+ RETURN NEW;
+ END IF;
+ RETURN OLD;
+END;
+$$ LANGUAGE PLPGSQL;
CREATE OR REPLACE FUNCTION authority.flatten_marc ( rid BIGINT ) RETURNS SETOF authority.full_rec AS $func$
DECLARE
@@ -1005,29 +1008,6 @@ BEGIN
END;
$func$ LANGUAGE PLPGSQL;
-
-CREATE OR REPLACE FUNCTION authority.flatten_marc ( rid BIGINT ) RETURNS SETOF authority.full_rec AS $func$
-DECLARE
- auth authority.record_entry%ROWTYPE;
- output authority.full_rec%ROWTYPE;
- field RECORD;
-BEGIN
- SELECT INTO auth * FROM authority.record_entry WHERE id = rid;
-
- FOR field IN SELECT * FROM vandelay.flatten_marc( auth.marc ) LOOP
- output.record := rid;
- output.ind1 := field.ind1;
- output.ind2 := field.ind2;
- output.tag := field.tag;
- output.subfield := field.subfield;
- output.value := field.value;
-
- RETURN NEXT output;
- END LOOP;
-END;
-$func$ LANGUAGE PLPGSQL;
-
-
-----------------------------------------------
-- Seed data for import errors
-----------------------------------------------
commit 70ea48192396caf3051673162cc06a423d065e02
Author: berick <berick at esilibrary.com>
Date: Thu May 26 10:32:15 2011 -0400
seed data for vandlelay export templates
diff --git a/Open-ILS/src/sql/Pg/950.data.seed-values.sql b/Open-ILS/src/sql/Pg/950.data.seed-values.sql
index 0ad9ad0..fe7618d 100644
--- a/Open-ILS/src/sql/Pg/950.data.seed-values.sql
+++ b/Open-ILS/src/sql/Pg/950.data.seed-values.sql
@@ -8823,4 +8823,573 @@ INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'overlay.missin
INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'import.auth.duplicate.acn', oils_i18n_gettext('import.auth.duplicate.acn', 'Import failed due to Accession Number collision', 'vie', 'description') );
INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'import.xml.malformed', oils_i18n_gettext('import.xml.malformed', 'Malformed record cause Import failure', 'vie', 'description') );
INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'overlay.xml.malformed', oils_i18n_gettext('overlay.xml.malformed', 'Malformed record cause Overlay failure', 'vie', 'description') );
+----------------------------------------------------------------
+-- Seed data for queued record/item exports
+----------------------------------------------------------------
+
+INSERT INTO action_trigger.hook (key,core_type,description,passive) VALUES (
+ 'vandelay.queued_bib_record.print',
+ 'vqbr',
+ oils_i18n_gettext(
+ 'vandelay.queued_bib_record.print',
+ 'Print output has been requested for records in an Importer Bib Queue.',
+ 'ath',
+ 'description'
+ ),
+ FALSE
+ )
+ ,(
+ 'vandelay.queued_bib_record.csv',
+ 'vqbr',
+ oils_i18n_gettext(
+ 'vandelay.queued_bib_record.csv',
+ 'CSV output has been requested for records in an Importer Bib Queue.',
+ 'ath',
+ 'description'
+ ),
+ FALSE
+ )
+ ,(
+ 'vandelay.queued_bib_record.email',
+ 'vqbr',
+ oils_i18n_gettext(
+ 'vandelay.queued_bib_record.email',
+ 'An email has been requested for records in an Importer Bib Queue.',
+ 'ath',
+ 'description'
+ ),
+ FALSE
+ )
+ ,(
+ 'vandelay.queued_auth_record.print',
+ 'vqar',
+ oils_i18n_gettext(
+ 'vandelay.queued_auth_record.print',
+ 'Print output has been requested for records in an Importer Authority Queue.',
+ 'ath',
+ 'description'
+ ),
+ FALSE
+ )
+ ,(
+ 'vandelay.queued_auth_record.csv',
+ 'vqar',
+ oils_i18n_gettext(
+ 'vandelay.queued_auth_record.csv',
+ 'CSV output has been requested for records in an Importer Authority Queue.',
+ 'ath',
+ 'description'
+ ),
+ FALSE
+ )
+ ,(
+ 'vandelay.queued_auth_record.email',
+ 'vqar',
+ oils_i18n_gettext(
+ 'vandelay.queued_auth_record.email',
+ 'An email has been requested for records in an Importer Authority Queue.',
+ 'ath',
+ 'description'
+ ),
+ FALSE
+ )
+ ,(
+ 'vandelay.import_items.print',
+ 'vii',
+ oils_i18n_gettext(
+ 'vandelay.import_items.print',
+ 'Print output has been requested for Import Items from records in an Importer Bib Queue.',
+ 'ath',
+ 'description'
+ ),
+ FALSE
+ )
+ ,(
+ 'vandelay.import_items.csv',
+ 'vii',
+ oils_i18n_gettext(
+ 'vandelay.import_items.csv',
+ 'CSV output has been requested for Import Items from records in an Importer Bib Queue.',
+ 'ath',
+ 'description'
+ ),
+ FALSE
+ )
+ ,(
+ 'vandelay.import_items.email',
+ 'vii',
+ oils_i18n_gettext(
+ 'vandelay.import_items.email',
+ 'An email has been requested for Import Items from records in an Importer Bib Queue.',
+ 'ath',
+ 'description'
+ ),
+ FALSE
+ )
+;
+
+INSERT INTO action_trigger.event_definition (
+ id,
+ active,
+ owner,
+ name,
+ hook,
+ validator,
+ reactor,
+ group_field,
+ granularity,
+ template
+ ) VALUES (
+ 38,
+ TRUE,
+ 1,
+ 'Print Output for Queued Bib Records',
+ 'vandelay.queued_bib_record.print',
+ 'NOOP_True',
+ 'ProcessTemplate',
+ 'queue.owner',
+ 'print-on-demand',
+$$
+[%- USE date -%]
+<pre>
+Queue ID: [% target.0.queue.id %]
+Queue Name: [% target.0.queue.name %]
+Queue Type: [% target.0.queue.queue_type %]
+Complete? [% target.0.queue.complete %]
+
+ [% FOR vqbr IN target %]
+=-=-=
+ Title of work | [% helpers.get_queued_bib_attr('title',vqbr.attributes) %]
+ Author of work | [% helpers.get_queued_bib_attr('author',vqbr.attributes) %]
+ Language of work | [% helpers.get_queued_bib_attr('language',vqbr.attributes) %]
+ Pagination | [% helpers.get_queued_bib_attr('pagination',vqbr.attributes) %]
+ ISBN | [% helpers.get_queued_bib_attr('isbn',vqbr.attributes) %]
+ ISSN | [% helpers.get_queued_bib_attr('issn',vqbr.attributes) %]
+ Price | [% helpers.get_queued_bib_attr('price',vqbr.attributes) %]
+ Accession Number | [% helpers.get_queued_bib_attr('rec_identifier',vqbr.attributes) %]
+ TCN Value | [% helpers.get_queued_bib_attr('eg_tcn',vqbr.attributes) %]
+ TCN Source | [% helpers.get_queued_bib_attr('eg_tcn_source',vqbr.attributes) %]
+ Internal ID | [% helpers.get_queued_bib_attr('eg_identifier',vqbr.attributes) %]
+ Publisher | [% helpers.get_queued_bib_attr('publisher',vqbr.attributes) %]
+ Publication Date | [% helpers.get_queued_bib_attr('pubdate',vqbr.attributes) %]
+ Edition | [% helpers.get_queued_bib_attr('edition',vqbr.attributes) %]
+ Item Barcode | [% helpers.get_queued_bib_attr('item_barcode',vqbr.attributes) %]
+
+ [% END %]
+</pre>
+$$
+ )
+;
+
+INSERT INTO action_trigger.environment ( event_def, path) VALUES (
+ 38, 'attributes')
+ ,( 38, 'queue')
+;
+
+INSERT INTO action_trigger.event_definition (
+ id,
+ active,
+ owner,
+ name,
+ hook,
+ validator,
+ reactor,
+ group_field,
+ granularity,
+ template
+ ) VALUES (
+ 39,
+ TRUE,
+ 1,
+ 'CSV Output for Queued Bib Records',
+ 'vandelay.queued_bib_record.csv',
+ 'NOOP_True',
+ 'ProcessTemplate',
+ 'queue.owner',
+ 'print-on-demand',
+$$
+[%- USE date -%]
+"Title of work","Author of work","Language of work","Pagination","ISBN","ISSN","Price","Accession Number","TCN Value","TCN Source","Internal ID","Publisher","Publication Date","Edition","Item Barcode"
+[% FOR vqbr IN target %]"[% helpers.get_queued_bib_attr('title',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('author',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('language',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('pagination',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('isbn',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('issn',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('price',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('rec_identifier',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('eg_tcn',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('eg_tcn_source',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('eg_identifier',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_att
r('publisher',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('pubdate',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('edition',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('item_barcode',vqbr.attributes) | replace('"', '""') %]"
+[% END %]
+$$
+ )
+;
+
+INSERT INTO action_trigger.environment ( event_def, path) VALUES (
+ 39, 'attributes')
+ ,( 39, 'queue')
+;
+
+INSERT INTO action_trigger.event_definition (
+ id,
+ active,
+ owner,
+ name,
+ hook,
+ validator,
+ reactor,
+ group_field,
+ granularity,
+ template
+ ) VALUES (
+ 40,
+ TRUE,
+ 1,
+ 'Email Output for Queued Bib Records',
+ 'vandelay.queued_bib_record.email',
+ 'NOOP_True',
+ 'SendEmail',
+ 'queue.owner',
+ NULL,
+$$
+[%- USE date -%]
+[%- SET user = target.0.queue.owner -%]
+To: [%- params.recipient_email || user.email || 'root at localhost' %]
+From: [%- params.sender_email || default_sender %]
+Subject: Bibs from Import Queue
+
+Queue ID: [% target.0.queue.id %]
+Queue Name: [% target.0.queue.name %]
+Queue Type: [% target.0.queue.queue_type %]
+Complete? [% target.0.queue.complete %]
+
+ [% FOR vqbr IN target %]
+=-=-=
+ Title of work | [% helpers.get_queued_bib_attr('title',vqbr.attributes) %]
+ Author of work | [% helpers.get_queued_bib_attr('author',vqbr.attributes) %]
+ Language of work | [% helpers.get_queued_bib_attr('language',vqbr.attributes) %]
+ Pagination | [% helpers.get_queued_bib_attr('pagination',vqbr.attributes) %]
+ ISBN | [% helpers.get_queued_bib_attr('isbn',vqbr.attributes) %]
+ ISSN | [% helpers.get_queued_bib_attr('issn',vqbr.attributes) %]
+ Price | [% helpers.get_queued_bib_attr('price',vqbr.attributes) %]
+ Accession Number | [% helpers.get_queued_bib_attr('rec_identifier',vqbr.attributes) %]
+ TCN Value | [% helpers.get_queued_bib_attr('eg_tcn',vqbr.attributes) %]
+ TCN Source | [% helpers.get_queued_bib_attr('eg_tcn_source',vqbr.attributes) %]
+ Internal ID | [% helpers.get_queued_bib_attr('eg_identifier',vqbr.attributes) %]
+ Publisher | [% helpers.get_queued_bib_attr('publisher',vqbr.attributes) %]
+ Publication Date | [% helpers.get_queued_bib_attr('pubdate',vqbr.attributes) %]
+ Edition | [% helpers.get_queued_bib_attr('edition',vqbr.attributes) %]
+ Item Barcode | [% helpers.get_queued_bib_attr('item_barcode',vqbr.attributes) %]
+
+ [% END %]
+
+$$
+ )
+;
+
+INSERT INTO action_trigger.environment ( event_def, path) VALUES (
+ 40, 'attributes')
+ ,( 40, 'queue')
+ ,( 40, 'queue.owner')
+;
+
+INSERT INTO action_trigger.event_definition (
+ id,
+ active,
+ owner,
+ name,
+ hook,
+ validator,
+ reactor,
+ group_field,
+ granularity,
+ template
+ ) VALUES (
+ 41,
+ TRUE,
+ 1,
+ 'Print Output for Queued Authority Records',
+ 'vandelay.queued_auth_record.print',
+ 'NOOP_True',
+ 'ProcessTemplate',
+ 'queue.owner',
+ 'print-on-demand',
+$$
+[%- USE date -%]
+<pre>
+Queue ID: [% target.0.queue.id %]
+Queue Name: [% target.0.queue.name %]
+Queue Type: [% target.0.queue.queue_type %]
+Complete? [% target.0.queue.complete %]
+
+ [% FOR vqar IN target %]
+=-=-=
+ Record Identifier | [% helpers.get_queued_auth_attr('rec_identifier',vqar.attributes) %]
+
+ [% END %]
+</pre>
+$$
+ )
+;
+
+INSERT INTO action_trigger.environment ( event_def, path) VALUES (
+ 41, 'attributes')
+ ,( 41, 'queue')
+;
+
+INSERT INTO action_trigger.event_definition (
+ id,
+ active,
+ owner,
+ name,
+ hook,
+ validator,
+ reactor,
+ group_field,
+ granularity,
+ template
+ ) VALUES (
+ 42,
+ TRUE,
+ 1,
+ 'CSV Output for Queued Authority Records',
+ 'vandelay.queued_auth_record.csv',
+ 'NOOP_True',
+ 'ProcessTemplate',
+ 'queue.owner',
+ 'print-on-demand',
+$$
+[%- USE date -%]
+"Record Identifier"
+[% FOR vqar IN target %]"[% helpers.get_queued_auth_attr('rec_identifier',vqar.attributes) | replace('"', '""') %]"
+[% END %]
+$$
+ )
+;
+
+INSERT INTO action_trigger.environment ( event_def, path) VALUES (
+ 42, 'attributes')
+ ,( 42, 'queue')
+;
+
+INSERT INTO action_trigger.event_definition (
+ id,
+ active,
+ owner,
+ name,
+ hook,
+ validator,
+ reactor,
+ group_field,
+ granularity,
+ template
+ ) VALUES (
+ 43,
+ TRUE,
+ 1,
+ 'Email Output for Queued Authority Records',
+ 'vandelay.queued_auth_record.email',
+ 'NOOP_True',
+ 'SendEmail',
+ 'queue.owner',
+ NULL,
+$$
+[%- USE date -%]
+[%- SET user = target.0.queue.owner -%]
+To: [%- params.recipient_email || user.email || 'root at localhost' %]
+From: [%- params.sender_email || default_sender %]
+Subject: Authorities from Import Queue
+
+Queue ID: [% target.0.queue.id %]
+Queue Name: [% target.0.queue.name %]
+Queue Type: [% target.0.queue.queue_type %]
+Complete? [% target.0.queue.complete %]
+
+ [% FOR vqar IN target %]
+=-=-=
+ Record Identifier | [% helpers.get_queued_auth_attr('rec_identifier',vqar.attributes) %]
+
+ [% END %]
+
+$$
+ )
+;
+
+INSERT INTO action_trigger.environment ( event_def, path) VALUES (
+ 43, 'attributes')
+ ,( 43, 'queue')
+ ,( 43, 'queue.owner')
+;
+
+INSERT INTO action_trigger.event_definition (
+ id,
+ active,
+ owner,
+ name,
+ hook,
+ validator,
+ reactor,
+ group_field,
+ granularity,
+ template
+ ) VALUES (
+ 44,
+ TRUE,
+ 1,
+ 'Print Output for Import Items from Queued Bib Records',
+ 'vandelay.import_items.print',
+ 'NOOP_True',
+ 'ProcessTemplate',
+ 'record.queue.owner',
+ 'print-on-demand',
+$$
+[%- USE date -%]
+<pre>
+Queue ID: [% target.0.record.queue.id %]
+Queue Name: [% target.0.record.queue.name %]
+Queue Type: [% target.0.record.queue.queue_type %]
+Complete? [% target.0.record.queue.complete %]
+
+ [% FOR vii IN target %]
+=-=-=
+ Import Item ID | [% vii.id %]
+ Title of work | [% helpers.get_queued_bib_attr('title',vii.record.attributes) %]
+ ISBN | [% helpers.get_queued_bib_attr('isbn',vii.record.attributes) %]
+ Attribute Definition | [% vii.definition %]
+ Import Error | [% vii.import_error %]
+ Import Error Detail | [% vii.error_detail %]
+ Owning Library | [% vii.owning_lib %]
+ Circulating Library | [% vii.circ_lib %]
+ Call Number | [% vii.call_number %]
+ Copy Number | [% vii.copy_number %]
+ Status | [% vii.status.name %]
+ Shelving Location | [% vii.location.name %]
+ Circulate | [% vii.circulate %]
+ Deposit | [% vii.deposit %]
+ Deposit Amount | [% vii.deposit_amount %]
+ Reference | [% vii.ref %]
+ Holdable | [% vii.holdable %]
+ Price | [% vii.price %]
+ Barcode | [% vii.barcode %]
+ Circulation Modifier | [% vii.circ_modifier %]
+ Circulate As MARC Type | [% vii.circ_as_type %]
+ Alert Message | [% vii.alert_message %]
+ Public Note | [% vii.pub_note %]
+ Private Note | [% vii.priv_note %]
+ OPAC Visible | [% vii.opac_visible %]
+
+ [% END %]
+</pre>
+$$
+ )
+;
+
+INSERT INTO action_trigger.environment ( event_def, path) VALUES (
+ 44, 'record')
+ ,( 44, 'record.attributes')
+ ,( 44, 'record.queue')
+ ,( 44, 'record.queue.owner')
+;
+
+INSERT INTO action_trigger.event_definition (
+ id,
+ active,
+ owner,
+ name,
+ hook,
+ validator,
+ reactor,
+ group_field,
+ granularity,
+ template
+ ) VALUES (
+ 45,
+ TRUE,
+ 1,
+ 'CSV Output for Import Items from Queued Bib Records',
+ 'vandelay.import_items.csv',
+ 'NOOP_True',
+ 'ProcessTemplate',
+ 'record.queue.owner',
+ 'print-on-demand',
+$$
+[%- USE date -%]
+"Import Item ID","Title of work","ISBN","Attribute Definition","Import Error","Import Error Detail","Owning Library","Circulating Library","Call Number","Copy Number","Status","Shelving Location","Circulate","Deposit","Deposit Amount","Reference","Holdable","Price","Barcode","Circulation Modifier","Circulate As MARC Type","Alert Message","Public Note","Private Note","OPAC Visible"
+[% FOR vii IN target %]"[% vii.id | replace('"', '""') %]","[% helpers.get_queued_bib_attr('title',vii.record.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('isbn',vii.record.attributes) | replace('"', '""') %]","[% vii.definition | replace('"', '""') %]","[% vii.import_error | replace('"', '""') %]","[% vii.error_detail | replace('"', '""') %]","[% vii.owning_lib | replace('"', '""') %]","[% vii.circ_lib | replace('"', '""') %]","[% vii.call_number | replace('"', '""') %]","[% vii.copy_number | replace('"', '""') %]","[% vii.status.name | replace('"', '""') %]","[% vii.location.name | replace('"', '""') %]","[% vii.circulate | replace('"', '""') %]","[% vii.deposit | replace('"', '""') %]","[% vii.deposit_amount | replace('"', '""') %]","[% vii.ref | replace('"', '""') %]","[% vii.holdable | replace('"', '""') %]","[% vii.price | replace('"', '""') %]","[% vii.barcode | replace('"', '""') %]","[% vii.circ_modifier | replace('"', '""') %]","[% vii.circ_
as_type | replace('"', '""') %]","[% vii.alert_message | replace('"', '""') %]","[% vii.pub_note | replace('"', '""') %]","[% vii.priv_note | replace('"', '""') %]","[% vii.opac_visible | replace('"', '""') %]"
+[% END %]
+$$
+ )
+;
+
+INSERT INTO action_trigger.environment ( event_def, path) VALUES (
+ 45, 'record')
+ ,( 45, 'record.attributes')
+ ,( 45, 'record.queue')
+ ,( 45, 'record.queue.owner')
+;
+
+INSERT INTO action_trigger.event_definition (
+ id,
+ active,
+ owner,
+ name,
+ hook,
+ validator,
+ reactor,
+ group_field,
+ granularity,
+ template
+ ) VALUES (
+ 46,
+ TRUE,
+ 1,
+ 'Email Output for Import Items from Queued Bib Records',
+ 'vandelay.import_items.email',
+ 'NOOP_True',
+ 'SendEmail',
+ 'record.queue.owner',
+ NULL,
+$$
+[%- USE date -%]
+[%- SET user = target.0.record.queue.owner -%]
+To: [%- params.recipient_email || user.email || 'root at localhost' %]
+From: [%- params.sender_email || default_sender %]
+Subject: Import Items from Import Queue
+
+Queue ID: [% target.0.record.queue.id %]
+Queue Name: [% target.0.record.queue.name %]
+Queue Type: [% target.0.record.queue.queue_type %]
+Complete? [% target.0.record.queue.complete %]
+
+ [% FOR vii IN target %]
+=-=-=
+ Import Item ID | [% vii.id %]
+ Title of work | [% helpers.get_queued_bib_attr('title',vii.record.attributes) %]
+ ISBN | [% helpers.get_queued_bib_attr('isbn',vii.record.attributes) %]
+ Attribute Definition | [% vii.definition %]
+ Import Error | [% vii.import_error %]
+ Import Error Detail | [% vii.error_detail %]
+ Owning Library | [% vii.owning_lib %]
+ Circulating Library | [% vii.circ_lib %]
+ Call Number | [% vii.call_number %]
+ Copy Number | [% vii.copy_number %]
+ Status | [% vii.status.name %]
+ Shelving Location | [% vii.location.name %]
+ Circulate | [% vii.circulate %]
+ Deposit | [% vii.deposit %]
+ Deposit Amount | [% vii.deposit_amount %]
+ Reference | [% vii.ref %]
+ Holdable | [% vii.holdable %]
+ Price | [% vii.price %]
+ Barcode | [% vii.barcode %]
+ Circulation Modifier | [% vii.circ_modifier %]
+ Circulate As MARC Type | [% vii.circ_as_type %]
+ Alert Message | [% vii.alert_message %]
+ Public Note | [% vii.pub_note %]
+ Private Note | [% vii.priv_note %]
+ OPAC Visible | [% vii.opac_visible %]
+
+ [% END %]
+$$
+ )
+;
+
+INSERT INTO action_trigger.environment ( event_def, path) VALUES (
+ 46, 'record')
+ ,( 46, 'record.attributes')
+ ,( 46, 'record.queue')
+ ,( 46, 'record.queue.owner')
+;
+
commit 55b5194b26062cef811f5fde9487d4b64158bcb5
Author: berick <berick at esilibrary.com>
Date: Thu May 26 10:30:59 2011 -0400
Initial upgrade script for vandelay improvements
TODO:
* Set up the ALTER TABLE statements
* Further review
* Testing
diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.vandelay-record-matching-and-quality.sql b/Open-ILS/src/sql/Pg/upgrade/XXXX.vandelay-record-matching-and-quality.sql
new file mode 100644
index 0000000..fd0c694
--- /dev/null
+++ b/Open-ILS/src/sql/Pg/upgrade/XXXX.vandelay-record-matching-and-quality.sql
@@ -0,0 +1,1618 @@
+-- Evergreen DB patch XXXX.vandelay-record-matching-and-quality.sql
+--
+-- FIXME: insert description of change, if needed
+--
+BEGIN;
+
+
+-- check whether patch can be applied
+SELECT evergreen.upgrade_deps_block_check('XXXX', :eg_version);
+
+CREATE OR REPLACE FUNCTION evergreen.array_remove_item_by_value(inp ANYARRAY, el ANYELEMENT) RETURNS anyarray AS $$ SELECT ARRAY_ACCUM(x.e) FROM UNNEST( $1 ) x(e) WHERE x.e <> $2; $$ LANGUAGE SQL;
+
+CREATE TABLE vandelay.match_set (
+ id SERIAL PRIMARY KEY,
+ name TEXT NOT NULL,
+ owner INT NOT NULL REFERENCES actor.org_unit (id) ON DELETE CASCADE,
+ mtype TEXT NOT NULL DEFAULT 'biblio', -- 'biblio','authority','mfhd'?, others?
+ CONSTRAINT name_once_per_owner_mtype UNIQUE (name, owner, mtype)
+);
+
+-- Table to define match points, either FF via SVF or tag+subfield
+CREATE TABLE vandelay.match_set_point (
+ id SERIAL PRIMARY KEY,
+ match_set INT REFERENCES vandelay.match_set (id) ON DELETE CASCADE,
+ parent INT REFERENCES vandelay.match_set_point (id),
+ bool_op TEXT CHECK (bool_op IS NULL OR (bool_op IN ('AND','OR','NOT'))),
+ svf TEXT REFERENCES config.record_attr_definition (name),
+ tag TEXT,
+ subfield TEXT,
+ negate BOOL DEFAULT FALSE,
+ quality INT NOT NULL DEFAULT 1, -- higher is better
+ CONSTRAINT vmsp_need_a_subfield_with_a_tag CHECK ((tag IS NOT NULL AND subfield IS NOT NULL) OR tag IS NULL),
+ CONSTRAINT vmsp_need_a_tag_or_a_ff_or_a_bo CHECK (
+ (tag IS NOT NULL AND svf IS NULL AND bool_op IS NULL) OR
+ (tag IS NULL AND svf IS NOT NULL AND bool_op IS NULL) OR
+ (tag IS NULL AND svf IS NULL AND bool_op IS NOT NULL)
+ )
+);
+
+CREATE TABLE vandelay.match_set_quality (
+ id SERIAL PRIMARY KEY,
+ match_set INT NOT NULL REFERENCES vandelay.match_set (id) ON DELETE CASCADE,
+ svf TEXT REFERENCES config.record_attr_definition,
+ tag TEXT,
+ subfield TEXT,
+ value TEXT NOT NULL,
+ quality INT NOT NULL DEFAULT 1, -- higher is better
+ CONSTRAINT vmsq_need_a_subfield_with_a_tag CHECK ((tag IS NOT NULL AND subfield IS NOT NULL) OR tag IS NULL),
+ CONSTRAINT vmsq_need_a_tag_or_a_ff CHECK ((tag IS NOT NULL AND svf IS NULL) OR (tag IS NULL AND svf IS NOT NULL))
+);
+CREATE UNIQUE INDEX vmsq_def_once_per_set ON vandelay.match_set_quality (match_set, COALESCE(tag,''), COALESCE(subfield,''), COALESCE(svf,''), value);
+
+
+-- ALTER TABLEs...
+
+ match_set INT REFERENCES vandelay.match_set (id) ON UPDATE CASCADE ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED,
+@@ -18,7 +60,8 @@ CREATE TABLE vandelay.queued_record (
+- marc TEXT NOT NULL
+ marc TEXT NOT NULL,
+ quality INT NOT NULL DEFAULT 0
+@@ -31,8 +74,7 @@ CREATE TABLE vandelay.bib_attr_definition (
+- remove TEXT NOT NULL DEFAULT '',
+- ident BOOL NOT NULL DEFAULT FALSE
+ remove TEXT NOT NULL DEFAULT ''
+@@ -67,6 +109,11 @@ CREATE TABLE vandelay.import_item_attr_definition (
+CREATE TABLE vandelay.import_error (
+ code TEXT PRIMARY KEY,
+ description TEXT NOT NULL -- i18n
+);
+
+@@ -75,9 +122,11 @@ CREATE TABLE vandelay.bib_queue (
+- queue INT NOT NULL REFERENCES vandelay.bib_queue (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
+- bib_source INT REFERENCES config.bib_source (id) DEFERRABLE INITIALLY DEFERRED,
+- imported_as BIGINT REFERENCES biblio.record_entry (id) DEFERRABLE INITIALLY DEFERRED
+ queue INT NOT NULL REFERENCES vandelay.bib_queue (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
+ bib_source INT REFERENCES config.bib_source (id) DEFERRABLE INITIALLY DEFERRED,
+ imported_as BIGINT REFERENCES biblio.record_entry (id) DEFERRABLE INITIALLY DEFERRED,
+ import_error TEXT REFERENCES vandelay.import_error (code) ON DELETE SET NULL ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
+ error_detail TEXT
+@@ -92,17 +141,20 @@ CREATE INDEX queued_bib_record_attr_record_idx ON vandelay.queued_bib_record_att
+- field_type TEXT NOT NULL CHECK (field_type in ('isbn','tcn_value','id')),
+- matched_attr INT REFERENCES vandelay.queued_bib_record_attr (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
+- eg_record BIGINT REFERENCES biblio.record_entry (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED
+ eg_record BIGINT REFERENCES biblio.record_entry (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
+ quality INT NOT NULL DEFAULT 1,
+ match_score INT NOT NULL DEFAULT 0
+--- DROP TABLE vandelay.import_item CASCADE;
+ import_error TEXT REFERENCES vandelay.import_error (code) ON DELETE SET NULL ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
+ error_detail TEXT,
+ imported_as BIGINT REFERENCES asset.copy (id) DEFERRABLE INITIALLY DEFERRED,
+ import_time TIMESTAMP WITH TIME ZONE,
+@@ -139,10 +191,592 @@ CREATE TABLE vandelay.merge_profile (
+ lwm_ratio NUMERIC,
+
+
+
+CREATE OR REPLACE FUNCTION vandelay.marc21_record_type( marc TEXT ) RETURNS config.marc21_rec_type_map AS $func$
+DECLARE
+ ldr TEXT;
+ tval TEXT;
+ tval_rec RECORD;
+ bval TEXT;
+ bval_rec RECORD;
+ retval config.marc21_rec_type_map%ROWTYPE;
+BEGIN
+ ldr := oils_xpath_string( '//*[local-name()="leader"]', marc );
+
+ IF ldr IS NULL OR ldr = '' THEN
+ SELECT * INTO retval FROM config.marc21_rec_type_map WHERE code = 'BKS';
+ RETURN retval;
+ END IF;
+
+ SELECT * INTO tval_rec FROM config.marc21_ff_pos_map WHERE fixed_field = 'Type' LIMIT 1; -- They're all the same
+ SELECT * INTO bval_rec FROM config.marc21_ff_pos_map WHERE fixed_field = 'BLvl' LIMIT 1; -- They're all the same
+
+
+ tval := SUBSTRING( ldr, tval_rec.start_pos + 1, tval_rec.length );
+ bval := SUBSTRING( ldr, bval_rec.start_pos + 1, bval_rec.length );
+
+ -- RAISE NOTICE 'type %, blvl %, ldr %', tval, bval, ldr;
+
+ SELECT * INTO retval FROM config.marc21_rec_type_map WHERE type_val LIKE '%' || tval || '%' AND blvl_val LIKE '%' || bval || '%';
+
+
+ IF retval.code IS NULL THEN
+ SELECT * INTO retval FROM config.marc21_rec_type_map WHERE code = 'BKS';
+ END IF;
+
+ RETURN retval;
+END;
+$func$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION vandelay.marc21_extract_fixed_field( marc TEXT, ff TEXT ) RETURNS TEXT AS $func$
+DECLARE
+ rtype TEXT;
+ ff_pos RECORD;
+ tag_data RECORD;
+ val TEXT;
+BEGIN
+ rtype := (vandelay.marc21_record_type( marc )).code;
+ FOR ff_pos IN SELECT * FROM config.marc21_ff_pos_map WHERE fixed_field = ff AND rec_type = rtype ORDER BY tag DESC LOOP
+ IF ff_pos.tag = 'ldr' THEN
+ val := oils_xpath_string('//*[local-name()="leader"]', marc);
+ IF val IS NOT NULL THEN
+ val := SUBSTRING( val, ff_pos.start_pos + 1, ff_pos.length );
+ RETURN val;
+ END IF;
+ ELSE
+ FOR tag_data IN SELECT value FROM UNNEST( oils_xpath( '//*[@tag="' || UPPER(ff_pos.tag) || '"]/text()', marc ) ) x(value) LOOP
+ val := SUBSTRING( tag_data.value, ff_pos.start_pos + 1, ff_pos.length );
+ RETURN val;
+ END LOOP;
+ END IF;
+ val := REPEAT( ff_pos.default_val, ff_pos.length );
+ RETURN val;
+ END LOOP;
+
+ RETURN NULL;
+END;
+$func$ LANGUAGE PLPGSQL;
+
+CREATE TYPE biblio.record_ff_map AS (record BIGINT, ff_name TEXT, ff_value TEXT);
+CREATE OR REPLACE FUNCTION vandelay.marc21_extract_all_fixed_fields( marc TEXT ) RETURNS SETOF biblio.record_ff_map AS $func$
+DECLARE
+ tag_data TEXT;
+ rtype TEXT;
+ ff_pos RECORD;
+ output biblio.record_ff_map%ROWTYPE;
+BEGIN
+ rtype := (vandelay.marc21_record_type( marc )).code;
+
+ FOR ff_pos IN SELECT * FROM config.marc21_ff_pos_map WHERE rec_type = rtype ORDER BY tag DESC LOOP
+ output.ff_name := ff_pos.fixed_field;
+ output.ff_value := NULL;
+
+ IF ff_pos.tag = 'ldr' THEN
+ output.ff_value := oils_xpath_string('//*[local-name()="leader"]', marc);
+ IF output.ff_value IS NOT NULL THEN
+ output.ff_value := SUBSTRING( output.ff_value, ff_pos.start_pos + 1, ff_pos.length );
+ RETURN NEXT output;
+ output.ff_value := NULL;
+ END IF;
+ ELSE
+ FOR tag_data IN SELECT value FROM UNNEST( oils_xpath( '//*[@tag="' || UPPER(ff_pos.tag) || '"]/text()', marc ) ) x(value) LOOP
+ output.ff_value := SUBSTRING( tag_data, ff_pos.start_pos + 1, ff_pos.length );
+ IF output.ff_value IS NULL THEN output.ff_value := REPEAT( ff_pos.default_val, ff_pos.length ); END IF;
+ RETURN NEXT output;
+ output.ff_value := NULL;
+ END LOOP;
+ END IF;
+
+ END LOOP;
+
+ RETURN;
+END;
+$func$ LANGUAGE PLPGSQL;
+
+CREATE TYPE biblio.marc21_physical_characteristics AS ( id INT, record BIGINT, ptype TEXT, subfield INT, value INT );
+CREATE OR REPLACE FUNCTION vandelay.marc21_physical_characteristics( marc TEXT) RETURNS SETOF biblio.marc21_physical_characteristics AS $func$
+DECLARE
+ rowid INT := 0;
+ _007 TEXT;
+ ptype config.marc21_physical_characteristic_type_map%ROWTYPE;
+ psf config.marc21_physical_characteristic_subfield_map%ROWTYPE;
+ pval config.marc21_physical_characteristic_value_map%ROWTYPE;
+ retval biblio.marc21_physical_characteristics%ROWTYPE;
+BEGIN
+
+ _007 := oils_xpath_string( '//*[@tag="007"]', marc );
+
+ IF _007 IS NOT NULL AND _007 <> '' THEN
+ SELECT * INTO ptype FROM config.marc21_physical_characteristic_type_map WHERE ptype_key = SUBSTRING( _007, 1, 1 );
+
+ IF ptype.ptype_key IS NOT NULL THEN
+ FOR psf IN SELECT * FROM config.marc21_physical_characteristic_subfield_map WHERE ptype_key = ptype.ptype_key LOOP
+ SELECT * INTO pval FROM config.marc21_physical_characteristic_value_map WHERE ptype_subfield = psf.id AND value = SUBSTRING( _007, psf.start_pos + 1, psf.length );
+
+ IF pval.id IS NOT NULL THEN
+ rowid := rowid + 1;
+ retval.id := rowid;
+ retval.ptype := ptype.ptype_key;
+ retval.subfield := psf.id;
+ retval.value := pval.id;
+ RETURN NEXT retval;
+ END IF;
+
+ END LOOP;
+ END IF;
+ END IF;
+
+ RETURN;
+END;
+$func$ LANGUAGE PLPGSQL;
+
+CREATE TYPE vandelay.flat_marc AS ( tag CHAR(3), ind1 TEXT, ind2 TEXT, subfield TEXT, value TEXT );
+CREATE OR REPLACE FUNCTION vandelay.flay_marc ( TEXT ) RETURNS SETOF vandelay.flat_marc AS $func$
+
+use MARC::Record;
+use MARC::File::XML (BinaryEncoding => 'UTF-8');
+use MARC::Charset;
+use strict;
+
+MARC::Charset->assume_unicode(1);
+
+my $xml = shift;
+my $r = MARC::Record->new_from_xml( $xml );
+
+return_next( { tag => 'LDR', value => $r->leader } );
+
+for my $f ( $r->fields ) {
+ if ($f->is_control_field) {
+ return_next({ tag => $f->tag, value => $f->data });
+ } else {
+ for my $s ($f->subfields) {
+ return_next({
+ tag => $f->tag,
+ ind1 => $f->indicator(1),
+ ind2 => $f->indicator(2),
+ subfield => $s->[0],
+ value => $s->[1]
+ });
+
+ if ( $f->tag eq '245' and $s->[0] eq 'a' ) {
+ my $trim = $f->indicator(2) || 0;
+ return_next({
+ tag => 'tnf',
+ ind1 => $f->indicator(1),
+ ind2 => $f->indicator(2),
+ subfield => 'a',
+ value => substr( $s->[1], $trim )
+ });
+ }
+ }
+ }
+}
+
+return undef;
+
+$func$ LANGUAGE PLPERLU;
+
+CREATE OR REPLACE FUNCTION vandelay.flatten_marc ( marc TEXT ) RETURNS SETOF vandelay.flat_marc AS $func$
+DECLARE
+ output vandelay.flat_marc%ROWTYPE;
+ field RECORD;
+BEGIN
+ FOR field IN SELECT * FROM vandelay.flay_marc( marc ) LOOP
+ output.ind1 := field.ind1;
+ output.ind2 := field.ind2;
+ output.tag := field.tag;
+ output.subfield := field.subfield;
+ IF field.subfield IS NOT NULL AND field.tag NOT IN ('020','022','024') THEN -- exclude standard numbers and control fields
+ output.value := naco_normalize(field.value, field.subfield);
+ ELSE
+ output.value := field.value;
+ END IF;
+
+ CONTINUE WHEN output.value IS NULL;
+
+ RETURN NEXT output;
+ END LOOP;
+END;
+$func$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION vandelay.extract_rec_attrs ( xml TEXT, attr_defs TEXT[]) RETURNS hstore AS $_$
+DECLARE
+ transformed_xml TEXT;
+ prev_xfrm TEXT;
+ normalizer RECORD;
+ xfrm config.xml_transform%ROWTYPE;
+ attr_value TEXT;
+ new_attrs HSTORE := ''::HSTORE;
+ attr_def config.record_attr_definition%ROWTYPE;
+BEGIN
+
+ FOR attr_def IN SELECT * FROM config.record_attr_definition WHERE name IN (SELECT * FROM UNNEST(attr_defs)) ORDER BY format LOOP
+
+ IF attr_def.tag IS NOT NULL THEN -- tag (and optional subfield list) selection
+ SELECT ARRAY_TO_STRING(ARRAY_ACCUM(x.value), COALESCE(attr_def.joiner,' ')) INTO attr_value
+ FROM vandelay.flatten_marc(xml) AS x
+ WHERE x.tag LIKE attr_def.tag
+ AND CASE
+ WHEN attr_def.sf_list IS NOT NULL
+ THEN POSITION(x.subfield IN attr_def.sf_list) > 0
+ ELSE TRUE
+ END
+ GROUP BY x.tag
+ ORDER BY x.tag
+ LIMIT 1;
+
+ ELSIF attr_def.fixed_field IS NOT NULL THEN -- a named fixed field, see config.marc21_ff_pos_map.fixed_field
+ attr_value := vandelay.marc21_extract_fixed_field(xml, attr_def.fixed_field);
+
+ ELSIF attr_def.xpath IS NOT NULL THEN -- and xpath expression
+
+ SELECT INTO xfrm * FROM config.xml_transform WHERE name = attr_def.format;
+
+ -- See if we can skip the XSLT ... it's expensive
+ IF prev_xfrm IS NULL OR prev_xfrm <> xfrm.name THEN
+ -- Can't skip the transform
+ IF xfrm.xslt <> '---' THEN
+ transformed_xml := oils_xslt_process(xml,xfrm.xslt);
+ ELSE
+ transformed_xml := xml;
+ END IF;
+
+ prev_xfrm := xfrm.name;
+ END IF;
+
+ IF xfrm.name IS NULL THEN
+ -- just grab the marcxml (empty) transform
+ SELECT INTO xfrm * FROM config.xml_transform WHERE xslt = '---' LIMIT 1;
+ prev_xfrm := xfrm.name;
+ END IF;
+
+ attr_value := oils_xpath_string(attr_def.xpath, transformed_xml, COALESCE(attr_def.joiner,' '), ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]]);
+
+ ELSIF attr_def.phys_char_sf IS NOT NULL THEN -- a named Physical Characteristic, see config.marc21_physical_characteristic_*_map
+ SELECT value::TEXT INTO attr_value
+ FROM vandelay.marc21_physical_characteristics(xml)
+ WHERE subfield = attr_def.phys_char_sf
+ LIMIT 1; -- Just in case ...
+
+ END IF;
+
+ -- apply index normalizers to attr_value
+ FOR normalizer IN
+ SELECT n.func AS func,
+ n.param_count AS param_count,
+ m.params AS params
+ FROM config.index_normalizer n
+ JOIN config.record_attr_index_norm_map m ON (m.norm = n.id)
+ WHERE attr = attr_def.name
+ ORDER BY m.pos LOOP
+ EXECUTE 'SELECT ' || normalizer.func || '(' ||
+ quote_literal( attr_value ) ||
+ CASE
+ WHEN normalizer.param_count > 0
+ THEN ',' || REPLACE(REPLACE(BTRIM(normalizer.params,'[]'),E'\'',E'\\\''),E'"',E'\'')
+ ELSE ''
+ END ||
+ ')' INTO attr_value;
+
+ END LOOP;
+
+ -- Add the new value to the hstore
+ new_attrs := new_attrs || hstore( attr_def.name, attr_value );
+
+ END LOOP;
+
+ RETURN new_attrs;
+END;
+$_$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION vandelay.extract_rec_attrs ( xml TEXT ) RETURNS hstore AS $_$
+ SELECT vandelay.extract_rec_attrs( $1, (SELECT ARRAY_ACCUM(name) FROM config.record_attr_definition));
+$_$ LANGUAGE SQL;
+
+-- Everything between this comment and the beginning of the definition of
+-- vandelay.match_bib_record() is strictly in service of that function.
+CREATE TYPE vandelay.match_set_test_result AS (record BIGINT, quality INTEGER);
+
+CREATE OR REPLACE FUNCTION vandelay.match_set_test_marcxml(
+ match_set_id INTEGER, record_xml TEXT
+) RETURNS SETOF vandelay.match_set_test_result AS $$
+DECLARE
+ tags_rstore HSTORE;
+ svf_rstore HSTORE;
+ coal TEXT;
+ joins TEXT;
+ query_ TEXT;
+ wq TEXT;
+ qvalue INTEGER;
+ rec RECORD;
+BEGIN
+ tags_rstore := vandelay.flatten_marc_hstore(record_xml);
+ svf_rstore := vandelay.extract_rec_attrs(record_xml);
+
+ CREATE TEMPORARY TABLE _vandelay_tmp_qrows (q INTEGER);
+ CREATE TEMPORARY TABLE _vandelay_tmp_jrows (j TEXT);
+
+ -- generate the where clause and return that directly (into wq), and as
+ -- a side-effect, populate the _vandelay_tmp_[qj]rows tables.
+ wq := vandelay.get_expr_from_match_set(match_set_id);
+
+ query_ := 'SELECT bre.id AS record, ';
+
+ -- qrows table is for the quality bits we add to the SELECT clause
+ SELECT ARRAY_TO_STRING(
+ ARRAY_ACCUM('COALESCE(n' || q::TEXT || '.quality, 0)'), ' + '
+ ) INTO coal FROM _vandelay_tmp_qrows;
+
+ -- our query string so far is the SELECT clause and the inital FROM.
+ -- no JOINs yet nor the WHERE clause
+ query_ := query_ || coal || ' AS quality ' || E'\n' ||
+ 'FROM biblio.record_entry bre ';
+
+ -- jrows table is for the joins we must make (and the real text conditions)
+ SELECT ARRAY_TO_STRING(ARRAY_ACCUM(j), E'\n') INTO joins
+ FROM _vandelay_tmp_jrows;
+
+ -- add those joins and the where clause to our query.
+ query_ := query_ || joins || E'\n' || 'WHERE ' || wq || ' AND not bre.deleted';
+
+ -- this will return rows of record,quality
+ FOR rec IN EXECUTE query_ USING tags_rstore, svf_rstore LOOP
+ RETURN NEXT rec;
+ END LOOP;
+
+ DROP TABLE _vandelay_tmp_qrows;
+ DROP TABLE _vandelay_tmp_jrows;
+ RETURN;
+END;
+
+$$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION vandelay.flatten_marc_hstore(
+ record_xml TEXT
+) RETURNS HSTORE AS $$
+BEGIN
+ RETURN (SELECT
+ HSTORE(
+ ARRAY_ACCUM(tag || (COALESCE(subfield, ''))),
+ ARRAY_ACCUM(value)
+ )
+ FROM (
+ SELECT tag, subfield, ARRAY_ACCUM(value)::TEXT AS value
+ FROM vandelay.flatten_marc(record_xml)
+ GROUP BY tag, subfield ORDER BY tag, subfield
+ ) subquery
+ );
+END;
+$$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION vandelay.get_expr_from_match_set(
+ match_set_id INTEGER
+) RETURNS TEXT AS $$
+DECLARE
+ root vandelay.match_set_point;
+BEGIN
+ SELECT * INTO root FROM vandelay.match_set_point
+ WHERE parent IS NULL AND match_set = match_set_id;
+
+ RETURN vandelay.get_expr_from_match_set_point(root);
+END;
+$$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION vandelay.get_expr_from_match_set_point(
+ node vandelay.match_set_point
+) RETURNS TEXT AS $$
+DECLARE
+ q TEXT;
+ i INTEGER;
+ this_op TEXT;
+ children INTEGER[];
+ child vandelay.match_set_point;
+BEGIN
+ SELECT ARRAY_ACCUM(id) INTO children FROM vandelay.match_set_point
+ WHERE parent = node.id;
+
+ IF ARRAY_LENGTH(children, 1) > 0 THEN
+ this_op := vandelay._get_expr_render_one(node);
+ q := '(';
+ i := 1;
+ WHILE children[i] IS NOT NULL LOOP
+ SELECT * INTO child FROM vandelay.match_set_point
+ WHERE id = children[i];
+ IF i > 1 THEN
+ q := q || ' ' || this_op || ' ';
+ END IF;
+ i := i + 1;
+ q := q || vandelay.get_expr_from_match_set_point(child);
+ END LOOP;
+ q := q || ')';
+ RETURN q;
+ ELSIF node.bool_op IS NULL THEN
+ PERFORM vandelay._get_expr_push_qrow(node);
+ PERFORM vandelay._get_expr_push_jrow(node);
+ RETURN vandelay._get_expr_render_one(node);
+ ELSE
+ RETURN '';
+ END IF;
+END;
+$$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION vandelay._get_expr_push_qrow(
+ node vandelay.match_set_point
+) RETURNS VOID AS $$
+DECLARE
+BEGIN
+ INSERT INTO _vandelay_tmp_qrows (q) VALUES (node.id);
+END;
+$$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION vandelay._get_expr_push_jrow(
+ node vandelay.match_set_point
+) RETURNS VOID AS $$
+DECLARE
+ jrow TEXT;
+ my_alias TEXT;
+ op TEXT;
+ tagkey TEXT;
+BEGIN
+ IF node.negate THEN
+ op := '<>';
+ ELSE
+ op := '=';
+ END IF;
+
+ IF node.tag IS NOT NULL THEN
+ tagkey := node.tag;
+ IF node.subfield IS NOT NULL THEN
+ tagkey := tagkey || node.subfield;
+ END IF;
+ END IF;
+
+ my_alias := 'n' || node.id::TEXT;
+
+ jrow := 'LEFT JOIN (SELECT *, ' || node.quality ||
+ ' AS quality FROM metabib.';
+ IF node.tag IS NOT NULL THEN
+ jrow := jrow || 'full_rec) ' || my_alias || ' ON (' ||
+ my_alias || '.record = bre.id AND ' || my_alias || '.tag = ''' ||
+ node.tag || '''';
+ IF node.subfield IS NOT NULL THEN
+ jrow := jrow || ' AND ' || my_alias || '.subfield = ''' ||
+ node.subfield || '''';
+ END IF;
+ jrow := jrow || ' AND (' || my_alias || '.value ' || op ||
+ ' ANY(($1->''' || tagkey || ''')::TEXT[])))';
+ ELSE -- svf
+ jrow := jrow || 'record_attr) ' || my_alias || ' ON (' ||
+ my_alias || '.id = bre.id AND (' ||
+ my_alias || '.attrs->''' || node.svf ||
+ ''' ' || op || ' $2->''' || node.svf || '''))';
+ END IF;
+ INSERT INTO _vandelay_tmp_jrows (j) VALUES (jrow);
+END;
+$$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION vandelay._get_expr_render_one(
+ node vandelay.match_set_point
+) RETURNS TEXT AS $$
+DECLARE
+ s TEXT;
+BEGIN
+ IF node.bool_op IS NOT NULL THEN
+ RETURN node.bool_op;
+ ELSE
+ RETURN '(n' || node.id::TEXT || '.id IS NOT NULL)';
+ END IF;
+END;
+$$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION vandelay.match_bib_record() RETURNS TRIGGER AS $func$
+DECLARE
+ incoming_existing_id TEXT;
+ test_result vandelay.match_set_test_result%ROWTYPE;
+ tmp_rec BIGINT;
+ match_set INT;
+BEGIN
+ IF TG_OP IN ('INSERT','UPDATE') AND NEW.imported_as IS NOT NULL THEN
+ RETURN NEW;
+ END IF;
+
+ DELETE FROM vandelay.bib_match WHERE queued_record = NEW.id;
+
+ SELECT q.match_set INTO match_set FROM vandelay.bib_queue q WHERE q.id = NEW.queue;
+
+ IF match_set IS NOT NULL THEN
+ NEW.quality := vandelay.measure_record_quality( NEW.marc, match_set );
+ END IF;
+
+ -- Perfect matches on 901$c exit early with a match with high quality.
+ incoming_existing_id :=
+ oils_xpath_string('//*[@tag="901"]/*[@code="c"][1]', NEW.marc);
+
+ IF incoming_existing_id IS NOT NULL AND incoming_existing_id != '' THEN
+ SELECT id INTO tmp_rec FROM biblio.record_entry WHERE id = incoming_existing_id::bigint;
+ IF tmp_rec IS NOT NULL THEN
+ INSERT INTO vandelay.bib_match (queued_record, eg_record, match_score, quality)
+ SELECT
+ NEW.id,
+ b.id,
+ 9999,
+ -- note: no match_set means quality==0
+ vandelay.measure_record_quality( b.marc, match_set )
+ FROM biblio.record_entry b
+ WHERE id = incoming_existing_id::bigint;
+ END IF;
+ END IF;
+
+ IF match_set IS NULL THEN
+ RETURN NEW;
+ END IF;
+
+ FOR test_result IN SELECT * FROM
+ vandelay.match_set_test_marcxml(match_set, NEW.marc) LOOP
+
+ INSERT INTO vandelay.bib_match ( queued_record, eg_record, match_score, quality )
+ SELECT
+ NEW.id,
+ test_result.record,
+ test_result.quality,
+ vandelay.measure_record_quality( b.marc, match_set )
+ FROM biblio.record_entry b
+ WHERE id = test_result.record;
+
+ END LOOP;
+
+ RETURN NEW;
+END;
+$func$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION vandelay.measure_record_quality ( xml TEXT, match_set_id INT ) RETURNS INT AS $_$
+DECLARE
+ out_q INT := 0;
+ rvalue TEXT;
+ test vandelay.match_set_quality%ROWTYPE;
+BEGIN
+
+ FOR test IN SELECT * FROM vandelay.match_set_quality WHERE match_set = match_set_id LOOP
+ IF test.tag IS NOT NULL THEN
+ FOR rvalue IN SELECT value FROM vandelay.flatten_marc( xml ) WHERE tag = test.tag AND subfield = test.subfield LOOP
+ IF test.value = rvalue THEN
+ out_q := out_q + test.quality;
+ END IF;
+ END LOOP;
+ ELSE
+ IF test.value = vandelay.extract_rec_attrs(xml, ARRAY[test.svf]) -> test.svf THEN
+ out_q := out_q + test.quality;
+ END IF;
+ END IF;
+ END LOOP;
+
+ RETURN out_q;
+END;
+$_$ LANGUAGE PLPGSQL;
+
+
+CREATE OR REPLACE FUNCTION vandelay.overlay_bib_record ( import_id BIGINT, eg_id BIGINT, merge_profile_id INT ) RETURNS BOOL AS $$
+DECLARE
+ merge_profile vandelay.merge_profile%ROWTYPE;
+ dyn_profile vandelay.compile_profile%ROWTYPE;
+ editor_string TEXT;
+ editor_id INT;
+ source_marc TEXT;
+ target_marc TEXT;
+ eg_marc TEXT;
+ v_marc TEXT;
+ replace_rule TEXT;
+BEGIN
+
+ SELECT q.marc INTO v_marc
+ FROM vandelay.queued_record q
+ JOIN vandelay.bib_match m ON (m.queued_record = q.id AND q.id = import_id)
+ LIMIT 1;
+
+ IF v_marc IS NULL THEN
+ -- RAISE NOTICE 'no marc for vandelay or bib record';
+ RETURN FALSE;
+ END IF;
+
+ IF vandelay.template_overlay_bib_record( v_marc, eg_id, merge_profile_id) THEN
+ UPDATE vandelay.queued_bib_record
+ SET imported_as = eg_id,
+ import_time = NOW()
+ WHERE id = import_id;
+
+ editor_string := (oils_xpath('//*[@tag="905"]/*[@code="u"]/text()',v_marc))[1];
+
+ IF editor_string IS NOT NULL AND editor_string <> '' THEN
+ SELECT usr INTO editor_id FROM actor.card WHERE barcode = editor_string;
+
+ IF editor_id IS NULL THEN
+ SELECT id INTO editor_id FROM actor.usr WHERE usrname = editor_string;
+ END IF;
+
+ IF editor_id IS NOT NULL THEN
+ UPDATE biblio.record_entry SET editor = editor_id WHERE id = eg_id;
+ END IF;
+ END IF;
+
+ RETURN TRUE;
+ END IF;
+
+ -- RAISE NOTICE 'update of biblio.record_entry failed';
+
+ RETURN FALSE;
+
+END;
+$$ LANGUAGE PLPGSQL;
+
+
+CREATE OR REPLACE FUNCTION vandelay.auto_overlay_bib_record_with_best ( import_id BIGINT, merge_profile_id INT, lwm_ratio_value_p NUMERIC ) RETURNS BOOL AS $$
+DECLARE
+ eg_id BIGINT;
+ lwm_ratio_value NUMERIC;
+BEGIN
+
+ lwm_ratio_value := COALESCE(lwm_ratio_value_p, 0.0);
+
+ PERFORM * FROM vandelay.queued_bib_record WHERE import_time IS NOT NULL AND id = import_id;
+
+ IF FOUND THEN
+ -- RAISE NOTICE 'already imported, cannot auto-overlay'
+ RETURN FALSE;
+ END IF;
+
+ SELECT m.eg_record INTO eg_id
+ FROM vandelay.bib_match m
+ JOIN vandelay.queued_bib_record qr ON (m.queued_record = qr.id)
+ JOIN vandelay.bib_queue q ON (qr.queue = q.id)
+ JOIN biblio.record_entry r ON (r.id = m.eg_record)
+ WHERE m.queued_record = import_id
+ AND qr.quality::NUMERIC / COALESCE(NULLIF(m.quality,0),1)::NUMERIC >= lwm_ratio_value
+ ORDER BY m.match_score DESC, -- required match score
+ qr.quality::NUMERIC / COALESCE(NULLIF(m.quality,0),1)::NUMERIC DESC, -- quality tie breaker
+ m.id -- when in doubt, use the first match
+ LIMIT 1;
+
+ IF eg_id IS NULL THEN
+ -- RAISE NOTICE 'incoming record is not of high enough quality';
+ RETURN FALSE;
+ END IF;
+
+ RETURN vandelay.overlay_bib_record( import_id, eg_id, merge_profile_id );
+END;
+$$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION vandelay.auto_overlay_bib_record_with_best ( import_id BIGINT, merge_profile_id INT, lwm_ratio_value_p NUMERIC ) RETURNS BOOL AS $$
+DECLARE
+ eg_id BIGINT;
+ lwm_ratio_value NUMERIC;
+BEGIN
+
+ lwm_ratio_value := COALESCE(lwm_ratio_value_p, 0.0);
+
+ PERFORM * FROM vandelay.queued_bib_record WHERE import_time IS NOT NULL AND id = import_id;
+
+ IF FOUND THEN
+ -- RAISE NOTICE 'already imported, cannot auto-overlay'
+ RETURN FALSE;
+ END IF;
+
+ SELECT m.eg_record INTO eg_id
+ FROM vandelay.bib_match m
+ JOIN vandelay.queued_bib_record qr ON (m.queued_record = qr.id)
+ JOIN vandelay.bib_queue q ON (qr.queue = q.id)
+ JOIN biblio.record_entry r ON (r.id = m.eg_record)
+ WHERE m.queued_record = import_id
+ AND qr.quality::NUMERIC / COALESCE(NULLIF(m.quality,0),1)::NUMERIC >= lwm_ratio_value
+ ORDER BY m.match_score DESC, -- required match score
+ qr.quality::NUMERIC / COALESCE(NULLIF(m.quality,0),1)::NUMERIC DESC, -- quality tie breaker
+ m.id -- when in doubt, use the first match
+ LIMIT 1;
+
+ IF eg_id IS NULL THEN
+ -- RAISE NOTICE 'incoming record is not of high enough quality';
+ RETURN FALSE;
+ END IF;
+
+ RETURN vandelay.overlay_bib_record( import_id, eg_id, merge_profile_id );
+END;
+$$ LANGUAGE PLPGSQL;
+
+
+CREATE OR REPLACE FUNCTION vandelay.auto_overlay_bib_queue_with_best ( queue_id BIGINT, merge_profile_id INT, lwm_ratio_value NUMERIC ) RETURNS SETOF BIGINT AS $$
+DECLARE
+ queued_record vandelay.queued_bib_record%ROWTYPE;
+BEGIN
+
+ FOR queued_record IN SELECT * FROM vandelay.queued_bib_record WHERE queue = queue_id AND import_time IS NULL LOOP
+
+ IF vandelay.auto_overlay_bib_record_with_best( queued_record.id, merge_profile_id, lwm_ratio_value ) THEN
+ RETURN NEXT queued_record.id;
+ END IF;
+
+ END LOOP;
+
+ RETURN;
+
+END;
+$$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION vandelay.auto_overlay_bib_queue_with_best ( import_id BIGINT, merge_profile_id INT ) RETURNS SETOF BIGINT AS $$
+ SELECT vandelay.auto_overlay_bib_queue_with_best( $1, $2, p.lwm_ratio ) FROM vandelay.merge_profile p WHERE id = $2;
+$$ LANGUAGE SQL;
+
+CREATE OR REPLACE FUNCTION vandelay.ingest_bib_marc ( ) RETURNS TRIGGER AS $$
+DECLARE
+ value TEXT;
+ atype TEXT;
+ adef RECORD;
+BEGIN
+ IF TG_OP IN ('INSERT','UPDATE') AND NEW.imported_as IS NOT NULL THEN
+ RETURN NEW;
+ END IF;
+
+ FOR adef IN SELECT * FROM vandelay.bib_attr_definition LOOP
+
+ SELECT extract_marc_field('vandelay.queued_bib_record', id, adef.xpath, adef.remove) INTO value FROM vandelay.queued_bib_record WHERE id = NEW.id;
+ IF (value IS NOT NULL AND value <> '') THEN
+ INSERT INTO vandelay.queued_bib_record_attr (record, field, attr_value) VALUES (NEW.id, adef.id, value);
+ END IF;
+
+ END LOOP;
+
+ RETURN NULL;
+END;
+$$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION vandelay.ingest_bib_items ( ) RETURNS TRIGGER AS $func$
+DECLARE
+ attr_def BIGINT;
+ item_data vandelay.import_item%ROWTYPE;
+BEGIN
+
+ IF TG_OP IN ('INSERT','UPDATE') AND NEW.imported_as IS NOT NULL THEN
+ RETURN NEW;
+ END IF;
+
+ SELECT item_attr_def INTO attr_def FROM vandelay.bib_queue WHERE id = NEW.queue;
+
+ FOR item_data IN SELECT * FROM vandelay.ingest_items( NEW.id::BIGINT, attr_def ) LOOP
+ INSERT INTO vandelay.import_item (
+ record,
+ definition,
+ owning_lib,
+ circ_lib,
+ call_number,
+ copy_number,
+ status,
+ location,
+ circulate,
+ deposit,
+ deposit_amount,
+ ref,
+ holdable,
+ price,
+ barcode,
+ circ_modifier,
+ circ_as_type,
+ alert_message,
+ pub_note,
+ priv_note,
+ opac_visible
+ ) VALUES (
+ NEW.id,
+ item_data.definition,
+ item_data.owning_lib,
+ item_data.circ_lib,
+ item_data.call_number,
+ item_data.copy_number,
+ item_data.status,
+ item_data.location,
+ item_data.circulate,
+ item_data.deposit,
+ item_data.deposit_amount,
+ item_data.ref,
+ item_data.holdable,
+ item_data.price,
+ item_data.barcode,
+ item_data.circ_modifier,
+ item_data.circ_as_type,
+ item_data.alert_message,
+ item_data.pub_note,
+ item_data.priv_note,
+ item_data.opac_visible
+ );
+ END LOOP;
+
+ RETURN NULL;
+END;
+$func$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION vandelay.cleanup_bib_marc ( ) RETURNS TRIGGER AS $$
+BEGIN
+ IF TG_OP IN ('INSERT','UPDATE') AND NEW.imported_as IS NOT NULL THEN
+ RETURN NEW;
+ END IF;
+
+ DELETE FROM vandelay.queued_bib_record_attr WHERE record = OLD.id;
+ DELETE FROM vandelay.import_item WHERE record = OLD.id;
+
+ IF TG_OP = 'UPDATE' THEN
+ RETURN NEW;
+ END IF;
+ RETURN OLD;
+END;
+$$ LANGUAGE PLPGSQL;
+
+
+-- ALTER TABLEs...
+
+-
+-CREATE OR REPLACE FUNCTION vandelay.cleanup_bib_marc ( ) RETURNS TRIGGER AS $$
+-BEGIN
+@@ -1200,7 +1818,7 @@ CREATE TRIGGER ingest_item_trigger
+- AFTER INSERT OR UPDATE ON vandelay.queued_bib_record
+ BEFORE INSERT OR UPDATE ON vandelay.queued_bib_record
+@@ -1211,8 +1829,7 @@ CREATE TABLE vandelay.authority_attr_definition (
+- remove TEXT NOT NULL DEFAULT '',
+- ident BOOL NOT NULL DEFAULT FALSE
+ remove TEXT NOT NULL DEFAULT ''
+@@ -1223,7 +1840,9 @@ ALTER TABLE vandelay.authority_queue ADD PRIMARY KEY (id);
+- imported_as INT REFERENCES authority.record_entry (id) DEFERRABLE INITIALLY DEFERRED
+ imported_as INT REFERENCES authority.record_entry (id) DEFERRABLE INITIALLY DEFERRED,
+ import_error TEXT REFERENCES vandelay.import_error (code) ON DELETE SET NULL ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
+ error_detail TEXT
+@@ -1238,9 +1857,9 @@ CREATE INDEX queued_authority_record_attr_record_idx ON vandelay.queued_authorit
+- matched_attr INT REFERENCES vandelay.queued_authority_record_attr (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
+- eg_record BIGINT REFERENCES authority.record_entry (id) DEFERRABLE INITIALLY DEFERRED
+ eg_record BIGINT REFERENCES authority.record_entry (id) DEFERRABLE INITIALLY DEFERRED,
+ quality INT NOT NULL DEFAULT 0
+@@ -1249,6 +1868,10 @@ DECLARE
+ IF TG_OP IN ('INSERT','UPDATE') AND NEW.imported_as IS NOT NULL THEN
+ RETURN NEW;
+ END IF;
+
+@@ -1264,6 +1887,10 @@ $$ LANGUAGE PLPGSQL;
+ IF TG_OP IN ('INSERT','UPDATE') AND NEW.imported_as IS NOT NULL THEN
+ RETURN NEW;
+ END IF;
+@@ -372,6 +372,27 @@ CREATE OR REPLACE FUNCTION biblio.extract_metabib_field_entry ( BIGINT ) RETURNS
+
+CREATE OR REPLACE FUNCTION authority.flatten_marc ( rid BIGINT ) RETURNS SETOF authority.full_rec AS $func$
+DECLARE
+ auth authority.record_entry%ROWTYPE;
+ output authority.full_rec%ROWTYPE;
+ field RECORD;
+BEGIN
+ SELECT INTO auth * FROM authority.record_entry WHERE id = rid;
+
+ FOR field IN SELECT * FROM vandelay.flatten_marc( auth.marc ) LOOP
+ output.record := rid;
+ output.ind1 := field.ind1;
+ output.ind2 := field.ind2;
+ output.tag := field.tag;
+ output.subfield := field.subfield;
+ output.value := field.value;
+
+ RETURN NEXT output;
+ END LOOP;
+END;
+$func$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION biblio.flatten_marc ( rid BIGINT ) RETURNS SETOF metabib.full_rec AS $func$
+DECLARE
+ bib biblio.record_entry%ROWTYPE;
+ output metabib.full_rec%ROWTYPE;
+ field RECORD;
+BEGIN
+ SELECT INTO bib * FROM biblio.record_entry WHERE id = rid;
+
+ FOR field IN SELECT * FROM vandelay.flatten_marc( bib.marc ) LOOP
+ output.record := rid;
+ output.ind1 := field.ind1;
+ output.ind2 := field.ind2;
+ output.tag := field.tag;
+ output.subfield := field.subfield;
+ output.value := field.value;
+
+ RETURN NEXT output;
+ END LOOP;
+END;
+$func$ LANGUAGE PLPGSQL;
+
+
+CREATE OR REPLACE FUNCTION authority.flatten_marc ( rid BIGINT ) RETURNS SETOF authority.full_rec AS $func$
+DECLARE
+ auth authority.record_entry%ROWTYPE;
+ output authority.full_rec%ROWTYPE;
+ field RECORD;
+BEGIN
+ SELECT INTO auth * FROM authority.record_entry WHERE id = rid;
+
+ FOR field IN SELECT * FROM vandelay.flatten_marc( auth.marc ) LOOP
+ output.record := rid;
+ output.ind1 := field.ind1;
+ output.ind2 := field.ind2;
+ output.tag := field.tag;
+ output.subfield := field.subfield;
+ output.value := field.value;
+
+ RETURN NEXT output;
+ END LOOP;
+END;
+$func$ LANGUAGE PLPGSQL;
+
+
+-----------------------------------------------
+-- Seed data for import errors
+-----------------------------------------------
+
+INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'general.unknown', oils_i18n_gettext('general.unknown', 'Import or Overlay failed', 'vie', 'description') );
+INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'import.item.duplicate.barcode', oils_i18n_gettext('import.item.duplicate.barcode', 'Import failed due to barcode collision', 'vie', 'description') );
+INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'import.item.invalid.circ_modifier', oils_i18n_gettext('import.item.invalid.circ_modifier', 'Import failed due to invalid circulation modifier', 'vie', 'description') );
+INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'import.item.invalid.location', oils_i18n_gettext('import.item.invalid.location', 'Import failed due to invalid copy location', 'vie', 'description') );
+INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'import.duplicate.sysid', oils_i18n_gettext('import.duplicate.sysid', 'Import failed due to system id collision', 'vie', 'description') );
+INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'import.duplicate.tcn', oils_i18n_gettext('import.duplicate.sysid', 'Import failed due to system id collision', 'vie', 'description') );
+INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'overlay.missing.sysid', oils_i18n_gettext('overlay.missing.sysid', 'Overlay failed due to missing system id', 'vie', 'description') );
+INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'import.auth.duplicate.acn', oils_i18n_gettext('import.auth.duplicate.acn', 'Import failed due to Accession Number collision', 'vie', 'description') );
+INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'import.xml.malformed', oils_i18n_gettext('import.xml.malformed', 'Malformed record cause Import failure', 'vie', 'description') );
+INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'overlay.xml.malformed', oils_i18n_gettext('overlay.xml.malformed', 'Malformed record cause Overlay failure', 'vie', 'description') );
+INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'overlay.record.quality', oils_i18n_gettext('overlay.record.quality', 'New record had insufficient quality', 'vie', 'description') );
+
+
+----------------------------------------------------------------
+-- Seed data for queued record/item exports
+----------------------------------------------------------------
+
+INSERT INTO action_trigger.hook (key,core_type,description,passive) VALUES (
+ 'vandelay.queued_bib_record.print',
+ 'vqbr',
+ oils_i18n_gettext(
+ 'vandelay.queued_bib_record.print',
+ 'Print output has been requested for records in an Importer Bib Queue.',
+ 'ath',
+ 'description'
+ ),
+ FALSE
+ )
+ ,(
+ 'vandelay.queued_bib_record.csv',
+ 'vqbr',
+ oils_i18n_gettext(
+ 'vandelay.queued_bib_record.csv',
+ 'CSV output has been requested for records in an Importer Bib Queue.',
+ 'ath',
+ 'description'
+ ),
+ FALSE
+ )
+ ,(
+ 'vandelay.queued_bib_record.email',
+ 'vqbr',
+ oils_i18n_gettext(
+ 'vandelay.queued_bib_record.email',
+ 'An email has been requested for records in an Importer Bib Queue.',
+ 'ath',
+ 'description'
+ ),
+ FALSE
+ )
+ ,(
+ 'vandelay.queued_auth_record.print',
+ 'vqar',
+ oils_i18n_gettext(
+ 'vandelay.queued_auth_record.print',
+ 'Print output has been requested for records in an Importer Authority Queue.',
+ 'ath',
+ 'description'
+ ),
+ FALSE
+ )
+ ,(
+ 'vandelay.queued_auth_record.csv',
+ 'vqar',
+ oils_i18n_gettext(
+ 'vandelay.queued_auth_record.csv',
+ 'CSV output has been requested for records in an Importer Authority Queue.',
+ 'ath',
+ 'description'
+ ),
+ FALSE
+ )
+ ,(
+ 'vandelay.queued_auth_record.email',
+ 'vqar',
+ oils_i18n_gettext(
+ 'vandelay.queued_auth_record.email',
+ 'An email has been requested for records in an Importer Authority Queue.',
+ 'ath',
+ 'description'
+ ),
+ FALSE
+ )
+ ,(
+ 'vandelay.import_items.print',
+ 'vii',
+ oils_i18n_gettext(
+ 'vandelay.import_items.print',
+ 'Print output has been requested for Import Items from records in an Importer Bib Queue.',
+ 'ath',
+ 'description'
+ ),
+ FALSE
+ )
+ ,(
+ 'vandelay.import_items.csv',
+ 'vii',
+ oils_i18n_gettext(
+ 'vandelay.import_items.csv',
+ 'CSV output has been requested for Import Items from records in an Importer Bib Queue.',
+ 'ath',
+ 'description'
+ ),
+ FALSE
+ )
+ ,(
+ 'vandelay.import_items.email',
+ 'vii',
+ oils_i18n_gettext(
+ 'vandelay.import_items.email',
+ 'An email has been requested for Import Items from records in an Importer Bib Queue.',
+ 'ath',
+ 'description'
+ ),
+ FALSE
+ )
+;
+
+INSERT INTO action_trigger.event_definition (
+ id,
+ active,
+ owner,
+ name,
+ hook,
+ validator,
+ reactor,
+ group_field,
+ granularity,
+ template
+ ) VALUES (
+ 38,
+ TRUE,
+ 1,
+ 'Print Output for Queued Bib Records',
+ 'vandelay.queued_bib_record.print',
+ 'NOOP_True',
+ 'ProcessTemplate',
+ 'queue.owner',
+ 'print-on-demand',
+$$
+[%- USE date -%]
+<pre>
+Queue ID: [% target.0.queue.id %]
+Queue Name: [% target.0.queue.name %]
+Queue Type: [% target.0.queue.queue_type %]
+Complete? [% target.0.queue.complete %]
+
+ [% FOR vqbr IN target %]
+=-=-=
+ Title of work | [% helpers.get_queued_bib_attr('title',vqbr.attributes) %]
+ Author of work | [% helpers.get_queued_bib_attr('author',vqbr.attributes) %]
+ Language of work | [% helpers.get_queued_bib_attr('language',vqbr.attributes) %]
+ Pagination | [% helpers.get_queued_bib_attr('pagination',vqbr.attributes) %]
+ ISBN | [% helpers.get_queued_bib_attr('isbn',vqbr.attributes) %]
+ ISSN | [% helpers.get_queued_bib_attr('issn',vqbr.attributes) %]
+ Price | [% helpers.get_queued_bib_attr('price',vqbr.attributes) %]
+ Accession Number | [% helpers.get_queued_bib_attr('rec_identifier',vqbr.attributes) %]
+ TCN Value | [% helpers.get_queued_bib_attr('eg_tcn',vqbr.attributes) %]
+ TCN Source | [% helpers.get_queued_bib_attr('eg_tcn_source',vqbr.attributes) %]
+ Internal ID | [% helpers.get_queued_bib_attr('eg_identifier',vqbr.attributes) %]
+ Publisher | [% helpers.get_queued_bib_attr('publisher',vqbr.attributes) %]
+ Publication Date | [% helpers.get_queued_bib_attr('pubdate',vqbr.attributes) %]
+ Edition | [% helpers.get_queued_bib_attr('edition',vqbr.attributes) %]
+ Item Barcode | [% helpers.get_queued_bib_attr('item_barcode',vqbr.attributes) %]
+
+ [% END %]
+</pre>
+$$
+ )
+;
+
+INSERT INTO action_trigger.environment ( event_def, path) VALUES (
+ 38, 'attributes')
+ ,( 38, 'queue')
+;
+
+INSERT INTO action_trigger.event_definition (
+ id,
+ active,
+ owner,
+ name,
+ hook,
+ validator,
+ reactor,
+ group_field,
+ granularity,
+ template
+ ) VALUES (
+ 39,
+ TRUE,
+ 1,
+ 'CSV Output for Queued Bib Records',
+ 'vandelay.queued_bib_record.csv',
+ 'NOOP_True',
+ 'ProcessTemplate',
+ 'queue.owner',
+ 'print-on-demand',
+$$
+[%- USE date -%]
+"Title of work","Author of work","Language of work","Pagination","ISBN","ISSN","Price","Accession Number","TCN Value","TCN Source","Internal ID","Publisher","Publication Date","Edition","Item Barcode"
+[% FOR vqbr IN target %]"[% helpers.get_queued_bib_attr('title',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('author',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('language',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('pagination',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('isbn',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('issn',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('price',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('rec_identifier',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('eg_tcn',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('eg_tcn_source',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('eg_identifier',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_att
r('publisher',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('pubdate',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('edition',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('item_barcode',vqbr.attributes) | replace('"', '""') %]"
+[% END %]
+$$
+ )
+;
+
+INSERT INTO action_trigger.environment ( event_def, path) VALUES (
+ 39, 'attributes')
+ ,( 39, 'queue')
+;
+
+INSERT INTO action_trigger.event_definition (
+ id,
+ active,
+ owner,
+ name,
+ hook,
+ validator,
+ reactor,
+ group_field,
+ granularity,
+ template
+ ) VALUES (
+ 40,
+ TRUE,
+ 1,
+ 'Email Output for Queued Bib Records',
+ 'vandelay.queued_bib_record.email',
+ 'NOOP_True',
+ 'SendEmail',
+ 'queue.owner',
+ NULL,
+$$
+[%- USE date -%]
+[%- SET user = target.0.queue.owner -%]
+To: [%- params.recipient_email || user.email || 'root at localhost' %]
+From: [%- params.sender_email || default_sender %]
+Subject: Bibs from Import Queue
+
+Queue ID: [% target.0.queue.id %]
+Queue Name: [% target.0.queue.name %]
+Queue Type: [% target.0.queue.queue_type %]
+Complete? [% target.0.queue.complete %]
+
+ [% FOR vqbr IN target %]
+=-=-=
+ Title of work | [% helpers.get_queued_bib_attr('title',vqbr.attributes) %]
+ Author of work | [% helpers.get_queued_bib_attr('author',vqbr.attributes) %]
+ Language of work | [% helpers.get_queued_bib_attr('language',vqbr.attributes) %]
+ Pagination | [% helpers.get_queued_bib_attr('pagination',vqbr.attributes) %]
+ ISBN | [% helpers.get_queued_bib_attr('isbn',vqbr.attributes) %]
+ ISSN | [% helpers.get_queued_bib_attr('issn',vqbr.attributes) %]
+ Price | [% helpers.get_queued_bib_attr('price',vqbr.attributes) %]
+ Accession Number | [% helpers.get_queued_bib_attr('rec_identifier',vqbr.attributes) %]
+ TCN Value | [% helpers.get_queued_bib_attr('eg_tcn',vqbr.attributes) %]
+ TCN Source | [% helpers.get_queued_bib_attr('eg_tcn_source',vqbr.attributes) %]
+ Internal ID | [% helpers.get_queued_bib_attr('eg_identifier',vqbr.attributes) %]
+ Publisher | [% helpers.get_queued_bib_attr('publisher',vqbr.attributes) %]
+ Publication Date | [% helpers.get_queued_bib_attr('pubdate',vqbr.attributes) %]
+ Edition | [% helpers.get_queued_bib_attr('edition',vqbr.attributes) %]
+ Item Barcode | [% helpers.get_queued_bib_attr('item_barcode',vqbr.attributes) %]
+
+ [% END %]
+
+$$
+ )
+;
+
+INSERT INTO action_trigger.environment ( event_def, path) VALUES (
+ 40, 'attributes')
+ ,( 40, 'queue')
+ ,( 40, 'queue.owner')
+;
+
+INSERT INTO action_trigger.event_definition (
+ id,
+ active,
+ owner,
+ name,
+ hook,
+ validator,
+ reactor,
+ group_field,
+ granularity,
+ template
+ ) VALUES (
+ 41,
+ TRUE,
+ 1,
+ 'Print Output for Queued Authority Records',
+ 'vandelay.queued_auth_record.print',
+ 'NOOP_True',
+ 'ProcessTemplate',
+ 'queue.owner',
+ 'print-on-demand',
+$$
+[%- USE date -%]
+<pre>
+Queue ID: [% target.0.queue.id %]
+Queue Name: [% target.0.queue.name %]
+Queue Type: [% target.0.queue.queue_type %]
+Complete? [% target.0.queue.complete %]
+
+ [% FOR vqar IN target %]
+=-=-=
+ Record Identifier | [% helpers.get_queued_auth_attr('rec_identifier',vqar.attributes) %]
+
+ [% END %]
+</pre>
+$$
+ )
+;
+
+INSERT INTO action_trigger.environment ( event_def, path) VALUES (
+ 41, 'attributes')
+ ,( 41, 'queue')
+;
+
+INSERT INTO action_trigger.event_definition (
+ id,
+ active,
+ owner,
+ name,
+ hook,
+ validator,
+ reactor,
+ group_field,
+ granularity,
+ template
+ ) VALUES (
+ 42,
+ TRUE,
+ 1,
+ 'CSV Output for Queued Authority Records',
+ 'vandelay.queued_auth_record.csv',
+ 'NOOP_True',
+ 'ProcessTemplate',
+ 'queue.owner',
+ 'print-on-demand',
+$$
+[%- USE date -%]
+"Record Identifier"
+[% FOR vqar IN target %]"[% helpers.get_queued_auth_attr('rec_identifier',vqar.attributes) | replace('"', '""') %]"
+[% END %]
+$$
+ )
+;
+
+INSERT INTO action_trigger.environment ( event_def, path) VALUES (
+ 42, 'attributes')
+ ,( 42, 'queue')
+;
+
+INSERT INTO action_trigger.event_definition (
+ id,
+ active,
+ owner,
+ name,
+ hook,
+ validator,
+ reactor,
+ group_field,
+ granularity,
+ template
+ ) VALUES (
+ 43,
+ TRUE,
+ 1,
+ 'Email Output for Queued Authority Records',
+ 'vandelay.queued_auth_record.email',
+ 'NOOP_True',
+ 'SendEmail',
+ 'queue.owner',
+ NULL,
+$$
+[%- USE date -%]
+[%- SET user = target.0.queue.owner -%]
+To: [%- params.recipient_email || user.email || 'root at localhost' %]
+From: [%- params.sender_email || default_sender %]
+Subject: Authorities from Import Queue
+
+Queue ID: [% target.0.queue.id %]
+Queue Name: [% target.0.queue.name %]
+Queue Type: [% target.0.queue.queue_type %]
+Complete? [% target.0.queue.complete %]
+
+ [% FOR vqar IN target %]
+=-=-=
+ Record Identifier | [% helpers.get_queued_auth_attr('rec_identifier',vqar.attributes) %]
+
+ [% END %]
+
+$$
+ )
+;
+
+INSERT INTO action_trigger.environment ( event_def, path) VALUES (
+ 43, 'attributes')
+ ,( 43, 'queue')
+ ,( 43, 'queue.owner')
+;
+
+INSERT INTO action_trigger.event_definition (
+ id,
+ active,
+ owner,
+ name,
+ hook,
+ validator,
+ reactor,
+ group_field,
+ granularity,
+ template
+ ) VALUES (
+ 44,
+ TRUE,
+ 1,
+ 'Print Output for Import Items from Queued Bib Records',
+ 'vandelay.import_items.print',
+ 'NOOP_True',
+ 'ProcessTemplate',
+ 'record.queue.owner',
+ 'print-on-demand',
+$$
+[%- USE date -%]
+<pre>
+Queue ID: [% target.0.record.queue.id %]
+Queue Name: [% target.0.record.queue.name %]
+Queue Type: [% target.0.record.queue.queue_type %]
+Complete? [% target.0.record.queue.complete %]
+
+ [% FOR vii IN target %]
+=-=-=
+ Import Item ID | [% vii.id %]
+ Title of work | [% helpers.get_queued_bib_attr('title',vii.record.attributes) %]
+ ISBN | [% helpers.get_queued_bib_attr('isbn',vii.record.attributes) %]
+ Attribute Definition | [% vii.definition %]
+ Import Error | [% vii.import_error %]
+ Import Error Detail | [% vii.error_detail %]
+ Owning Library | [% vii.owning_lib %]
+ Circulating Library | [% vii.circ_lib %]
+ Call Number | [% vii.call_number %]
+ Copy Number | [% vii.copy_number %]
+ Status | [% vii.status.name %]
+ Shelving Location | [% vii.location.name %]
+ Circulate | [% vii.circulate %]
+ Deposit | [% vii.deposit %]
+ Deposit Amount | [% vii.deposit_amount %]
+ Reference | [% vii.ref %]
+ Holdable | [% vii.holdable %]
+ Price | [% vii.price %]
+ Barcode | [% vii.barcode %]
+ Circulation Modifier | [% vii.circ_modifier %]
+ Circulate As MARC Type | [% vii.circ_as_type %]
+ Alert Message | [% vii.alert_message %]
+ Public Note | [% vii.pub_note %]
+ Private Note | [% vii.priv_note %]
+ OPAC Visible | [% vii.opac_visible %]
+
+ [% END %]
+</pre>
+$$
+ )
+;
+
+INSERT INTO action_trigger.environment ( event_def, path) VALUES (
+ 44, 'record')
+ ,( 44, 'record.attributes')
+ ,( 44, 'record.queue')
+ ,( 44, 'record.queue.owner')
+;
+
+INSERT INTO action_trigger.event_definition (
+ id,
+ active,
+ owner,
+ name,
+ hook,
+ validator,
+ reactor,
+ group_field,
+ granularity,
+ template
+ ) VALUES (
+ 45,
+ TRUE,
+ 1,
+ 'CSV Output for Import Items from Queued Bib Records',
+ 'vandelay.import_items.csv',
+ 'NOOP_True',
+ 'ProcessTemplate',
+ 'record.queue.owner',
+ 'print-on-demand',
+$$
+[%- USE date -%]
+"Import Item ID","Title of work","ISBN","Attribute Definition","Import Error","Import Error Detail","Owning Library","Circulating Library","Call Number","Copy Number","Status","Shelving Location","Circulate","Deposit","Deposit Amount","Reference","Holdable","Price","Barcode","Circulation Modifier","Circulate As MARC Type","Alert Message","Public Note","Private Note","OPAC Visible"
+[% FOR vii IN target %]"[% vii.id | replace('"', '""') %]","[% helpers.get_queued_bib_attr('title',vii.record.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('isbn',vii.record.attributes) | replace('"', '""') %]","[% vii.definition | replace('"', '""') %]","[% vii.import_error | replace('"', '""') %]","[% vii.error_detail | replace('"', '""') %]","[% vii.owning_lib | replace('"', '""') %]","[% vii.circ_lib | replace('"', '""') %]","[% vii.call_number | replace('"', '""') %]","[% vii.copy_number | replace('"', '""') %]","[% vii.status.name | replace('"', '""') %]","[% vii.location.name | replace('"', '""') %]","[% vii.circulate | replace('"', '""') %]","[% vii.deposit | replace('"', '""') %]","[% vii.deposit_amount | replace('"', '""') %]","[% vii.ref | replace('"', '""') %]","[% vii.holdable | replace('"', '""') %]","[% vii.price | replace('"', '""') %]","[% vii.barcode | replace('"', '""') %]","[% vii.circ_modifier | replace('"', '""') %]","[% vii.circ_
as_type | replace('"', '""') %]","[% vii.alert_message | replace('"', '""') %]","[% vii.pub_note | replace('"', '""') %]","[% vii.priv_note | replace('"', '""') %]","[% vii.opac_visible | replace('"', '""') %]"
+[% END %]
+$$
+ )
+;
+
+INSERT INTO action_trigger.environment ( event_def, path) VALUES (
+ 45, 'record')
+ ,( 45, 'record.attributes')
+ ,( 45, 'record.queue')
+ ,( 45, 'record.queue.owner')
+;
+
+INSERT INTO action_trigger.event_definition (
+ id,
+ active,
+ owner,
+ name,
+ hook,
+ validator,
+ reactor,
+ group_field,
+ granularity,
+ template
+ ) VALUES (
+ 46,
+ TRUE,
+ 1,
+ 'Email Output for Import Items from Queued Bib Records',
+ 'vandelay.import_items.email',
+ 'NOOP_True',
+ 'SendEmail',
+ 'record.queue.owner',
+ NULL,
+$$
+[%- USE date -%]
+[%- SET user = target.0.record.queue.owner -%]
+To: [%- params.recipient_email || user.email || 'root at localhost' %]
+From: [%- params.sender_email || default_sender %]
+Subject: Import Items from Import Queue
+
+Queue ID: [% target.0.record.queue.id %]
+Queue Name: [% target.0.record.queue.name %]
+Queue Type: [% target.0.record.queue.queue_type %]
+Complete? [% target.0.record.queue.complete %]
+
+ [% FOR vii IN target %]
+=-=-=
+ Import Item ID | [% vii.id %]
+ Title of work | [% helpers.get_queued_bib_attr('title',vii.record.attributes) %]
+ ISBN | [% helpers.get_queued_bib_attr('isbn',vii.record.attributes) %]
+ Attribute Definition | [% vii.definition %]
+ Import Error | [% vii.import_error %]
+ Import Error Detail | [% vii.error_detail %]
+ Owning Library | [% vii.owning_lib %]
+ Circulating Library | [% vii.circ_lib %]
+ Call Number | [% vii.call_number %]
+ Copy Number | [% vii.copy_number %]
+ Status | [% vii.status.name %]
+ Shelving Location | [% vii.location.name %]
+ Circulate | [% vii.circulate %]
+ Deposit | [% vii.deposit %]
+ Deposit Amount | [% vii.deposit_amount %]
+ Reference | [% vii.ref %]
+ Holdable | [% vii.holdable %]
+ Price | [% vii.price %]
+ Barcode | [% vii.barcode %]
+ Circulation Modifier | [% vii.circ_modifier %]
+ Circulate As MARC Type | [% vii.circ_as_type %]
+ Alert Message | [% vii.alert_message %]
+ Public Note | [% vii.pub_note %]
+ Private Note | [% vii.priv_note %]
+ OPAC Visible | [% vii.opac_visible %]
+
+ [% END %]
+$$
+ )
+;
+
+INSERT INTO action_trigger.environment ( event_def, path) VALUES (
+ 46, 'record')
+ ,( 46, 'record.attributes')
+ ,( 46, 'record.queue')
+ ,( 46, 'record.queue.owner')
+;
+
+
+COMMIT;
commit b79724aa8ad7ea1783b8f100e19effa493b39b34
Author: berick <berick at esilibrary.com>
Date: Tue May 24 09:16:10 2011 -0400
repair selector column width (move to width attr) to free up space in queue display
diff --git a/Open-ILS/web/templates/default/vandelay/inc/queue.tt2 b/Open-ILS/web/templates/default/vandelay/inc/queue.tt2
index 783ffa5..466ee4f 100644
--- a/Open-ILS/web/templates/default/vandelay/inc/queue.tt2
+++ b/Open-ILS/web/templates/default/vandelay/inc/queue.tt2
@@ -116,7 +116,8 @@
field='+row_selector'
get='vlQueueGridDrawSelectBox'
formatter='vlQueueGridFormatSelectBox'
- styles='text-align: center;width:30px;'
+ width='16'
+ styles='text-align: center;'
nonSelectable='true'>
<input id="vl-queue-grid-row-selector" type="checkbox" onclick="vlToggleQueueGridSelect();"></input>
</th>
commit a513654859fd4eeb188097355a34074406a85479
Author: berick <berick at esilibrary.com>
Date: Tue May 24 09:15:13 2011 -0400
disable sorting on selector column in queue grid
diff --git a/Open-ILS/web/js/ui/default/vandelay/vandelay.js b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
index de1361e..97be36b 100644
--- a/Open-ILS/web/js/ui/default/vandelay/vandelay.js
+++ b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
@@ -893,6 +893,9 @@ var vlQueueGridLayout = null;
function buildRecordGrid(type) {
displayGlobalDiv('vl-queue-div');
+ vlBibQueueGrid.canSort = function(col){ if(Math.abs(col) == 1) { return false; } else { return true; } };
+ vlAuthQueueGrid.canSort = function(col){ if(Math.abs(col) == 1) { return false; } else { return true; } };
+
if(type == 'bib') {
openils.Util.show('vl-bib-queue-grid-wrapper');
openils.Util.hide('vl-auth-queue-grid-wrapper');
commit 19ab89718293f1ae761a0237cea47ecbfda76f9c
Author: berick <berick at esilibrary.com>
Date: Mon May 23 14:17:08 2011 -0400
avoid pile-up of dojo-attached event handlers for queue upload inputs
diff --git a/Open-ILS/web/js/ui/default/vandelay/vandelay.js b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
index 57e220b..de1361e 100644
--- a/Open-ILS/web/js/ui/default/vandelay/vandelay.js
+++ b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
@@ -1032,9 +1032,13 @@ function vlFetchQueueSummary(qId, type, onload) {
);
}
+var _importCancelHandler;
+var _importGoHandler;
function vlHandleQueueItemsAction(action) {
- dojo.connect(
+ if(_importCancelHandler) dojo.disconnect(_importCancelHandler);
+
+ _importCancelHandler = dojo.connect(
queueItemsImportCancelButton,
'onClick',
function() {
@@ -1042,7 +1046,10 @@ function vlHandleQueueItemsAction(action) {
}
);
- dojo.connect(
+ if(_importGoHandler)
+ dojo.disconnect(_importGoHandler);
+
+ _importGoHandler = dojo.connect(
queueItemsImportGoButton,
'onClick',
function() {
commit 4c0d9bcacb0cb29c2a2c33032fed8392299353b5
Author: berick <berick at esilibrary.com>
Date: Mon May 23 14:16:32 2011 -0400
set imported_as / import_time on import items after successful import
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
index c4ca18c..b3e516b 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
@@ -1550,6 +1550,16 @@ sub import_record_asset_list_impl {
next;
}
+ # set the import data on the import item
+ $item->imported_as($copy->id); # $copy->id is set by create_copy() ^--
+ $item->import_time('now');
+
+ unless($e->update_vandelay_import_item($item)) {
+ $$report_args{evt} = $e->die_event;
+ respond_with_status($report_args);
+ next;
+ }
+
# --------------------------------------------------------------------------------
# Item import succeeded
# --------------------------------------------------------------------------------
commit 669d12b7b58da33fa889fc0faa8b1ea40f4733d8
Author: berick <berick at esilibrary.com>
Date: Mon May 23 11:51:05 2011 -0400
Yet more Vandelay fixes
* Remove the deprecated .nomatch API call. no-match is now a runtime
option
* Re-fetch queued record after auto-import to avoid clobbering
imported_as as set by the DB during auto import
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
index 9dd923e..c4ca18c 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
@@ -765,7 +765,13 @@ __PACKAGE__->register_method(
argc => 2,
stream => 1,
max_chunk_size => 0,
- record_type => 'bib'
+ record_type => 'bib',
+ signature => {
+ desc => q/
+ Attempts to import all non-imported records for the selected queue.
+ Will also attempt import of all non-imported items.
+ /
+ }
);
__PACKAGE__->register_method(
@@ -777,31 +783,7 @@ __PACKAGE__->register_method(
max_chunk_size => 0,
record_type => 'auth'
);
-__PACKAGE__->register_method(
- api_name => "open-ils.vandelay.bib_queue.nomatch.import",
- method => 'import_queue',
- api_level => 1,
- argc => 2,
- stream => 1,
- signature => {
- desc => q/Only import records that have no collisions/
- },
- max_chunk_size => 0,
- record_type => 'bib'
-);
-__PACKAGE__->register_method(
- api_name => "open-ils.vandelay.auth_queue.nomatch.import",
- method => 'import_queue',
- api_level => 1,
- argc => 2,
- stream => 1,
- signature => {
- desc => q/Only import records that have no collisions/
- },
- max_chunk_size => 0,
- record_type => 'auth'
-);
sub import_queue {
my($self, $conn, $auth, $q_id, $options) = @_;
my $e = new_editor(authtoken => $auth, xact => 1);
@@ -810,16 +792,31 @@ sub import_queue {
my $type = $self->{record_type};
my $class = ($type eq 'bib') ? 'vqbr' : 'vqar';
+ # First, collect the not-yet-imported records
my $query = {queue => $q_id, import_time => undef};
+ my $search = ($type eq 'bib') ?
+ 'search_vandelay_queued_bib_record' :
+ 'search_vandelay_queued_authority_record';
+ my $rec_ids = $e->$search($query, {idlist => 1});
- if($self->api_name =~ /nomatch/) {
- my $matched_recs = queued_records_with_matches($e, $type, $q_id, undef, undef, {import_time => undef});
- $query->{id} = {'not in' => $matched_recs} if @$matched_recs;
+ # Now add any imported records that have un-imported items
+
+ if($type eq 'bib') {
+ my $item_recs = $e->json_query({
+ select => {vqbr => ['id']},
+ from => {vqbr => 'vii'},
+ where => {
+ '+vqbr' => {
+ queue => $q_id,
+ import_time => {'!=' => undef}
+ },
+ '+vii' => {import_time => undef}
+ },
+ distinct => 1
+ });
+ push(@$rec_ids, map {$_->{id}} @$item_recs);
}
- my $search = ($type eq 'bib') ?
- 'search_vandelay_queued_bib_record' : 'search_vandelay_queued_authority_record';
- my $rec_ids = $e->$search($query, {idlist => 1});
my $err = import_record_list_impl($self, $conn, $rec_ids, $e->requestor, $options);
try {$e->rollback} otherwise {}; # only using this to make the read authoritative -- don't die from it
return $err if $err;
@@ -828,6 +825,7 @@ sub import_queue {
# returns a list of queued record IDs for a given queue that
# have at least one entry in the match table
+# XXX DEPRECATED?
sub queued_records_with_matches {
my($e, $type, $q_id, $limit, $offset, $filter) = @_;
@@ -943,13 +941,15 @@ sub import_record_list_impl {
next;
}
- $$report_args{rec} = $rec;
-
if($rec->import_time) {
+ # if the record is already imported, that means it may have
+ # un-imported copies. Add to success list for later processing.
+ push(@success_rec_ids, $rec_id);
$e->rollback;
next;
}
+ $$report_args{rec} = $rec;
$queues{$rec->queue} = 1;
my $record;
@@ -1009,6 +1009,12 @@ sub import_record_list_impl {
if($res->{$auto_overlay_best_func} eq 't') {
$logger->info("vl: $type overlay-1match succeeded for queued rec $rec_id");
$imported = 1;
+
+ # re-fetch the record to pick up the imported_as value from the DB
+ $$report_args{rec} = $rec = $e->$retrieve_func([
+ $rec_id, {flesh => 1, flesh_fields => {$rec_class => ['matches']}}]);
+
+
} else {
$$report_args{import_error} = 'overlay.record.quality' if $match_quality_ratio > 0;
$logger->info("vl: $type overlay-1match failed for queued rec $rec_id");
@@ -1041,6 +1047,11 @@ sub import_record_list_impl {
if($res->{$auto_overlay_func} eq 't') {
$logger->info("vl: $type auto-overlay succeeded for queued rec $rec_id");
$imported = 1;
+
+ # re-fetch the record to pick up the imported_as value from the DB
+ $$report_args{rec} = $rec = $e->$retrieve_func([
+ $rec_id, {flesh => 1, flesh_fields => {$rec_class => ['matches']}}]);
+
} else {
$logger->info("vl: $type auto-overlay failed for queued rec $rec_id");
}
@@ -1071,6 +1082,11 @@ sub import_record_list_impl {
if($res->{$auto_overlay_best_func} eq 't') {
$logger->info("vl: $type auto-overlay-best succeeded for queued rec $rec_id");
$imported = 1;
+
+ # re-fetch the record to pick up the imported_as value from the DB
+ $$report_args{rec} = $rec = $e->$retrieve_func([
+ $rec_id, {flesh => 1, flesh_fields => {$rec_class => ['matches']}}]);
+
} else {
$$report_args{import_error} = 'overlay.record.quality' if $match_quality_ratio > 0;
$logger->info("vl: $type auto-overlay-best failed for queued rec $rec_id");
diff --git a/Open-ILS/web/js/ui/default/vandelay/vandelay.js b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
index d9a26a1..57e220b 100644
--- a/Open-ILS/web/js/ui/default/vandelay/vandelay.js
+++ b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
@@ -1122,7 +1122,6 @@ function vlImportRecordQueue(type, queueId, recList, onload) {
displayGlobalDiv('vl-generic-progress-with-total');
/* set up options */
- var mergeOpt = false;
var options = {overlay_map : currentOverlayRecordsMap};
if(vlUploadQueueImportNoMatch.checked) {
@@ -1133,21 +1132,18 @@ function vlImportRecordQueue(type, queueId, recList, onload) {
if(vlUploadQueueAutoOverlayExact.checked) {
options.auto_overlay_exact = true;
vlUploadQueueAutoOverlayExact.checked = false;
- mergeOpt = true;
}
if(vlUploadQueueAutoOverlayBestMatch.checked) {
options.auto_overlay_best_match = true;
vlUploadQueueAutoOverlayBestMatch.checked = false;
options.match_quality_ratio = vlUploadQueueAutoOverlayBestMatchRatio.attr('value');
- mergeOpt = true;
}
if(vlUploadQueueAutoOverlay1Match.checked) {
options.auto_overlay_1match = true;
vlUploadQueueAutoOverlay1Match.checked = false;
options.match_quality_ratio = vlUploadQueueAutoOverlayBestMatchRatio.attr('value');
- mergeOpt = true;
}
var profile = vlUploadMergeProfile.attr('value');
@@ -1161,13 +1157,6 @@ function vlImportRecordQueue(type, queueId, recList, onload) {
if(type == 'auth')
method = method.replace('bib', 'auth');
- if(!mergeOpt) {
- // in the interest of speed, if no merge options are
- // chosen, tell the back-end code to only process records
- // that have no matches
- method = method.replace(/\.import/, '.nomatch.import');
- }
-
var params = [authtoken, queueId, options];
if(recList) {
method = 'open-ils.vandelay.'+currentType+'_record.list.import';
commit 0612489eb8d325b30c4fa1bf7afa961cd9c45979
Author: Mike Rylander <mrylander at gmail.com>
Date: Sat May 21 09:05:04 2011 -0400
Spacing and code comments to keep future-miker from becoming confused again by the lack thereof
Signed-off-by: Mike Rylander <mrylander at gmail.com>
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
index d88e3a4..9dd923e 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
@@ -1383,6 +1383,7 @@ sub retrieve_queue_summary {
if($type eq 'bib') {
+ # count of all items attached to records in the queue in question
my $query = {
select => {vii => [{alias => 'count', column => 'id', transform => 'count', aggregate => 1}]},
from => 'vii',
@@ -1396,10 +1397,13 @@ sub retrieve_queue_summary {
}
}
};
-
$summary->{total_items} = $e->json_query($query)->[0]->{count};
+
+ # count of items we attempted to import, but errored, attached to records in the queue in question
$query->{where}->{import_error} = {'!=' => undef};
$summary->{item_import_errors} = $e->json_query($query)->[0]->{count};
+
+ # count of items we successfully imported attached to records in the queue in question
delete $query->{where}->{import_error};
$query->{where}->{import_time} = {'!=' => undef};
$summary->{total_items_imported} = $e->json_query($query)->[0]->{count};
commit bae1ec5dd89662529127eab766ba100afe53c618
Author: Lebbeous Fogle-Weekley <lebbeous at esilibrary.com>
Date: Fri May 20 18:12:58 2011 -0400
Show the "match score," a hopefully clearer term for match point quality,
in the expression tree UI
Signed-off-by: Lebbeous Fogle-Weekley <lebbeous at esilibrary.com>
diff --git a/Open-ILS/web/js/dojo/openils/vandelay/nls/match_set.js b/Open-ILS/web/js/dojo/openils/vandelay/nls/match_set.js
index 92851d2..be2c79b 100644
--- a/Open-ILS/web/js/dojo/openils/vandelay/nls/match_set.js
+++ b/Open-ILS/web/js/dojo/openils/vandelay/nls/match_set.js
@@ -11,5 +11,6 @@
"FAULTY_MARC": "A MARC tag must be identified by three digits, and the subfield must be one non-whitespace, non-control character.",
"WORKING_MP_HERE": "Choose from among the three buttons above to add a new match point.",
"WORKING_QM_HERE": "Use buttons above and to the right to add new quality metrics.",
- "SVF": "Record Attribute"
+ "SVF": "Record Attribute",
+ "MATCH_SCORE": "Match score ${0}"
}
diff --git a/Open-ILS/web/js/ui/default/conify/global/vandelay/match_set.js b/Open-ILS/web/js/ui/default/conify/global/vandelay/match_set.js
index 28f30b5..87656a3 100644
--- a/Open-ILS/web/js/ui/default/conify/global/vandelay/match_set.js
+++ b/Open-ILS/web/js/ui/default/conify/global/vandelay/match_set.js
@@ -339,19 +339,27 @@ function find_crad_by_name(name) {
}
function render_vmsp_label(point, minimal) {
- /* "minimal" has this implication:
+ /* "minimal" has these implications:
* for svf, only show the code, not the longer label.
+ * no quality display
*/
if (point.bool_op()) {
return point.bool_op();
} else if (point.svf()) {
return (openils.Util.isTrue(point.negate()) ? "NOT " : "") + (
minimal ? point.svf() :
- (point.svf() + " / " + find_crad_by_name(point.svf()).label())
+ (point.svf() + " / " + find_crad_by_name(point.svf()).label()) +
+ " | " + dojo.string.substitute(
+ localeStrings.MATCH_SCORE, [point.quality()]
+ )
);
} else {
return (openils.Util.isTrue(point.negate()) ? "NOT " : "") +
- point.tag() + " \u2021" + point.subfield();
+ point.tag() + " \u2021" + point.subfield() + (minimal ? "" : " | " +
+ dojo.string.substitute(
+ localeStrings.MATCH_SCORE, [point.quality()]
+ )
+ );
}
}
diff --git a/Open-ILS/web/templates/default/conify/global/vandelay/match_set_tree.tt2 b/Open-ILS/web/templates/default/conify/global/vandelay/match_set_tree.tt2
index 99367c0..cc5c788 100644
--- a/Open-ILS/web/templates/default/conify/global/vandelay/match_set_tree.tt2
+++ b/Open-ILS/web/templates/default/conify/global/vandelay/match_set_tree.tt2
@@ -61,7 +61,7 @@
<td>
<label for="quality-input"
title="A relative number representing the impact of this expression on the score of the overall record match"><!-- XXX tooltipize -->
- Math Score
+ Match Score
</label>
</td>
<td>
commit 3b250d8c958b209e0739eda15bb58b1456e2ff5a
Author: berick <berick at esilibrary.com>
Date: Fri May 20 17:13:13 2011 -0400
Add items-imported to VL queue summary
Added total_items_imported value to queue summary API call. Displaying
value in vandelay queue summary area.
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
index 0647c88..d88e3a4 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
@@ -1400,6 +1400,9 @@ sub retrieve_queue_summary {
$summary->{total_items} = $e->json_query($query)->[0]->{count};
$query->{where}->{import_error} = {'!=' => undef};
$summary->{item_import_errors} = $e->json_query($query)->[0]->{count};
+ delete $query->{where}->{import_error};
+ $query->{where}->{import_time} = {'!=' => undef};
+ $summary->{total_items_imported} = $e->json_query($query)->[0]->{count};
}
return $summary;
diff --git a/Open-ILS/web/js/ui/default/vandelay/vandelay.js b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
index 1c03486..d9a26a1 100644
--- a/Open-ILS/web/js/ui/default/vandelay/vandelay.js
+++ b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
@@ -1010,6 +1010,7 @@ var handleRetrieveRecords = function() {
dojo.byId('vl-queue-summary-total-count').innerHTML = summary.total +'';
dojo.byId('vl-queue-summary-import-count').innerHTML = summary.imported + '';
dojo.byId('vl-queue-summary-import-item-count').innerHTML = summary.total_items + '';
+ dojo.byId('vl-queue-summary-import-item-imported-count').innerHTML = summary.total_items_imported + '';
dojo.byId('vl-queue-summary-rec-error-count').innerHTML = summary.rec_import_errors + '';
dojo.byId('vl-queue-summary-item-error-count').innerHTML = summary.item_import_errors + '';
}
diff --git a/Open-ILS/web/templates/default/vandelay/inc/queue.tt2 b/Open-ILS/web/templates/default/vandelay/inc/queue.tt2
index c34c57f..783ffa5 100644
--- a/Open-ILS/web/templates/default/vandelay/inc/queue.tt2
+++ b/Open-ILS/web/templates/default/vandelay/inc/queue.tt2
@@ -28,6 +28,7 @@
<tr><td>&vandelay.queue.imported;</td><td> <span style='font-weight:bold;' id='vl-queue-summary-import-count'/></td></tr>
<tr><td>Record Import Failures</td><td> <span style='font-weight:bold;' id='vl-queue-summary-rec-error-count'/></td></tr>
<tr><td>Items in Queue</td><td> <span style='font-weight:bold;' id='vl-queue-summary-import-item-count'/></td></tr>
+ <tr><td>Items Imported</td><td> <span style='font-weight:bold;' id='vl-queue-summary-import-item-imported-count'/></td></tr>
<tr><td>Item Import Failures</td><td> <span style='font-weight:bold;' id='vl-queue-summary-item-error-count'/></td></tr>
</tbody>
</table>
commit a56d95c3218ed1a4c78434430df3206e752c1a54
Author: berick <berick at esilibrary.com>
Date: Fri May 20 17:06:05 2011 -0400
Track import time and target copy on import items
Added import_time and imported_as columns to vandelay.import_item
For you branch trackers:
ALTER TABLE vandelay.import_item
ADD import_time TIMESTAMP WITH TIME ZONE;
ALTER TABLE vandelay.import_item
ADD imported_as BIGINT REFERENCES
asset.copy (id) DEFERRABLE INITIALLY DEFERRED;
diff --git a/Open-ILS/examples/fm_IDL.xml b/Open-ILS/examples/fm_IDL.xml
index 06cf384..27cdcd7 100644
--- a/Open-ILS/examples/fm_IDL.xml
+++ b/Open-ILS/examples/fm_IDL.xml
@@ -189,6 +189,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
<field reporter:label="Attribute Definition" name="definition" reporter:datatype="link"/>
<field reporter:label="Import Error" name="import_error" reporter:datatype="link"/>
<field reporter:label="Import Error Detail" name="error_detail" reporter:datatype="text"/>
+ <field reporter:label="Final Target Copy" name="imported_as" reporter:datatype="link"/>
+ <field reporter:label="Import Time" name="import_time" reporter:datatype="timestamp"/>
<field reporter:label="Owning Library" name="owning_lib" reporter:datatype="int"/>
<field reporter:label="Circulating Library" name="circ_lib" reporter:datatype="int"/>
<field reporter:label="Call Number" name="call_number" reporter:datatype="text"/>
@@ -213,6 +215,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
<link field="import_error" reltype="has_a" key="code" map="" class="vie"/>
<link field="record" reltype="has_a" key="id" map="" class="vqbr"/>
<link field="definition" reltype="has_a" key="id" map="" class="viiad"/>
+ <link field="imported_as" reltype="has_a" key="id" map="" class="acp"/>
</links>
<permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
<actions>
diff --git a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
index d461d4f..9a5c3ef 100644
--- a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
+++ b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
@@ -153,6 +153,8 @@ CREATE TABLE vandelay.import_item (
definition BIGINT NOT NULL REFERENCES vandelay.import_item_attr_definition (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
import_error TEXT REFERENCES vandelay.import_error (code) ON DELETE SET NULL ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
error_detail TEXT,
+ imported_as BIGINT REFERENCES asset.copy (id) DEFERRABLE INITIALLY DEFERRED,
+ import_time TIMESTAMP WITH TIME ZONE,
owning_lib INT,
circ_lib INT,
call_number TEXT,
commit 205675af130077e3fe74325983f22c68d74267a9
Author: berick <berick at esilibrary.com>
Date: Fri May 20 13:45:52 2011 -0400
more delineation of quality vs. score in match set config
diff --git a/Open-ILS/web/templates/default/conify/global/vandelay/match_set_tree.tt2 b/Open-ILS/web/templates/default/conify/global/vandelay/match_set_tree.tt2
index d7bf224..99367c0 100644
--- a/Open-ILS/web/templates/default/conify/global/vandelay/match_set_tree.tt2
+++ b/Open-ILS/web/templates/default/conify/global/vandelay/match_set_tree.tt2
@@ -60,8 +60,8 @@
<tr consistent-controls="1">
<td>
<label for="quality-input"
- title="A relative number representing the impact of this expression on the quality of the overall record match"><!-- XXX tooltipize -->
- Math Score Value
+ title="A relative number representing the impact of this expression on the score of the overall record match"><!-- XXX tooltipize -->
+ Math Score
</label>
</td>
<td>
commit 780e59e5baa189e7c7fa01c41378cd51cbbfb834
Author: berick <berick at esilibrary.com>
Date: Fri May 20 13:26:03 2011 -0400
Match set point quality terminology change
Change "Quality" in the context of a match set
point to "Match Score Value" to avoid overriding the term "quality".
diff --git a/Open-ILS/web/templates/default/conify/global/vandelay/match_set_tree.tt2 b/Open-ILS/web/templates/default/conify/global/vandelay/match_set_tree.tt2
index 8ad1eea..d7bf224 100644
--- a/Open-ILS/web/templates/default/conify/global/vandelay/match_set_tree.tt2
+++ b/Open-ILS/web/templates/default/conify/global/vandelay/match_set_tree.tt2
@@ -61,7 +61,7 @@
<td>
<label for="quality-input"
title="A relative number representing the impact of this expression on the quality of the overall record match"><!-- XXX tooltipize -->
- Quality:
+ Math Score Value
</label>
</td>
<td>
commit f2218fa2015df835718d4bba856c3365e84333f3
Author: berick <berick at esilibrary.com>
Date: Fri May 20 13:23:08 2011 -0400
Return to dijit.form.Button for VL upload form
Otherwise the form is not correctly POSTed
diff --git a/Open-ILS/web/templates/default/vandelay/inc/upload.tt2 b/Open-ILS/web/templates/default/vandelay/inc/upload.tt2
index 40aae32..b432252 100644
--- a/Open-ILS/web/templates/default/vandelay/inc/upload.tt2
+++ b/Open-ILS/web/templates/default/vandelay/inc/upload.tt2
@@ -88,7 +88,7 @@
<td colspan='5'>
<span id="vl-file-label">&vandelay.file.to.upload;</span>
<input size='48' style='border:1px solid #888;' type="file" name="marc_upload"/>
- <span style='margin-left:10px;'><button onclick="batchUpload()">&vandelay.upload;</button></span>
+ <span style='margin-left:10px;'><button dojoType="dijit.form.Button" onclick="batchUpload()">&vandelay.upload;</button></span>
</td>
</tr>
</table>
commit f18a260e1f75c090e1a1567173c53d82fd651fb2
Author: berick <berick at esilibrary.com>
Date: Fri May 20 13:20:40 2011 -0400
show activity dialog on vandelay item export
diff --git a/Open-ILS/web/js/ui/default/vandelay/vandelay.js b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
index e0a7eaf..1c03486 100644
--- a/Open-ILS/web/js/ui/default/vandelay/vandelay.js
+++ b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
@@ -404,6 +404,7 @@ function vlExportInit() {
if(!value) return;
if(!confirm('Export as "' + value + '"?')) return; // TODO: i18n
+ displayGlobalDiv('vl-generic-progress');
var method = 'open-ils.vandelay.import_item.queue.export.' + value + '.atomic';
fieldmapper.standardRequest(
@@ -422,6 +423,7 @@ function vlExportInit() {
}
function exportHandler(type, response) {
+ displayGlobalDiv('vl-import-error-div');
try {
var content = openils.Util.readResponse(response);
if (type=='email') {
commit 05c990e3c61a140b5036ea1b55f3274cd5cb04a4
Author: berick <berick at esilibrary.com>
Date: Fri May 20 09:07:44 2011 -0400
More Vandelay text and style cleanup
* More consistent use of the word "match"
* Make upload input more obvious w/ a border
* Move some strings into DTD
diff --git a/Open-ILS/web/opac/locale/en-US/vandelay.dtd b/Open-ILS/web/opac/locale/en-US/vandelay.dtd
index 7928620..68eb92e 100644
--- a/Open-ILS/web/opac/locale/en-US/vandelay.dtd
+++ b/Open-ILS/web/opac/locale/en-US/vandelay.dtd
@@ -1,7 +1,8 @@
<!ENTITY vandelay.add.existing.queue "or Add to an Existing Queue">
<!ENTITY vandelay.auth.attrs "Authority attributes">
<!ENTITY vandelay.auth.records "Authority Records">
-<!ENTITY vandelay.auto.import.noncolliding "Import Non-Colliding Records">
+<!ENTITY vandelay.import.actions "Record Import Actions">
+<!ENTITY vandelay.auto.import.noncolliding "Import Non-Matching Records">
<!ENTITY vandelay.auto.import.auto_overlay_exact "Merge On Exact Match (901c)">
<!ENTITY vandelay.auto.import.auto_overlay_1match "Merge On Single Match">
<!ENTITY vandelay.auto.import.auto_overlay_best "Merge On Best Match">
diff --git a/Open-ILS/web/templates/default/vandelay/inc/upload.tt2 b/Open-ILS/web/templates/default/vandelay/inc/upload.tt2
index f742104..40aae32 100644
--- a/Open-ILS/web/templates/default/vandelay/inc/upload.tt2
+++ b/Open-ILS/web/templates/default/vandelay/inc/upload.tt2
@@ -44,7 +44,9 @@
dojoType='dijit.form.FilteringSelect' labelAttr='source' searchAttr='source'/>
</td>
</tr>
- <tr><td colspan='2' style='margin-top:10px;border-bottom:1px solid #888;border-top:1px solid #888'><b>Import Actions</b></td></tr>
+ <tr><td colspan='2' style='margin-top:10px;border-bottom:1px solid #888;border-top:2px solid #888'>
+ <b>&vandelay.import.actions;</b>
+ </td></tr>
<tr>
<td>&vandelay.auto.import.merge_profile;</td>
<td colspan='4'>
@@ -80,13 +82,13 @@
<span style='padding-left: 10px; font-size:90%'>(&vandelay.auto.import.auto_overlay_best_ratio.desc;)</span>
</td>
</tr>
-
- <tr><td colspan='2' style='border-bottom:1px solid #888'></td></tr>
+ <tr><td colspan='2' style='border-bottom:2px solid #888;'></td></tr>
+ <tr><td colspan='2' style='padding-bottom: 10px;'></td></tr>
<tr>
<td colspan='5'>
<span id="vl-file-label">&vandelay.file.to.upload;</span>
- <input size='48' type="file" name="marc_upload"/>
- <span style='margin-left:10px;'><button dojoType="dijit.form.Button" onclick="batchUpload()">&vandelay.upload;</button></span>
+ <input size='48' style='border:1px solid #888;' type="file" name="marc_upload"/>
+ <span style='margin-left:10px;'><button onclick="batchUpload()">&vandelay.upload;</button></span>
</td>
</tr>
</table>
commit 70f893c2d049f17ae7ff35d86c2f48cae01e1503
Author: berick <berick at esilibrary.com>
Date: Thu May 19 15:40:30 2011 -0400
Flexible TCN match configuration
If users do not want records with duplicate TCN values imported, users
should rely on match-sets to enforce this policy instead of a hard-coded
duplicate tcn block. This is done by automatically calling the 'override'
version of bib XML import. The only tcn-related failure that can now
occur is if no free, non-dupe TCN value can be extracted from the record.
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
index 65a0013..0647c88 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
@@ -1089,14 +1089,16 @@ sub import_record_list_impl {
$logger->info("vl: creating new $type record for queued record $rec_id");
if($type eq 'bib') {
- $record = OpenILS::Application::Cat::BibCommon->biblio_record_xml_import($e, $rec->marc, $bib_sources{$rec->bib_source});
+ $record = OpenILS::Application::Cat::BibCommon->biblio_record_xml_import(
+ $e, $rec->marc, $bib_sources{$rec->bib_source}, undef, 1);
} else {
$record = OpenILS::Application::Cat::AuthCommon->import_authority_record($e, $rec->marc); #$source);
}
if($U->event_code($record)) {
- $$report_args{import_error} = 'import.duplicate.tcn' if $record->{textcode} eq 'TCN_EXISTS';
+ $$report_args{import_error} = 'import.duplicate.tcn'
+ if $record->{textcode} eq 'OPEN_TCN_NOT_FOUND';
$$report_args{evt} = $record;
} else {
commit 12029c8f696863957ddbbdb784c4dda0a8e94f56
Author: berick <berick at esilibrary.com>
Date: Thu May 19 15:26:49 2011 -0400
Vandelay import improvements / bug fixes
* Allow for quality ratio control during import-on-1match
* Allow for 901c matching when no match-set is selected
* Tidy up some display strings
* Numerous small bug fixes
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
index 4a0bf99..65a0013 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
@@ -927,8 +927,8 @@ sub import_record_list_impl {
$e->requestor($requestor);
$$report_args{e} = $e;
- $$report_args{import_error} = undef;
$$report_args{evt} = undef;
+ $$report_args{import_error} = undef;
my $rec = $e->$retrieve_func([
$rec_id,
@@ -962,7 +962,7 @@ sub import_record_list_impl {
{
from => [
$overlay_func,
- $rec->id,
+ $rec_id,
$overlay_target,
$merge_profile
]
@@ -972,8 +972,8 @@ sub import_record_list_impl {
if($res and ($res = $res->[0])) {
if($res->{$overlay_func} eq 't') {
- $logger->info("vl: $type direct overlay succeeded for queued rec " .
- $rec->id . " and overlay target $overlay_target");
+ $logger->info("vl: $type direct overlay succeeded for queued rec ".
+ "$rec_id and overlay target $overlay_target");
$imported = 1;
}
@@ -984,34 +984,39 @@ sub import_record_list_impl {
} else {
- if($auto_overlay_1match) {
- # caller says to overlay if there is exactly 1 match
+ if($auto_overlay_1match) { # overlay if there is exactly 1 match
my %match_recs = map { $_->eg_record => 1 } @{$rec->matches};
if( scalar(keys %match_recs) == 1) { # all matches point to the same record
+ # $auto_overlay_best_func will find the 1 match and
+ # overlay if the quality ratio allows it
+
my $res = $e->json_query(
{
from => [
- $overlay_func,
- $rec->id,
- $rec->matches->[0]->eg_record,
- $merge_profile
+ $auto_overlay_best_func,
+ $rec_id,
+ $merge_profile,
+ $match_quality_ratio
]
}
);
if($res and ($res = $res->[0])) {
- if($res->{$overlay_func} eq 't') {
- $logger->info("vl: $type overlay-1match succeeded for queued rec " . $rec->id);
+ if($res->{$auto_overlay_best_func} eq 't') {
+ $logger->info("vl: $type overlay-1match succeeded for queued rec $rec_id");
$imported = 1;
+ } else {
+ $$report_args{import_error} = 'overlay.record.quality' if $match_quality_ratio > 0;
+ $logger->info("vl: $type overlay-1match failed for queued rec $rec_id");
}
} else {
$error = 1;
- $logger->error("vl: Error attempting overlay with func=$overlay_func, profile=$merge_profile, record=$rec_id");
+ $logger->error("vl: Error attempting overlay with func=$auto_overlay_best_func, profile=$merge_profile, record=$rec_id");
}
}
}
@@ -1019,12 +1024,13 @@ sub import_record_list_impl {
if(!$imported and !$error and $auto_overlay_exact and scalar(@{$rec->matches}) == 1 ) {
# caller says to overlay if there is an /exact/ match
+ # $auto_overlay_func only proceeds and returns true on exact matches
my $res = $e->json_query(
{
from => [
$auto_overlay_func,
- $rec->id,
+ $rec_id,
$merge_profile
]
}
@@ -1033,10 +1039,10 @@ sub import_record_list_impl {
if($res and ($res = $res->[0])) {
if($res->{$auto_overlay_func} eq 't') {
- $logger->info("vl: $type auto-overlay succeeded for queued rec " . $rec->id);
+ $logger->info("vl: $type auto-overlay succeeded for queued rec $rec_id");
$imported = 1;
} else {
- $logger->info("vl: $type auto-overlay failed for queued rec " . $rec->id);
+ $logger->info("vl: $type auto-overlay failed for queued rec $rec_id");
}
} else {
@@ -1053,7 +1059,7 @@ sub import_record_list_impl {
{
from => [
$auto_overlay_best_func,
- $rec->id,
+ $rec_id,
$merge_profile,
$match_quality_ratio
]
@@ -1063,11 +1069,11 @@ sub import_record_list_impl {
if($res and ($res = $res->[0])) {
if($res->{$auto_overlay_best_func} eq 't') {
- $logger->info("vl: $type auto-overlay-best succeeded for queued rec " . $rec->id);
+ $logger->info("vl: $type auto-overlay-best succeeded for queued rec $rec_id");
$imported = 1;
} else {
$$report_args{import_error} = 'overlay.record.quality' if $match_quality_ratio > 0;
- $logger->info("vl: $type auto-overlay-best failed for queued rec " . $rec->id);
+ $logger->info("vl: $type auto-overlay-best failed for queued rec $rec_id");
}
} else {
@@ -1097,20 +1103,28 @@ sub import_record_list_impl {
$logger->info("vl: successfully imported new $type record");
$rec->imported_as($record->id);
- $rec->import_time('now');
- $rec->clear_import_error;
- $rec->clear_error_detail;
- $imported = 1 if $e->$update_func($rec);
}
}
}
if($imported) {
- push @success_rec_ids, $rec_id;
- finish_rec_import_attempt($report_args);
- } else {
- # Send an update whenever there's an error
+ $rec->import_time('now');
+ $rec->clear_import_error;
+ $rec->clear_error_detail;
+
+ if($e->$update_func($rec)) {
+
+ push @success_rec_ids, $rec_id;
+ finish_rec_import_attempt($report_args);
+
+ } else {
+ $imported = 0;
+ }
+ }
+
+ if(!$imported) {
+ $logger->info("vl: record $rec_id was not imported");
$$report_args{evt} = $e->event unless $$report_args{evt};
finish_rec_import_attempt($report_args);
}
@@ -1137,7 +1151,7 @@ sub import_record_list_impl {
}
# import the copies
- import_record_asset_list_impl($conn, \@success_rec_ids, $requestor);
+ import_record_asset_list_impl($conn, \@success_rec_ids, $requestor) if @success_rec_ids;
$conn->respond({total => $$report_args{total}, progress => $$report_args{progress}});
return undef;
@@ -1402,7 +1416,10 @@ sub import_record_asset_list_impl {
$rec_ids = $roe->json_query({
select => {vqbr => ['id']},
from => {vqbr => 'vii'},
- where => {'+vqbr' => {import_time => {'!=' => undef}}},
+ where => {'+vqbr' => {
+ id => $rec_ids,
+ import_time => {'!=' => undef}
+ }},
distinct => 1
});
$rec_ids = [map {$_->{id}} @$rec_ids];
@@ -1555,7 +1572,9 @@ sub respond_with_status {
if($$args{report_all} or ($$args{progress} % $$args{step}) == 0) {
$$args{conn}->respond({
- map { $_ => $args->{$_} } qw/total progress success_count/,
+ total => $$args{total},
+ progress => $$args{progress},
+ success_count => $$args{success_count},
err_event => $evt
});
$$args{step} *= 2 unless $$args{step} == 256;
diff --git a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
index b136e8e..d461d4f 100644
--- a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
+++ b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
@@ -677,9 +677,9 @@ $$ LANGUAGE PLPGSQL;
CREATE OR REPLACE FUNCTION vandelay.match_bib_record() RETURNS TRIGGER AS $func$
DECLARE
incoming_existing_id TEXT;
- my_bib_queue vandelay.bib_queue%ROWTYPE;
test_result vandelay.match_set_test_result%ROWTYPE;
tmp_rec BIGINT;
+ match_set INT;
BEGIN
IF TG_OP IN ('INSERT','UPDATE') AND NEW.imported_as IS NOT NULL THEN
RETURN NEW;
@@ -687,14 +687,12 @@ BEGIN
DELETE FROM vandelay.bib_match WHERE queued_record = NEW.id;
- SELECT * INTO my_bib_queue FROM vandelay.bib_queue WHERE id = NEW.queue;
+ SELECT q.match_set INTO match_set FROM vandelay.bib_queue q WHERE q.id = NEW.queue;
- IF my_bib_queue.match_set IS NULL THEN
- RETURN NEW;
+ IF match_set IS NOT NULL THEN
+ NEW.quality := vandelay.measure_record_quality( NEW.marc, match_set );
END IF;
- NEW.quality := vandelay.measure_record_quality( NEW.marc, my_bib_queue.match_set );
-
-- Perfect matches on 901$c exit early with a match with high quality.
incoming_existing_id :=
oils_xpath_string('//*[@tag="901"]/*[@code="c"][1]', NEW.marc);
@@ -702,22 +700,33 @@ BEGIN
IF incoming_existing_id IS NOT NULL AND incoming_existing_id != '' THEN
SELECT id INTO tmp_rec FROM biblio.record_entry WHERE id = incoming_existing_id::bigint;
IF tmp_rec IS NOT NULL THEN
- INSERT INTO vandelay.bib_match (queued_record, eg_record, quality) VALUES ( NEW.id, incoming_existing_id::bigint, 9999);
- RETURN NEW;
+ INSERT INTO vandelay.bib_match (queued_record, eg_record, match_score, quality)
+ SELECT
+ NEW.id,
+ b.id,
+ 9999,
+ -- note: no match_set means quality==0
+ vandelay.measure_record_quality( b.marc, match_set )
+ FROM biblio.record_entry b
+ WHERE id = incoming_existing_id::bigint;
END IF;
END IF;
+ IF match_set IS NULL THEN
+ RETURN NEW;
+ END IF;
FOR test_result IN SELECT * FROM
- vandelay.match_set_test_marcxml(my_bib_queue.match_set, NEW.marc) LOOP
+ vandelay.match_set_test_marcxml(match_set, NEW.marc) LOOP
INSERT INTO vandelay.bib_match ( queued_record, eg_record, match_score, quality )
- SELECT NEW.id,
- test_result.record,
+ SELECT
+ NEW.id,
+ test_result.record,
test_result.quality,
- vandelay.measure_record_quality( b.marc, my_bib_queue.match_set )
- FROM biblio.record_entry b
- WHERE id = test_result.record;
+ vandelay.measure_record_quality( b.marc, match_set )
+ FROM biblio.record_entry b
+ WHERE id = test_result.record;
END LOOP;
diff --git a/Open-ILS/web/js/ui/default/vandelay/vandelay.js b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
index b67352a..e0a7eaf 100644
--- a/Open-ILS/web/js/ui/default/vandelay/vandelay.js
+++ b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
@@ -1143,6 +1143,7 @@ function vlImportRecordQueue(type, queueId, recList, onload) {
if(vlUploadQueueAutoOverlay1Match.checked) {
options.auto_overlay_1match = true;
vlUploadQueueAutoOverlay1Match.checked = false;
+ options.match_quality_ratio = vlUploadQueueAutoOverlayBestMatchRatio.attr('value');
mergeOpt = true;
}
diff --git a/Open-ILS/web/opac/locale/en-US/vandelay.dtd b/Open-ILS/web/opac/locale/en-US/vandelay.dtd
index d2d1789..7928620 100644
--- a/Open-ILS/web/opac/locale/en-US/vandelay.dtd
+++ b/Open-ILS/web/opac/locale/en-US/vandelay.dtd
@@ -2,12 +2,12 @@
<!ENTITY vandelay.auth.attrs "Authority attributes">
<!ENTITY vandelay.auth.records "Authority Records">
<!ENTITY vandelay.auto.import.noncolliding "Import Non-Colliding Records">
-<!ENTITY vandelay.auto.import.auto_overlay_exact "Merge/Overlay Exact Matches (901c)">
-<!ENTITY vandelay.auto.import.auto_overlay_1match "Merge/Overlay Single Matches">
-<!ENTITY vandelay.auto.import.auto_overlay_best "Merge/Overlay Best Match">
-<!ENTITY vandelay.auto.import.auto_overlay_best_ratio "Best Match Minimum Quality Ratio">
+<!ENTITY vandelay.auto.import.auto_overlay_exact "Merge On Exact Match (901c)">
+<!ENTITY vandelay.auto.import.auto_overlay_1match "Merge On Single Match">
+<!ENTITY vandelay.auto.import.auto_overlay_best "Merge On Best Match">
+<!ENTITY vandelay.auto.import.auto_overlay_best_ratio "Best/Single Match Minimum Quality Ratio">
<!ENTITY vandelay.auto.import.auto_overlay_best_ratio.desc "New Record Quaility / Quality of Best Match">
-<!ENTITY vandelay.auto.import.merge_profile "Merge/Overlay Profile">
+<!ENTITY vandelay.auto.import.merge_profile "Merge Profile">
<!ENTITY vandelay.auto.width "Auto Width">
<!ENTITY vandelay.back.to.import.queue "Back To Import Queue">
<!ENTITY vandelay.bib.attrs "Bibliographic attributes">
@@ -52,8 +52,8 @@
<!ENTITY vandelay.marc.record "MARC Record">
<!ENTITY vandelay.matches "Matches">
<!ENTITY vandelay.next.page "Next »">
-<!ENTITY vandelay.overlay.selected.record "Overlay selected record with imported record">
-<!ENTITY vandelay.overlay.target "Overlay Target">
+<!ENTITY vandelay.overlay.selected.record "Merge selected record with imported record">
+<!ENTITY vandelay.overlay.target "Merge Target">
<!ENTITY vandelay.page "Page">
<!ENTITY vandelay.powered.by.evergreen "Powered by Evergreen!">
<!ENTITY vandelay.prev.page "« Previous">
commit 7f913b210b523d68dd4bb7395b37dd5f824e1e22
Author: berick <berick at esilibrary.com>
Date: Thu May 19 12:37:52 2011 -0400
Clean up match_set data on delete
Delete via cascade match_set_point's and match_set_quality entries
for a given match_set on delete
diff --git a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
index d6810f6..b136e8e 100644
--- a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
+++ b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
@@ -15,7 +15,7 @@ CREATE TABLE vandelay.match_set (
-- Table to define match points, either FF via SVF or tag+subfield
CREATE TABLE vandelay.match_set_point (
id SERIAL PRIMARY KEY,
- match_set INT REFERENCES vandelay.match_set (id),
+ match_set INT REFERENCES vandelay.match_set (id) ON DELETE CASCADE,
parent INT REFERENCES vandelay.match_set_point (id),
bool_op TEXT CHECK (bool_op IS NULL OR (bool_op IN ('AND','OR','NOT'))),
svf TEXT REFERENCES config.record_attr_definition (name),
@@ -33,7 +33,7 @@ CREATE TABLE vandelay.match_set_point (
CREATE TABLE vandelay.match_set_quality (
id SERIAL PRIMARY KEY,
- match_set INT NOT NULL REFERENCES vandelay.match_set (id),
+ match_set INT NOT NULL REFERENCES vandelay.match_set (id) ON DELETE CASCADE,
svf TEXT REFERENCES config.record_attr_definition,
tag TEXT,
subfield TEXT,
commit 0cf7d27b68cba7d10942db2ee8d8ae3ff8fc17ec
Author: berick <berick at esilibrary.com>
Date: Thu May 19 10:23:36 2011 -0400
Display org shortname in merge profile editor
...instead of org unit ID
diff --git a/Open-ILS/web/templates/default/vandelay/inc/profiles.tt2 b/Open-ILS/web/templates/default/vandelay/inc/profiles.tt2
index ca67f3a..0220d6a 100644
--- a/Open-ILS/web/templates/default/vandelay/inc/profiles.tt2
+++ b/Open-ILS/web/templates/default/vandelay/inc/profiles.tt2
@@ -19,5 +19,10 @@
fmClass='vmp'
showPaginator='true'
editOnEnter='true'>
+ <thead>
+ <tr>
+ <th field='owner' get='vlGetOrg'/>
+ </tr>
+ </thead>
</table>
</div>
commit 10c443b05e002ba1cf3c917c228b77e312f35c59
Author: Jason Etheridge <jason at esilibrary.com>
Date: Sat May 14 13:44:56 2011 -0400
return after Email sent alert
diff --git a/Open-ILS/web/js/ui/default/vandelay/vandelay.js b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
index e78ebcc..b67352a 100644
--- a/Open-ILS/web/js/ui/default/vandelay/vandelay.js
+++ b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
@@ -425,7 +425,7 @@ function exportHandler(type, response) {
try {
var content = openils.Util.readResponse(response);
if (type=='email') {
- if (content==1) { alert('Email sent.'); }
+ if (content==1) { alert('Email sent.'); return; }
throw(content);
}
/* handle .atomic versus non-atomic method calls */
commit e9c64425a8df9e91c9f14051e87138edd5d84aeb
Author: Jason Etheridge <jason at esilibrary.com>
Date: Sat May 14 13:40:36 2011 -0400
This function also gets used with authority queues, so don't assume import_items()
diff --git a/Open-ILS/web/js/ui/default/vandelay/vandelay.js b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
index ea06944..e78ebcc 100644
--- a/Open-ILS/web/js/ui/default/vandelay/vandelay.js
+++ b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
@@ -675,7 +675,10 @@ function vlGetViewErrors(rowIdx, item) {
// id:rec_error:item_import_error_count
return id + ':' +
(rec.import_error() ? 1 : '') + ':' +
- rec.import_items().filter(function(i) {return i.import_error()}).length;
+ (typeof rec.import_items == 'function'
+ ? rec.import_items().filter(function(i) {return i.import_error()}).length
+ :''
+ );
}
return -1
}
commit c094b362e18e9fed3551c2c2fa9375dbb0627789
Author: Jason Etheridge <jason at esilibrary.com>
Date: Sat May 14 13:30:29 2011 -0400
email template for import items export
diff --git a/Open-ILS/src/sql/Pg/upgrade/renumber_me.sql b/Open-ILS/src/sql/Pg/upgrade/renumber_me.sql
index 1b64567..5396747 100644
--- a/Open-ILS/src/sql/Pg/upgrade/renumber_me.sql
+++ b/Open-ILS/src/sql/Pg/upgrade/renumber_me.sql
@@ -494,7 +494,79 @@ INSERT INTO action_trigger.environment ( event_def, path) VALUES (
,( 45, 'record.queue.owner')
;
+INSERT INTO action_trigger.event_definition (
+ id,
+ active,
+ owner,
+ name,
+ hook,
+ validator,
+ reactor,
+ group_field,
+ granularity,
+ template
+ ) VALUES (
+ 46,
+ TRUE,
+ 1,
+ 'Email Output for Import Items from Queued Bib Records',
+ 'vandelay.import_items.email',
+ 'NOOP_True',
+ 'SendEmail',
+ 'record.queue.owner',
+ NULL,
+$$
+[%- USE date -%]
+[%- SET user = target.0.record.queue.owner -%]
+To: [%- params.recipient_email || user.email || 'root at localhost' %]
+From: [%- params.sender_email || default_sender %]
+Subject: Import Items from Import Queue
+
+Queue ID: [% target.0.record.queue.id %]
+Queue Name: [% target.0.record.queue.name %]
+Queue Type: [% target.0.record.queue.queue_type %]
+Complete? [% target.0.record.queue.complete %]
+
+ [% FOR vii IN target %]
+=-=-=
+ Import Item ID | [% vii.id %]
+ Title of work | [% helpers.get_queued_bib_attr('title',vii.record.attributes) %]
+ ISBN | [% helpers.get_queued_bib_attr('isbn',vii.record.attributes) %]
+ Attribute Definition | [% vii.definition %]
+ Import Error | [% vii.import_error %]
+ Import Error Detail | [% vii.error_detail %]
+ Owning Library | [% vii.owning_lib %]
+ Circulating Library | [% vii.circ_lib %]
+ Call Number | [% vii.call_number %]
+ Copy Number | [% vii.copy_number %]
+ Status | [% vii.status.name %]
+ Shelving Location | [% vii.location.name %]
+ Circulate | [% vii.circulate %]
+ Deposit | [% vii.deposit %]
+ Deposit Amount | [% vii.deposit_amount %]
+ Reference | [% vii.ref %]
+ Holdable | [% vii.holdable %]
+ Price | [% vii.price %]
+ Barcode | [% vii.barcode %]
+ Circulation Modifier | [% vii.circ_modifier %]
+ Circulate As MARC Type | [% vii.circ_as_type %]
+ Alert Message | [% vii.alert_message %]
+ Public Note | [% vii.pub_note %]
+ Private Note | [% vii.priv_note %]
+ OPAC Visible | [% vii.opac_visible %]
+
+ [% END %]
+$$
+ )
+;
+
+INSERT INTO action_trigger.environment ( event_def, path) VALUES (
+ 46, 'record')
+ ,( 46, 'record.attributes')
+ ,( 46, 'record.queue')
+ ,( 46, 'record.queue.owner')
+;
COMMIT;
--- BEGIN; DELETE FROM action_trigger.event WHERE event_def IN (38,39,40,41,42,43,44,45); DELETE FROM action_trigger.environment WHERE event_def IN (38,39,40,41,42,43,44,45); DELETE FROM action_trigger.event_definition WHERE id IN (38,39,40,41,42,43,44,45); DELETE FROM action_trigger.hook WHERE key IN ('vandelay.queued_bib_record.print','vandelay.queued_bib_record.csv','vandelay.queued_bib_record.email','vandelay.queued_auth_record.print','vandelay.queued_auth_record.csv','vandelay.queued_auth_record.email','vandelay.import_items.print','vandelay.import_items.csv','vandelay.import_items.email'); DELETE FROM action_trigger.event_output WHERE id IN ((SELECT template_output FROM action_trigger.event WHERE event_def IN (38,39,40,41,42,43,44,45))UNION(SELECT error_output FROM action_trigger.event WHERE event_def IN (38,39,40,41,42,43,44,45))); DELETE FROM config.upgrade_log WHERE version = 'test'; COMMIT;
+-- BEGIN; DELETE FROM action_trigger.event WHERE event_def IN (38,39,40,41,42,43,44,45,46); DELETE FROM action_trigger.environment WHERE event_def IN (38,39,40,41,42,43,44,45,46); DELETE FROM action_trigger.event_definition WHERE id IN (38,39,40,41,42,43,44,45,46); DELETE FROM action_trigger.hook WHERE key IN ('vandelay.queued_bib_record.print','vandelay.queued_bib_record.csv','vandelay.queued_bib_record.email','vandelay.queued_auth_record.print','vandelay.queued_auth_record.csv','vandelay.queued_auth_record.email','vandelay.import_items.print','vandelay.import_items.csv','vandelay.import_items.email'); DELETE FROM action_trigger.event_output WHERE id IN ((SELECT template_output FROM action_trigger.event WHERE event_def IN (38,39,40,41,42,43,44,45,46))UNION(SELECT error_output FROM action_trigger.event WHERE event_def IN (38,39,40,41,42,43,44,45,46))); DELETE FROM config.upgrade_log WHERE version = 'test'; COMMIT;
commit 40a118a3ddf858ad88f5696406b6b3abac9dcc0f
Author: Jason Etheridge <jason at esilibrary.com>
Date: Sat May 14 13:21:02 2011 -0400
tweak formatting for CSV export templates, and add headers
diff --git a/Open-ILS/src/sql/Pg/upgrade/renumber_me.sql b/Open-ILS/src/sql/Pg/upgrade/renumber_me.sql
index b4f7b3b..1b64567 100644
--- a/Open-ILS/src/sql/Pg/upgrade/renumber_me.sql
+++ b/Open-ILS/src/sql/Pg/upgrade/renumber_me.sql
@@ -183,7 +183,10 @@ INSERT INTO action_trigger.event_definition (
'queue.owner',
'print-on-demand',
$$
-[%- USE date -%][%- FOR vqbr IN target -%]"[% helpers.get_queued_bib_attr('title',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('author',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('language',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('pagination',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('isbn',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('issn',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('price',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('rec_identifier',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('eg_tcn',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('eg_tcn_source',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('eg_identifier',vqbr.attributes) | replace('"', '""') %]","[% helpers.
get_queued_bib_attr('publisher',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('pubdate',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('edition',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('item_barcode',vqbr.attributes) | replace('"', '""') %]"[%- END -%]
+[%- USE date -%]
+"Title of work","Author of work","Language of work","Pagination","ISBN","ISSN","Price","Accession Number","TCN Value","TCN Source","Internal ID","Publisher","Publication Date","Edition","Item Barcode"
+[% FOR vqbr IN target %]"[% helpers.get_queued_bib_attr('title',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('author',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('language',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('pagination',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('isbn',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('issn',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('price',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('rec_identifier',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('eg_tcn',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('eg_tcn_source',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('eg_identifier',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_att
r('publisher',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('pubdate',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('edition',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('item_barcode',vqbr.attributes) | replace('"', '""') %]"
+[% END %]
$$
)
;
@@ -322,7 +325,10 @@ INSERT INTO action_trigger.event_definition (
'queue.owner',
'print-on-demand',
$$
-[%- USE date -%][%- FOR vqar IN target -%]"[% helpers.get_queued_auth_attr('rec_identifier',vqar.attributes) | replace('"', '""') %]"[%- END -%]
+[%- USE date -%]
+"Record Identifier"
+[% FOR vqar IN target %]"[% helpers.get_queued_auth_attr('rec_identifier',vqar.attributes) | replace('"', '""') %]"
+[% END %]
$$
)
;
@@ -473,7 +479,9 @@ INSERT INTO action_trigger.event_definition (
'record.queue.owner',
'print-on-demand',
$$
-[%- USE date -%][% FOR vii IN target %]"[% vii.id | replace('"', '""') %]","[% helpers.get_queued_bib_attr('title',vii.record.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('isbn',vii.record.attributes) | replace('"', '""') %]","[% vii.definition | replace('"', '""') %]","[% vii.import_error | replace('"', '""') %]","[% vii.error_detail | replace('"', '""') %]","[% vii.owning_lib | replace('"', '""') %]","[% vii.circ_lib | replace('"', '""') %]","[% vii.call_number | replace('"', '""') %]","[% vii.copy_number | replace('"', '""') %]","[% vii.status.name | replace('"', '""') %]","[% vii.location.name | replace('"', '""') %]","[% vii.circulate | replace('"', '""') %]","[% vii.deposit | replace('"', '""') %]","[% vii.deposit_amount | replace('"', '""') %]","[% vii.ref | replace('"', '""') %]","[% vii.holdable | replace('"', '""') %]","[% vii.price | replace('"', '""') %]","[% vii.barcode | replace('"', '""') %]","[% vii.circ_modifier | replace('"', '""') %
]","[% vii.circ_as_type | replace('"', '""') %]","[% vii.alert_message | replace('"', '""') %]","[% vii.pub_note | replace('"', '""') %]","[% vii.priv_note | replace('"', '""') %]","[% vii.opac_visible | replace('"', '""') %]"
+[%- USE date -%]
+"Import Item ID","Title of work","ISBN","Attribute Definition","Import Error","Import Error Detail","Owning Library","Circulating Library","Call Number","Copy Number","Status","Shelving Location","Circulate","Deposit","Deposit Amount","Reference","Holdable","Price","Barcode","Circulation Modifier","Circulate As MARC Type","Alert Message","Public Note","Private Note","OPAC Visible"
+[% FOR vii IN target %]"[% vii.id | replace('"', '""') %]","[% helpers.get_queued_bib_attr('title',vii.record.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('isbn',vii.record.attributes) | replace('"', '""') %]","[% vii.definition | replace('"', '""') %]","[% vii.import_error | replace('"', '""') %]","[% vii.error_detail | replace('"', '""') %]","[% vii.owning_lib | replace('"', '""') %]","[% vii.circ_lib | replace('"', '""') %]","[% vii.call_number | replace('"', '""') %]","[% vii.copy_number | replace('"', '""') %]","[% vii.status.name | replace('"', '""') %]","[% vii.location.name | replace('"', '""') %]","[% vii.circulate | replace('"', '""') %]","[% vii.deposit | replace('"', '""') %]","[% vii.deposit_amount | replace('"', '""') %]","[% vii.ref | replace('"', '""') %]","[% vii.holdable | replace('"', '""') %]","[% vii.price | replace('"', '""') %]","[% vii.barcode | replace('"', '""') %]","[% vii.circ_modifier | replace('"', '""') %]","[% vii.circ_
as_type | replace('"', '""') %]","[% vii.alert_message | replace('"', '""') %]","[% vii.pub_note | replace('"', '""') %]","[% vii.priv_note | replace('"', '""') %]","[% vii.opac_visible | replace('"', '""') %]"
[% END %]
$$
)
commit 98d5a7532ec67ce24c385648ba4cc8a24fdefb26
Author: Jason Etheridge <jason at esilibrary.com>
Date: Sat May 14 13:15:15 2011 -0400
CSV template for import items export
diff --git a/Open-ILS/src/sql/Pg/upgrade/renumber_me.sql b/Open-ILS/src/sql/Pg/upgrade/renumber_me.sql
index 92340b1..b4f7b3b 100644
--- a/Open-ILS/src/sql/Pg/upgrade/renumber_me.sql
+++ b/Open-ILS/src/sql/Pg/upgrade/renumber_me.sql
@@ -451,6 +451,42 @@ INSERT INTO action_trigger.environment ( event_def, path) VALUES (
,( 44, 'record.queue.owner')
;
+INSERT INTO action_trigger.event_definition (
+ id,
+ active,
+ owner,
+ name,
+ hook,
+ validator,
+ reactor,
+ group_field,
+ granularity,
+ template
+ ) VALUES (
+ 45,
+ TRUE,
+ 1,
+ 'CSV Output for Import Items from Queued Bib Records',
+ 'vandelay.import_items.csv',
+ 'NOOP_True',
+ 'ProcessTemplate',
+ 'record.queue.owner',
+ 'print-on-demand',
+$$
+[%- USE date -%][% FOR vii IN target %]"[% vii.id | replace('"', '""') %]","[% helpers.get_queued_bib_attr('title',vii.record.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('isbn',vii.record.attributes) | replace('"', '""') %]","[% vii.definition | replace('"', '""') %]","[% vii.import_error | replace('"', '""') %]","[% vii.error_detail | replace('"', '""') %]","[% vii.owning_lib | replace('"', '""') %]","[% vii.circ_lib | replace('"', '""') %]","[% vii.call_number | replace('"', '""') %]","[% vii.copy_number | replace('"', '""') %]","[% vii.status.name | replace('"', '""') %]","[% vii.location.name | replace('"', '""') %]","[% vii.circulate | replace('"', '""') %]","[% vii.deposit | replace('"', '""') %]","[% vii.deposit_amount | replace('"', '""') %]","[% vii.ref | replace('"', '""') %]","[% vii.holdable | replace('"', '""') %]","[% vii.price | replace('"', '""') %]","[% vii.barcode | replace('"', '""') %]","[% vii.circ_modifier | replace('"', '""') %
]","[% vii.circ_as_type | replace('"', '""') %]","[% vii.alert_message | replace('"', '""') %]","[% vii.pub_note | replace('"', '""') %]","[% vii.priv_note | replace('"', '""') %]","[% vii.opac_visible | replace('"', '""') %]"
+[% END %]
+$$
+ )
+;
+
+INSERT INTO action_trigger.environment ( event_def, path) VALUES (
+ 45, 'record')
+ ,( 45, 'record.attributes')
+ ,( 45, 'record.queue')
+ ,( 45, 'record.queue.owner')
+;
+
+
COMMIT;
--- BEGIN; DELETE FROM action_trigger.event_output WHERE id IN ((SELECT template_output FROM action_trigger.event WHERE event_def IN (38,39,40,41,42,43,44))UNION(SELECT error_output FROM action_trigger.event WHERE event_def IN (38,39,40,41,42,43,44))); DELETE FROM action_trigger.event WHERE event_def IN (38,39,40,41,42,43,44); DELETE FROM action_trigger.environment WHERE event_def IN (38,39,40,41,42,43,44); DELETE FROM action_trigger.event_definition WHERE id IN (38,39,40,41,42,43,44); DELETE FROM action_trigger.hook WHERE key IN ('vandelay.queued_bib_record.print','vandelay.queued_bib_record.csv','vandelay.queued_bib_record.email','vandelay.queued_auth_record.print','vandelay.queued_auth_record.csv','vandelay.queued_auth_record.email','vandelay.import_items.print','vandelay.import_items.csv','vandelay.import_items.email'); DELETE FROM config.upgrade_log WHERE version = 'test'; COMMIT;
+-- BEGIN; DELETE FROM action_trigger.event WHERE event_def IN (38,39,40,41,42,43,44,45); DELETE FROM action_trigger.environment WHERE event_def IN (38,39,40,41,42,43,44,45); DELETE FROM action_trigger.event_definition WHERE id IN (38,39,40,41,42,43,44,45); DELETE FROM action_trigger.hook WHERE key IN ('vandelay.queued_bib_record.print','vandelay.queued_bib_record.csv','vandelay.queued_bib_record.email','vandelay.queued_auth_record.print','vandelay.queued_auth_record.csv','vandelay.queued_auth_record.email','vandelay.import_items.print','vandelay.import_items.csv','vandelay.import_items.email'); DELETE FROM action_trigger.event_output WHERE id IN ((SELECT template_output FROM action_trigger.event WHERE event_def IN (38,39,40,41,42,43,44,45))UNION(SELECT error_output FROM action_trigger.event WHERE event_def IN (38,39,40,41,42,43,44,45))); DELETE FROM config.upgrade_log WHERE version = 'test'; COMMIT;
commit a65d906c7591a7c1d6312d3772b44272f61627b2
Author: Jason Etheridge <jason at esilibrary.com>
Date: Sat May 14 12:58:31 2011 -0400
robustify exportHandler, assume response of 1 is success for email methods, and make import_item export methods atomic
diff --git a/Open-ILS/web/js/ui/default/vandelay/vandelay.js b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
index 7c96ed5..ea06944 100644
--- a/Open-ILS/web/js/ui/default/vandelay/vandelay.js
+++ b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
@@ -404,7 +404,7 @@ function vlExportInit() {
if(!value) return;
if(!confirm('Export as "' + value + '"?')) return; // TODO: i18n
- var method = 'open-ils.vandelay.import_item.queue.export.' + value;
+ var method = 'open-ils.vandelay.import_item.queue.export.' + value + '.atomic';
fieldmapper.standardRequest(
['open-ils.vandelay', method],
@@ -425,10 +425,13 @@ function exportHandler(type, response) {
try {
var content = openils.Util.readResponse(response);
if (type=='email') {
- if (content) { throw(content); }
- return;
+ if (content==1) { alert('Email sent.'); }
+ throw(content);
}
- content = content[0].template_output().data();
+ /* handle .atomic versus non-atomic method calls */
+ content = content.constructor == Array
+ ? content[0].template_output().data()
+ : content.template_output().data();
switch(type) {
case 'print':
openils.Util.printHtmlString(content);
commit bd61d29819665315ba2f8ac2de9e162e864dabd0
Author: Jason Etheridge <jason at esilibrary.com>
Date: Thu May 12 23:18:57 2011 -0400
toward Import Item templates for export. May want to consider providing IDL links for some of these fields so we can flesh them in the environment
diff --git a/Open-ILS/src/sql/Pg/upgrade/renumber_me.sql b/Open-ILS/src/sql/Pg/upgrade/renumber_me.sql
index fbbda48..92340b1 100644
--- a/Open-ILS/src/sql/Pg/upgrade/renumber_me.sql
+++ b/Open-ILS/src/sql/Pg/upgrade/renumber_me.sql
@@ -381,6 +381,76 @@ INSERT INTO action_trigger.environment ( event_def, path) VALUES (
,( 43, 'queue.owner')
;
+INSERT INTO action_trigger.event_definition (
+ id,
+ active,
+ owner,
+ name,
+ hook,
+ validator,
+ reactor,
+ group_field,
+ granularity,
+ template
+ ) VALUES (
+ 44,
+ TRUE,
+ 1,
+ 'Print Output for Import Items from Queued Bib Records',
+ 'vandelay.import_items.print',
+ 'NOOP_True',
+ 'ProcessTemplate',
+ 'record.queue.owner',
+ 'print-on-demand',
+$$
+[%- USE date -%]
+<pre>
+Queue ID: [% target.0.record.queue.id %]
+Queue Name: [% target.0.record.queue.name %]
+Queue Type: [% target.0.record.queue.queue_type %]
+Complete? [% target.0.record.queue.complete %]
+
+ [% FOR vii IN target %]
+=-=-=
+ Import Item ID | [% vii.id %]
+ Title of work | [% helpers.get_queued_bib_attr('title',vii.record.attributes) %]
+ ISBN | [% helpers.get_queued_bib_attr('isbn',vii.record.attributes) %]
+ Attribute Definition | [% vii.definition %]
+ Import Error | [% vii.import_error %]
+ Import Error Detail | [% vii.error_detail %]
+ Owning Library | [% vii.owning_lib %]
+ Circulating Library | [% vii.circ_lib %]
+ Call Number | [% vii.call_number %]
+ Copy Number | [% vii.copy_number %]
+ Status | [% vii.status.name %]
+ Shelving Location | [% vii.location.name %]
+ Circulate | [% vii.circulate %]
+ Deposit | [% vii.deposit %]
+ Deposit Amount | [% vii.deposit_amount %]
+ Reference | [% vii.ref %]
+ Holdable | [% vii.holdable %]
+ Price | [% vii.price %]
+ Barcode | [% vii.barcode %]
+ Circulation Modifier | [% vii.circ_modifier %]
+ Circulate As MARC Type | [% vii.circ_as_type %]
+ Alert Message | [% vii.alert_message %]
+ Public Note | [% vii.pub_note %]
+ Private Note | [% vii.priv_note %]
+ OPAC Visible | [% vii.opac_visible %]
+
+ [% END %]
+</pre>
+$$
+ )
+;
+
+INSERT INTO action_trigger.environment ( event_def, path) VALUES (
+ 44, 'record')
+ ,( 44, 'record.attributes')
+ ,( 44, 'record.queue')
+ ,( 44, 'record.queue.owner')
+;
+
COMMIT;
--- DELETE FROM action_trigger.event_output WHERE id IN ((SELECT template_output FROM action_trigger.event WHERE event_def IN (38,39,40,41,42,43))UNION(SELECT error_output FROM action_trigger.event WHERE event_def IN (38,39,40,41,42,43))); DELETE FROM action_trigger.event WHERE event_def IN (38,39,40,41,42,43); DELETE FROM action_trigger.environment WHERE event_def IN (38,39,40,41,42,43); DELETE FROM action_trigger.event_definition WHERE id IN (38,39,40,41,42,43); DELETE FROM action_trigger.hook WHERE key IN ('vandelay.queued_bib_record.print','vandelay.queued_bib_record.csv','vandelay.queued_bib_record.email','vandelay.queued_auth_record.print','vandelay.queued_auth_record.csv','vandelay.queued_auth_record.email','vandelay.import_items.print','vandelay.import_items.csv','vandelay.import_items.email'); DELETE FROM config.upgrade_log WHERE version = 'test';
+-- BEGIN; DELETE FROM action_trigger.event_output WHERE id IN ((SELECT template_output FROM action_trigger.event WHERE event_def IN (38,39,40,41,42,43,44))UNION(SELECT error_output FROM action_trigger.event WHERE event_def IN (38,39,40,41,42,43,44))); DELETE FROM action_trigger.event WHERE event_def IN (38,39,40,41,42,43,44); DELETE FROM action_trigger.environment WHERE event_def IN (38,39,40,41,42,43,44); DELETE FROM action_trigger.event_definition WHERE id IN (38,39,40,41,42,43,44); DELETE FROM action_trigger.hook WHERE key IN ('vandelay.queued_bib_record.print','vandelay.queued_bib_record.csv','vandelay.queued_bib_record.email','vandelay.queued_auth_record.print','vandelay.queued_auth_record.csv','vandelay.queued_auth_record.email','vandelay.import_items.print','vandelay.import_items.csv','vandelay.import_items.email'); DELETE FROM config.upgrade_log WHERE version = 'test'; COMMIT;
commit 6e2fb189b6c199f0ec08662352803044b228abe7
Author: Mike Rylander <mrylander at gmail.com>
Date: Thu May 12 23:05:35 2011 -0400
Remove excised field from IDL
diff --git a/Open-ILS/examples/fm_IDL.xml b/Open-ILS/examples/fm_IDL.xml
index 3f93a59..06cf384 100644
--- a/Open-ILS/examples/fm_IDL.xml
+++ b/Open-ILS/examples/fm_IDL.xml
@@ -511,14 +511,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
<fields oils_persist:primary="id" oils_persist:sequence="vandelay.authority_match_id_seq">
<field reporter:label="Match ID" name="id" reporter:datatype="id"/>
<field reporter:label="Queued Record" name="queued_record" reporter:datatype="link"/>
- <field reporter:label="Matched Attribute" name="matched_attr" reporter:datatype="link"/>
<field reporter:label="Evergreen Record" name="eg_record" reporter:datatype="link"/>
<field reporter:label="Quality" name="quality" reporter:datatype="int"/>
</fields>
<links>
<link field="queued_record" reltype="has_a" key="id" map="" class="vqbr"/>
<link field="eg_record" reltype="has_a" key="id" map="" class="bre"/>
- <link field="matched_attr" reltype="has_a" key="id" map="" class="vqbra"/>
</links>
<permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
<actions>
commit 78366c9c9a039c722fd5b1187a6a9d431f3a61e0
Author: Jason Etheridge <jason at esilibrary.com>
Date: Thu May 12 22:35:22 2011 -0400
fix variable name for Import Items Export
diff --git a/Open-ILS/web/js/ui/default/vandelay/vandelay.js b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
index 46b063f..7c96ed5 100644
--- a/Open-ILS/web/js/ui/default/vandelay/vandelay.js
+++ b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
@@ -415,7 +415,7 @@ function vlExportInit() {
{with_import_error: (vlImportItemsShowErrors.checked) ? 1 : null}
],
async : true,
- oncomplete : function(r) {exportHandler(type, r)}
+ oncomplete : function(r) {exportHandler(value, r)}
}
);
}
commit 93aef19351dcb1538c9a4ddf2d5bfcbd37284015
Author: Jason Etheridge <jason at esilibrary.com>
Date: Thu May 12 21:42:43 2011 -0400
change the group field for these templates, though they weren't breaking anything before (these are called with fire_object_event and instead of create_events_for_hook, if that makes a difference)
diff --git a/Open-ILS/src/sql/Pg/upgrade/renumber_me.sql b/Open-ILS/src/sql/Pg/upgrade/renumber_me.sql
index 0310127..fbbda48 100644
--- a/Open-ILS/src/sql/Pg/upgrade/renumber_me.sql
+++ b/Open-ILS/src/sql/Pg/upgrade/renumber_me.sql
@@ -122,7 +122,7 @@ INSERT INTO action_trigger.event_definition (
'vandelay.queued_bib_record.print',
'NOOP_True',
'ProcessTemplate',
- 'usr',
+ 'queue.owner',
'print-on-demand',
$$
[%- USE date -%]
@@ -180,7 +180,7 @@ INSERT INTO action_trigger.event_definition (
'vandelay.queued_bib_record.csv',
'NOOP_True',
'ProcessTemplate',
- 'usr',
+ 'queue.owner',
'print-on-demand',
$$
[%- USE date -%][%- FOR vqbr IN target -%]"[% helpers.get_queued_bib_attr('title',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('author',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('language',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('pagination',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('isbn',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('issn',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('price',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('rec_identifier',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('eg_tcn',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('eg_tcn_source',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('eg_identifier',vqbr.attributes) | replace('"', '""') %]","[% helpers.
get_queued_bib_attr('publisher',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('pubdate',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('edition',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('item_barcode',vqbr.attributes) | replace('"', '""') %]"[%- END -%]
@@ -275,7 +275,7 @@ INSERT INTO action_trigger.event_definition (
'vandelay.queued_auth_record.print',
'NOOP_True',
'ProcessTemplate',
- 'usr',
+ 'queue.owner',
'print-on-demand',
$$
[%- USE date -%]
@@ -319,7 +319,7 @@ INSERT INTO action_trigger.event_definition (
'vandelay.queued_auth_record.csv',
'NOOP_True',
'ProcessTemplate',
- 'usr',
+ 'queue.owner',
'print-on-demand',
$$
[%- USE date -%][%- FOR vqar IN target -%]"[% helpers.get_queued_auth_attr('rec_identifier',vqar.attributes) | replace('"', '""') %]"[%- END -%]
commit 6162208b18d9351870770648d70e68575d7d68a2
Author: Jason Etheridge <jason at esilibrary.com>
Date: Thu May 12 21:38:54 2011 -0400
templates for exporting authority queues, but needs testing. blockers here include importing authority records being broken, and possibly selection of an authority queue to inspect being broken
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Trigger/Reactor.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Trigger/Reactor.pm
index 6442531..cfeeca6 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Trigger/Reactor.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Trigger/Reactor.pm
@@ -173,6 +173,32 @@ my $_TT_helpers = {
}
return;
},
+
+ get_queued_auth_attr => sub {
+ my $name = shift or return; # the first arg is always the name
+ my ($attr) = @_;
+ # use Data::Dumper; $logger->warn("get_queued_auth_attr: " . Dumper($attr));
+ ($name and @$attr) or return;
+
+ my $query = {
+ select => {'vqarad' => ['id']},
+ from => 'vqarad',
+ where => {code => $name}
+ };
+
+ my $def_ids = new_editor()->json_query($query);
+ @$def_ids or return;
+
+ my $length;
+ $name =~ s/^(\D+)_(\d+)$/$1/ and $length = $2;
+ foreach (@$attr) {
+ $_->field eq @{$def_ids}[0]->{id} or next;
+ next if $length and $length != length($_->attr_value);
+ return $_->attr_value;
+ }
+ return;
+ },
+
};
diff --git a/Open-ILS/src/sql/Pg/upgrade/renumber_me.sql b/Open-ILS/src/sql/Pg/upgrade/renumber_me.sql
index 6e59409..0310127 100644
--- a/Open-ILS/src/sql/Pg/upgrade/renumber_me.sql
+++ b/Open-ILS/src/sql/Pg/upgrade/renumber_me.sql
@@ -255,6 +255,132 @@ INSERT INTO action_trigger.environment ( event_def, path) VALUES (
,( 40, 'queue')
,( 40, 'queue.owner')
;
+
+INSERT INTO action_trigger.event_definition (
+ id,
+ active,
+ owner,
+ name,
+ hook,
+ validator,
+ reactor,
+ group_field,
+ granularity,
+ template
+ ) VALUES (
+ 41,
+ TRUE,
+ 1,
+ 'Print Output for Queued Authority Records',
+ 'vandelay.queued_auth_record.print',
+ 'NOOP_True',
+ 'ProcessTemplate',
+ 'usr',
+ 'print-on-demand',
+$$
+[%- USE date -%]
+<pre>
+Queue ID: [% target.0.queue.id %]
+Queue Name: [% target.0.queue.name %]
+Queue Type: [% target.0.queue.queue_type %]
+Complete? [% target.0.queue.complete %]
+
+ [% FOR vqar IN target %]
+=-=-=
+ Record Identifier | [% helpers.get_queued_auth_attr('rec_identifier',vqar.attributes) %]
+
+ [% END %]
+</pre>
+$$
+ )
+;
+
+INSERT INTO action_trigger.environment ( event_def, path) VALUES (
+ 41, 'attributes')
+ ,( 41, 'queue')
+;
+
+INSERT INTO action_trigger.event_definition (
+ id,
+ active,
+ owner,
+ name,
+ hook,
+ validator,
+ reactor,
+ group_field,
+ granularity,
+ template
+ ) VALUES (
+ 42,
+ TRUE,
+ 1,
+ 'CSV Output for Queued Authority Records',
+ 'vandelay.queued_auth_record.csv',
+ 'NOOP_True',
+ 'ProcessTemplate',
+ 'usr',
+ 'print-on-demand',
+$$
+[%- USE date -%][%- FOR vqar IN target -%]"[% helpers.get_queued_auth_attr('rec_identifier',vqar.attributes) | replace('"', '""') %]"[%- END -%]
+$$
+ )
+;
+
+INSERT INTO action_trigger.environment ( event_def, path) VALUES (
+ 42, 'attributes')
+ ,( 42, 'queue')
+;
+
+INSERT INTO action_trigger.event_definition (
+ id,
+ active,
+ owner,
+ name,
+ hook,
+ validator,
+ reactor,
+ group_field,
+ granularity,
+ template
+ ) VALUES (
+ 43,
+ TRUE,
+ 1,
+ 'Email Output for Queued Authority Records',
+ 'vandelay.queued_auth_record.email',
+ 'NOOP_True',
+ 'SendEmail',
+ 'queue.owner',
+ NULL,
+$$
+[%- USE date -%]
+[%- SET user = target.0.queue.owner -%]
+To: [%- params.recipient_email || user.email || 'root at localhost' %]
+From: [%- params.sender_email || default_sender %]
+Subject: Authorities from Import Queue
+
+Queue ID: [% target.0.queue.id %]
+Queue Name: [% target.0.queue.name %]
+Queue Type: [% target.0.queue.queue_type %]
+Complete? [% target.0.queue.complete %]
+
+ [% FOR vqar IN target %]
+=-=-=
+ Record Identifier | [% helpers.get_queued_auth_attr('rec_identifier',vqar.attributes) %]
+
+ [% END %]
+
+$$
+ )
+;
+
+INSERT INTO action_trigger.environment ( event_def, path) VALUES (
+ 43, 'attributes')
+ ,( 43, 'queue')
+ ,( 43, 'queue.owner')
+;
+
COMMIT;
--- DELETE FROM action_trigger.event_output WHERE id IN ((SELECT template_output FROM action_trigger.event WHERE event_def IN (38,39,40))UNION(SELECT error_output FROM action_trigger.event WHERE event_def IN (38,39,40))); DELETE FROM action_trigger.event WHERE event_def IN (38,39,40); DELETE FROM action_trigger.environment WHERE event_def IN (38,39,40); DELETE FROM action_trigger.event_definition WHERE id IN (38,39,40); DELETE FROM action_trigger.hook WHERE key IN ('vandelay.queued_bib_record.print','vandelay.queued_bib_record.csv','vandelay.queued_bib_record.email','vandelay.queued_auth_record.print','vandelay.queued_auth_record.csv','vandelay.queued_auth_record.email','vandelay.import_items.print','vandelay.import_items.csv','vandelay.import_items.email'); DELETE FROM config.upgrade_log WHERE version = 'test';
+-- DELETE FROM action_trigger.event_output WHERE id IN ((SELECT template_output FROM action_trigger.event WHERE event_def IN (38,39,40,41,42,43))UNION(SELECT error_output FROM action_trigger.event WHERE event_def IN (38,39,40,41,42,43))); DELETE FROM action_trigger.event WHERE event_def IN (38,39,40,41,42,43); DELETE FROM action_trigger.environment WHERE event_def IN (38,39,40,41,42,43); DELETE FROM action_trigger.event_definition WHERE id IN (38,39,40,41,42,43); DELETE FROM action_trigger.hook WHERE key IN ('vandelay.queued_bib_record.print','vandelay.queued_bib_record.csv','vandelay.queued_bib_record.email','vandelay.queued_auth_record.print','vandelay.queued_auth_record.csv','vandelay.queued_auth_record.email','vandelay.import_items.print','vandelay.import_items.csv','vandelay.import_items.email'); DELETE FROM config.upgrade_log WHERE version = 'test';
commit eb4fbe43bb76aefc210bb92137996474887da0bf
Author: Jason Etheridge <jason at esilibrary.com>
Date: Thu May 12 19:50:08 2011 -0400
email template for queued bib records
diff --git a/Open-ILS/src/sql/Pg/upgrade/renumber_me.sql b/Open-ILS/src/sql/Pg/upgrade/renumber_me.sql
index 4560389..6e59409 100644
--- a/Open-ILS/src/sql/Pg/upgrade/renumber_me.sql
+++ b/Open-ILS/src/sql/Pg/upgrade/renumber_me.sql
@@ -193,6 +193,68 @@ INSERT INTO action_trigger.environment ( event_def, path) VALUES (
,( 39, 'queue')
;
+INSERT INTO action_trigger.event_definition (
+ id,
+ active,
+ owner,
+ name,
+ hook,
+ validator,
+ reactor,
+ group_field,
+ granularity,
+ template
+ ) VALUES (
+ 40,
+ TRUE,
+ 1,
+ 'Email Output for Queued Bib Records',
+ 'vandelay.queued_bib_record.email',
+ 'NOOP_True',
+ 'SendEmail',
+ 'queue.owner',
+ NULL,
+$$
+[%- USE date -%]
+[%- SET user = target.0.queue.owner -%]
+To: [%- params.recipient_email || user.email || 'root at localhost' %]
+From: [%- params.sender_email || default_sender %]
+Subject: Bibs from Import Queue
+
+Queue ID: [% target.0.queue.id %]
+Queue Name: [% target.0.queue.name %]
+Queue Type: [% target.0.queue.queue_type %]
+Complete? [% target.0.queue.complete %]
+
+ [% FOR vqbr IN target %]
+=-=-=
+ Title of work | [% helpers.get_queued_bib_attr('title',vqbr.attributes) %]
+ Author of work | [% helpers.get_queued_bib_attr('author',vqbr.attributes) %]
+ Language of work | [% helpers.get_queued_bib_attr('language',vqbr.attributes) %]
+ Pagination | [% helpers.get_queued_bib_attr('pagination',vqbr.attributes) %]
+ ISBN | [% helpers.get_queued_bib_attr('isbn',vqbr.attributes) %]
+ ISSN | [% helpers.get_queued_bib_attr('issn',vqbr.attributes) %]
+ Price | [% helpers.get_queued_bib_attr('price',vqbr.attributes) %]
+ Accession Number | [% helpers.get_queued_bib_attr('rec_identifier',vqbr.attributes) %]
+ TCN Value | [% helpers.get_queued_bib_attr('eg_tcn',vqbr.attributes) %]
+ TCN Source | [% helpers.get_queued_bib_attr('eg_tcn_source',vqbr.attributes) %]
+ Internal ID | [% helpers.get_queued_bib_attr('eg_identifier',vqbr.attributes) %]
+ Publisher | [% helpers.get_queued_bib_attr('publisher',vqbr.attributes) %]
+ Publication Date | [% helpers.get_queued_bib_attr('pubdate',vqbr.attributes) %]
+ Edition | [% helpers.get_queued_bib_attr('edition',vqbr.attributes) %]
+ Item Barcode | [% helpers.get_queued_bib_attr('item_barcode',vqbr.attributes) %]
+
+ [% END %]
+
+$$
+ )
+;
+INSERT INTO action_trigger.environment ( event_def, path) VALUES (
+ 40, 'attributes')
+ ,( 40, 'queue')
+ ,( 40, 'queue.owner')
+;
COMMIT;
--- DELETE FROM action_trigger.event WHERE event_def IN (38,39); DELETE FROM action_trigger.environment WHERE event_def IN (38,39); DELETE FROM action_trigger.event_definition WHERE id IN (38,39); DELETE FROM action_trigger.hook WHERE key IN ('vandelay.queued_bib_record.print','vandelay.queued_bib_record.csv','vandelay.queued_bib_record.email','vandelay.queued_auth_record.print','vandelay.queued_auth_record.csv','vandelay.queued_auth_record.email','vandelay.import_items.print','vandelay.import_items.csv','vandelay.import_items.email'); DELETE FROM config.upgrade_log WHERE version = 'test';
+
+-- DELETE FROM action_trigger.event_output WHERE id IN ((SELECT template_output FROM action_trigger.event WHERE event_def IN (38,39,40))UNION(SELECT error_output FROM action_trigger.event WHERE event_def IN (38,39,40))); DELETE FROM action_trigger.event WHERE event_def IN (38,39,40); DELETE FROM action_trigger.environment WHERE event_def IN (38,39,40); DELETE FROM action_trigger.event_definition WHERE id IN (38,39,40); DELETE FROM action_trigger.hook WHERE key IN ('vandelay.queued_bib_record.print','vandelay.queued_bib_record.csv','vandelay.queued_bib_record.email','vandelay.queued_auth_record.print','vandelay.queued_auth_record.csv','vandelay.queued_auth_record.email','vandelay.import_items.print','vandelay.import_items.csv','vandelay.import_items.email'); DELETE FROM config.upgrade_log WHERE version = 'test';
commit 9cc978be2ed4741410ce4d95913f4cf53cb93ba7
Author: senator <lebbeous at esilibrary.com>
Date: Wed May 11 11:44:02 2011 -0400
In the event that a bib queue is not using a match_set, bail out of...
... match_set_test_marcxml() early. Needs tested. Also may need
special check for non-null but empty match_sets.
diff --git a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
index 2009df6..d6810f6 100644
--- a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
+++ b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
@@ -689,6 +689,10 @@ BEGIN
SELECT * INTO my_bib_queue FROM vandelay.bib_queue WHERE id = NEW.queue;
+ IF my_bib_queue.match_set IS NULL THEN
+ RETURN NEW;
+ END IF;
+
NEW.quality := vandelay.measure_record_quality( NEW.marc, my_bib_queue.match_set );
-- Perfect matches on 901$c exit early with a match with high quality.
commit 72522570c89283573ebf914a604c12c016761208
Author: Jason Etheridge <jason at esilibrary.com>
Date: Wed May 11 02:42:30 2011 -0400
CSV template and file saving worked out
diff --git a/Open-ILS/src/sql/Pg/upgrade/renumber_me.sql b/Open-ILS/src/sql/Pg/upgrade/renumber_me.sql
index 42e8aec..4560389 100644
--- a/Open-ILS/src/sql/Pg/upgrade/renumber_me.sql
+++ b/Open-ILS/src/sql/Pg/upgrade/renumber_me.sql
@@ -161,5 +161,38 @@ INSERT INTO action_trigger.environment ( event_def, path) VALUES (
,( 38, 'queue')
;
+INSERT INTO action_trigger.event_definition (
+ id,
+ active,
+ owner,
+ name,
+ hook,
+ validator,
+ reactor,
+ group_field,
+ granularity,
+ template
+ ) VALUES (
+ 39,
+ TRUE,
+ 1,
+ 'CSV Output for Queued Bib Records',
+ 'vandelay.queued_bib_record.csv',
+ 'NOOP_True',
+ 'ProcessTemplate',
+ 'usr',
+ 'print-on-demand',
+$$
+[%- USE date -%][%- FOR vqbr IN target -%]"[% helpers.get_queued_bib_attr('title',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('author',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('language',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('pagination',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('isbn',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('issn',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('price',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('rec_identifier',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('eg_tcn',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('eg_tcn_source',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('eg_identifier',vqbr.attributes) | replace('"', '""') %]","[% helpers.
get_queued_bib_attr('publisher',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('pubdate',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('edition',vqbr.attributes) | replace('"', '""') %]","[% helpers.get_queued_bib_attr('item_barcode',vqbr.attributes) | replace('"', '""') %]"[%- END -%]
+$$
+ )
+;
+
+INSERT INTO action_trigger.environment ( event_def, path) VALUES (
+ 39, 'attributes')
+ ,( 39, 'queue')
+;
+
+
COMMIT;
--- DELETE FROM action_trigger.event WHERE event_def IN (38); DELETE FROM action_trigger.environment WHERE event_def IN (38); DELETE FROM action_trigger.event_definition WHERE id IN (38); DELETE FROM action_trigger.hook WHERE key IN ('vandelay.queued_bib_record.print','vandelay.queued_bib_record.csv','vandelay.queued_bib_record.email','vandelay.queued_auth_record.print','vandelay.queued_auth_record.csv','vandelay.queued_auth_record.email','vandelay.import_items.print','vandelay.import_items.csv','vandelay.import_items.email'); DELETE FROM config.upgrade_log WHERE version = 'test';
+-- DELETE FROM action_trigger.event WHERE event_def IN (38,39); DELETE FROM action_trigger.environment WHERE event_def IN (38,39); DELETE FROM action_trigger.event_definition WHERE id IN (38,39); DELETE FROM action_trigger.hook WHERE key IN ('vandelay.queued_bib_record.print','vandelay.queued_bib_record.csv','vandelay.queued_bib_record.email','vandelay.queued_auth_record.print','vandelay.queued_auth_record.csv','vandelay.queued_auth_record.email','vandelay.import_items.print','vandelay.import_items.csv','vandelay.import_items.email'); DELETE FROM config.upgrade_log WHERE version = 'test';
diff --git a/Open-ILS/web/js/ui/default/vandelay/vandelay.js b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
index 9565869..46b063f 100644
--- a/Open-ILS/web/js/ui/default/vandelay/vandelay.js
+++ b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
@@ -423,10 +423,22 @@ function vlExportInit() {
function exportHandler(type, response) {
try {
- var content = openils.Util.readResponse(response)[0].template_output().data();
+ var content = openils.Util.readResponse(response);
+ if (type=='email') {
+ if (content) { throw(content); }
+ return;
+ }
+ content = content[0].template_output().data();
switch(type) {
- case 'print': openils.Util.printHtmlString(content); break;
- default: alert('response = ' + response + ' content:\n' + content);
+ case 'print':
+ openils.Util.printHtmlString(content);
+ break;
+ case 'csv':
+ //content = content.replace(/\\t/g,'\t'); // if we really wanted to do .tsv instead
+ openils.XUL.contentToFileSaveDialog(content);
+ break;
+ default:
+ alert('response = ' + response + '\tcontent:\n' + content);
}
} catch(E) {
alert('Error exporting data: ' + E);
commit 0853fdbf76f0ceadc77be39c7a5961dde409d756
Author: Jason Etheridge <jason at esilibrary.com>
Date: Wed May 11 01:39:32 2011 -0400
first template and supporting code, printing queued bib records
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Trigger/Reactor.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Trigger/Reactor.pm
index 4251519..6442531 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Trigger/Reactor.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Trigger/Reactor.pm
@@ -148,6 +148,31 @@ my $_TT_helpers = {
}
return;
},
+
+ get_queued_bib_attr => sub {
+ my $name = shift or return; # the first arg is always the name
+ my ($attr) = @_;
+ # use Data::Dumper; $logger->warn("get_queued_bib_attr: " . Dumper($attr));
+ ($name and @$attr) or return;
+
+ my $query = {
+ select => {'vqbrad' => ['id']},
+ from => 'vqbrad',
+ where => {code => $name}
+ };
+
+ my $def_ids = new_editor()->json_query($query);
+ @$def_ids or return;
+
+ my $length;
+ $name =~ s/^(\D+)_(\d+)$/$1/ and $length = $2;
+ foreach (@$attr) {
+ $_->field eq @{$def_ids}[0]->{id} or next;
+ next if $length and $length != length($_->attr_value);
+ return $_->attr_value;
+ }
+ return;
+ },
};
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
index 4134e83..4a0bf99 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
@@ -517,15 +517,18 @@ sub retrieve_queued_records {
my $retrieve = ($type eq 'bib') ?
'retrieve_vandelay_queued_bib_record' : 'retrieve_vandelay_queued_authority_record';
+ my $search = ($type eq 'bib') ?
+ 'search_vandelay_queued_bib_record' : 'search_vandelay_queued_authority_record';
if ($self->api_name =~ /export/) {
+ my $rec_list = $e->$search({id => [map { $_->{id} } @$record_ids]});
if ($self->api_name =~ /print/) {
$e->rollback;
return $U->fire_object_event(
undef,
'vandelay.queued_'.$type.'_record.print',
- [map {$_->{id}} @$record_ids],
+ $rec_list,
$e->requestor->ws_ou
);
@@ -535,7 +538,7 @@ sub retrieve_queued_records {
return $U->fire_object_event(
undef,
'vandelay.queued_'.$type.'_record.csv',
- [map {$_->{id}} @$record_ids],
+ $rec_list,
$e->requestor->ws_ou
);
@@ -543,10 +546,10 @@ sub retrieve_queued_records {
$conn->respond_complete(1);
- for my $rec_id (@$record_ids) {
+ for my $rec (@$rec_list) {
$U->create_events_for_hook(
'vandelay.queued_'.$type.'_record.email',
- $rec_id->{id},
+ $rec,
$e->requestor->home_ou,
undef,
undef,
@@ -665,13 +668,14 @@ sub retrieve_queue_import_items {
if $$options{with_import_error};
my $items = $e->json_query($query);
+ my $item_list = $e->search_vandelay_import_item({id => [map { $_->{id} } @$items]});
if ($self->api_name =~ /export/) {
if ($self->api_name =~ /print/) {
return $U->fire_object_event(
undef,
'vandelay.import_items.print',
- [map {$_->{id}} @$items],
+ $item_list,
$e->requestor->ws_ou
);
@@ -680,7 +684,7 @@ sub retrieve_queue_import_items {
return $U->fire_object_event(
undef,
'vandelay.import_items.csv',
- [map {$_->{id}} @$items],
+ $item_list,
$e->requestor->ws_ou
);
@@ -688,10 +692,10 @@ sub retrieve_queue_import_items {
$conn->respond_complete(1);
- for my $item (@$items) {
+ for my $item (@$item_list) {
$U->create_events_for_hook(
'vandelay.import_items.email',
- $item->{id},
+ $item,
$e->requestor->home_ou,
undef,
undef,
@@ -701,8 +705,8 @@ sub retrieve_queue_import_items {
}
} else {
- for my $item (@$items) {
- $conn->respond($e->retrieve_vandelay_import_item($item->{id}));
+ for my $item (@$item_list) {
+ $conn->respond($item);
}
}
diff --git a/Open-ILS/src/sql/Pg/upgrade/renumber_me.sql b/Open-ILS/src/sql/Pg/upgrade/renumber_me.sql
new file mode 100644
index 0000000..42e8aec
--- /dev/null
+++ b/Open-ILS/src/sql/Pg/upgrade/renumber_me.sql
@@ -0,0 +1,165 @@
+BEGIN;
+
+INSERT INTO config.upgrade_log (version) VALUES ('test'); -- phasefx
+
+INSERT INTO action_trigger.hook (key,core_type,description,passive) VALUES (
+ 'vandelay.queued_bib_record.print',
+ 'vqbr',
+ oils_i18n_gettext(
+ 'vandelay.queued_bib_record.print',
+ 'Print output has been requested for records in an Importer Bib Queue.',
+ 'ath',
+ 'description'
+ ),
+ FALSE
+ )
+ ,(
+ 'vandelay.queued_bib_record.csv',
+ 'vqbr',
+ oils_i18n_gettext(
+ 'vandelay.queued_bib_record.csv',
+ 'CSV output has been requested for records in an Importer Bib Queue.',
+ 'ath',
+ 'description'
+ ),
+ FALSE
+ )
+ ,(
+ 'vandelay.queued_bib_record.email',
+ 'vqbr',
+ oils_i18n_gettext(
+ 'vandelay.queued_bib_record.email',
+ 'An email has been requested for records in an Importer Bib Queue.',
+ 'ath',
+ 'description'
+ ),
+ FALSE
+ )
+ ,(
+ 'vandelay.queued_auth_record.print',
+ 'vqar',
+ oils_i18n_gettext(
+ 'vandelay.queued_auth_record.print',
+ 'Print output has been requested for records in an Importer Authority Queue.',
+ 'ath',
+ 'description'
+ ),
+ FALSE
+ )
+ ,(
+ 'vandelay.queued_auth_record.csv',
+ 'vqar',
+ oils_i18n_gettext(
+ 'vandelay.queued_auth_record.csv',
+ 'CSV output has been requested for records in an Importer Authority Queue.',
+ 'ath',
+ 'description'
+ ),
+ FALSE
+ )
+ ,(
+ 'vandelay.queued_auth_record.email',
+ 'vqar',
+ oils_i18n_gettext(
+ 'vandelay.queued_auth_record.email',
+ 'An email has been requested for records in an Importer Authority Queue.',
+ 'ath',
+ 'description'
+ ),
+ FALSE
+ )
+ ,(
+ 'vandelay.import_items.print',
+ 'vii',
+ oils_i18n_gettext(
+ 'vandelay.import_items.print',
+ 'Print output has been requested for Import Items from records in an Importer Bib Queue.',
+ 'ath',
+ 'description'
+ ),
+ FALSE
+ )
+ ,(
+ 'vandelay.import_items.csv',
+ 'vii',
+ oils_i18n_gettext(
+ 'vandelay.import_items.csv',
+ 'CSV output has been requested for Import Items from records in an Importer Bib Queue.',
+ 'ath',
+ 'description'
+ ),
+ FALSE
+ )
+ ,(
+ 'vandelay.import_items.email',
+ 'vii',
+ oils_i18n_gettext(
+ 'vandelay.import_items.email',
+ 'An email has been requested for Import Items from records in an Importer Bib Queue.',
+ 'ath',
+ 'description'
+ ),
+ FALSE
+ )
+;
+
+INSERT INTO action_trigger.event_definition (
+ id,
+ active,
+ owner,
+ name,
+ hook,
+ validator,
+ reactor,
+ group_field,
+ granularity,
+ template
+ ) VALUES (
+ 38,
+ TRUE,
+ 1,
+ 'Print Output for Queued Bib Records',
+ 'vandelay.queued_bib_record.print',
+ 'NOOP_True',
+ 'ProcessTemplate',
+ 'usr',
+ 'print-on-demand',
+$$
+[%- USE date -%]
+<pre>
+Queue ID: [% target.0.queue.id %]
+Queue Name: [% target.0.queue.name %]
+Queue Type: [% target.0.queue.queue_type %]
+Complete? [% target.0.queue.complete %]
+
+ [% FOR vqbr IN target %]
+=-=-=
+ Title of work | [% helpers.get_queued_bib_attr('title',vqbr.attributes) %]
+ Author of work | [% helpers.get_queued_bib_attr('author',vqbr.attributes) %]
+ Language of work | [% helpers.get_queued_bib_attr('language',vqbr.attributes) %]
+ Pagination | [% helpers.get_queued_bib_attr('pagination',vqbr.attributes) %]
+ ISBN | [% helpers.get_queued_bib_attr('isbn',vqbr.attributes) %]
+ ISSN | [% helpers.get_queued_bib_attr('issn',vqbr.attributes) %]
+ Price | [% helpers.get_queued_bib_attr('price',vqbr.attributes) %]
+ Accession Number | [% helpers.get_queued_bib_attr('rec_identifier',vqbr.attributes) %]
+ TCN Value | [% helpers.get_queued_bib_attr('eg_tcn',vqbr.attributes) %]
+ TCN Source | [% helpers.get_queued_bib_attr('eg_tcn_source',vqbr.attributes) %]
+ Internal ID | [% helpers.get_queued_bib_attr('eg_identifier',vqbr.attributes) %]
+ Publisher | [% helpers.get_queued_bib_attr('publisher',vqbr.attributes) %]
+ Publication Date | [% helpers.get_queued_bib_attr('pubdate',vqbr.attributes) %]
+ Edition | [% helpers.get_queued_bib_attr('edition',vqbr.attributes) %]
+ Item Barcode | [% helpers.get_queued_bib_attr('item_barcode',vqbr.attributes) %]
+
+ [% END %]
+</pre>
+$$
+ )
+;
+
+INSERT INTO action_trigger.environment ( event_def, path) VALUES (
+ 38, 'attributes')
+ ,( 38, 'queue')
+;
+
+COMMIT;
+-- DELETE FROM action_trigger.event WHERE event_def IN (38); DELETE FROM action_trigger.environment WHERE event_def IN (38); DELETE FROM action_trigger.event_definition WHERE id IN (38); DELETE FROM action_trigger.hook WHERE key IN ('vandelay.queued_bib_record.print','vandelay.queued_bib_record.csv','vandelay.queued_bib_record.email','vandelay.queued_auth_record.print','vandelay.queued_auth_record.csv','vandelay.queued_auth_record.email','vandelay.import_items.print','vandelay.import_items.csv','vandelay.import_items.email'); DELETE FROM config.upgrade_log WHERE version = 'test';
diff --git a/Open-ILS/web/js/ui/default/vandelay/vandelay.js b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
index bc9a153..9565869 100644
--- a/Open-ILS/web/js/ui/default/vandelay/vandelay.js
+++ b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
@@ -422,11 +422,15 @@ function vlExportInit() {
}
function exportHandler(type, response) {
- var content = openils.Util.readResponse(response);
- if(type == 'print') {
- // TODO print the content
+ try {
+ var content = openils.Util.readResponse(response)[0].template_output().data();
+ switch(type) {
+ case 'print': openils.Util.printHtmlString(content); break;
+ default: alert('response = ' + response + ' content:\n' + content);
+ }
+ } catch(E) {
+ alert('Error exporting data: ' + E);
}
- alert('response = ' + response);
}
function retrieveQueuedRecords(type, queueId, onload, doExport) {
@@ -465,7 +469,7 @@ function retrieveQueuedRecords(type, queueId, onload, doExport) {
{ async: true,
params: params,
oncomplete: function(r){
- if(doExport) return onload();
+ if(doExport) return onload(r);
var recs = r.recv().content();
if(e = openils.Event.parse(recs[0]))
return alert(e);
commit 97f5bf78b56c673678404eec7c8961e49316cb35
Author: Jason Etheridge <jason at esilibrary.com>
Date: Tue May 10 13:18:18 2011 -0400
remove .atomic. from these method names
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
index 3185f9b..4134e83 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
@@ -370,7 +370,7 @@ __PACKAGE__->register_method(
record_type => 'bib'
);
__PACKAGE__->register_method(
- api_name => "open-ils.vandelay.bib_queue.records.retrieve.atomic.export.print",
+ api_name => "open-ils.vandelay.bib_queue.records.retrieve.export.print",
method => 'retrieve_queued_records',
api_level => 1,
argc => 2,
@@ -378,7 +378,7 @@ __PACKAGE__->register_method(
record_type => 'bib'
);
__PACKAGE__->register_method(
- api_name => "open-ils.vandelay.bib_queue.records.retrieve.atomic.export.csv",
+ api_name => "open-ils.vandelay.bib_queue.records.retrieve.export.csv",
method => 'retrieve_queued_records',
api_level => 1,
argc => 2,
@@ -386,7 +386,7 @@ __PACKAGE__->register_method(
record_type => 'bib'
);
__PACKAGE__->register_method(
- api_name => "open-ils.vandelay.bib_queue.records.retrieve.atomic.export.email",
+ api_name => "open-ils.vandelay.bib_queue.records.retrieve.export.email",
method => 'retrieve_queued_records',
api_level => 1,
argc => 2,
@@ -403,7 +403,7 @@ __PACKAGE__->register_method(
record_type => 'auth'
);
__PACKAGE__->register_method(
- api_name => "open-ils.vandelay.auth_queue.records.retrieve.atomic.export.print",
+ api_name => "open-ils.vandelay.auth_queue.records.retrieve.export.print",
method => 'retrieve_queued_records',
api_level => 1,
argc => 2,
@@ -411,7 +411,7 @@ __PACKAGE__->register_method(
record_type => 'auth'
);
__PACKAGE__->register_method(
- api_name => "open-ils.vandelay.auth_queue.records.retrieve.atomic.export.csv",
+ api_name => "open-ils.vandelay.auth_queue.records.retrieve.export.csv",
method => 'retrieve_queued_records',
api_level => 1,
argc => 2,
@@ -419,7 +419,7 @@ __PACKAGE__->register_method(
record_type => 'auth'
);
__PACKAGE__->register_method(
- api_name => "open-ils.vandelay.auth_queue.records.retrieve.atomic.export.email",
+ api_name => "open-ils.vandelay.auth_queue.records.retrieve.export.email",
method => 'retrieve_queued_records',
api_level => 1,
argc => 2,
commit d49ebdc0a9995bfcf7829cd3f5e0b0c2a88509cb
Author: berick <berick at esilibrary.com>
Date: Tue May 10 10:54:37 2011 -0400
add .atomic to the end of the queue export API calls where it belongs
diff --git a/Open-ILS/web/js/ui/default/vandelay/vandelay.js b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
index d2405cc..bc9a153 100644
--- a/Open-ILS/web/js/ui/default/vandelay/vandelay.js
+++ b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
@@ -441,12 +441,14 @@ function retrieveQueuedRecords(type, queueId, onload, doExport) {
if(!queueId) queueId = currentQueueId;
if(!onload) onload = handleRetrieveRecords;
- var method = 'open-ils.vandelay.'+type+'_queue.records.retrieve.atomic';
+ var method = 'open-ils.vandelay.'+type+'_queue.records.retrieve';
if(doExport) method += '.export.' + doExport;
if(vlQueueGridShowMatches.checked)
method = method.replace('records', 'records.matches');
+ method += '.atomic';
+
var sel = dojo.byId('vl-queue-display-limit-selector');
var limit = parseInt(sel.options[sel.selectedIndex].value);
var offset = limit * parseInt(vlQueueDisplayPage.attr('value')-1);
commit 43e5b25daf7eecea247aebaf76fd2e2c722ab5af
Author: Jason Etheridge <jason at esilibrary.com>
Date: Tue May 10 00:29:56 2011 -0400
wire in the event firing, though we still need the templates. Put streaming back in for the print/csv/email export methods, since we can respond_complete for email and it to doesn't hurt the other two.
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
index 7745030..3185f9b 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
@@ -374,6 +374,7 @@ __PACKAGE__->register_method(
method => 'retrieve_queued_records',
api_level => 1,
argc => 2,
+ stream => 1,
record_type => 'bib'
);
__PACKAGE__->register_method(
@@ -381,6 +382,7 @@ __PACKAGE__->register_method(
method => 'retrieve_queued_records',
api_level => 1,
argc => 2,
+ stream => 1,
record_type => 'bib'
);
__PACKAGE__->register_method(
@@ -388,6 +390,7 @@ __PACKAGE__->register_method(
method => 'retrieve_queued_records',
api_level => 1,
argc => 2,
+ stream => 1,
record_type => 'bib'
);
@@ -404,6 +407,7 @@ __PACKAGE__->register_method(
method => 'retrieve_queued_records',
api_level => 1,
argc => 2,
+ stream => 1,
record_type => 'auth'
);
__PACKAGE__->register_method(
@@ -411,6 +415,7 @@ __PACKAGE__->register_method(
method => 'retrieve_queued_records',
api_level => 1,
argc => 2,
+ stream => 1,
record_type => 'auth'
);
__PACKAGE__->register_method(
@@ -418,6 +423,7 @@ __PACKAGE__->register_method(
method => 'retrieve_queued_records',
api_level => 1,
argc => 2,
+ stream => 1,
record_type => 'auth'
);
@@ -512,13 +518,52 @@ sub retrieve_queued_records {
my $retrieve = ($type eq 'bib') ?
'retrieve_vandelay_queued_bib_record' : 'retrieve_vandelay_queued_authority_record';
- for my $rec_id (@$record_ids) {
- my $flesh = ['attributes', 'matches'];
- push(@$flesh, 'import_items') if $$options{flesh_import_items};
- my $params = {flesh => 1, flesh_fields => {$class => $flesh}};
- my $rec = $e->$retrieve([$rec_id->{id}, $params]);
- $rec->clear_marc if $$options{clear_marc};
- $conn->respond($rec);
+ if ($self->api_name =~ /export/) {
+ if ($self->api_name =~ /print/) {
+
+ $e->rollback;
+ return $U->fire_object_event(
+ undef,
+ 'vandelay.queued_'.$type.'_record.print',
+ [map {$_->{id}} @$record_ids],
+ $e->requestor->ws_ou
+ );
+
+ } elsif ($self->api_name =~ /csv/) {
+
+ $e->rollback;
+ return $U->fire_object_event(
+ undef,
+ 'vandelay.queued_'.$type.'_record.csv',
+ [map {$_->{id}} @$record_ids],
+ $e->requestor->ws_ou
+ );
+
+ } elsif ($self->api_name =~ /email/) {
+
+ $conn->respond_complete(1);
+
+ for my $rec_id (@$record_ids) {
+ $U->create_events_for_hook(
+ 'vandelay.queued_'.$type.'_record.email',
+ $rec_id->{id},
+ $e->requestor->home_ou,
+ undef,
+ undef,
+ 1
+ );
+ }
+
+ }
+ } else {
+ for my $rec_id (@$record_ids) {
+ my $flesh = ['attributes', 'matches'];
+ push(@$flesh, 'import_items') if $$options{flesh_import_items};
+ my $params = {flesh => 1, flesh_fields => {$class => $flesh}};
+ my $rec = $e->$retrieve([$rec_id->{id}, $params]);
+ $rec->clear_marc if $$options{clear_marc};
+ $conn->respond($rec);
+ }
}
$e->rollback;
@@ -543,6 +588,7 @@ __PACKAGE__->register_method(
method => 'retrieve_queue_import_items',
api_level => 1,
argc => 2,
+ stream => 1,
authoritative => 1,
signature => q/
Returns template-generated printable output of Import Item (vii) objects for the selected queue.
@@ -555,6 +601,7 @@ __PACKAGE__->register_method(
method => 'retrieve_queue_import_items',
api_level => 1,
argc => 2,
+ stream => 1,
authoritative => 1,
signature => q/
Returns template-generated CSV output of Import Item (vii) objects for the selected queue.
@@ -567,6 +614,7 @@ __PACKAGE__->register_method(
method => 'retrieve_queue_import_items',
api_level => 1,
argc => 2,
+ stream => 1,
authoritative => 1,
signature => q/
Emails template-generated output of Import Item (vii) objects for the selected queue.
@@ -617,8 +665,45 @@ sub retrieve_queue_import_items {
if $$options{with_import_error};
my $items = $e->json_query($query);
- for my $item (@$items) {
- $conn->respond($e->retrieve_vandelay_import_item($item->{id}));
+ if ($self->api_name =~ /export/) {
+ if ($self->api_name =~ /print/) {
+
+ return $U->fire_object_event(
+ undef,
+ 'vandelay.import_items.print',
+ [map {$_->{id}} @$items],
+ $e->requestor->ws_ou
+ );
+
+ } elsif ($self->api_name =~ /csv/) {
+
+ return $U->fire_object_event(
+ undef,
+ 'vandelay.import_items.csv',
+ [map {$_->{id}} @$items],
+ $e->requestor->ws_ou
+ );
+
+ } elsif ($self->api_name =~ /email/) {
+
+ $conn->respond_complete(1);
+
+ for my $item (@$items) {
+ $U->create_events_for_hook(
+ 'vandelay.import_items.email',
+ $item->{id},
+ $e->requestor->home_ou,
+ undef,
+ undef,
+ 1
+ );
+ }
+
+ }
+ } else {
+ for my $item (@$items) {
+ $conn->respond($e->retrieve_vandelay_import_item($item->{id}));
+ }
}
return undef;
commit f9ef894ebd6d76f1a85c67d82473c6af31ad4ac3
Author: Jason Etheridge <jason at esilibrary.com>
Date: Mon May 9 23:50:31 2011 -0400
register the methods we're expecting for the print/csv/email exports in Vandelay, and remove limit/offset options for such methods, and expectation of streaming
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
index 94b7a32..7745030 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
@@ -369,6 +369,28 @@ __PACKAGE__->register_method(
stream => 1,
record_type => 'bib'
);
+__PACKAGE__->register_method(
+ api_name => "open-ils.vandelay.bib_queue.records.retrieve.atomic.export.print",
+ method => 'retrieve_queued_records',
+ api_level => 1,
+ argc => 2,
+ record_type => 'bib'
+);
+__PACKAGE__->register_method(
+ api_name => "open-ils.vandelay.bib_queue.records.retrieve.atomic.export.csv",
+ method => 'retrieve_queued_records',
+ api_level => 1,
+ argc => 2,
+ record_type => 'bib'
+);
+__PACKAGE__->register_method(
+ api_name => "open-ils.vandelay.bib_queue.records.retrieve.atomic.export.email",
+ method => 'retrieve_queued_records',
+ api_level => 1,
+ argc => 2,
+ record_type => 'bib'
+);
+
__PACKAGE__->register_method(
api_name => "open-ils.vandelay.auth_queue.records.retrieve",
method => 'retrieve_queued_records',
@@ -377,6 +399,27 @@ __PACKAGE__->register_method(
stream => 1,
record_type => 'auth'
);
+__PACKAGE__->register_method(
+ api_name => "open-ils.vandelay.auth_queue.records.retrieve.atomic.export.print",
+ method => 'retrieve_queued_records',
+ api_level => 1,
+ argc => 2,
+ record_type => 'auth'
+);
+__PACKAGE__->register_method(
+ api_name => "open-ils.vandelay.auth_queue.records.retrieve.atomic.export.csv",
+ method => 'retrieve_queued_records',
+ api_level => 1,
+ argc => 2,
+ record_type => 'auth'
+);
+__PACKAGE__->register_method(
+ api_name => "open-ils.vandelay.auth_queue.records.retrieve.atomic.export.email",
+ method => 'retrieve_queued_records',
+ api_level => 1,
+ argc => 2,
+ record_type => 'auth'
+);
__PACKAGE__->register_method(
api_name => "open-ils.vandelay.bib_queue.records.matches.retrieve",
@@ -431,6 +474,10 @@ sub retrieve_queued_records {
limit => $limit,
offset => $offset,
};
+ if($self->api_name =~ /export/) {
+ delete $query->{limit};
+ delete $query->{offset};
+ }
$query->{where}->{import_time} = undef if $$options{non_imported};
@@ -491,6 +538,42 @@ __PACKAGE__->register_method(
with_import_error : only return items that failed to import
/
);
+__PACKAGE__->register_method(
+ api_name => 'open-ils.vandelay.import_item.queue.export.print',
+ method => 'retrieve_queue_import_items',
+ api_level => 1,
+ argc => 2,
+ authoritative => 1,
+ signature => q/
+ Returns template-generated printable output of Import Item (vii) objects for the selected queue.
+ Filter options:
+ with_import_error : only return items that failed to import
+ /
+);
+__PACKAGE__->register_method(
+ api_name => 'open-ils.vandelay.import_item.queue.export.csv',
+ method => 'retrieve_queue_import_items',
+ api_level => 1,
+ argc => 2,
+ authoritative => 1,
+ signature => q/
+ Returns template-generated CSV output of Import Item (vii) objects for the selected queue.
+ Filter options:
+ with_import_error : only return items that failed to import
+ /
+);
+__PACKAGE__->register_method(
+ api_name => 'open-ils.vandelay.import_item.queue.export.email',
+ method => 'retrieve_queue_import_items',
+ api_level => 1,
+ argc => 2,
+ authoritative => 1,
+ signature => q/
+ Emails template-generated output of Import Item (vii) objects for the selected queue.
+ Filter options:
+ with_import_error : only return items that failed to import
+ /
+);
sub retrieve_queue_import_items {
my($self, $conn, $auth, $q_id, $options) = @_;
@@ -525,6 +608,10 @@ sub retrieve_queue_import_items {
limit => $limit,
offset => $offset
};
+ if($self->api_name =~ /export/) {
+ delete $query->{limit};
+ delete $query->{offset};
+ }
$query->{where} = {'+vii' => {import_error => {'!=' => undef}}}
if $$options{with_import_error};
commit 57692a847e30c2a95c568f2b15ed0cc6669a392c
Author: berick <berick at esilibrary.com>
Date: Fri May 6 15:37:32 2011 -0400
initial export drop-down for items UI
diff --git a/Open-ILS/web/js/ui/default/vandelay/vandelay.js b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
index 193056c..d2405cc 100644
--- a/Open-ILS/web/js/ui/default/vandelay/vandelay.js
+++ b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
@@ -377,6 +377,8 @@ function processSpool(key, queueId, type, onload) {
}
function vlExportInit() {
+
+ // queue export
var qsel = dojo.byId('vl-queue-export-options');
qsel.onchange = function(newVal) {
var value = qsel.options[qsel.selectedIndex].value;
@@ -386,10 +388,37 @@ function vlExportInit() {
retrieveQueuedRecords(
currentType,
currentQueueId,
- function(r) { exportHandler(value, r) },
+ function(r) {
+ exportHandler(value, r);
+ displayGlobalDiv('vl-queue-div');
+ },
value
);
}
+
+ // item export
+ var isel = dojo.byId('vl-item-export-options');
+ isel.onchange = function(newVal) {
+ var value = isel.options[isel.selectedIndex].value;
+ isel.selectedIndex = 0;
+ if(!value) return;
+ if(!confirm('Export as "' + value + '"?')) return; // TODO: i18n
+
+ var method = 'open-ils.vandelay.import_item.queue.export.' + value;
+
+ fieldmapper.standardRequest(
+ ['open-ils.vandelay', method],
+ {
+ params : [
+ authtoken,
+ currentQueueId,
+ {with_import_error: (vlImportItemsShowErrors.checked) ? 1 : null}
+ ],
+ async : true,
+ oncomplete : function(r) {exportHandler(type, r)}
+ }
+ );
+ }
}
function exportHandler(type, response) {
diff --git a/Open-ILS/web/templates/default/vandelay/inc/import_errors.tt2 b/Open-ILS/web/templates/default/vandelay/inc/import_errors.tt2
index f72630b..5554f00 100644
--- a/Open-ILS/web/templates/default/vandelay/inc/import_errors.tt2
+++ b/Open-ILS/web/templates/default/vandelay/inc/import_errors.tt2
@@ -47,6 +47,15 @@
<h1>Import Items</h1><br/>
<input dojoType='dijit.form.CheckBox' jsId='vlImportItemsShowErrors' onchange='vlLoadErrorUIAll();'/>
<span>Limit to Import Failures</span>
+ <table width='100%'><tr><td width='100%' align='right'>
+ <select id='vl-item-export-options' style='margin-right: 10px;'>
+ <!-- TODO I18N -->
+ <option value=''>Export Items As...</option>
+ <option value='print'>Print</option>
+ <option value='csv'>CSV</option>
+ <option value='email'>Email</option>
+ </select>
+ </td></tr></table>
<table jsId="vlAllImportErrorGrid"
dojoType="openils.widget.AutoGrid"
autoHeight='true'
commit e4f5a23f414a1afe91a758e563bed1112d0bc9d6
Author: berick <berick at esilibrary.com>
Date: Fri May 6 14:46:25 2011 -0400
initial export drop-down for queue UI
diff --git a/Open-ILS/web/js/ui/default/vandelay/vandelay.js b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
index f076da8..193056c 100644
--- a/Open-ILS/web/js/ui/default/vandelay/vandelay.js
+++ b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
@@ -185,6 +185,7 @@ function vlInit() {
);
vlAttrEditorInit();
+ vlExportInit();
}
@@ -375,20 +376,45 @@ function processSpool(key, queueId, type, onload) {
);
}
-function retrieveQueuedRecords(type, queueId, onload) {
+function vlExportInit() {
+ var qsel = dojo.byId('vl-queue-export-options');
+ qsel.onchange = function(newVal) {
+ var value = qsel.options[qsel.selectedIndex].value;
+ qsel.selectedIndex = 0;
+ if(!value) return;
+ if(!confirm('Export as "' + value + '"?')) return; // TODO: i18n
+ retrieveQueuedRecords(
+ currentType,
+ currentQueueId,
+ function(r) { exportHandler(value, r) },
+ value
+ );
+ }
+}
+
+function exportHandler(type, response) {
+ var content = openils.Util.readResponse(response);
+ if(type == 'print') {
+ // TODO print the content
+ }
+ alert('response = ' + response);
+}
+
+function retrieveQueuedRecords(type, queueId, onload, doExport) {
displayGlobalDiv('vl-generic-progress');
queuedRecords = [];
queuedRecordsMap = {};
currentOverlayRecordsMap = {};
currentOverlayRecordsMapGid = {};
selectableGridRecords = {};
- //resetVlQueueGridLayout();
if(!type) type = currentType;
if(!queueId) queueId = currentQueueId;
if(!onload) onload = handleRetrieveRecords;
var method = 'open-ils.vandelay.'+type+'_queue.records.retrieve.atomic';
+
+ if(doExport) method += '.export.' + doExport;
if(vlQueueGridShowMatches.checked)
method = method.replace('records', 'records.matches');
@@ -407,18 +433,8 @@ function retrieveQueuedRecords(type, queueId, onload) {
['open-ils.vandelay', method],
{ async: true,
params: params,
- /*
- onresponse: function(r) {
- console.log("ONREPONSE");
- var rec = r.recv().content();
- if(e = openils.Event.parse(rec))
- return alert(e);
- console.log("got record " + rec.id());
- queuedRecords.push(rec);
- queuedRecordsMap[rec.id()] = rec;
- },
- */
oncomplete: function(r){
+ if(doExport) return onload();
var recs = r.recv().content();
if(e = openils.Event.parse(recs[0]))
return alert(e);
diff --git a/Open-ILS/web/templates/default/vandelay/inc/queue.tt2 b/Open-ILS/web/templates/default/vandelay/inc/queue.tt2
index b340264..c34c57f 100644
--- a/Open-ILS/web/templates/default/vandelay/inc/queue.tt2
+++ b/Open-ILS/web/templates/default/vandelay/inc/queue.tt2
@@ -69,6 +69,13 @@
<table id='vl-queue-paging-table' class='queue-nav-table'>
<tbody>
<tr><td valign='bottom' align='right'>
+ <select id='vl-queue-export-options' style='margin-right: 10px;'>
+ <!-- TODO I18N -->
+ <option value=''>Export Queue As...</option>
+ <option value='print'>Print</option>
+ <option value='csv'>CSV</option>
+ <option value='email'>Email</option>
+ </select>
<span style='padding-right:5px;'>&vandelay.results.per.page;</span>
<span class='queue-pager-span'>
<select jsId='vlQueueDisplayLimit' id='vl-queue-display-limit-selector'
commit 0f725603bf94f71bf71de57f9c9e8c42f445cc0c
Author: berick <berick at esilibrary.com>
Date: Thu May 5 14:56:39 2011 -0400
more import error tracking and reporting bug fixes
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
index 8c95b70..94b7a32 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
@@ -922,6 +922,8 @@ sub import_record_list_impl {
$logger->info("vl: successfully imported new $type record");
$rec->imported_as($record->id);
$rec->import_time('now');
+ $rec->clear_import_error;
+ $rec->clear_error_detail;
$imported = 1 if $e->$update_func($rec);
}
}
@@ -996,9 +998,7 @@ sub finish_rec_import_attempt {
$e->$method($rec) and $e->commit or $e->rollback;
} else {
- # successful import
- $rec->clear_import_error;
- $rec->clear_error_detail;
+ # commit the successful import
$e->commit;
}
@@ -1226,17 +1226,18 @@ sub import_record_asset_list_impl {
$rec_ids = $roe->json_query({
select => {vqbr => ['id']},
from => {vqbr => 'vii'},
- where => {'+vqbr' => {import_time => {'!=' => undef}}}
+ where => {'+vqbr' => {import_time => {'!=' => undef}}},
+ distinct => 1
});
$rec_ids = [map {$_->{id}} @$rec_ids];
- my %report_args = (
+ my $report_args = {
conn => $conn,
total => scalar(@$rec_ids),
step => 1, # how often to respond
progress => 1,
in_count => 0,
- );
+ };
for my $rec_id (@$rec_ids) {
my $rec = $roe->retrieve_vandelay_queued_bib_record($rec_id);
@@ -1245,10 +1246,10 @@ sub import_record_asset_list_impl {
for my $item_id (@$item_ids) {
my $e = new_editor(requestor => $requestor, xact => 1);
my $item = $e->retrieve_vandelay_import_item($item_id);
- $report_args{import_item} = $item;
- $report_args{e} = $e;
- $report_args{import_error} = undef;
- $report_args{evt} = undef;
+ $$report_args{import_item} = $item;
+ $$report_args{e} = $e;
+ $$report_args{import_error} = undef;
+ $$report_args{evt} = undef;
# --------------------------------------------------------------------------------
# Find or create the volume
@@ -1258,7 +1259,9 @@ sub import_record_asset_list_impl {
$e, $item->call_number, $rec->imported_as, $item->owning_lib);
if($evt) {
- respond_with_status(%report_args, evt => $evt);
+
+ $$report_args{evt} = $evt;
+ respond_with_status($report_args);
next;
}
@@ -1287,30 +1290,24 @@ sub import_record_asset_list_impl {
# see if a valid circ_modifier was provided
# --------------------------------------------------------------------------------
if($copy->circ_modifier and not $e->search_config_circ_modifier({code=>$item->circ_modifier})->[0]) {
- respond_with_status(
- %report_args,
- evt => $e->die_event,
- import_error => 'import.item.invalid.circ_modifier'
- );
+ $$report_args{evt} = $e->die_event;
+ $$report_args{import_error} = 'import.item.invalid.circ_modifier';
+ respond_with_status($report_args);
next;
}
if($copy->location and not $e->retrieve_asset_copy_location($copy->location)) {
- respond_with_status(
- %report_args,
- evt => $e->die_event,
- import_error => 'import.item.invalid.location'
- );
+ $$report_args{evt} = $e->die_event;
+ $$report_args{import_error} = 'import.item.invalid.location';
+ respond_with_status($report_args);
next;
}
if($evt = OpenILS::Application::Cat::AssetCommon->create_copy($e, $vol, $copy)) {
- respond_with_status(
- %report_args,
- evt => $evt,
- import_error => ($evt->{textcode} eq 'ITEM_BARCODE_EXISTS') ?
- 'import.item.duplicate.barcode' : undef
- );
+ $$report_args{evt} = $evt;
+ $$report_args{import_error} = 'import.item.duplicate.barcode'
+ if $evt->{textcode} eq 'ITEM_BARCODE_EXISTS';
+ respond_with_status($report_args);
next;
}
@@ -1321,7 +1318,8 @@ sub import_record_asset_list_impl {
$e, $copy, '', $item->pub_note, 1) if $item->pub_note;
if($evt) {
- respond_with_status(%report_args, evt => $evt);
+ $$report_args{evt} = $evt;
+ respond_with_status($report_args);
next;
}
@@ -1329,7 +1327,8 @@ sub import_record_asset_list_impl {
$e, $copy, '', $item->priv_note, 1) if $item->priv_note;
if($evt) {
- respond_with_status(%report_args, evt => $evt);
+ $$report_args{evt} = $evt;
+ respond_with_status($report_args);
next;
}
@@ -1337,8 +1336,8 @@ sub import_record_asset_list_impl {
# Item import succeeded
# --------------------------------------------------------------------------------
$e->commit;
- $report_args{in_count}++;
- respond_with_status(%report_args, imported_as => $copy->id);
+ $$report_args{in_count}++;
+ respond_with_status($report_args);
$logger->info("vl: successfully imported item " . $item->barcode);
}
commit 6baadbc2fcd5baf128d6ad7768726addae1d9a2b
Author: berick <berick at esilibrary.com>
Date: Thu May 5 14:11:10 2011 -0400
run zz_match_bibs_trigger before update/insert so NEW.quality:= will work
diff --git a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
index cc02d17..2009df6 100644
--- a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
+++ b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
@@ -1866,7 +1866,7 @@ CREATE TRIGGER ingest_item_trigger
FOR EACH ROW EXECUTE PROCEDURE vandelay.ingest_bib_items();
CREATE TRIGGER zz_match_bibs_trigger
- AFTER INSERT OR UPDATE ON vandelay.queued_bib_record
+ BEFORE INSERT OR UPDATE ON vandelay.queued_bib_record
FOR EACH ROW EXECUTE PROCEDURE vandelay.match_bib_record();
commit 64e04af74bc1d40a168dd6e4244b0769cfafcb44
Author: berick <berick at esilibrary.com>
Date: Thu May 5 13:21:56 2011 -0400
expose new import options to queue interface importer dialog; mucho import bug fixes in the middle layer code; expose queued rec quality in matches interface
diff --git a/Open-ILS/examples/fm_IDL.xml b/Open-ILS/examples/fm_IDL.xml
index d2c2f1c..3f93a59 100644
--- a/Open-ILS/examples/fm_IDL.xml
+++ b/Open-ILS/examples/fm_IDL.xml
@@ -329,6 +329,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
<field reporter:label="Attributes" name="attributes" oils_persist:virtual="true" reporter:datatype="link"/>
<field reporter:label="Matches" name="matches" oils_persist:virtual="true" reporter:datatype="link"/>
<field reporter:label="Import Items" name="import_items" oils_persist:virtual="true" reporter:datatype="link"/>
+ <field reporter:label="Quality" name="quality" reporter:datatype="int"/>
</fields>
<links>
<link field="import_error" reltype="has_a" key="code" map="" class="vie"/>
@@ -447,6 +448,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
<field reporter:label="Purpose" name="purpose" reporter:datatype="text"/>
<field reporter:label="Attributes" name="attributes" oils_persist:virtual="true" reporter:datatype="link"/>
<field reporter:label="Matches" name="matches" oils_persist:virtual="true" reporter:datatype="link"/>
+ <field reporter:label="Quality" name="quality" reporter:datatype="int"/>
</fields>
<links>
<link field="import_error" reltype="has_a" key="code" map="" class="vie"/>
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
index 3755ad2..8c95b70 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
@@ -576,7 +576,7 @@ sub import_record_list {
return $e->die_event unless $e->checkauth;
$args ||= {};
my $err = import_record_list_impl($self, $conn, $rec_ids, $e->requestor, $args);
- $e->rollback;
+ try {$e->rollback} otherwise {};
return $err if $err;
return {complete => 1};
}
@@ -698,13 +698,13 @@ sub import_record_list_impl {
my $type = $self->{record_type};
my %queues;
- my %report_args = (
- progress => 0,
+ my $report_args = {
+ progress => 1,
step => 1,
conn => $conn,
total => scalar(@$rec_ids),
report_all => $$args{report_all}
- );
+ };
my $auto_overlay_exact = $$args{auto_overlay_exact};
my $auto_overlay_1match = $$args{auto_overlay_1match};
@@ -750,10 +750,9 @@ sub import_record_list_impl {
my $e = new_editor(xact => 1);
$e->requestor($requestor);
- $report_args{progress}++;
- $report_args{e} = $e;
- $report_args{import_error} = undef;
- $report_args{evt} = undef;
+ $$report_args{e} = $e;
+ $$report_args{import_error} = undef;
+ $$report_args{evt} = undef;
my $rec = $e->$retrieve_func([
$rec_id,
@@ -763,11 +762,12 @@ sub import_record_list_impl {
]);
unless($rec) {
- finish_rec_import_attempt(%report_args, evt => $e->event);
+ $$report_args{evt} = $e->event;
+ finish_rec_import_attempt($report_args);
next;
}
- $report_args{rec} = $rec;
+ $$report_args{rec} = $rec;
if($rec->import_time) {
$e->rollback;
@@ -890,7 +890,7 @@ sub import_record_list_impl {
$logger->info("vl: $type auto-overlay-best succeeded for queued rec " . $rec->id);
$imported = 1;
} else {
- $report_args{import_error} = 'overlay.record.quality' if $match_quality_ratio > 0;
+ $$report_args{import_error} = 'overlay.record.quality' if $match_quality_ratio > 0;
$logger->info("vl: $type auto-overlay-best failed for queued rec " . $rec->id);
}
@@ -914,8 +914,8 @@ sub import_record_list_impl {
}
if($U->event_code($record)) {
- $report_args{import_error} = 'import.duplicate.tcn' if $record->{textcode} eq 'TCN_EXISTS';
- $report_args{evt} = $record;
+ $$report_args{import_error} = 'import.duplicate.tcn' if $record->{textcode} eq 'TCN_EXISTS';
+ $$report_args{evt} = $record;
} else {
@@ -929,11 +929,12 @@ sub import_record_list_impl {
if($imported) {
push @success_rec_ids, $rec_id;
- finish_rec_import_attempt(%report_args);
+ finish_rec_import_attempt($report_args);
} else {
# Send an update whenever there's an error
- finish_rec_import_attempt(%report_args, evt => $e->event);
+ $$report_args{evt} = $e->event unless $$report_args{evt};
+ finish_rec_import_attempt($report_args);
}
}
@@ -960,18 +961,18 @@ sub import_record_list_impl {
# import the copies
import_record_asset_list_impl($conn, \@success_rec_ids, $requestor);
- $conn->respond({total => $report_args{total}, progress => $report_args{progress}});
+ $conn->respond({total => $$report_args{total}, progress => $$report_args{progress}});
return undef;
}
# tracks any import errors, commits the current xact, responds to the client
sub finish_rec_import_attempt {
- my %args = @_;
- my $evt = $args{evt};
- my $rec = $args{rec};
- my $e = $args{e};
+ my $args = shift;
+ my $evt = $$args{evt};
+ my $rec = $$args{rec};
+ my $e = $$args{e};
- my $error = $args{import_error};
+ my $error = $$args{import_error};
$error = 'general.unknown' if $evt and not $error;
# error tracking
@@ -991,7 +992,7 @@ sub finish_rec_import_attempt {
}
my $method = 'update_vandelay_queued_bib_record';
- $method =~ s/bib/authority/ if $args{type} eq 'auth';
+ $method =~ s/bib/authority/ if $$args{type} eq 'auth';
$e->$method($rec) and $e->commit or $e->rollback;
} else {
@@ -1007,18 +1008,17 @@ sub finish_rec_import_attempt {
}
# respond to client
- if($args{report_all} or ($args{progress} % $args{step}) == 0) {
-
- $args{conn}->respond({
- total => $args{total},
- progress => $args{progress},
+ if($$args{report_all} or ($$args{progress} % $$args{step}) == 0) {
+ $$args{conn}->respond({
+ total => $$args{total},
+ progress => $$args{progress},
imported => ($rec) ? $rec->id : undef,
err_event => $evt
});
-
- # report often at first, climb quickly, then hold steady
- $args{step} *= 2 unless $args{step} == 256;
+ $$args{step} *= 2 unless $$args{step} == 256;
}
+
+ $$args{progress}++;
}
@@ -1221,25 +1221,34 @@ sub import_record_asset_list_impl {
my $roe = new_editor(xact=> 1, requestor => $requestor);
+ # for speed, filter out any records have not been
+ # imported or have no import items to load
+ $rec_ids = $roe->json_query({
+ select => {vqbr => ['id']},
+ from => {vqbr => 'vii'},
+ where => {'+vqbr' => {import_time => {'!=' => undef}}}
+ });
+ $rec_ids = [map {$_->{id}} @$rec_ids];
+
my %report_args = (
conn => $conn,
total => scalar(@$rec_ids),
step => 1, # how often to respond
- progress => 0,
+ progress => 1,
in_count => 0,
);
for my $rec_id (@$rec_ids) {
my $rec = $roe->retrieve_vandelay_queued_bib_record($rec_id);
- next unless $rec and $rec->import_time;
my $item_ids = $roe->search_vandelay_import_item({record => $rec->id}, {idlist=>1});
for my $item_id (@$item_ids) {
my $e = new_editor(requestor => $requestor, xact => 1);
my $item = $e->retrieve_vandelay_import_item($item_id);
- $report_args{progress}++;
$report_args{import_item} = $item;
$report_args{e} = $e;
+ $report_args{import_error} = undef;
+ $report_args{evt} = undef;
# --------------------------------------------------------------------------------
# Find or create the volume
@@ -1332,24 +1341,26 @@ sub import_record_asset_list_impl {
respond_with_status(%report_args, imported_as => $copy->id);
$logger->info("vl: successfully imported item " . $item->barcode);
}
+
}
+
$roe->rollback;
return undef;
}
sub respond_with_status {
- my %args = @_;
- my $e = $args{e};
+ my $args = shift;
+ my $e = $$args{e};
# If the import failed, track the failure reason
- my $error = $args{import_error};
- my $evt = $args{evt};
+ my $error = $$args{import_error};
+ my $evt = $$args{evt};
if($error or $evt) {
- my $item = $args{import_item};
+ my $item = $$args{import_item};
$logger->info("vl: unable to import item " . $item->barcode);
$error ||= 'general.unknown';
@@ -1367,13 +1378,15 @@ sub respond_with_status {
$e->commit;
}
- return unless $args{report_all} or ($args{progress} % $args{step}) == 0;
- $args{step} *= 2 unless $args{step} == 256;
+ if($$args{report_all} or ($$args{progress} % $$args{step}) == 0) {
+ $$args{conn}->respond({
+ map { $_ => $args->{$_} } qw/total progress success_count/,
+ err_event => $evt
+ });
+ $$args{step} *= 2 unless $$args{step} == 256;
+ }
- $args{conn}->respond({
- map { $_ => $args{$_} } qw/total progress success_count/,
- err_event => $evt
- });
+ $$args{progress}++;
}
__PACKAGE__->register_method(
diff --git a/Open-ILS/web/js/ui/default/vandelay/vandelay.js b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
index b72438c..f076da8 100644
--- a/Open-ILS/web/js/ui/default/vandelay/vandelay.js
+++ b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
@@ -435,7 +435,8 @@ function retrieveQueuedRecords(type, queueId, onload) {
function vlLoadMatchUI(recId) {
displayGlobalDiv('vl-generic-progress');
- var matches = queuedRecordsMap[recId].matches();
+ var queuedRec = queuedRecordsMap[recId];
+ var matches = queuedRec.matches();
var records = [];
currentImportRecId = recId;
for(var i = 0; i < matches.length; i++)
@@ -465,7 +466,7 @@ function vlLoadMatchUI(recId) {
// build the data store of records with match information
var dataStore = bre.toStoreData(recs, null,
- {virtualFields:['_id', 'match_score', 'match_quality']});
+ {virtualFields:['_id', 'match_score', 'match_quality', 'rec_quality']});
dataStore.identifier = '_id';
var matchSeenMap = {};
@@ -479,6 +480,7 @@ function vlLoadMatchUI(recId) {
if(match.match_score)
item.match_score = match.match_score();
item.match_quality = match.quality();
+ item.rec_quality = queuedRec.quality();
matchSeenMap[match.id()] = 1;
break;
}
@@ -979,6 +981,8 @@ function vlHandleQueueItemsAction(action) {
vlUploadQueueAutoOverlayExact.attr('value', vlUploadQueueAutoOverlayExact2.attr('value'));
vlUploadQueueAutoOverlay1Match.attr('value', vlUploadQueueAutoOverlay1Match2.attr('value'));
vlUploadMergeProfile.attr('value', vlUploadMergeProfile2.attr('value'));
+ vlUploadQueueAutoOverlayBestMatch.attr('value', vlUploadQueueAutoOverlayBestMatch2.attr('value'));
+ vlUploadQueueAutoOverlayBestMatchRatio.attr('value', vlUploadQueueAutoOverlayBestMatchRatio2.attr('value'));
if(action == 'import') {
vlImportSelectedRecords();
@@ -995,6 +999,10 @@ function vlHandleQueueItemsAction(action) {
vlUploadQueueAutoOverlay1Match2.attr('value', false);
vlUploadMergeProfile.attr('value', '');
vlUploadMergeProfile2.attr('value', '');
+ vlUploadQueueAutoOverlayBestMatch.attr('value', false);
+ vlUploadQueueAutoOverlayBestMatch2.attr('value', false);
+ vlUploadQueueAutoOverlayBestMatchRatio.attr('value', '0.0');
+ vlUploadQueueAutoOverlayBestMatchRatio2.attr('value', '0.0');
}
);
@@ -1002,8 +1010,8 @@ function vlHandleQueueItemsAction(action) {
}
+/* import user-selected records */
function vlImportSelectedRecords() {
- displayGlobalDiv('vl-generic-progress-with-total');
var records = [];
for(var id in selectableGridRecords) {
@@ -1015,55 +1023,35 @@ function vlImportSelectedRecords() {
}
}
- var options = {overlay_map : currentOverlayRecordsMap};
-
- if(vlUploadQueueAutoOverlayExact.checked) {
- options.auto_overlay_exact = true;
- vlUploadQueueAutoOverlayExact.checked = false;
- }
-
- if(vlUploadQueueAutoOverlay1Match.checked) {
- options.auto_overlay_1match = true;
- vlUploadQueueAutoOverlay1Match.checked = false;
- }
-
- var profile = vlUploadMergeProfile.attr('value');
- if(profile != null && profile != '') {
- options.merge_profile = profile;
- }
-
- fieldmapper.standardRequest(
- ['open-ils.vandelay', 'open-ils.vandelay.'+currentType+'_record.list.import'],
- { async: true,
- params: [authtoken, records, options],
- onresponse: function(r) {
- var resp = r.recv().content();
- if(e = openils.Event.parse(resp))
- return alert(e);
- if(resp.complete) {
- return retrieveQueuedRecords(currentType, currentQueueId, handleRetrieveRecords);
- } else {
- vlControlledProgressBar.update({maximum:resp.total, progress:resp.progress});
- }
- },
+ vlImportRecordQueue(
+ currentType,
+ currentQueueId,
+ records,
+ function(){
+ retrieveQueuedRecords(currentType, currentQueueId, handleRetrieveRecords);
}
);
}
+/* import all (non-imported) queue records */
function vlImportAllRecords() {
- vlImportRecordQueue(currentType, currentQueueId, false,
- function(){displayGlobalDiv('vl-queue-div');});
+ vlImportRecordQueue(
+ currentType,
+ currentQueueId,
+ null,
+ function(){
+ retrieveQueuedRecords(currentType, currentQueueId, handleRetrieveRecords);
+ }
+ );
}
-function vlImportRecordQueue(type, queueId, onload) {
+/* if recList has values, import only those records */
+function vlImportRecordQueue(type, queueId, recList, onload) {
displayGlobalDiv('vl-generic-progress-with-total');
- var method = 'open-ils.vandelay.bib_queue.import';
- if(type == 'auth')
- method = method.replace('bib', 'auth');
-
+ /* set up options */
var mergeOpt = false;
- var options = {};
+ var options = {overlay_map : currentOverlayRecordsMap};
if(vlUploadQueueImportNoMatch.checked) {
options.import_no_match = true;
@@ -1089,22 +1077,34 @@ function vlImportRecordQueue(type, queueId, onload) {
mergeOpt = true;
}
+ var profile = vlUploadMergeProfile.attr('value');
+ if(profile != null && profile != '') {
+ options.merge_profile = profile;
+ }
+
+ /* determine which method we're calling */
+
+ var method = 'open-ils.vandelay.bib_queue.import';
+ if(type == 'auth')
+ method = method.replace('bib', 'auth');
+
if(!mergeOpt) {
// in the interest of speed, if no merge options are
// chosen, tell the back-end code to only process records
// that have no matches
- method = method.replace('.import', 'nomatch.import');
+ method = method.replace(/\.import/, '.nomatch.import');
}
-
- var profile = vlUploadMergeProfile.attr('value');
- if(profile != null && profile != '') {
- options.merge_profile = profile;
+
+ var params = [authtoken, queueId, options];
+ if(recList) {
+ method = 'open-ils.vandelay.'+currentType+'_record.list.import';
+ params[1] = recList;
}
fieldmapper.standardRequest(
['open-ils.vandelay', method],
{ async: true,
- params: [authtoken, queueId, options],
+ params: params,
onresponse: function(r) {
var resp = r.recv().content();
if(e = openils.Event.parse(resp))
@@ -1134,6 +1134,7 @@ function batchUpload() {
vlImportRecordQueue(
currentType,
currentQueueId,
+ null,
function() {
retrieveQueuedRecords(currentType, currentQueueId, handleRetrieveRecords);
}
@@ -1239,6 +1240,17 @@ function vlShowUploadForm() {
vlUploadQueueAutoOverlayBestMatchRatio.attr('value', profile.lwm_ratio()+'');
}
);
+ dojo.connect(
+ vlUploadMergeProfile2,
+ 'onChange',
+ function(val) {
+ if(!val) return;
+ var profile = mergeProfiles.filter(function(p) { return (p.id() == val); })[0];
+ if(profile.lwm_ratio() != null)
+ vlUploadQueueAutoOverlayBestMatchRatio2.attr('value', profile.lwm_ratio()+'');
+ }
+ );
+
}
function vlShowQueueSelect() {
diff --git a/Open-ILS/web/templates/default/vandelay/inc/matches.tt2 b/Open-ILS/web/templates/default/vandelay/inc/matches.tt2
index 40d6a80..2376dbc 100644
--- a/Open-ILS/web/templates/default/vandelay/inc/matches.tt2
+++ b/Open-ILS/web/templates/default/vandelay/inc/matches.tt2
@@ -15,6 +15,7 @@
formatter : vlFormatViewMatchMARC
},
{name: 'Match Score', field:'match_score'},
+ {name: 'Queued Record Quality', field:'rec_quality'},
{name: 'Matched Record Quality', field:'match_quality'},
{name: '&vandelay.creator;', get: vlGetCreator},
{name: '&vandelay.create.date;', field:'create_date', get: vlGetDateTimeField},
diff --git a/Open-ILS/web/templates/default/vandelay/inc/queue.tt2 b/Open-ILS/web/templates/default/vandelay/inc/queue.tt2
index 00c812d..b340264 100644
--- a/Open-ILS/web/templates/default/vandelay/inc/queue.tt2
+++ b/Open-ILS/web/templates/default/vandelay/inc/queue.tt2
@@ -9,10 +9,10 @@
<table class='queue-nav-table'>
<thead><tr><th colspan='2' class='queue-nav-table-label'>Queue Actions</th></tr></thead>
<tbody>
- <tr><td><a href='#' onclick='vlHandleQueueItemsAction("import")'>&vandelay.import.selected;</a></td></tr>
- <tr><td><a href='#' onclick='vlHandleQueueItemsAction("import_all")'>&vandelay.import.all;</a></td></tr>
- <tr><td><a href='#' onclick='vlLoadErrorUIAll();'>View Import Items</a></td></tr>
- <tr><td><a href='#' onclick='
+ <tr><td><a href='javascript:;' onclick='vlHandleQueueItemsAction("import")'>&vandelay.import.selected;</a></td></tr>
+ <tr><td><a href='javascript:;' onclick='vlHandleQueueItemsAction("import_all")'>&vandelay.import.all;</a></td></tr>
+ <tr><td><a href='javascript:;' onclick='vlLoadErrorUIAll();'>View Import Items</a></td></tr>
+ <tr><td><a href='javascript:;' onclick='
if(confirm("&vandelay.sure.to.delete.queue;")) {
vlDeleteQueue(currentType, currentQueueId,
function() { displayGlobalDiv("vl-marc-upload-div"); });}'>&vandelay.delete.queue;</a></td></tr>
@@ -186,9 +186,16 @@
<table class='form_table'>
<tbody>
<tr>
+ <td>&vandelay.auto.import.merge_profile;</td>
+ <td colspan='4'>
+ <div jsId='vlUploadMergeProfile2'
+ dojoType='dijit.form.FilteringSelect' required='false' labelAttr='name' searchAttr='name'/>
+ </td>
+ </tr>
+ <tr>
<td>&vandelay.auto.import.noncolliding;</td>
<td colspan='4'>
- <input jsId='vlUploadQueueAutoImport2' dojoType='dijit.form.CheckBox'/>
+ <input jsId='vlUploadQueueImportNoMatch2' dojoType='dijit.form.CheckBox'/>
</td>
</tr>
<tr>
@@ -204,10 +211,14 @@
</td>
</tr>
<tr>
- <td>&vandelay.auto.import.merge_profile;</td>
+ <td>&vandelay.auto.import.auto_overlay_best;</td>
+ <td colspan='4'><input jsId='vlUploadQueueAutoOverlayBestMatch2' dojoType='dijit.form.CheckBox'/></td>
+ </tr>
+ <tr>
+ <td>&vandelay.auto.import.auto_overlay_best_ratio;</td>
<td colspan='4'>
- <div jsId='vlUploadMergeProfile2'
- dojoType='dijit.form.FilteringSelect' required='false' labelAttr='name' searchAttr='name'/>
+ <input style='width:3em' value='0.0' jsId='vlUploadQueueAutoOverlayBestMatchRatio2' dojoType='dijit.form.TextBox'/>
+ <span style='padding-left: 10px; font-size:90%'>(&vandelay.auto.import.auto_overlay_best_ratio.desc;)</span>
</td>
</tr>
<tr>
commit 207dd51b5dae6f5c4f88f576f79d6736b16ef559
Author: berick <berick at esilibrary.com>
Date: Thu May 5 10:28:15 2011 -0400
added edit support for lwm_ratio on merge_profile; default ratio to that of the merge profile if selected and if a ratio is set on the profile
diff --git a/Open-ILS/web/js/ui/default/vandelay/vandelay.js b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
index 4aeef8f..b72438c 100644
--- a/Open-ILS/web/js/ui/default/vandelay/vandelay.js
+++ b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
@@ -87,6 +87,7 @@ var vlQueueGridColumePicker = {};
var vlBibSources = [];
var importItemDefs = [];
var matchSets = {};
+var mergeProfiles = [];
/**
* Grab initial data
@@ -106,13 +107,13 @@ function vlInit() {
runStartupCommands();
}
- var profiles = new openils.PermaCrud().retrieveAll('vmp');
- vlUploadMergeProfile.store = new dojo.data.ItemFileReadStore({data:fieldmapper.vmp.toStoreData(profiles)});
+ mergeProfiles = new openils.PermaCrud().retrieveAll('vmp');
+ vlUploadMergeProfile.store = new dojo.data.ItemFileReadStore({data:fieldmapper.vmp.toStoreData(mergeProfiles)});
vlUploadMergeProfile.labelAttr = 'name';
vlUploadMergeProfile.searchAttr = 'name';
vlUploadMergeProfile.startup();
- vlUploadMergeProfile2.store = new dojo.data.ItemFileReadStore({data:fieldmapper.vmp.toStoreData(profiles)});
+ vlUploadMergeProfile2.store = new dojo.data.ItemFileReadStore({data:fieldmapper.vmp.toStoreData(mergeProfiles)});
vlUploadMergeProfile2.labelAttr = 'name';
vlUploadMergeProfile2.searchAttr = 'name';
vlUploadMergeProfile2.startup();
@@ -1226,6 +1227,18 @@ function vlShowUploadForm() {
vlUploadQueueHoldingsImportProfile.store =
new dojo.data.ItemFileReadStore({data:viiad.toStoreData(importItemDefs)});
vlUpdateMatchSetSelector(vlUploadRecordType.getValue());
+
+ // use ratio from the merge profile if it's set
+ dojo.connect(
+ vlUploadMergeProfile,
+ 'onChange',
+ function(val) {
+ if(!val) return;
+ var profile = mergeProfiles.filter(function(p) { return (p.id() == val); })[0];
+ if(profile.lwm_ratio() != null)
+ vlUploadQueueAutoOverlayBestMatchRatio.attr('value', profile.lwm_ratio()+'');
+ }
+ );
}
function vlShowQueueSelect() {
diff --git a/Open-ILS/web/templates/default/vandelay/inc/profiles.tt2 b/Open-ILS/web/templates/default/vandelay/inc/profiles.tt2
index 5bd4d4d..ca67f3a 100644
--- a/Open-ILS/web/templates/default/vandelay/inc/profiles.tt2
+++ b/Open-ILS/web/templates/default/vandelay/inc/profiles.tt2
@@ -13,9 +13,9 @@
</div>
<table jsId="pGrid"
dojoType="openils.widget.AutoGrid"
- fieldOrder="['name', 'owner', 'preserve_spec', 'replace_spec', 'add_spec', 'strip_spec']"
+ fieldOrder="['name', 'owner', 'preserve_spec', 'replace_spec', 'add_spec', 'strip_spec', 'lwm_ratio']"
query="{id: '*'}"
- defaultCellWidth='"auto"'
+ defaultCellWidth='"14%"'
fmClass='vmp'
showPaginator='true'
editOnEnter='true'>
commit ff796bd6fc1ae0744a7f7efc73a0bdb11b9975e8
Author: berick <berick at esilibrary.com>
Date: Thu May 5 10:27:31 2011 -0400
added missing lwm_ratio field to vandelay.merge_profile
diff --git a/Open-ILS/examples/fm_IDL.xml b/Open-ILS/examples/fm_IDL.xml
index 97c2865..d2c2f1c 100644
--- a/Open-ILS/examples/fm_IDL.xml
+++ b/Open-ILS/examples/fm_IDL.xml
@@ -148,6 +148,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
<field reporter:label="Replace Specification" name="replace_spec" reporter:datatype="text"/>
<field reporter:label="Remove Specification" name="strip_spec" reporter:datatype="text"/>
<field reporter:label="Preserve Specification" name="preserve_spec" reporter:datatype="text"/>
+ <field reporter:label="Min. Quality Ratio" name="lwm_ratio" reporter:datatype="float"/>
</fields>
<links>
<link field="owner" reltype="has_a" key="id" map="" class="aou"/>
commit 130a5dcf1f0c8bdc79dc617873e20033dc433311
Author: berick <berick at esilibrary.com>
Date: Thu May 5 10:01:22 2011 -0400
record import error handling improvements
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
index 759a624..3755ad2 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
@@ -752,6 +752,8 @@ sub import_record_list_impl {
$report_args{progress}++;
$report_args{e} = $e;
+ $report_args{import_error} = undef;
+ $report_args{evt} = undef;
my $rec = $e->$retrieve_func([
$rec_id,
@@ -912,15 +914,14 @@ sub import_record_list_impl {
}
if($U->event_code($record)) {
- my $import_error = 'import.duplicate.tcn' if $record->{textcode} eq 'TCN_EXISTS';
- finish_rec_import_attempt(%report_args, import_error => $import_error, evt => $record);
+ $report_args{import_error} = 'import.duplicate.tcn' if $record->{textcode} eq 'TCN_EXISTS';
+ $report_args{evt} = $record;
} else {
$logger->info("vl: successfully imported new $type record");
$rec->imported_as($record->id);
$rec->import_time('now');
-
$imported = 1 if $e->$update_func($rec);
}
}
commit 815e3e2f48614f1cead864d4151f188c62a88d95
Author: senator <lebbeous at esilibrary.com>
Date: Wed May 4 17:33:29 2011 -0400
the vandelay match set editor now does quality metrics too
diff --git a/Open-ILS/examples/fm_IDL.xml b/Open-ILS/examples/fm_IDL.xml
index f7ad9e3..97c2865 100644
--- a/Open-ILS/examples/fm_IDL.xml
+++ b/Open-ILS/examples/fm_IDL.xml
@@ -599,10 +599,18 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
</links>
<permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
<actions>
- <create permission="ADMIN_IMPORT_MATCH_SET" context_field="owner"/>
- <retrieve permission="ADMIN_IMPORT_MATCH_SET" context_field="owner"/>
- <update permission="ADMIN_IMPORT_MATCH_SET" context_field="owner"/>
- <delete permission="ADMIN_IMPORT_MATCH_SET" context_field="owner"/>
+ <create permission="ADMIN_IMPORT_MATCH_SET">
+ <context link="match_set" field="owner"/>
+ </create>
+ <retrieve permission="ADMIN_IMPORT_MATCH_SET">
+ <context link="match_set" field="owner"/>
+ </retrieve>
+ <update permission="ADMIN_IMPORT_MATCH_SET">
+ <context link="match_set" field="owner"/>
+ </update>
+ <delete permission="ADMIN_IMPORT_MATCH_SET">
+ <context link="match_set" field="owner"/>
+ </delete>
</actions>
</permacrud>
</class>
diff --git a/Open-ILS/web/js/dojo/openils/vandelay/nls/match_set.js b/Open-ILS/web/js/dojo/openils/vandelay/nls/match_set.js
index 7e76613..92851d2 100644
--- a/Open-ILS/web/js/dojo/openils/vandelay/nls/match_set.js
+++ b/Open-ILS/web/js/dojo/openils/vandelay/nls/match_set.js
@@ -6,8 +6,10 @@
"ENTER_REPLACE_MODE": "Enter Replace Mode",
"NO_CAN_DO": "An error has occurred. Close this interface and try again.",
"OK": "Ok",
- "POINT_NEEDS_ONE": "A match point must be exactly one of the following: boolean operator, MARC tag/subfield pair, single-value-field.",
+ "CANCEL": "Cancel",
+ "POINT_NEEDS_ONE": "You have not entered valid data",
"FAULTY_MARC": "A MARC tag must be identified by three digits, and the subfield must be one non-whitespace, non-control character.",
"WORKING_MP_HERE": "Choose from among the three buttons above to add a new match point.",
+ "WORKING_QM_HERE": "Use buttons above and to the right to add new quality metrics.",
"SVF": "Record Attribute"
}
diff --git a/Open-ILS/web/js/ui/default/conify/global/vandelay/match_set.js b/Open-ILS/web/js/ui/default/conify/global/vandelay/match_set.js
index e07eeca..28f30b5 100644
--- a/Open-ILS/web/js/ui/default/conify/global/vandelay/match_set.js
+++ b/Open-ILS/web/js/ui/default/conify/global/vandelay/match_set.js
@@ -11,7 +11,7 @@ dojo.require("openils.PermaCrud");
dojo.require("openils.widget.ProgressDialog");
dojo.require("openils.widget.AutoGrid");
-var localeStrings, node_editor, _crads, CGI, tree, match_set;
+var localeStrings, node_editor, qnode_editor, _crads, CGI, tree, match_set;
var NodeEditorAbstract = {
"_svf_select_template": null,
@@ -25,11 +25,7 @@ var NodeEditorAbstract = {
},
"is_sensible": function(thing) {
var need_one = 0;
- var list = openils.Util.objectProperties(this._factories_by_type);
- console.log(list.join(" "));
- openils.Util.objectProperties(this._factories_by_type).forEach(
- function(field) { if (thing[field]()) need_one++; }
- );
+ this.foi.forEach(function(field) { if (thing[field]()) need_one++; });
if (need_one != 1) {
alert(localeStrings.POINT_NEEDS_ONE);
@@ -56,7 +52,6 @@ var NodeEditorAbstract = {
this._consistent_controls = [];
for (var i = 0; i < trs.length; i++)
this._consistent_controls[i] = dojo.clone(trs[i]);
- dojo.empty(trs[0].parentNode);
}
this._consistent_controls.forEach(
@@ -124,39 +119,53 @@ var NodeEditorAbstract = {
}, dojo.create("td", null, rows[1])
);
return rows;
+ },
+ "bool_op": function() {
+ var tr = dojo.create("tr");
+ dojo.create(
+ "label",
+ {"for": "operator-select", "innerHTML": "Operator:"},
+ dojo.create("td", null, tr)
+ );
+ var select = dojo.create(
+ "select", {"fmfield": "bool_op", "id": "operator-select"},
+ dojo.create("td", null, tr)
+ );
+ dojo.create("option", {"value": "AND", "innerHTML": "AND"}, select);
+ dojo.create("option", {"value": "OR", "innerHTML": "OR"}, select);
+
+ return [tr];
}
}
};
-function _find_crad_by_name(name) {
- for (var i = 0; i < _crads.length; i++) {
- if (_crads[i].name() == name)
- return _crads[i];
- }
- return null;
+function apply_base_class(cls, basecls) {
+ openils.Util.objectProperties(basecls).forEach(
+ function(m) { cls[m] = basecls[m]; }
+ );
}
function QualityNodeEditor() {
var self = this;
+ this.foi = ["tag", "svf"]; /* Fields of Interest - starting points for UI */
- this._init = function(dnd_source, qnode_editor_container) {
+ this._init = function(qnode_editor_container) {
this._consistent_controls_query =
"[consistent-controls], [quality-controls]";
- this.dnd_source = dnd_source;
this.qnode_editor_container = dojo.byId(qnode_editor_container);
+ this.clear();
};
this.clear = function() {
- this.dnd_source.selectAll().deleteSelectedNodes();
dojo.create(
- "em", {"innerHTML": localeStrings.WORKING_MP_HERE},
+ "em", {"innerHTML": localeStrings.WORKING_QM_HERE},
this.qnode_editor_container, "only"
);
- this.dnd_source._ready = false;
};
this.build_vmsq = function() {
var metric = new vmsq();
+ metric.match_set(match_set.id()); /* using global */
var controls = dojo.query("[fmfield]", this.qnode_editor_container);
for (var i = 0; i < controls.length; i++) {
var field = dojo.attr(controls[i], "fmfield");
@@ -171,7 +180,6 @@ function QualityNodeEditor() {
this.add = function(type) {
this.clear();
-
/* these are the editing widgets */
var table = dojo.create("table", {"className": "node-editor"});
@@ -180,19 +188,51 @@ function QualityNodeEditor() {
this._add_consistent_controls(table);
+ var ok_cxl_td = dojo.create(
+ "td", {"colspan": 2, "align": "center", "className": "space-me"},
+ dojo.create("tr", null, table)
+ );
+
dojo.create(
"input", {
"type": "submit", "value": localeStrings.OK,
- "onclick": function() { alert("would update draggable here"/* XXX TODO */); }
- }, dojo.create(
- "td", {"colspan": 2, "align": "center"},
- dojo.create("tr", null, table)
- )
+ "onclick": function() {
+ var metric = self.build_vmsq();
+ if (metric) {
+ self.clear();
+ pcrud.create(
+ metric, {
+ /* borrowed from openils.widget.AutoGrid */
+ "oncomplete": function(req, cudResults) {
+ var fmObject = cudResults[0];
+ if (vmsq_grid.onPostCreate)
+ vmsq_grid.onPostCreate(fmObject);
+ if (fmObject) {
+ vmsq_grid.store.newItem(
+ fmObject.toStoreItem()
+ );
+ }
+ setTimeout(function() {
+ try {
+ vmsq_grid.selection.select(vmsq_grid.rowCount-1);
+ vmsq_grid.views.views[0].getCellNode(vmsq_grid.rowCount-1, 1).focus();
+ } catch (E) {}
+ },200);
+ }
+ }
+ );
+ }
+ }
+ }, ok_cxl_td
+ );
+ dojo.create(
+ "input", {
+ "type": "reset", "value": localeStrings.CANCEL,
+ "onclick": function() { self.clear(); }
+ }, ok_cxl_td
);
- dojo.place(table, this.qnode_editor_container, "only");/* XXX put in dialog here */
-
- //this.dnd_source.insertNodes(false, [draggable]);
+ dojo.place(table, this.qnode_editor_container, "only");
/* nice */
try { dojo.query("select, input", table)[0].focus(); }
@@ -200,17 +240,17 @@ function QualityNodeEditor() {
};
- openils.Util.objectProperties(NodeEditorAbstract).forEach(
- function(m) { self[m] = NodeEditorAbstract[m]; }
- );
+ apply_base_class(self, NodeEditorAbstract);
this._init.apply(this, arguments);
}
function NodeEditor() {
var self = this;
+ this.foi = ["tag", "svf", "bool_op"]; /* Fields of Interest - starting points for UI */
this._init = function(dnd_source, node_editor_container) {
- this._consistent_controls_query = "[consistent-controls]";
+ this._consistent_controls_query =
+ "[consistent-controls], [point-controls]";
this.dnd_source = dnd_source;
this.node_editor_container = dojo.byId(node_editor_container);
};
@@ -285,29 +325,19 @@ function NodeEditor() {
};
- openils.Util.objectProperties(NodeEditorAbstract).forEach(
- function(m) { self[m] = NodeEditorAbstract[m]; }
- );
+ apply_base_class(self, NodeEditorAbstract);
- this._factories_by_type.bool_op = function() {
- var tr = dojo.create("tr");
- dojo.create(
- "label",
- {"for": "operator-select", "innerHTML": "Operator:"},
- dojo.create("td", null, tr)
- );
- var select = dojo.create(
- "select", {"fmfield": "bool_op", "id": "operator-select"},
- dojo.create("td", null, tr)
- );
- dojo.create("option", {"value": "AND", "innerHTML": "AND"}, select);
- dojo.create("option", {"value": "OR", "innerHTML": "OR"}, select);
-
- return [tr];
- };
this._init.apply(this, arguments);
}
+function find_crad_by_name(name) {
+ for (var i = 0; i < _crads.length; i++) {
+ if (_crads[i].name() == name)
+ return _crads[i];
+ }
+ return null;
+}
+
function render_vmsp_label(point, minimal) {
/* "minimal" has this implication:
* for svf, only show the code, not the longer label.
@@ -317,7 +347,7 @@ function render_vmsp_label(point, minimal) {
} else if (point.svf()) {
return (openils.Util.isTrue(point.negate()) ? "NOT " : "") + (
minimal ? point.svf() :
- (point.svf() + " / " + _find_crad_by_name(point.svf()).label())
+ (point.svf() + " / " + find_crad_by_name(point.svf()).label())
);
} else {
return (openils.Util.isTrue(point.negate()) ? "NOT " : "") +
@@ -459,7 +489,7 @@ function save_tree() {
root, function(r) {
fieldmapper.standardRequest(
["open-ils.vandelay",
- "open-ils.vandelay.match_set.update"],/* XXX TODO */{
+ "open-ils.vandelay.match_set.update"], {
"params": [
openils.User.authtoken, match_set.id(), r
],
@@ -482,7 +512,7 @@ function save_tree() {
function init_vmsq_grid() {
vmsq_grid.loadAll(
{"order_by": {"vmsq": "quality"}},
- {"match_set": CGI.param("match_set")}
+ {"match_set": match_set.id()}
);
}
@@ -538,6 +568,7 @@ function my_init() {
);
node_editor = new NodeEditor(src, "node-editor-container");
+ qnode_editor = new QualityNodeEditor("qnode-editor-container");
replace_mode(0);
diff --git a/Open-ILS/web/templates/default/conify/global/vandelay/match_set_tree.tt2 b/Open-ILS/web/templates/default/conify/global/vandelay/match_set_tree.tt2
index 7a11223..8ad1eea 100644
--- a/Open-ILS/web/templates/default/conify/global/vandelay/match_set_tree.tt2
+++ b/Open-ILS/web/templates/default/conify/global/vandelay/match_set_tree.tt2
@@ -3,6 +3,7 @@
<style type="text/css">
h1 { margin: 1ex 0; }
.outer { clear: both; margin-bottom: 1ex; }
+ .space-me input { margin: 0 1em; }
button { margin: 0 0.5em; }
input[type=submit] { padding: 0 0.5em; }
#tree-here { margin-bottom: 1.5em; }
@@ -48,6 +49,14 @@
give some indication of which match set we're editing the tree for
-->
<table class="hidden">
+ <tr quality-controls="1">
+ <td>
+ <label for="value-input">Value:</label>
+ </td>
+ <td>
+ <input id="value-input" type="text" fmfield="value" />
+ </td>
+ </tr>
<tr consistent-controls="1">
<td>
<label for="quality-input"
@@ -60,7 +69,7 @@
size="4" maxlength="3" fmfield="quality" />
</td>
</tr>
- <tr consistent-controls="1">
+ <tr point-controls="1">
<td>
<label for="negate-input">Negate?</label>
</td>
@@ -68,14 +77,6 @@
<input id="negate-input" type="checkbox" fmfield="negate" />
</td>
</tr>
- <tr quality-controls="1">
- <td>
- <label for="value-input">Value:</label>
- </td>
- <td>
- <input id="value-input" type="text" fmfield="value" />
- </td>
- </tr>
</table>
<div class="outer">
<div id="expr-preview-row">
@@ -131,6 +132,7 @@
</div>
</div>
<br style="clear: both;" />
+ <table id="qnode-editor-container"></table>
<table jsId="vmsq_grid"
dojoType="openils.widget.AutoGrid"
query="{id: '*'}"
commit da3a453442050482a419deff91d3dc92fdbf132a
Author: berick <berick at esilibrary.com>
Date: Wed May 4 17:15:03 2011 -0400
Best Match w/ quality ratio merging
* Mew Best Match option in merge/overlay
* support for upload time minimum record quality ratio
* We now /only/ create new records if no matches exist and the user
selected a match-free import
* Selecting a match-free import no longer trumps other merge imports.
They both work together now.
TODO: find out why queued record quality is not getting set at queued
rec creation time.
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
index 510d6bf..759a624 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
@@ -708,11 +708,15 @@ sub import_record_list_impl {
my $auto_overlay_exact = $$args{auto_overlay_exact};
my $auto_overlay_1match = $$args{auto_overlay_1match};
+ my $auto_overlay_best = $$args{auto_overlay_best_match};
+ my $match_quality_ratio = $$args{match_quality_ratio};
my $merge_profile = $$args{merge_profile};
my $bib_source = $$args{bib_source};
+ my $import_no_match = $$args{import_no_match};
my $overlay_func = 'vandelay.overlay_bib_record';
my $auto_overlay_func = 'vandelay.auto_overlay_bib_record';
+ my $auto_overlay_best_func = 'vandelay.auto_overlay_bib_record_with_best'; # XXX bib-only
my $retrieve_func = 'retrieve_vandelay_queued_bib_record';
my $update_func = 'update_vandelay_queued_bib_record';
my $search_func = 'search_vandelay_queued_bib_record';
@@ -863,7 +867,39 @@ sub import_record_list_impl {
}
}
- if(!$imported and !$error) {
+ if(!$imported and !$error and $auto_overlay_best and scalar(@{$rec->matches}) > 0 ) {
+
+ # caller says to overlay the best match
+
+ my $res = $e->json_query(
+ {
+ from => [
+ $auto_overlay_best_func,
+ $rec->id,
+ $merge_profile,
+ $match_quality_ratio
+ ]
+ }
+ );
+
+ if($res and ($res = $res->[0])) {
+
+ if($res->{$auto_overlay_best_func} eq 't') {
+ $logger->info("vl: $type auto-overlay-best succeeded for queued rec " . $rec->id);
+ $imported = 1;
+ } else {
+ $report_args{import_error} = 'overlay.record.quality' if $match_quality_ratio > 0;
+ $logger->info("vl: $type auto-overlay-best failed for queued rec " . $rec->id);
+ }
+
+ } else {
+ $error = 1;
+ $logger->error("vl: Error attempting overlay with func=$auto_overlay_best_func, ".
+ "quality_ratio=$match_quality_ratio, profile=$merge_profile, record=$rec_id");
+ }
+ }
+
+ if(!$imported and !$error and $import_no_match and scalar(@{$rec->matches}) == 0) {
# No overlay / merge occurred. Do a traditional record import by creating a new record
diff --git a/Open-ILS/src/sql/Pg/950.data.seed-values.sql b/Open-ILS/src/sql/Pg/950.data.seed-values.sql
index e45999d..0ad9ad0 100644
--- a/Open-ILS/src/sql/Pg/950.data.seed-values.sql
+++ b/Open-ILS/src/sql/Pg/950.data.seed-values.sql
@@ -8667,6 +8667,7 @@ INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'overlay.missin
INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'import.auth.duplicate.acn', oils_i18n_gettext('import.auth.duplicate.acn', 'Import failed due to Accession Number collision', 'vie', 'description') );
INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'import.xml.malformed', oils_i18n_gettext('import.xml.malformed', 'Malformed record cause Import failure', 'vie', 'description') );
INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'overlay.xml.malformed', oils_i18n_gettext('overlay.xml.malformed', 'Malformed record cause Overlay failure', 'vie', 'description') );
+INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'overlay.record.quality', oils_i18n_gettext('overlay.record.quality', 'New record had insufficient quality', 'vie', 'description') );
INSERT INTO config.org_unit_setting_type ( name, label, description, datatype ) VALUES (
'ui.cat.volume_copy_editor.horizontal',
diff --git a/Open-ILS/web/js/ui/default/vandelay/vandelay.js b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
index 5b000b7..4aeef8f 100644
--- a/Open-ILS/web/js/ui/default/vandelay/vandelay.js
+++ b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
@@ -974,7 +974,7 @@ function vlHandleQueueItemsAction(action) {
queueItemsImportDialog.hide();
// hack to set the widgets the import funcs will be looking at. Reset them below.
- vlUploadQueueAutoImport.attr('value', vlUploadQueueAutoImport2.attr('value'));
+ vlUploadQueueImportNoMatch.attr('value', vlUploadQueueImportNoMatch2.attr('value'));
vlUploadQueueAutoOverlayExact.attr('value', vlUploadQueueAutoOverlayExact2.attr('value'));
vlUploadQueueAutoOverlay1Match.attr('value', vlUploadQueueAutoOverlay1Match2.attr('value'));
vlUploadMergeProfile.attr('value', vlUploadMergeProfile2.attr('value'));
@@ -986,8 +986,8 @@ function vlHandleQueueItemsAction(action) {
}
// reset the widgets to prevent accidental future actions
- vlUploadQueueAutoImport.attr('value', false);
- vlUploadQueueAutoImport2.attr('value', false);
+ vlUploadQueueImportNoMatch.attr('value', false);
+ vlUploadQueueImportNoMatch2.attr('value', false);
vlUploadQueueAutoOverlayExact.attr('value', false);
vlUploadQueueAutoOverlayExact2.attr('value', false);
vlUploadQueueAutoOverlay1Match.attr('value', false);
@@ -1054,23 +1054,45 @@ function vlImportAllRecords() {
function(){displayGlobalDiv('vl-queue-div');});
}
-function vlImportRecordQueue(type, queueId, noMatchOnly, onload) {
+function vlImportRecordQueue(type, queueId, onload) {
displayGlobalDiv('vl-generic-progress-with-total');
var method = 'open-ils.vandelay.bib_queue.import';
- if(noMatchOnly)
- method = method.replace('import', 'nomatch.import');
if(type == 'auth')
method = method.replace('bib', 'auth');
+
+ var mergeOpt = false;
var options = {};
+
+ if(vlUploadQueueImportNoMatch.checked) {
+ options.import_no_match = true;
+ vlUploadQueueImportNoMatch.checked = false;
+ }
+
if(vlUploadQueueAutoOverlayExact.checked) {
options.auto_overlay_exact = true;
vlUploadQueueAutoOverlayExact.checked = false;
+ mergeOpt = true;
+ }
+
+ if(vlUploadQueueAutoOverlayBestMatch.checked) {
+ options.auto_overlay_best_match = true;
+ vlUploadQueueAutoOverlayBestMatch.checked = false;
+ options.match_quality_ratio = vlUploadQueueAutoOverlayBestMatchRatio.attr('value');
+ mergeOpt = true;
}
if(vlUploadQueueAutoOverlay1Match.checked) {
options.auto_overlay_1match = true;
vlUploadQueueAutoOverlay1Match.checked = false;
+ mergeOpt = true;
+ }
+
+ if(!mergeOpt) {
+ // in the interest of speed, if no merge options are
+ // chosen, tell the back-end code to only process records
+ // that have no matches
+ method = method.replace('.import', 'nomatch.import');
}
var profile = vlUploadMergeProfile.attr('value');
@@ -1102,16 +1124,19 @@ function batchUpload() {
currentType = dijit.byId('vl-record-type').getValue();
var handleProcessSpool = function() {
- if(vlUploadQueueAutoImport.checked || vlUploadQueueAutoOverlayExact.checked || vlUploadQueueAutoOverlay1Match.checked) {
- var noMatchOnly = !vlUploadQueueAutoOverlayExact.checked && !vlUploadQueueAutoOverlay1Match.checked;
- vlImportRecordQueue(
- currentType,
- currentQueueId,
- noMatchOnly,
- function() {
- retrieveQueuedRecords(currentType, currentQueueId, handleRetrieveRecords);
- }
- );
+ if(
+ vlUploadQueueImportNoMatch.checked ||
+ vlUploadQueueAutoOverlayExact.checked ||
+ vlUploadQueueAutoOverlay1Match.checked ||
+ vlUploadQueueAutoOverlayBestMatch.checked ) {
+
+ vlImportRecordQueue(
+ currentType,
+ currentQueueId,
+ function() {
+ retrieveQueuedRecords(currentType, currentQueueId, handleRetrieveRecords);
+ }
+ );
} else {
retrieveQueuedRecords(currentType, currentQueueId, handleRetrieveRecords);
}
diff --git a/Open-ILS/web/opac/locale/en-US/vandelay.dtd b/Open-ILS/web/opac/locale/en-US/vandelay.dtd
index 48db0a6..d2d1789 100644
--- a/Open-ILS/web/opac/locale/en-US/vandelay.dtd
+++ b/Open-ILS/web/opac/locale/en-US/vandelay.dtd
@@ -6,6 +6,7 @@
<!ENTITY vandelay.auto.import.auto_overlay_1match "Merge/Overlay Single Matches">
<!ENTITY vandelay.auto.import.auto_overlay_best "Merge/Overlay Best Match">
<!ENTITY vandelay.auto.import.auto_overlay_best_ratio "Best Match Minimum Quality Ratio">
+<!ENTITY vandelay.auto.import.auto_overlay_best_ratio.desc "New Record Quaility / Quality of Best Match">
<!ENTITY vandelay.auto.import.merge_profile "Merge/Overlay Profile">
<!ENTITY vandelay.auto.width "Auto Width">
<!ENTITY vandelay.back.to.import.queue "Back To Import Queue">
diff --git a/Open-ILS/web/templates/default/vandelay/inc/matches.tt2 b/Open-ILS/web/templates/default/vandelay/inc/matches.tt2
index 9cccbdb..40d6a80 100644
--- a/Open-ILS/web/templates/default/vandelay/inc/matches.tt2
+++ b/Open-ILS/web/templates/default/vandelay/inc/matches.tt2
@@ -15,7 +15,7 @@
formatter : vlFormatViewMatchMARC
},
{name: 'Match Score', field:'match_score'},
- {name: 'Match Quality', field:'match_quality'},
+ {name: 'Matched Record Quality', field:'match_quality'},
{name: '&vandelay.creator;', get: vlGetCreator},
{name: '&vandelay.create.date;', field:'create_date', get: vlGetDateTimeField},
{name: '&vandelay.last.edit.date;', field:'edit_date', get: vlGetDateTimeField},
diff --git a/Open-ILS/web/templates/default/vandelay/inc/upload.tt2 b/Open-ILS/web/templates/default/vandelay/inc/upload.tt2
index 8462ebc..f742104 100644
--- a/Open-ILS/web/templates/default/vandelay/inc/upload.tt2
+++ b/Open-ILS/web/templates/default/vandelay/inc/upload.tt2
@@ -54,7 +54,7 @@
<tr>
<td>&vandelay.auto.import.noncolliding;</td>
<td colspan='4'>
- <input jsId='vlUploadQueueAutoImport' dojoType='dijit.form.CheckBox'/>
+ <input jsId='vlUploadQueueImportNoMatch' dojoType='dijit.form.CheckBox'/>
</td>
</tr>
<tr>
@@ -75,7 +75,10 @@
</tr>
<tr>
<td>&vandelay.auto.import.auto_overlay_best_ratio;</td>
- <td colspan='4'><input style='width:3em' value='0.0' jsId='vlUploadQueueAutoOverlayBestMatchRatio' dojoType='dijit.form.TextBox'/></td>
+ <td colspan='4'>
+ <input style='width:3em' value='0.0' jsId='vlUploadQueueAutoOverlayBestMatchRatio' dojoType='dijit.form.TextBox'/>
+ <span style='padding-left: 10px; font-size:90%'>(&vandelay.auto.import.auto_overlay_best_ratio.desc;)</span>
+ </td>
</tr>
<tr><td colspan='2' style='border-bottom:1px solid #888'></td></tr>
commit 9e9c1c3b6ab1c85e803f7611a38cfd4a9113e027
Author: senator <lebbeous at esilibrary.com>
Date: Wed May 4 16:41:20 2011 -0400
working in quality metric editor
diff --git a/Open-ILS/examples/fm_IDL.xml b/Open-ILS/examples/fm_IDL.xml
index 8aa6685..f7ad9e3 100644
--- a/Open-ILS/examples/fm_IDL.xml
+++ b/Open-ILS/examples/fm_IDL.xml
@@ -588,11 +588,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
<fields oils_persist:primary="id" oils_persist:sequence="vandelay.match_set_quality_id_seq">
<field reporter:label="Quality Metric ID" name="id" reporter:datatype="id"/>
<field reporter:label="Match Set" name="match_set" reporter:datatype="link"/>
- <field reporter:label="Coded Field" name="svf" reporter:datatype="text"/>
+ <field reporter:label="Record Attribute" name="svf" reporter:datatype="text"/>
<field reporter:label="Tag" name="tag" reporter:datatype="text"/>
<field reporter:label="Subfield" name="subfield" reporter:datatype="text"/>
<field reporter:label="Value" name="value" reporter:datatype="text"/>
- <field reporter:label="Importance" name="quality" reporter:datatype="int"/>
+ <field reporter:label="Quality" name="quality" reporter:datatype="int"/>
</fields>
<links>
<link field="match_set" reltype="has_a" key="id" map="" class="vms"/>
diff --git a/Open-ILS/web/js/ui/default/conify/global/vandelay/match_set.js b/Open-ILS/web/js/ui/default/conify/global/vandelay/match_set.js
index 5128bd2..e07eeca 100644
--- a/Open-ILS/web/js/ui/default/conify/global/vandelay/match_set.js
+++ b/Open-ILS/web/js/ui/default/conify/global/vandelay/match_set.js
@@ -9,25 +9,64 @@ dojo.require("openils.User");
dojo.require("openils.Util");
dojo.require("openils.PermaCrud");
dojo.require("openils.widget.ProgressDialog");
+dojo.require("openils.widget.AutoGrid");
var localeStrings, node_editor, _crads, CGI, tree, match_set;
-function _find_crad_by_name(name) {
- for (var i = 0; i < _crads.length; i++) {
- if (_crads[i].name() == name)
- return _crads[i];
- }
- return null;
-}
+var NodeEditorAbstract = {
+ "_svf_select_template": null,
+ "_simple_value_getter": function(control) {
+ if (typeof control.selectedIndex != "undefined")
+ return control.options[control.selectedIndex].value;
+ else if (dojo.attr(control, "type") == "checkbox")
+ return control.checked;
+ else
+ return control.value;
+ },
+ "is_sensible": function(thing) {
+ var need_one = 0;
+ var list = openils.Util.objectProperties(this._factories_by_type);
+ console.log(list.join(" "));
+ openils.Util.objectProperties(this._factories_by_type).forEach(
+ function(field) { if (thing[field]()) need_one++; }
+ );
-function NodeEditor() {
- var self = this;
+ if (need_one != 1) {
+ alert(localeStrings.POINT_NEEDS_ONE);
+ return false;
+ }
+
+ if (thing.tag()) {
+ if (
+ !thing.tag().match(/^\d{3}$/) ||
+ thing.subfield().length != 1 ||
+ !thing.subfield().match(/\S/) ||
+ thing.subfield().charCodeAt(0) < 32
+ ) {
+ alert(localeStrings.FAULTY_MARC);
+ return false;
+ }
+ }
- var _svf_select_template = null;
- var _factories_by_type = {
+ return true;
+ },
+ "_add_consistent_controls": function(tgt) {
+ if (!this._consistent_controls) {
+ var trs = dojo.query(this._consistent_controls_query);
+ this._consistent_controls = [];
+ for (var i = 0; i < trs.length; i++)
+ this._consistent_controls[i] = dojo.clone(trs[i]);
+ dojo.empty(trs[0].parentNode);
+ }
+
+ this._consistent_controls.forEach(
+ function(node) { dojo.place(dojo.clone(node), tgt); }
+ );
+ },
+ "_factories_by_type": {
"svf": function() {
- if (!_svf_select_template) {
- _svf_select_template = dojo.create(
+ if (!self._svf_select_template) {
+ self._svf_select_template = dojo.create(
"select", {"fmfield": "svf"}
);
for (var i=0; i<_crads.length; i++) {
@@ -35,12 +74,12 @@ function NodeEditor() {
"option", {
"value": _crads[i].name(),
"innerHTML": _crads[i].label()
- }, _svf_select_template
+ }, self._svf_select_template
);
}
}
- var select = dojo.clone(_svf_select_template);
+ var select = dojo.clone(self._svf_select_template);
dojo.attr(select, "id", "svf-select");
var label = dojo.create(
"label", {
@@ -85,72 +124,104 @@ function NodeEditor() {
}, dojo.create("td", null, rows[1])
);
return rows;
- },
- "bool_op": function() {
- var tr = dojo.create("tr");
- dojo.create(
- "label",
- {"for": "operator-select", "innerHTML": "Operator:"},
- dojo.create("td", null, tr)
- );
- var select = dojo.create(
- "select", {"fmfield": "bool_op", "id": "operator-select"},
- dojo.create("td", null, tr)
- );
- dojo.create("option", {"value": "AND", "innerHTML": "AND"}, select);
- dojo.create("option", {"value": "OR", "innerHTML": "OR"}, select);
-
- return [tr];
}
- };
+ }
+};
- function _simple_value_getter(control) {
- if (typeof control.selectedIndex != "undefined")
- return control.options[control.selectedIndex].value;
- else if (dojo.attr(control, "type") == "checkbox")
- return control.checked;
- else
- return control.value;
- };
+function _find_crad_by_name(name) {
+ for (var i = 0; i < _crads.length; i++) {
+ if (_crads[i].name() == name)
+ return _crads[i];
+ }
+ return null;
+}
- this._init = function(dnd_source, node_editor_container) {
+function QualityNodeEditor() {
+ var self = this;
+
+ this._init = function(dnd_source, qnode_editor_container) {
+ this._consistent_controls_query =
+ "[consistent-controls], [quality-controls]";
this.dnd_source = dnd_source;
- this.node_editor_container = dojo.byId(node_editor_container);
+ this.qnode_editor_container = dojo.byId(qnode_editor_container);
};
this.clear = function() {
this.dnd_source.selectAll().deleteSelectedNodes();
dojo.create(
"em", {"innerHTML": localeStrings.WORKING_MP_HERE},
- this.node_editor_container, "only"
+ this.qnode_editor_container, "only"
);
this.dnd_source._ready = false;
};
- this.is_sensible = function(mp) {
- var need_one = 0;
- ["tag", "svf", "bool_op"].forEach(
- function(field) { if (mp[field]()) need_one++; }
+ this.build_vmsq = function() {
+ var metric = new vmsq();
+ var controls = dojo.query("[fmfield]", this.qnode_editor_container);
+ for (var i = 0; i < controls.length; i++) {
+ var field = dojo.attr(controls[i], "fmfield");
+ var value = this._simple_value_getter(controls[i]);
+ metric[field](value);
+ }
+
+ if (!this.is_sensible(metric)) return null; /* will alert() */
+ else return metric;
+ };
+
+ this.add = function(type) {
+ this.clear();
+
+
+ /* these are the editing widgets */
+ var table = dojo.create("table", {"className": "node-editor"});
+
+ var nodes = this._factories_by_type[type]();
+ for (var i = 0; i < nodes.length; i++) dojo.place(nodes[i], table);
+
+ this._add_consistent_controls(table);
+
+ dojo.create(
+ "input", {
+ "type": "submit", "value": localeStrings.OK,
+ "onclick": function() { alert("would update draggable here"/* XXX TODO */); }
+ }, dojo.create(
+ "td", {"colspan": 2, "align": "center"},
+ dojo.create("tr", null, table)
+ )
);
- if (need_one != 1) {
- alert(localeStrings.POINT_NEEDS_ONE);
- return false;
- }
+ dojo.place(table, this.qnode_editor_container, "only");/* XXX put in dialog here */
- if (mp.tag()) {
- if (
- !mp.tag().match(/^\d{3}$/) ||
- mp.subfield().length != 1 ||
- !mp.subfield().match(/\S/) ||
- mp.subfield().charCodeAt(0) < 32
- ) {
- alert(localeStrings.FAULTY_MARC);
- return false;
- }
- }
+ //this.dnd_source.insertNodes(false, [draggable]);
- return true;
+ /* nice */
+ try { dojo.query("select, input", table)[0].focus(); }
+ catch(E) { console.log(String(E)); }
+
+ };
+
+ openils.Util.objectProperties(NodeEditorAbstract).forEach(
+ function(m) { self[m] = NodeEditorAbstract[m]; }
+ );
+ this._init.apply(this, arguments);
+}
+
+function NodeEditor() {
+ var self = this;
+
+ this._init = function(dnd_source, node_editor_container) {
+ this._consistent_controls_query = "[consistent-controls]";
+ this.dnd_source = dnd_source;
+ this.node_editor_container = dojo.byId(node_editor_container);
+ };
+
+ this.clear = function() {
+ this.dnd_source.selectAll().deleteSelectedNodes();
+ dojo.create(
+ "em", {"innerHTML": localeStrings.WORKING_MP_HERE},
+ this.node_editor_container, "only"
+ );
+ this.dnd_source._ready = false;
};
this.build_vmsp = function() {
@@ -158,7 +229,7 @@ function NodeEditor() {
var controls = dojo.query("[fmfield]", this.node_editor_container);
for (var i = 0; i < controls.length; i++) {
var field = dojo.attr(controls[i], "fmfield");
- var value = _simple_value_getter(controls[i]);
+ var value = this._simple_value_getter(controls[i]);
match_point[field](value);
}
@@ -176,20 +247,6 @@ function NodeEditor() {
this.dnd_source._ready = true;
};
- this._add_consistent_controls = function(tgt) {
- if (!this._consistent_controls) {
- var trs = dojo.query("[consistent-controls]");
- this._consistent_controls = [];
- for (var i = 0; i < trs.length; i++)
- this._consistent_controls[i] = dojo.clone(trs[i]);
- dojo.empty(trs[0].parentNode);
- }
-
- this._consistent_controls.forEach(
- function(node) { dojo.place(dojo.clone(node), tgt); }
- );
- };
-
this.add = function(type) {
this.clear();
@@ -202,7 +259,7 @@ function NodeEditor() {
/* these are the editing widgets */
var table = dojo.create("table", {"className": "node-editor"});
- var nodes = _factories_by_type[type]();
+ var nodes = this._factories_by_type[type]();
for (var i = 0; i < nodes.length; i++) dojo.place(nodes[i], table);
if (type != "bool_op")
@@ -228,6 +285,26 @@ function NodeEditor() {
};
+ openils.Util.objectProperties(NodeEditorAbstract).forEach(
+ function(m) { self[m] = NodeEditorAbstract[m]; }
+ );
+
+ this._factories_by_type.bool_op = function() {
+ var tr = dojo.create("tr");
+ dojo.create(
+ "label",
+ {"for": "operator-select", "innerHTML": "Operator:"},
+ dojo.create("td", null, tr)
+ );
+ var select = dojo.create(
+ "select", {"fmfield": "bool_op", "id": "operator-select"},
+ dojo.create("td", null, tr)
+ );
+ dojo.create("option", {"value": "AND", "innerHTML": "AND"}, select);
+ dojo.create("option", {"value": "OR", "innerHTML": "OR"}, select);
+
+ return [tr];
+ };
this._init.apply(this, arguments);
}
@@ -401,6 +478,14 @@ function save_tree() {
}
);
}
+
+function init_vmsq_grid() {
+ vmsq_grid.loadAll(
+ {"order_by": {"vmsq": "quality"}},
+ {"match_set": CGI.param("match_set")}
+ );
+}
+
function my_init() {
progress_dialog.show(true);
@@ -473,6 +558,9 @@ function my_init() {
redraw_expression_preview();
node_editor.clear();
+
+ init_vmsq_grid();
+
progress_dialog.hide();
}
diff --git a/Open-ILS/web/templates/default/conify/global/vandelay/match_set_tree.tt2 b/Open-ILS/web/templates/default/conify/global/vandelay/match_set_tree.tt2
index 4290e0b..7a11223 100644
--- a/Open-ILS/web/templates/default/conify/global/vandelay/match_set_tree.tt2
+++ b/Open-ILS/web/templates/default/conify/global/vandelay/match_set_tree.tt2
@@ -68,6 +68,14 @@
<input id="negate-input" type="checkbox" fmfield="negate" />
</td>
</tr>
+ <tr quality-controls="1">
+ <td>
+ <label for="value-input">Value:</label>
+ </td>
+ <td>
+ <input id="value-input" type="text" fmfield="value" />
+ </td>
+ </tr>
</table>
<div class="outer">
<div id="expr-preview-row">
@@ -102,8 +110,37 @@
</div>
</div>
<div id="submit-row">
- <hr />
- <button onclick="save_tree()">Save Changes</button>
+ <button onclick="save_tree()">Save Changes To Expression</button>
+</div>
+<hr />
+<div id="quality-editor-wrapper">
+ <div>
+ <div style="float: left; width: 50%;">
+ <big>Quality Metrics for this Match Set</big>
+ </div>
+ <div style="float: right; width: 49%; text-align: right;">
+ <button onclick="qnode_editor.add('svf')">
+ Record Attribute
+ </button>
+ <button onclick="qnode_editor.add('tag')">
+ MARC Tag and Subfield
+ </button>
+ <button onclick="vmsq_grid.deleteSelected()">
+ Delete Selected Metrics
+ </button>
+ </div>
+ </div>
+ <br style="clear: both;" />
+ <table jsId="vmsq_grid"
+ dojoType="openils.widget.AutoGrid"
+ query="{id: '*'}"
+ defaultCellWidth="'17%'"
+ fmClass="vmsq"
+ fieldOrder="['quality','svf','tag','subfield','value']"
+ suppressFields="['match_set']"
+ showPaginator="true"
+ editOnEnter="false">
+ </table>
</div>
<div jsId="progress_dialog" dojoType="openils.widget.ProgressDialog"></div>
<script type="text/javascript"
commit aa4fbb88b33a5b8f55295605caecf4841cfbb05a
Author: berick <berick at esilibrary.com>
Date: Wed May 4 15:58:37 2011 -0400
grab attr value from vandelay.extract_rec_attrs hstore to compare to configured value
diff --git a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
index 4082296..cc02d17 100644
--- a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
+++ b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
@@ -736,7 +736,7 @@ BEGIN
END IF;
END LOOP;
ELSE
- IF test.value = vandelay.extract_rec_attrs(xml, ARRAY[test.svf]) THEN
+ IF test.value = vandelay.extract_rec_attrs(xml, ARRAY[test.svf]) -> test.svf THEN
out_q := out_q + test.quality;
END IF;
END IF;
commit 5a13cc0b51f5d5a96a125beac16bf587c6189701
Author: berick <berick at esilibrary.com>
Date: Wed May 4 15:45:55 2011 -0400
repaired copy/paste error in match_bib_record
diff --git a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
index 8c18550..4082296 100644
--- a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
+++ b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
@@ -689,7 +689,7 @@ BEGIN
SELECT * INTO my_bib_queue FROM vandelay.bib_queue WHERE id = NEW.queue;
- NEW.quality := vandelay.measure_record_quality( b.marc, my_bib_queue.match_set );
+ NEW.quality := vandelay.measure_record_quality( NEW.marc, my_bib_queue.match_set );
-- Perfect matches on 901$c exit early with a match with high quality.
incoming_existing_id :=
commit b212468779aa74dd719cb9ac614919c749927260
Author: Mike Rylander <mrylander at gmail.com>
Date: Wed May 4 15:44:19 2011 -0400
Allow different quality measures for different values on the same tag+sf/svf
diff --git a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
index b5d72df..8c18550 100644
--- a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
+++ b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
@@ -42,7 +42,7 @@ CREATE TABLE vandelay.match_set_quality (
CONSTRAINT vmsq_need_a_subfield_with_a_tag CHECK ((tag IS NOT NULL AND subfield IS NOT NULL) OR tag IS NULL),
CONSTRAINT vmsq_need_a_tag_or_a_ff CHECK ((tag IS NOT NULL AND svf IS NULL) OR (tag IS NULL AND svf IS NOT NULL))
);
-CREATE UNIQUE INDEX vmsq_def_once_per_set ON vandelay.match_set_quality (match_set, COALESCE(tag,''), COALESCE(subfield,''), COALESCE(svf,''));
+CREATE UNIQUE INDEX vmsq_def_once_per_set ON vandelay.match_set_quality (match_set, COALESCE(tag,''), COALESCE(subfield,''), COALESCE(svf,''), value);
CREATE TABLE vandelay.queue (
commit 45cf5cbebb15792d0439346d857e0a85aee7200d
Author: Mike Rylander <mrylander at gmail.com>
Date: Wed May 4 14:43:59 2011 -0400
Save incumbent record quality in bib_match.quality, incoming in queued_record.quality
diff --git a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
index c18fe36..b5d72df 100644
--- a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
+++ b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
@@ -143,7 +143,7 @@ CREATE TABLE vandelay.bib_match (
id BIGSERIAL PRIMARY KEY,
queued_record BIGINT REFERENCES vandelay.queued_bib_record (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
eg_record BIGINT REFERENCES biblio.record_entry (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
- quality INT NOT NULL DEFAULT 0,
+ quality INT NOT NULL DEFAULT 1,
match_score INT NOT NULL DEFAULT 0
);
@@ -687,6 +687,10 @@ BEGIN
DELETE FROM vandelay.bib_match WHERE queued_record = NEW.id;
+ SELECT * INTO my_bib_queue FROM vandelay.bib_queue WHERE id = NEW.queue;
+
+ NEW.quality := vandelay.measure_record_quality( b.marc, my_bib_queue.match_set );
+
-- Perfect matches on 901$c exit early with a match with high quality.
incoming_existing_id :=
oils_xpath_string('//*[@tag="901"]/*[@code="c"][1]', NEW.marc);
@@ -699,17 +703,17 @@ BEGIN
END IF;
END IF;
- SELECT * INTO my_bib_queue FROM vandelay.bib_queue WHERE id = NEW.queue;
FOR test_result IN SELECT * FROM
vandelay.match_set_test_marcxml(my_bib_queue.match_set, NEW.marc) LOOP
- INSERT INTO vandelay.bib_match (
- queued_record, eg_record, match_score, quality
- ) VALUES (
- NEW.id, test_result.record,
- test_result.quality, vandelay.incoming_record_quality(NEW.marc, my_bib_queue.match_set)
- );
+ INSERT INTO vandelay.bib_match ( queued_record, eg_record, match_score, quality )
+ SELECT NEW.id,
+ test_result.record,
+ test_result.quality,
+ vandelay.measure_record_quality( b.marc, my_bib_queue.match_set )
+ FROM biblio.record_entry b
+ WHERE id = test_result.record;
END LOOP;
@@ -717,7 +721,7 @@ BEGIN
END;
$func$ LANGUAGE PLPGSQL;
-CREATE OR REPLACE FUNCTION vandelay.incoming_record_quality ( xml TEXT, match_set_id INT ) RETURNS INT AS $_$
+CREATE OR REPLACE FUNCTION vandelay.measure_record_quality ( xml TEXT, match_set_id INT ) RETURNS INT AS $_$
DECLARE
out_q INT := 0;
rvalue TEXT;
@@ -1283,14 +1287,13 @@ BEGIN
END;
$$ LANGUAGE PLPGSQL;
-CREATE OR REPLACE FUNCTION vandelay.auto_overlay_bib_record_with_best ( import_id BIGINT, merge_profile_id INT, lwm_ratio_value NUMERIC ) RETURNS BOOL AS $$
+CREATE OR REPLACE FUNCTION vandelay.auto_overlay_bib_record_with_best ( import_id BIGINT, merge_profile_id INT, lwm_ratio_value_p NUMERIC ) RETURNS BOOL AS $$
DECLARE
eg_id BIGINT;
+ lwm_ratio_value NUMERIC;
BEGIN
- IF lwm_ratio_value IS NULL THEN
- lwm_ratio_value := 0.0;
- END IF;
+ lwm_ratio_value := COALESCE(lwm_ratio_value_p, 0.0);
PERFORM * FROM vandelay.queued_bib_record WHERE import_time IS NOT NULL AND id = import_id;
@@ -1305,9 +1308,9 @@ BEGIN
JOIN vandelay.bib_queue q ON (qr.queue = q.id)
JOIN biblio.record_entry r ON (r.id = m.eg_record)
WHERE m.queued_record = import_id
- AND m.quality::NUMERIC / COALESCE(NULLIF(vandelay.incoming_record_quality(r.marc, q.match_set),0),1)::NUMERIC >= lwm_ratio_value
+ AND qr.quality::NUMERIC / COALESCE(NULLIF(m.quality,0),1)::NUMERIC >= lwm_ratio_value
ORDER BY m.match_score DESC, -- required match score
- m.quality::NUMERIC / COALESCE(NULLIF(vandelay.incoming_record_quality(r.marc, q.match_set),0),1)::NUMERIC DESC, -- quality tie breaker
+ qr.quality::NUMERIC / COALESCE(NULLIF(m.quality,0),1)::NUMERIC DESC, -- quality tie breaker
m.id -- when in doubt, use the first match
LIMIT 1;
commit 1395a488c2db041cffc9558d48c2beaef276845a
Author: berick <berick at esilibrary.com>
Date: Wed May 4 14:37:25 2011 -0400
initial support for selecting merge-on-best-match and setting minimum quality ratio
diff --git a/Open-ILS/web/opac/locale/en-US/vandelay.dtd b/Open-ILS/web/opac/locale/en-US/vandelay.dtd
index a97639f..48db0a6 100644
--- a/Open-ILS/web/opac/locale/en-US/vandelay.dtd
+++ b/Open-ILS/web/opac/locale/en-US/vandelay.dtd
@@ -1,9 +1,11 @@
<!ENTITY vandelay.add.existing.queue "or Add to an Existing Queue">
<!ENTITY vandelay.auth.attrs "Authority attributes">
<!ENTITY vandelay.auth.records "Authority Records">
-<!ENTITY vandelay.auto.import.noncolliding "Auto-Import Non-Colliding Records">
-<!ENTITY vandelay.auto.import.auto_overlay_exact "Auto Merge/Overlay Exact Matches">
-<!ENTITY vandelay.auto.import.auto_overlay_1match "Auto Merge/Overlay When Exactly 1 Match is Found">
+<!ENTITY vandelay.auto.import.noncolliding "Import Non-Colliding Records">
+<!ENTITY vandelay.auto.import.auto_overlay_exact "Merge/Overlay Exact Matches (901c)">
+<!ENTITY vandelay.auto.import.auto_overlay_1match "Merge/Overlay Single Matches">
+<!ENTITY vandelay.auto.import.auto_overlay_best "Merge/Overlay Best Match">
+<!ENTITY vandelay.auto.import.auto_overlay_best_ratio "Best Match Minimum Quality Ratio">
<!ENTITY vandelay.auto.import.merge_profile "Merge/Overlay Profile">
<!ENTITY vandelay.auto.width "Auto Width">
<!ENTITY vandelay.back.to.import.queue "Back To Import Queue">
diff --git a/Open-ILS/web/templates/default/vandelay/inc/upload.tt2 b/Open-ILS/web/templates/default/vandelay/inc/upload.tt2
index 909670e..8462ebc 100644
--- a/Open-ILS/web/templates/default/vandelay/inc/upload.tt2
+++ b/Open-ILS/web/templates/default/vandelay/inc/upload.tt2
@@ -69,6 +69,15 @@
<input jsId='vlUploadQueueAutoOverlay1Match' dojoType='dijit.form.CheckBox'/>
</td>
</tr>
+ <tr>
+ <td>&vandelay.auto.import.auto_overlay_best;</td>
+ <td colspan='4'><input jsId='vlUploadQueueAutoOverlayBestMatch' dojoType='dijit.form.CheckBox'/></td>
+ </tr>
+ <tr>
+ <td>&vandelay.auto.import.auto_overlay_best_ratio;</td>
+ <td colspan='4'><input style='width:3em' value='0.0' jsId='vlUploadQueueAutoOverlayBestMatchRatio' dojoType='dijit.form.TextBox'/></td>
+ </tr>
+
<tr><td colspan='2' style='border-bottom:1px solid #888'></td></tr>
<tr>
<td colspan='5'>
commit 054ac72165d347166553d3b0987d1442c194ee2d
Author: berick <berick at esilibrary.com>
Date: Wed May 4 13:14:38 2011 -0400
show match score/quality in VL record match grid
diff --git a/Open-ILS/web/js/ui/default/vandelay/vandelay.js b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
index bb6ce0c..5b000b7 100644
--- a/Open-ILS/web/js/ui/default/vandelay/vandelay.js
+++ b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
@@ -464,26 +464,24 @@ function vlLoadMatchUI(recId) {
// build the data store of records with match information
var dataStore = bre.toStoreData(recs, null,
- {virtualFields:['_id']});
+ {virtualFields:['_id', 'match_score', 'match_quality']});
dataStore.identifier = '_id';
var matchSeenMap = {};
- // XXX much of this is no longer needed with changes to match_set
for(var i = 0; i < dataStore.items.length; i++) {
var item = dataStore.items[i];
item._id = i; // just need something unique
- /*
for(var j = 0; j < matches.length; j++) {
var match = matches[j];
if(match.eg_record() == item.id && !matchSeenMap[match.id()]) {
- var attr = getRecAttrFromMatch(queuedRecordsMap[recId], match);
- item.src_matchpoint = getRecAttrDefFromAttr(attr, currentType).code();
+ if(match.match_score)
+ item.match_score = match.match_score();
+ item.match_quality = match.quality();
matchSeenMap[match.id()] = 1;
break;
}
}
- */
}
// now populate the grid
diff --git a/Open-ILS/web/templates/default/vandelay/inc/matches.tt2 b/Open-ILS/web/templates/default/vandelay/inc/matches.tt2
index 39f8261..9cccbdb 100644
--- a/Open-ILS/web/templates/default/vandelay/inc/matches.tt2
+++ b/Open-ILS/web/templates/default/vandelay/inc/matches.tt2
@@ -14,6 +14,8 @@
get: vlGetViewMARC,
formatter : vlFormatViewMatchMARC
},
+ {name: 'Match Score', field:'match_score'},
+ {name: 'Match Quality', field:'match_quality'},
{name: '&vandelay.creator;', get: vlGetCreator},
{name: '&vandelay.create.date;', field:'create_date', get: vlGetDateTimeField},
{name: '&vandelay.last.edit.date;', field:'edit_date', get: vlGetDateTimeField},
commit d856654f61afd4c674440c2d2b068336c3d5dfbd
Author: berick <berick at esilibrary.com>
Date: Wed May 4 13:14:01 2011 -0400
added missing bib_match.match_score field to IDL
diff --git a/Open-ILS/examples/fm_IDL.xml b/Open-ILS/examples/fm_IDL.xml
index 068403d..8aa6685 100644
--- a/Open-ILS/examples/fm_IDL.xml
+++ b/Open-ILS/examples/fm_IDL.xml
@@ -394,6 +394,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
<field reporter:label="Queued Record" name="queued_record" reporter:datatype="link"/>
<field reporter:label="Evergreen Record" name="eg_record" reporter:datatype="link"/>
<field reporter:label="Quality" name="quality" reporter:datatype="text"/>
+ <field reporter:label="Match Score" name="match_score" reporter:datatype="text"/>
</fields>
<links>
<link field="queued_record" reltype="has_a" key="id" map="" class="vqbr"/>
commit 76699369880f251fa0aae5f936642e53cb658a92
Author: berick <berick at esilibrary.com>
Date: Wed May 4 12:03:22 2011 -0400
slight mods to vandelay match set page to sync w/ updated bib/auth match table layout
diff --git a/Open-ILS/web/js/ui/default/vandelay/vandelay.js b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
index ad93a3c..bb6ce0c 100644
--- a/Open-ILS/web/js/ui/default/vandelay/vandelay.js
+++ b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
@@ -444,7 +444,7 @@ function vlLoadMatchUI(recId) {
var params = [records];
if(currentType == 'auth') {
retrieve = ['open-ils.cat', 'open-ils.cat.authority.record.retrieve'];
- parmas = [authtoken, records, {clear_marc:1}];
+ params = [authtoken, records, {clear_marc:1}];
}
fieldmapper.standardRequest(
@@ -464,24 +464,26 @@ function vlLoadMatchUI(recId) {
// build the data store of records with match information
var dataStore = bre.toStoreData(recs, null,
- {virtualFields:['dest_matchpoint', 'src_matchpoint', '_id']});
+ {virtualFields:['_id']});
dataStore.identifier = '_id';
var matchSeenMap = {};
+ // XXX much of this is no longer needed with changes to match_set
for(var i = 0; i < dataStore.items.length; i++) {
var item = dataStore.items[i];
item._id = i; // just need something unique
+ /*
for(var j = 0; j < matches.length; j++) {
var match = matches[j];
if(match.eg_record() == item.id && !matchSeenMap[match.id()]) {
- item.dest_matchpoint = match.field_type();
var attr = getRecAttrFromMatch(queuedRecordsMap[recId], match);
item.src_matchpoint = getRecAttrDefFromAttr(attr, currentType).code();
matchSeenMap[match.id()] = 1;
break;
}
}
+ */
}
// now populate the grid
@@ -554,6 +556,7 @@ function getRecMatchesFromAttrCode(rec, attrCode) {
}
*/
+/*
function getRecAttrFromMatch(rec, match) {
for(var i = 0; i < rec.attributes().length; i++) {
var attr = rec.attributes()[i];
@@ -561,6 +564,7 @@ function getRecAttrFromMatch(rec, match) {
return attr;
}
}
+*/
function getRecAttrDefFromAttr(attr, type) {
var defs = (type == 'bib') ? bibAttrDefs : authAttrDefs;
diff --git a/Open-ILS/web/templates/default/vandelay/inc/matches.tt2 b/Open-ILS/web/templates/default/vandelay/inc/matches.tt2
index 90f3546..39f8261 100644
--- a/Open-ILS/web/templates/default/vandelay/inc/matches.tt2
+++ b/Open-ILS/web/templates/default/vandelay/inc/matches.tt2
@@ -8,13 +8,7 @@
name: '&vandelay.overlay.target;',
get: vlGetOverlayTargetSelector,
formatter : vlFormatOverlayTargetSelector,
- /*
- value: '<input type="checkbox" name="vl-overlay-target-RECID" '+
- 'onclick="vlHandleOverlayTargetSelected(ID, GRIDID);" gridid="GRIDID" match="ID"/>'
- */
},
- {name:'&vandelay.source.match.point;', field:'src_matchpoint'},
- {name:'&vandelay.dest.match.point;', field:'dest_matchpoint'},
{name: '&vandelay.id;', field:'id'},
{ name: '&vandelay.view.marc;',
get: vlGetViewMARC,
commit 9af9f804e7e272845b0dce09d98c1f88f0097670
Author: Mike Rylander <mrylander at gmail.com>
Date: Wed May 4 11:52:31 2011 -0400
Give authority flattening the same treatment as biblio flattening
diff --git a/Open-ILS/src/sql/Pg/030.schema.metabib.sql b/Open-ILS/src/sql/Pg/030.schema.metabib.sql
index 22bc674..9f00d0c 100644
--- a/Open-ILS/src/sql/Pg/030.schema.metabib.sql
+++ b/Open-ILS/src/sql/Pg/030.schema.metabib.sql
@@ -409,6 +409,27 @@ CREATE OR REPLACE FUNCTION biblio.extract_metabib_field_entry ( BIGINT ) RETURNS
SELECT * FROM biblio.extract_metabib_field_entry($1, ' ');
$func$ LANGUAGE SQL;
+CREATE OR REPLACE FUNCTION authority.flatten_marc ( rid BIGINT ) RETURNS SETOF authority.full_rec AS $func$
+DECLARE
+ auth authority.record_entry%ROWTYPE;
+ output authority.full_rec%ROWTYPE;
+ field RECORD;
+BEGIN
+ SELECT INTO auth * FROM authority.record_entry WHERE id = rid;
+
+ FOR field IN SELECT * FROM vandelay.flatten_marc( auth.marc ) LOOP
+ output.record := rid;
+ output.ind1 := field.ind1;
+ output.ind2 := field.ind2;
+ output.tag := field.tag;
+ output.subfield := field.subfield;
+ output.value := field.value;
+
+ RETURN NEXT output;
+ END LOOP;
+END;
+$func$ LANGUAGE PLPGSQL;
+
CREATE OR REPLACE FUNCTION biblio.flatten_marc ( rid BIGINT ) RETURNS SETOF metabib.full_rec AS $func$
DECLARE
bib biblio.record_entry%ROWTYPE;
diff --git a/Open-ILS/src/sql/Pg/999.functions.global.sql b/Open-ILS/src/sql/Pg/999.functions.global.sql
index 66532cb..0152417 100644
--- a/Open-ILS/src/sql/Pg/999.functions.global.sql
+++ b/Open-ILS/src/sql/Pg/999.functions.global.sql
@@ -1378,67 +1378,6 @@ CREATE OR REPLACE FUNCTION authority.propagate_changes (aid BIGINT) RETURNS SETO
SELECT authority.propagate_changes( authority, bib ) FROM authority.bib_linking WHERE authority = $1;
$func$ LANGUAGE SQL;
-CREATE OR REPLACE FUNCTION authority.flatten_marc ( TEXT ) RETURNS SETOF authority.full_rec AS $func$
-
-use MARC::Record;
-use MARC::File::XML (BinaryEncoding => 'UTF-8');
-use MARC::Charset;
-
-MARC::Charset->assume_unicode(1);
-
-my $xml = shift;
-my $r = MARC::Record->new_from_xml( $xml );
-
-return_next( { tag => 'LDR', value => $r->leader } );
-
-for my $f ( $r->fields ) {
- if ($f->is_control_field) {
- return_next({ tag => $f->tag, value => $f->data });
- } else {
- for my $s ($f->subfields) {
- return_next({
- tag => $f->tag,
- ind1 => $f->indicator(1),
- ind2 => $f->indicator(2),
- subfield => $s->[0],
- value => $s->[1]
- });
-
- }
- }
-}
-
-return undef;
-
-$func$ LANGUAGE PLPERLU;
-
-CREATE OR REPLACE FUNCTION authority.flatten_marc ( rid BIGINT ) RETURNS SETOF authority.full_rec AS $func$
-DECLARE
- auth authority.record_entry%ROWTYPE;
- output authority.full_rec%ROWTYPE;
- field RECORD;
-BEGIN
- SELECT INTO auth * FROM authority.record_entry WHERE id = rid;
-
- FOR field IN SELECT * FROM authority.flatten_marc( auth.marc ) LOOP
- output.record := rid;
- output.ind1 := field.ind1;
- output.ind2 := field.ind2;
- output.tag := field.tag;
- output.subfield := field.subfield;
- IF field.subfield IS NOT NULL THEN
- output.value := naco_normalize(field.value, field.subfield);
- ELSE
- output.value := field.value;
- END IF;
-
- CONTINUE WHEN output.value IS NULL;
-
- RETURN NEXT output;
- END LOOP;
-END;
-$func$ LANGUAGE PLPGSQL;
-
-- authority.rec_descriptor appears to be unused currently
CREATE OR REPLACE FUNCTION authority.reingest_authority_rec_descriptor( auth_id BIGINT ) RETURNS VOID AS $func$
BEGIN
commit 5c858d48ef21bb7ed74697b209120faf88c5fcef
Author: Mike Rylander <mrylander at gmail.com>
Date: Wed May 4 11:08:13 2011 -0400
Only ingest bibs and items and run matches /before/ we import a bib
diff --git a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
index 88de9d7..c18fe36 100644
--- a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
+++ b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
@@ -681,6 +681,10 @@ DECLARE
test_result vandelay.match_set_test_result%ROWTYPE;
tmp_rec BIGINT;
BEGIN
+ IF TG_OP IN ('INSERT','UPDATE') AND NEW.imported_as IS NOT NULL THEN
+ RETURN NEW;
+ END IF;
+
DELETE FROM vandelay.bib_match WHERE queued_record = NEW.id;
-- Perfect matches on 901$c exit early with a match with high quality.
@@ -1669,6 +1673,10 @@ DECLARE
atype TEXT;
adef RECORD;
BEGIN
+ IF TG_OP IN ('INSERT','UPDATE') AND NEW.imported_as IS NOT NULL THEN
+ RETURN NEW;
+ END IF;
+
FOR adef IN SELECT * FROM vandelay.bib_attr_definition LOOP
SELECT extract_marc_field('vandelay.queued_bib_record', id, adef.xpath, adef.remove) INTO value FROM vandelay.queued_bib_record WHERE id = NEW.id;
@@ -1688,6 +1696,10 @@ DECLARE
item_data vandelay.import_item%ROWTYPE;
BEGIN
+ IF TG_OP IN ('INSERT','UPDATE') AND NEW.imported_as IS NOT NULL THEN
+ RETURN NEW;
+ END IF;
+
SELECT item_attr_def INTO attr_def FROM vandelay.bib_queue WHERE id = NEW.queue;
FOR item_data IN SELECT * FROM vandelay.ingest_items( NEW.id::BIGINT, attr_def ) LOOP
@@ -1824,6 +1836,10 @@ $func$ LANGUAGE PLPGSQL;
CREATE OR REPLACE FUNCTION vandelay.cleanup_bib_marc ( ) RETURNS TRIGGER AS $$
BEGIN
+ IF TG_OP IN ('INSERT','UPDATE') AND NEW.imported_as IS NOT NULL THEN
+ RETURN NEW;
+ END IF;
+
DELETE FROM vandelay.queued_bib_record_attr WHERE record = OLD.id;
DELETE FROM vandelay.import_item WHERE record = OLD.id;
@@ -1897,6 +1913,10 @@ DECLARE
atype TEXT;
adef RECORD;
BEGIN
+ IF TG_OP IN ('INSERT','UPDATE') AND NEW.imported_as IS NOT NULL THEN
+ RETURN NEW;
+ END IF;
+
FOR adef IN SELECT * FROM vandelay.authority_attr_definition LOOP
SELECT extract_marc_field('vandelay.queued_authority_record', id, adef.xpath, adef.remove) INTO value FROM vandelay.queued_authority_record WHERE id = NEW.id;
@@ -1912,6 +1932,10 @@ $$ LANGUAGE PLPGSQL;
CREATE OR REPLACE FUNCTION vandelay.cleanup_authority_marc ( ) RETURNS TRIGGER AS $$
BEGIN
+ IF TG_OP IN ('INSERT','UPDATE') AND NEW.imported_as IS NOT NULL THEN
+ RETURN NEW;
+ END IF;
+
DELETE FROM vandelay.queued_authority_record_attr WHERE record = OLD.id;
IF TG_OP = 'UPDATE' THEN
RETURN NEW;
commit c3201eb4258ce9f1317910417ea6d3b810354727
Author: berick <berick at esilibrary.com>
Date: Wed May 4 10:45:57 2011 -0400
more vandelay menubar slimming
diff --git a/Open-ILS/web/opac/locale/en-US/vandelay.dtd b/Open-ILS/web/opac/locale/en-US/vandelay.dtd
index f8fa799..a97639f 100644
--- a/Open-ILS/web/opac/locale/en-US/vandelay.dtd
+++ b/Open-ILS/web/opac/locale/en-US/vandelay.dtd
@@ -26,7 +26,7 @@
<!ENTITY vandelay.done "Done">
<!ENTITY vandelay.edit.attributes "Record Display Attributes">
<!ENTITY vandelay.edit.attrs "Record Display Attributes">
-<!ENTITY vandelay.edit.profiles "Edit Merge / Overlay Profiles">
+<!ENTITY vandelay.edit.profiles "Merge / Overlay Profiles">
<!ENTITY vandelay.edit.match_set "Record Match Sets">
<!ENTITY vandelay.edit.import_item_attrs "Import Item Attributes">
<!ENTITY vandelay.false "False">
commit 8c40a2e78e76a495bd3d77abdf565ac1175c89c0
Author: berick <berick at esilibrary.com>
Date: Wed May 4 10:45:40 2011 -0400
don't match on deleted bib records
diff --git a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
index eb089a4..88de9d7 100644
--- a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
+++ b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
@@ -522,7 +522,7 @@ BEGIN
FROM _vandelay_tmp_jrows;
-- add those joins and the where clause to our query.
- query_ := query_ || joins || E'\n' || 'WHERE ' || wq;
+ query_ := query_ || joins || E'\n' || 'WHERE ' || wq || ' AND not bre.deleted';
-- this will return rows of record,quality
FOR rec IN EXECUTE query_ USING tags_rstore, svf_rstore LOOP
commit b27b7881d3c3c776bca73b78e02149b3a9459f4c
Author: berick <berick at esilibrary.com>
Date: Wed May 4 10:13:42 2011 -0400
also remove matched_set from IDL
diff --git a/Open-ILS/examples/fm_IDL.xml b/Open-ILS/examples/fm_IDL.xml
index dd522fa..068403d 100644
--- a/Open-ILS/examples/fm_IDL.xml
+++ b/Open-ILS/examples/fm_IDL.xml
@@ -392,14 +392,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
<fields oils_persist:primary="id" oils_persist:sequence="vandelay.bib_match_id_seq">
<field reporter:label="Match ID" name="id" reporter:datatype="id"/>
<field reporter:label="Queued Record" name="queued_record" reporter:datatype="link"/>
- <field reporter:label="Matched Set" name="matched_set" reporter:datatype="link"/>
<field reporter:label="Evergreen Record" name="eg_record" reporter:datatype="link"/>
<field reporter:label="Quality" name="quality" reporter:datatype="text"/>
</fields>
<links>
<link field="queued_record" reltype="has_a" key="id" map="" class="vqbr"/>
<link field="eg_record" reltype="has_a" key="id" map="" class="bre"/>
- <link field="matched_set" reltype="has_a" key="id" map="" class="vms"/>
</links>
<permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
<actions>
commit 8c223ecec89a5e097f13d788e9db016544f761e9
Author: Mike Rylander <mrylander at gmail.com>
Date: Tue May 3 20:23:57 2011 -0400
Clean up uses of vandelay.incoming_record_quality to provide all required params; Remove matched_set on matches, just look at the match_set for the queue of the vandelay record in question
diff --git a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
index e639998..eb089a4 100644
--- a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
+++ b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
@@ -141,7 +141,6 @@ CREATE INDEX queued_bib_record_attr_record_idx ON vandelay.queued_bib_record_att
CREATE TABLE vandelay.bib_match (
id BIGSERIAL PRIMARY KEY,
- matched_set INT REFERENCES vandelay.match_set (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
queued_record BIGINT REFERENCES vandelay.queued_bib_record (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
eg_record BIGINT REFERENCES biblio.record_entry (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
quality INT NOT NULL DEFAULT 0,
@@ -702,10 +701,10 @@ BEGIN
vandelay.match_set_test_marcxml(my_bib_queue.match_set, NEW.marc) LOOP
INSERT INTO vandelay.bib_match (
- matched_set, queued_record, eg_record, match_score, quality
+ queued_record, eg_record, match_score, quality
) VALUES (
- my_bib_queue.match_set, NEW.id, test_result.record,
- test_result.quality, vandelay.incoming_record_quality(NEW.marc)
+ NEW.id, test_result.record,
+ test_result.quality, vandelay.incoming_record_quality(NEW.marc, my_bib_queue.match_set)
);
END LOOP;
@@ -1298,17 +1297,18 @@ BEGIN
SELECT m.eg_record INTO eg_id
FROM vandelay.bib_match m
- JOIN biblio.record_entry r
+ JOIN vandelay.queued_bib_record qr ON (m.queued_record = qr.id)
+ JOIN vandelay.bib_queue q ON (qr.queue = q.id)
+ JOIN biblio.record_entry r ON (r.id = m.eg_record)
WHERE m.queued_record = import_id
- AND r.id = m.eg_record
- AND m.quality::NUMERIC / COALESCE(NULLIF(vandelay.incoming_record_quality(r.marc),0),1)::NUMERIC >= lwm_ratio_value
- ORDER BY m.match_score DESC,
- m.quality::NUMERIC / COALESCE(NULLIF(vandelay.incoming_record_quality(r.marc),0),1)::NUMERIC DESC,
- id
+ AND m.quality::NUMERIC / COALESCE(NULLIF(vandelay.incoming_record_quality(r.marc, q.match_set),0),1)::NUMERIC >= lwm_ratio_value
+ ORDER BY m.match_score DESC, -- required match score
+ m.quality::NUMERIC / COALESCE(NULLIF(vandelay.incoming_record_quality(r.marc, q.match_set),0),1)::NUMERIC DESC, -- quality tie breaker
+ m.id -- when in doubt, use the first match
LIMIT 1;
IF eg_id IS NULL THEN
- -- RAISE NOTICE 'incoming record is not of hight enough quality';
+ -- RAISE NOTICE 'incoming record is not of high enough quality';
RETURN FALSE;
END IF;
@@ -1886,7 +1886,6 @@ CREATE INDEX queued_authority_record_attr_record_idx ON vandelay.queued_authorit
CREATE TABLE vandelay.authority_match (
id BIGSERIAL PRIMARY KEY,
- matched_set INT REFERENCES vandelay.match_set (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
queued_record BIGINT REFERENCES vandelay.queued_authority_record (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
eg_record BIGINT REFERENCES authority.record_entry (id) DEFERRABLE INITIALLY DEFERRED,
quality INT NOT NULL DEFAULT 0
commit 065b545d3e1ad5ab06205ce8205d49b7dc632610
Author: Mike Rylander <mrylander at gmail.com>
Date: Tue May 3 20:06:46 2011 -0400
Add MARC::Charset dance to the remaining plperlu function
diff --git a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
index c5740d7..e639998 100644
--- a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
+++ b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
@@ -321,6 +321,10 @@ CREATE OR REPLACE FUNCTION vandelay.flay_marc ( TEXT ) RETURNS SETOF vandelay.fl
use MARC::Record;
use MARC::File::XML (BinaryEncoding => 'UTF-8');
+use MARC::Charset;
+use strict;
+
+MARC::Charset->assume_unicode(1);
my $xml = shift;
my $r = MARC::Record->new_from_xml( $xml );
commit b81fd284cb7e600c6f4011741f9d7f91618cab12
Author: berick <berick at esilibrary.com>
Date: Tue May 3 15:18:55 2011 -0400
match set selection support in vl uploage UI, part 1
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
index 0820cb0..510d6bf 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
@@ -60,6 +60,7 @@ sub create_bib_queue {
my $name = shift;
my $owner = shift;
my $type = shift;
+ my $match_set = shift;
my $import_def = shift;
my $e = new_editor(authtoken => $auth, xact => 1);
@@ -78,6 +79,7 @@ sub create_bib_queue {
$queue->owner( $owner );
$queue->queue_type( $type ) if ($type);
$queue->item_attr_def( $import_def ) if ($import_def);
+ $queue->match_set($match_set) if $match_set;
my $new_q = $e->create_vandelay_bib_queue( $queue );
return $e->die_event unless ($new_q);
@@ -100,6 +102,7 @@ sub create_auth_queue {
my $name = shift;
my $owner = shift;
my $type = shift;
+ my $match_set = shift;
my $e = new_editor(authtoken => $auth, xact => 1);
diff --git a/Open-ILS/web/js/ui/default/vandelay/vandelay.js b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
index 6ce390f..ad93a3c 100644
--- a/Open-ILS/web/js/ui/default/vandelay/vandelay.js
+++ b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
@@ -86,13 +86,14 @@ var cgi = new openils.CGI();
var vlQueueGridColumePicker = {};
var vlBibSources = [];
var importItemDefs = [];
+var matchSets = {};
/**
* Grab initial data
*/
function vlInit() {
authtoken = openils.User.authtoken;
- var initNeeded = 6; // how many async responses do we need before we're init'd
+ var initNeeded = 7; // how many async responses do we need before we're init'd
var initCount = 0; // how many async reponses we've received
openils.Util.registerEnterHandler(
@@ -165,6 +166,23 @@ function vlInit() {
}
);
+ new openils.PermaCrud().search('vms',
+ {owner: owner.map(function(org) { return org.id(); })},
+ { async: true,
+ oncomplete: function(r) {
+ var sets = openils.Util.readResponse(r);
+ dojo.forEach(sets,
+ function(set) {
+ if(!matchSets[set.mtype()])
+ matchSets[set.mtype()] = [];
+ matchSets[set.mtype()].push(set);
+ }
+ );
+ checkInitDone();
+ }
+ }
+ );
+
vlAttrEditorInit();
}
@@ -319,13 +337,13 @@ function uploadMARC(onload){
/**
* Creates a new vandelay queue
*/
-function createQueue(queueName, type, onload, importDefId) {
+function createQueue(queueName, type, onload, importDefId, matchSet) {
var name = (type=='bib') ? 'bib' : 'authority';
var method = 'open-ils.vandelay.'+ name +'_queue.create'
fieldmapper.standardRequest(
['open-ils.vandelay', method],
{ async: true,
- params: [authtoken, queueName, null, name, importDefId],
+ params: [authtoken, queueName, null, name, matchSet, importDefId],
oncomplete : function(r) {
var queue = r.recv().content();
if(e = openils.Event.parse(queue))
@@ -1111,7 +1129,10 @@ function batchUpload() {
currentQueueId = vlUploadQueueSelector.getValue();
uploadMARC(handleUploadMARC);
} else {
- createQueue(queueName, currentType, handleCreateQueue, vlUploadQueueHoldingsImportProfile.attr('value'));
+ createQueue(queueName, currentType, handleCreateQueue,
+ vlUploadQueueHoldingsImportProfile.attr('value'),
+ vlUploadQueueMatchSet.attr('value')
+ );
}
}
@@ -1134,9 +1155,13 @@ function vlFleshQueueSelect(selector, type) {
if(val) {
vlUploadQueueHoldingsImportProfile.attr('value', queue.item_attr_def() || '');
vlUploadQueueHoldingsImportProfile.attr('disabled', true);
+ vlUploadQueueMatchSet.attr('value', queue.match_set() || '');
+ vlUploadQueueMatchSet.attr('disabled', true);
} else {
vlUploadQueueHoldingsImportProfile.attr('value', '');
vlUploadQueueHoldingsImportProfile.attr('disabled', false);
+ vlUploadQueueMatchSet.attr('value', '');
+ vlUploadQueueMatchSet.attr('disabled', false);
}
dojo.disconnect(qInput._onchange);
qInput.attr('value', '');
@@ -1148,6 +1173,8 @@ function vlFleshQueueSelect(selector, type) {
// user entered a new queue name. clear the selector
vlUploadQueueHoldingsImportProfile.attr('value', '');
vlUploadQueueHoldingsImportProfile.attr('disabled', false);
+ vlUploadQueueMatchSet.attr('value', '');
+ vlUploadQueueMatchSet.attr('disabled', false);
dojo.disconnect(selector._onchange);
selector.attr('value', '');
selector._onchange = dojo.connect(selector, 'onChange', selChange);
@@ -1157,6 +1184,12 @@ function vlFleshQueueSelect(selector, type) {
qInput._onchange = dojo.connect(qInput, 'onChange', inputChange);
}
+function vlUpdateMatchSetSelector(type) {
+ type = (type.match(/bib/)) ? 'biblio' : 'authority';
+ vlUploadQueueMatchSet.store =
+ new dojo.data.ItemFileReadStore({data:vms.toStoreData(matchSets[type])});
+}
+
function vlShowUploadForm() {
displayGlobalDiv('vl-marc-upload-div');
vlFleshQueueSelect(vlUploadQueueSelector, vlUploadRecordType.getValue());
@@ -1165,6 +1198,7 @@ function vlShowUploadForm() {
vlUploadSourceSelector.setValue(vlBibSources[0].id());
vlUploadQueueHoldingsImportProfile.store =
new dojo.data.ItemFileReadStore({data:viiad.toStoreData(importItemDefs)});
+ vlUpdateMatchSetSelector(vlUploadRecordType.getValue());
}
function vlShowQueueSelect() {
diff --git a/Open-ILS/web/templates/default/vandelay/inc/upload.tt2 b/Open-ILS/web/templates/default/vandelay/inc/upload.tt2
index 8356075..909670e 100644
--- a/Open-ILS/web/templates/default/vandelay/inc/upload.tt2
+++ b/Open-ILS/web/templates/default/vandelay/inc/upload.tt2
@@ -24,6 +24,13 @@
</td>
</tr>
<tr>
+ <td>Record Match Set</td>
+ <td>
+ <input jsId='vlUploadQueueMatchSet'
+ dojoType='dijit.form.FilteringSelect' labelAttr='name' searchAttr='name'/>
+ </td>
+ </tr>
+ <tr>
<td>Holdings Import Profile</td>
<td>
<input jsId='vlUploadQueueHoldingsImportProfile'
commit f1170755a54cfeb7f55d394989ebbb5c14d9cc85
Author: berick <berick at esilibrary.com>
Date: Tue May 3 14:42:09 2011 -0400
delete match_set_point's starting with leaf nodes to avoid foreign key constraints on nodes w/ children
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
index 1d69eb4..0820cb0 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
@@ -1420,8 +1420,15 @@ sub match_set_update_tree {
{"order_by" => {"vmsp" => "id DESC"}}
]) or return $e->die_event;
- foreach (@$existing) {
- $e->delete_vandelay_match_set_point($_) or return $e->die_event;
+ # delete points, working up from leaf points to the root
+ while(@$existing) {
+ for my $point (shift @$existing) {
+ if( grep {$_->parent eq $point->id} @$existing) {
+ push(@$existing, $point);
+ } else {
+ $e->delete_vandelay_match_set_point($point) or return $e->die_event;
+ }
+ }
}
_walk_new_vmsp($e, $match_set_id, $tree);
commit ce07a23e829a7271fc4b11af72117b8c14837ad3
Author: berick <berick at esilibrary.com>
Date: Tue May 3 13:55:22 2011 -0400
create an embedded view of the vandelay match-set admin ui inside of vandelay (as one of the tabs)
diff --git a/Open-ILS/web/js/ui/default/vandelay/vandelay.js b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
index 26d73c7..6ce390f 100644
--- a/Open-ILS/web/js/ui/default/vandelay/vandelay.js
+++ b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
@@ -258,6 +258,10 @@ function displayGlobalDiv(id) {
openils.Util.removeCSSClass(dojo.byId('vl-menu-queue-select'), 'toolbar_selected');
openils.Util.removeCSSClass(dojo.byId('vl-menu-attr-editor'), 'toolbar_selected');
openils.Util.removeCSSClass(dojo.byId('vl-menu-profile-editor'), 'toolbar_selected');
+ openils.Util.removeCSSClass(dojo.byId('vl-menu-match-set-editor'), 'toolbar_selected');
+
+ if(dojo.byId('vl-match-set-iframe'))
+ dojo.byId('vl-match-set-editor-div').removeChild(dojo.byId('vl-match-set-iframe'));
switch(id) {
case 'vl-marc-export-div':
@@ -278,6 +282,9 @@ function displayGlobalDiv(id) {
case 'vl-item-attr-editor-div':
openils.Util.addCSSClass(dojo.byId('vl-menu-import-item-attr-editor'), 'toolbar_selected');
break;
+ case 'vl-match-set-editor-div':
+ openils.Util.addCSSClass(dojo.byId('vl-menu-match-set-editor'), 'toolbar_selected');
+ break;
}
}
@@ -1165,6 +1172,17 @@ function vlShowQueueSelect() {
vlFleshQueueSelect(vlQueueSelectQueueList, vlQueueSelectType.getValue());
}
+function vlShowMatchSetEditor() {
+ displayGlobalDiv('vl-match-set-editor-div');
+ dojo.byId('vl-match-set-editor-div').appendChild(
+ dojo.create('iframe', {
+ id : 'vl-match-set-iframe',
+ src : oilsBasePath + '/eg/conify/global/vandelay/match_set',
+ style : 'width:100%; height:500px; border:none; margin:0px;'
+ })
+ );
+}
+
function vlFetchQueueFromForm() {
currentType = vlQueueSelectType.getValue();
currentQueueId = vlQueueSelectQueueList.getValue();
@@ -1321,7 +1339,6 @@ function onAttrEditorClick() {
var parsed_xpath = xpathParser.parse(this.store.getValue(row, 'xpath'));
dijit.byId('attr-editor-tags').attr('value', parsed_xpath.tags);
dijit.byId('attr-editor-subfields').attr('value', parsed_xpath.subfields);
- dijit.byId('attr-editor-identifier').attr('value', this.store.getValue(row, 'ident'));
dijit.byId('attr-editor-xpath').attr('value', this.store.getValue(row, 'xpath'));
dijit.byId('attr-editor-remove').attr('value', this.store.getValue(row, 'remove'));
diff --git a/Open-ILS/web/opac/locale/en-US/vandelay.dtd b/Open-ILS/web/opac/locale/en-US/vandelay.dtd
index e94f8c7..f8fa799 100644
--- a/Open-ILS/web/opac/locale/en-US/vandelay.dtd
+++ b/Open-ILS/web/opac/locale/en-US/vandelay.dtd
@@ -24,10 +24,11 @@
<!ENTITY vandelay.dest.match.point "Destination Match Point">
<!ENTITY vandelay.display "Display">
<!ENTITY vandelay.done "Done">
-<!ENTITY vandelay.edit.attributes "Edit Attributes">
-<!ENTITY vandelay.edit.attrs "Edit Attributes">
+<!ENTITY vandelay.edit.attributes "Record Display Attributes">
+<!ENTITY vandelay.edit.attrs "Record Display Attributes">
<!ENTITY vandelay.edit.profiles "Edit Merge / Overlay Profiles">
-<!ENTITY vandelay.edit.import_item_attrs "Edit Import Item Attributes">
+<!ENTITY vandelay.edit.match_set "Record Match Sets">
+<!ENTITY vandelay.edit.import_item_attrs "Import Item Attributes">
<!ENTITY vandelay.false "False">
<!ENTITY vandelay.file.to.upload "File to Upload:">
<!ENTITY vandelay.for.example "Example">
diff --git a/Open-ILS/web/templates/default/vandelay/inc/attrs.tt2 b/Open-ILS/web/templates/default/vandelay/inc/attrs.tt2
index d06b176..1a09b0b 100644
--- a/Open-ILS/web/templates/default/vandelay/inc/attrs.tt2
+++ b/Open-ILS/web/templates/default/vandelay/inc/attrs.tt2
@@ -38,15 +38,6 @@
</td>
</tr>
<tr>
- <td><label for="ident">&vandelay.id.field;: </label></td>
- <td>
- <select dojoType="dijit.form.FilteringSelect" name="ident" id="attr-editor-identifier">
- <option value='f' selected='selected'>&vandelay.false;</option>
- <option value='t'>&vandelay.true;</option>
- </select>
- </td>
- </tr>
- <tr>
<td><label for="attr-editor-xpath">&vandelay.xpath.advanced;: </label></td>
<td><input dojoType="dijit.form.TextBox" id="attr-editor-xpath" name="xpath"></input></td>
@@ -90,7 +81,6 @@
<th field='description' width='auto'>&vandelay.descrip;</th>
<th field='tag' get='attrGridGetTag'>&vandelay.tag;</th>
<th field='subfield' get='attrGridGetSubfield'>&vandelay.subfield;</th>
- <th field='ident'>&vandelay.identifier;</th>
<th field='xpath' width='auto'>&vandelay.xpath;</th>
<th field='remove' width='auto'>&vandelay.remove;</th>
</tr>
diff --git a/Open-ILS/web/templates/default/vandelay/inc/toolbar.tt2 b/Open-ILS/web/templates/default/vandelay/inc/toolbar.tt2
index 69c2190..144cd45 100644
--- a/Open-ILS/web/templates/default/vandelay/inc/toolbar.tt2
+++ b/Open-ILS/web/templates/default/vandelay/inc/toolbar.tt2
@@ -9,6 +9,8 @@
onclick="vlShowAttrEditor();" showLabel="true">&vandelay.edit.attributes;</div>
<div dojoType="dijit.form.Button" iconClass="dijitEditorIcon dijitEditorIconCopy" id='vl-menu-profile-editor'
onclick="vlShowProfileEditor();" showLabel="true">&vandelay.edit.profiles;</div>
+ <div dojoType="dijit.form.Button" iconClass="dijitEditorIcon dijitEditorIconCopy" id='vl-menu-match-set-editor'
+ onclick="vlShowMatchSetEditor();" showLabel="true">&vandelay.edit.match_set;</div>
<div dojoType="dijit.form.Button" iconClass="dijitEditorIcon dijitEditorIconCopy" id='vl-menu-import-item-attr-editor'
onclick="vlShowImportItemAttrEditor();" showLabel="true">&vandelay.edit.import_item_attrs;</div>
</div>
diff --git a/Open-ILS/web/templates/default/vandelay/vandelay.tt2 b/Open-ILS/web/templates/default/vandelay/vandelay.tt2
index 4ca2f37..78f23a8 100644
--- a/Open-ILS/web/templates/default/vandelay/vandelay.tt2
+++ b/Open-ILS/web/templates/default/vandelay/vandelay.tt2
@@ -37,6 +37,8 @@
<div dojoType="dijit.layout.ContentPane" layoutAlign='client' id='vl-profile-editor-div' class='hidden content'>
[% INCLUDE 'default/vandelay/inc/profiles.tt2' %]
</div>
+<div dojoType="dijit.layout.ContentPane" layoutAlign='client' id='vl-match-set-editor-div' class='hidden content'>
+</div>
<div dojoType="dijit.layout.ContentPane" layoutAlign='client' id='vl-item-attr-editor-div' class='hidden content'>
[% INCLUDE 'default/vandelay/inc/item_attrs.tt2' %]
</div>
commit d2127cf97568f02c8b7cf40e8d981b677455f619
Author: berick <berick at esilibrary.com>
Date: Tue May 3 11:11:11 2011 -0400
added support for viewing all import-items related to a queue, with a filter to limit to those that failed import
diff --git a/Open-ILS/web/js/ui/default/vandelay/vandelay.js b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
index 182cf5c..26d73c7 100644
--- a/Open-ILS/web/js/ui/default/vandelay/vandelay.js
+++ b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
@@ -648,9 +648,12 @@ function vlLoadErrorUIAll() {
displayGlobalDiv('vl-import-error-div');
openils.Util.hide('vl-import-error-grid-some');
+ openils.Util.hide('vl-import-error-record');
openils.Util.show('vl-import-error-grid-all');
vlAllImportErrorGrid.resetStore();
+ vlImportErrorGrid.displayOffset = 0;
+
vlAllImportErrorGrid.dataLoader = function() {
vlAllImportErrorGrid.showLoadProgressIndicator();
@@ -661,7 +664,7 @@ function vlLoadErrorUIAll() {
async : true,
params : [
authtoken, currentQueueId, {
- with_import_error:1,
+ with_import_error: (vlImportItemsShowErrors.checked) ? 1 : null,
offset : vlAllImportErrorGrid.displayOffset,
limit : vlAllImportErrorGrid.displayLimit
}
diff --git a/Open-ILS/web/templates/default/vandelay/inc/import_errors.tt2 b/Open-ILS/web/templates/default/vandelay/inc/import_errors.tt2
index 6b08db4..f72630b 100644
--- a/Open-ILS/web/templates/default/vandelay/inc/import_errors.tt2
+++ b/Open-ILS/web/templates/default/vandelay/inc/import_errors.tt2
@@ -1,4 +1,3 @@
-<h1>Import Errors</h1><br/>
<div dojoType="dijit.layout.ContentPane" layoutAlign='client'>
<button dojoType='dijit.form.Button'
@@ -6,23 +5,25 @@
</div>
<div dojoType="dijit.layout.ContentPane" layoutAlign='client'>
- <table id='vl-import-error-record' class='hidden'>
- <tbody>
- <tr><td>ID</td><td id='vl-error-id'/></tr>
- <tr><td>Import Error</td><td id='vl-error-import-error'/></tr>
- <tr><td>Error Detail</td><td id='vl-error-error-detail'/></tr>
- <tr><td>Title</td><td id='vl-error-title'/></tr>
- <tr><td>Author</td><td id='vl-error-author'/></tr>
- <tr><td>ISBN</td><td id='vl-error-isbn'/></tr>
- <tr><td>ISSN</td><td id='vl-error-issn'/></tr>
- <tr><td>UPC</td><td id='vl-error-upc'/></tr>
- </tbody>
- </table>
+ <div id='vl-import-error-record' class='hidden'>
+ <h1>Import Errors</h1><br/>
+ <table>
+ <tbody>
+ <tr><td>ID</td><td id='vl-error-id'/></tr>
+ <tr><td>Import Error</td><td id='vl-error-import-error'/></tr>
+ <tr><td>Error Detail</td><td id='vl-error-error-detail'/></tr>
+ <tr><td>Title</td><td id='vl-error-title'/></tr>
+ <tr><td>Author</td><td id='vl-error-author'/></tr>
+ <tr><td>ISBN</td><td id='vl-error-isbn'/></tr>
+ <tr><td>ISSN</td><td id='vl-error-issn'/></tr>
+ <tr><td>UPC</td><td id='vl-error-upc'/></tr>
+ </tbody>
+ </table>
+ </div>
</div>
<div dojoType="dijit.layout.ContentPane" layoutAlign='client'>
<div class='hidden' id='vl-import-error-grid-some'>
- <h3>Item Import Errors</h3>
<table jsId="vlImportErrorGrid"
dojoType="openils.widget.AutoGrid"
autoHeight='true'
@@ -33,15 +34,19 @@
columnPickerPrefix='"vandelay.item.import_error"'
fmClass='vii'>
<thead>
- <th field='owning_lib' get='vlGetOrg'/>
- <th field='circ_lib' get='vlGetOrg'/>
+ <tr>
+ <th field='owning_lib' get='vlGetOrg'/>
+ <th field='circ_lib' get='vlGetOrg'/>
+ </tr>
</thead>
</table>
</div>
</div>
<div dojoType="dijit.layout.ContentPane" layoutAlign='client'>
<div class='hidden' id='vl-import-error-grid-all'>
- <h3>Item Import Errors</h3>
+ <h1>Import Items</h1><br/>
+ <input dojoType='dijit.form.CheckBox' jsId='vlImportItemsShowErrors' onchange='vlLoadErrorUIAll();'/>
+ <span>Limit to Import Failures</span>
<table jsId="vlAllImportErrorGrid"
dojoType="openils.widget.AutoGrid"
autoHeight='true'
@@ -52,8 +57,10 @@
columnPickerPrefix='"vandelay.item.import_error"'
fmClass='vii'>
<thead>
- <th field='owning_lib' get='vlGetOrg'/>
- <th field='circ_lib' get='vlGetOrg'/>
+ <tr>
+ <th field='owning_lib' get='vlGetOrg'/>
+ <th field='circ_lib' get='vlGetOrg'/>
+ </tr>
</thead>
</table>
</div>
diff --git a/Open-ILS/web/templates/default/vandelay/inc/queue.tt2 b/Open-ILS/web/templates/default/vandelay/inc/queue.tt2
index 50f74b4..00c812d 100644
--- a/Open-ILS/web/templates/default/vandelay/inc/queue.tt2
+++ b/Open-ILS/web/templates/default/vandelay/inc/queue.tt2
@@ -11,7 +11,7 @@
<tbody>
<tr><td><a href='#' onclick='vlHandleQueueItemsAction("import")'>&vandelay.import.selected;</a></td></tr>
<tr><td><a href='#' onclick='vlHandleQueueItemsAction("import_all")'>&vandelay.import.all;</a></td></tr>
- <tr><td><a href='#' onclick='vlLoadErrorUIAll();'>View Item Import Failures</a></td></tr>
+ <tr><td><a href='#' onclick='vlLoadErrorUIAll();'>View Import Items</a></td></tr>
<tr><td><a href='#' onclick='
if(confirm("&vandelay.sure.to.delete.queue;")) {
vlDeleteQueue(currentType, currentQueueId,
commit 0d784d89f00fd350181e6559a9c94bca039210c8
Author: berick <berick at esilibrary.com>
Date: Mon May 2 17:48:29 2011 -0400
added view for all failed item imports for a queue; next up is export options
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
index 4df6c1d..1d69eb4 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
@@ -518,7 +518,9 @@ sub retrieve_queue_import_items {
}
}
},
- order_by => {'vii' => ['record','id']}
+ order_by => {'vii' => ['record','id']},
+ limit => $limit,
+ offset => $offset
};
$query->{where} = {'+vii' => {import_error => {'!=' => undef}}}
diff --git a/Open-ILS/web/js/ui/default/vandelay/vandelay.js b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
index cd6cd82..182cf5c 100644
--- a/Open-ILS/web/js/ui/default/vandelay/vandelay.js
+++ b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
@@ -644,6 +644,43 @@ function vlLoadErrorUI(id) {
}
}
+function vlLoadErrorUIAll() {
+
+ displayGlobalDiv('vl-import-error-div');
+ openils.Util.hide('vl-import-error-grid-some');
+ openils.Util.show('vl-import-error-grid-all');
+ vlAllImportErrorGrid.resetStore();
+
+ vlAllImportErrorGrid.dataLoader = function() {
+
+ vlAllImportErrorGrid.showLoadProgressIndicator();
+
+ fieldmapper.standardRequest(
+ ['open-ils.vandelay', 'open-ils.vandelay.import_item.queue.retrieve'],
+ {
+ async : true,
+ params : [
+ authtoken, currentQueueId, {
+ with_import_error:1,
+ offset : vlAllImportErrorGrid.displayOffset,
+ limit : vlAllImportErrorGrid.displayLimit
+ }
+ ],
+ onresponse : function(r) {
+ var item = openils.Util.readResponse(r);
+ if(!item) return;
+ vlAllImportErrorGrid.store.newItem(vii.toStoreItem(item));
+ },
+ oncomplete : function() {
+ vlAllImportErrorGrid.hideLoadProgressIndicator();
+ }
+ }
+ );
+ };
+
+ vlAllImportErrorGrid.dataLoader();
+}
+
function vlGetOrg(rowIdx, item) {
if(!item) return '';
var value = this.grid.store.getValue(item, this.field);
diff --git a/Open-ILS/web/templates/default/vandelay/inc/queue.tt2 b/Open-ILS/web/templates/default/vandelay/inc/queue.tt2
index 25e22a2..50f74b4 100644
--- a/Open-ILS/web/templates/default/vandelay/inc/queue.tt2
+++ b/Open-ILS/web/templates/default/vandelay/inc/queue.tt2
@@ -11,7 +11,7 @@
<tbody>
<tr><td><a href='#' onclick='vlHandleQueueItemsAction("import")'>&vandelay.import.selected;</a></td></tr>
<tr><td><a href='#' onclick='vlHandleQueueItemsAction("import_all")'>&vandelay.import.all;</a></td></tr>
- <tr><td><a href='#' onclick='alert("coming soon"); return;vlHandleQueueItemsAction("item_errors")'>View Item Import Failures</a></td></tr>
+ <tr><td><a href='#' onclick='vlLoadErrorUIAll();'>View Item Import Failures</a></td></tr>
<tr><td><a href='#' onclick='
if(confirm("&vandelay.sure.to.delete.queue;")) {
vlDeleteQueue(currentType, currentQueueId,
@@ -99,62 +99,6 @@
</fieldset>
</div>
-<!-- queue grid navigation row -->
-<div dojoType="dijit.layout.ContentPane" layoutAlign='client'>
- <table width='100%' style='margin-bottom:0px;'>
- <tr>
- <!--
- <td align='left' valign='bottom'>
- <select id='vl-queue-actions-selector'>
- <option selected='selected' disabled='disabled' value='select-actions'>&vandelay.select_actions;</option>
- <option value='import'>&vandelay.import.selected;</option>
- <option value='import_all'>&vandelay.import.all;</option>
- <option value='delete_queue'>&vandelay.delete.queue;</option>
- </select>
- <script type="text/javascript">
- var sel = dojo.byId('vl-queue-actions-selector');
- sel.onchange = function(evt) {
- switch(openils.Util.selectorValue(evt.target)) {
- case 'import': vlHandleQueueItemsAction('import'); break;;
- case 'import_all': vlHandleQueueItemsAction('import_all'); break;;
- case 'delete_queue':
- if(confirm('&vandelay.sure.to.delete.queue;')) {
- vlDeleteQueue(currentType, currentQueueId,
- function() { displayGlobalDiv('vl-marc-upload-div'); });
- }
- }
- evt.target.selectedIndex = 0;
- }
- </script>
- </td>
- <td align='right' valign='bottom'>
- <style type="text/css">.filter_span { padding-right: 5px; border-right: 2px solid #e8e1cf; } </style>
- <span>&vandelay.results.per.page;</span>
- <span class='filter_span'>
- <select jsId='vlQueueDisplayLimit' id='vl-queue-display-limit-selector'
- value='10' onchange='retrieveQueuedRecords();'>
- <option value='10'>10</option>
- <option value='20'>20</option>
- <option value='50'>50</option>
- <option value='100'>100</option>
- </select>
- </span>
- <span style='padding-left:5px;'>&vandelay.page;</span>
- <input style='width:36px;' dojoType='dijit.form.TextBox' jsId='vlQueueDisplayPage' value='1'/>
-
- <span style='padding-right:4px;'>
- <a href='javascript:void(0);' onclick='vlQueueGridPrevPage();'>&vandelay.prev.page;</a>
- </span>
- <span style='padding-right:10px;'>
- <a href='javascript:void(0);' onclick='vlQueueGridNextPage();'>&vandelay.next.page;</a>
- </span>
- </td>
- -->
- </tr>
- </table>
-</div>
-
-
<!-- Bib Queue Grid -->
<div class='' id='vl-bib-queue-grid-wrapper' dojoType='dijit.layout.ContentPane'>
<table dojoType='dojox.grid.DataGrid' jsId='vlBibQueueGrid' query="{id:'*'}" autoHeight='true'>
commit a978e74d8303bf39bdcd081c2f77bb5289d1159d
Author: berick <berick at esilibrary.com>
Date: Mon May 2 15:51:15 2011 -0400
added support for 'limit records to those with any import errors' in vandelay queue display
diff --git a/Open-ILS/web/js/ui/default/vandelay/vandelay.js b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
index fa97b8c..cd6cd82 100644
--- a/Open-ILS/web/js/ui/default/vandelay/vandelay.js
+++ b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
@@ -374,6 +374,9 @@ function retrieveQueuedRecords(type, queueId, onload) {
if(vlQueueGridShowNonImport.checked)
params[2].non_imported = 1;
+ if(vlQueueGridShowImportErrors.checked)
+ params[2].with_import_error = 1;
+
fieldmapper.standardRequest(
['open-ils.vandelay', method],
{ async: true,
commit 0aec475a117564063a98a4e0219b35946eb393db
Author: berick <berick at esilibrary.com>
Date: Mon May 2 15:49:33 2011 -0400
added 'with_import_error' option to queued record retrieval; returns recs with either a record or item import failure (or both)
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
index 7f34422..4df6c1d 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
@@ -430,19 +430,25 @@ sub retrieve_queued_records {
};
$query->{where}->{import_time} = undef if $$options{non_imported};
- $query->{where}->{import_error} = {'!=' => undef} if $$options{with_rec_import_error};
-
- if($$options{with_item_import_error} and $type eq 'bib') {
- # limit to recs that have at least 1 item import error
- $query->{from} = {
- $class => {
- vii => {
- field => 'record',
- fkey => 'id',
- filter => {import_error => {'!=' => undef}}
- }
- }
- };
+
+ if($$options{with_import_error}) {
+
+ $query->{from} = {$class => {vii => {type => 'right'}}};
+ $query->{where}->{'-or'} = [
+ {'+vqbr' => {import_error => {'!=' => undef}}},
+ {'+vii' => {import_error => {'!=' => undef}}}
+ ];
+
+ } else {
+
+ if($$options{with_rec_import_error}) {
+ $query->{where}->{import_error} = {'!=' => undef};
+
+ } elsif( $$options{with_item_import_error} and $type eq 'bib') {
+
+ $query->{from} = {$class => 'vii'};
+ $query->{where}->{'+vii'} = {import_error => {'!=' => undef}};
+ }
}
if($self->api_name =~ /matches/) {
commit 90047c17588fa07bb6cabca1ec14f290198d8883
Author: berick <berick at esilibrary.com>
Date: Mon May 2 12:52:30 2011 -0400
Vandelay file upload page cleanup
* Separate data configuration parameters from import actions
* Since import item profile is linked to queue, show the profile for
the selected queue and dissallow changing the profile for existing
queues in the UI (which has no effect)
diff --git a/Open-ILS/web/css/skin/default/vandelay.css b/Open-ILS/web/css/skin/default/vandelay.css
index 1f0303a..b1987f8 100644
--- a/Open-ILS/web/css/skin/default/vandelay.css
+++ b/Open-ILS/web/css/skin/default/vandelay.css
@@ -47,3 +47,4 @@ table.dijitTooltipTable { border-collapse: separate; }
.queue-nav-table-label { font-weight: bold; text-decoration:underline;}
.queue-pager-span { padding-right: 5px; margin-right: 5px; border-right: 2px solid #e8e1cf; }
#vl-queue-paging-table td { padding-bottom: 0px; }
+#vl-file-label { margin-right: 10px; }
diff --git a/Open-ILS/web/js/ui/default/vandelay/vandelay.js b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
index b6022c2..fa97b8c 100644
--- a/Open-ILS/web/js/ui/default/vandelay/vandelay.js
+++ b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
@@ -1073,6 +1073,38 @@ function vlFleshQueueSelect(selector, type) {
selector.setDisplayedValue('');
if(data[0])
selector.setValue(data[0].id());
+
+ var qInput = dijit.byId('vl-queue-name');
+
+ var selChange = function(val) {
+ console.log('selector onchange');
+ // user selected a queue from the selector; clear the input and
+ // set the item import profile already defined for the queue
+ var queue = allUserBibQueues.filter(function(q) { return (q.id() == val) })[0];
+ if(val) {
+ vlUploadQueueHoldingsImportProfile.attr('value', queue.item_attr_def() || '');
+ vlUploadQueueHoldingsImportProfile.attr('disabled', true);
+ } else {
+ vlUploadQueueHoldingsImportProfile.attr('value', '');
+ vlUploadQueueHoldingsImportProfile.attr('disabled', false);
+ }
+ dojo.disconnect(qInput._onchange);
+ qInput.attr('value', '');
+ qInput._onchange = dojo.connect(qInput, 'onChange', inputChange);
+ }
+
+ var inputChange = function(val) {
+ console.log('qinput onchange');
+ // user entered a new queue name. clear the selector
+ vlUploadQueueHoldingsImportProfile.attr('value', '');
+ vlUploadQueueHoldingsImportProfile.attr('disabled', false);
+ dojo.disconnect(selector._onchange);
+ selector.attr('value', '');
+ selector._onchange = dojo.connect(selector, 'onChange', selChange);
+ }
+
+ selector._onchange = dojo.connect(selector, 'onChange', selChange);
+ qInput._onchange = dojo.connect(qInput, 'onChange', inputChange);
}
function vlShowUploadForm() {
diff --git a/Open-ILS/web/templates/default/vandelay/inc/upload.tt2 b/Open-ILS/web/templates/default/vandelay/inc/upload.tt2
index aca6320..8356075 100644
--- a/Open-ILS/web/templates/default/vandelay/inc/upload.tt2
+++ b/Open-ILS/web/templates/default/vandelay/inc/upload.tt2
@@ -24,54 +24,50 @@
</td>
</tr>
<tr>
- <td>&vandelay.auto.import.noncolliding;</td>
- <td colspan='4'>
- <input jsId='vlUploadQueueAutoImport' dojoType='dijit.form.CheckBox'/>
+ <td>Holdings Import Profile</td>
+ <td>
+ <input jsId='vlUploadQueueHoldingsImportProfile'
+ dojoType='dijit.form.FilteringSelect' labelAttr='name' searchAttr='name'/>
</td>
</tr>
<tr>
- <td>&vandelay.auto.import.auto_overlay_exact;</td>
- <td colspan='4'>
- <input jsId='vlUploadQueueAutoOverlayExact' dojoType='dijit.form.CheckBox'/>
+ <td>&vandelay.import.bib_sources;</td>
+ <td>
+ <select name='bib_source' jsId='vlUploadSourceSelector'
+ dojoType='dijit.form.FilteringSelect' labelAttr='source' searchAttr='source'/>
</td>
</tr>
+ <tr><td colspan='2' style='margin-top:10px;border-bottom:1px solid #888;border-top:1px solid #888'><b>Import Actions</b></td></tr>
<tr>
- <td>&vandelay.auto.import.auto_overlay_1match;</td>
+ <td>&vandelay.auto.import.merge_profile;</td>
<td colspan='4'>
- <input jsId='vlUploadQueueAutoOverlay1Match' dojoType='dijit.form.CheckBox'/>
+ <div jsId='vlUploadMergeProfile' dojoType='dijit.form.FilteringSelect' required='false' labelAttr='name' searchAttr='name'/>
</td>
</tr>
<tr>
- <td>&vandelay.auto.import.merge_profile;</td>
+ <td>&vandelay.auto.import.noncolliding;</td>
<td colspan='4'>
- <div jsId='vlUploadMergeProfile' dojoType='dijit.form.FilteringSelect' required='false' labelAttr='name' searchAttr='name'/>
+ <input jsId='vlUploadQueueAutoImport' dojoType='dijit.form.CheckBox'/>
</td>
</tr>
<tr>
- <td>Holdings Import Profile</td>
- <td>
- <input jsId='vlUploadQueueHoldingsImportProfile'
- dojoType='dijit.form.FilteringSelect' labelAttr='name' searchAttr='name'/>
+ <td>&vandelay.auto.import.auto_overlay_exact;</td>
+ <td colspan='4'>
+ <input jsId='vlUploadQueueAutoOverlayExact' dojoType='dijit.form.CheckBox'/>
</td>
</tr>
<tr>
- <td>&vandelay.import.bib_sources;</td>
- <td>
- <select name='bib_source' jsId='vlUploadSourceSelector'
- dojoType='dijit.form.FilteringSelect' labelAttr='source' searchAttr='source'/>
+ <td>&vandelay.auto.import.auto_overlay_1match;</td>
+ <td colspan='4'>
+ <input jsId='vlUploadQueueAutoOverlay1Match' dojoType='dijit.form.CheckBox'/>
</td>
</tr>
+ <tr><td colspan='2' style='border-bottom:1px solid #888'></td></tr>
<tr>
- <td>
+ <td colspan='5'>
<span id="vl-file-label">&vandelay.file.to.upload;</span>
- </td>
- <td id='vl-input-td' colspan='4'>
<input size='48' type="file" name="marc_upload"/>
- </td>
- </tr>
- <tr>
- <td align='center' colspan='4'>
- <button dojoType="dijit.form.Button" onclick="batchUpload()">&vandelay.upload;</button>
+ <span style='margin-left:10px;'><button dojoType="dijit.form.Button" onclick="batchUpload()">&vandelay.upload;</button></span>
</td>
</tr>
</table>
commit a8f7f42453896dc97af0d51729a1a04ea7b3e900
Author: berick <berick at esilibrary.com>
Date: Mon Apr 25 16:34:54 2011 -0400
added new stub actions for limit-to-import-errors and show all item import errors; displaying new summary info; much rearrangement to bettet fit the UI pieces
diff --git a/Open-ILS/web/css/skin/default/vandelay.css b/Open-ILS/web/css/skin/default/vandelay.css
index 7476377..1f0303a 100644
--- a/Open-ILS/web/css/skin/default/vandelay.css
+++ b/Open-ILS/web/css/skin/default/vandelay.css
@@ -34,3 +34,16 @@ table.dijitTooltipTable { border-collapse: separate; }
#vl-import-error-record td:first-child { text-decoration: underline; }
#vl-import-error-record td { padding: 5px; }
#vl-error-import-error { font-weight: bold; }
+
+#vl-queue-filter-fieldset { padding-top: 3px; border:2px dashed #d9e8f9; }
+#vl-queue-filter-fieldset { margin: 5px; }
+#vl-queue-filter-fieldset td { padding: 5px; }
+#vl-queue-filter-fieldset th { padding: 5px; }
+#vl-queue-filter-fieldset legend { font-weight: bold; font-size: 1.3em }
+
+#vl-queue-filter-table { margin-left: 15px; padding-left: 15px; border-left: 2px dashed #d9e8f9;}
+#vl-queue-summary-table { margin-left: 15px; padding-left: 15px; border-left: 2px dashed #d9e8f9;}
+.queue-nav-table tr:nth-child(even) {background: #EEE}
+.queue-nav-table-label { font-weight: bold; text-decoration:underline;}
+.queue-pager-span { padding-right: 5px; margin-right: 5px; border-right: 2px solid #e8e1cf; }
+#vl-queue-paging-table td { padding-bottom: 0px; }
diff --git a/Open-ILS/web/js/ui/default/vandelay/vandelay.js b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
index 490d84c..b6022c2 100644
--- a/Open-ILS/web/js/ui/default/vandelay/vandelay.js
+++ b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
@@ -865,6 +865,9 @@ var handleRetrieveRecords = function() {
dojo.byId('vl-queue-summary-name').innerHTML = summary.queue.name();
dojo.byId('vl-queue-summary-total-count').innerHTML = summary.total +'';
dojo.byId('vl-queue-summary-import-count').innerHTML = summary.imported + '';
+ dojo.byId('vl-queue-summary-import-item-count').innerHTML = summary.total_items + '';
+ dojo.byId('vl-queue-summary-rec-error-count').innerHTML = summary.rec_import_errors + '';
+ dojo.byId('vl-queue-summary-item-error-count').innerHTML = summary.item_import_errors + '';
}
);
}
diff --git a/Open-ILS/web/opac/locale/en-US/vandelay.dtd b/Open-ILS/web/opac/locale/en-US/vandelay.dtd
index 31fdc67..e94f8c7 100644
--- a/Open-ILS/web/opac/locale/en-US/vandelay.dtd
+++ b/Open-ILS/web/opac/locale/en-US/vandelay.dtd
@@ -36,22 +36,23 @@
<!ENTITY vandelay.id "ID">
<!ENTITY vandelay.import.matches "Import Matches">
<!ENTITY vandelay.import.records "Import Records">
-<!ENTITY vandelay.import.selected "Import Selected">
-<!ENTITY vandelay.import.all "Import All">
+<!ENTITY vandelay.import.selected "Import Selected Records">
+<!ENTITY vandelay.import.all "Import All Records">
<!ENTITY vandelay.import.time "Import Time">
<!ENTITY vandelay.inspect.queue "Inspect Queue">
<!ENTITY vandelay.last.edit.date "Last Edit Date">
-<!ENTITY vandelay.limit.to.collision.matches "Limit to Collision Matches">
+<!ENTITY vandelay.limit.to.collision.matches "Limit to Records with Matches">
<!ENTITY vandelay.limit.to.non.imported "Limit to Non-Imported Records">
+<!ENTITY vandelay.limit.to.import_error "Limit to Records with Import Errors">
<!ENTITY vandelay.marc.file.upload "Evergreen MARC File Upload">
<!ENTITY vandelay.marc.record "MARC Record">
<!ENTITY vandelay.matches "Matches">
-<!ENTITY vandelay.next.page "Next Page »">
+<!ENTITY vandelay.next.page "Next »">
<!ENTITY vandelay.overlay.selected.record "Overlay selected record with imported record">
<!ENTITY vandelay.overlay.target "Overlay Target">
<!ENTITY vandelay.page "Page">
<!ENTITY vandelay.powered.by.evergreen "Powered by Evergreen!">
-<!ENTITY vandelay.prev.page "« Previous Page">
+<!ENTITY vandelay.prev.page "« Previous">
<!ENTITY vandelay.processing "Processing... ">
<!ENTITY vandelay.queue "Queue">
<!ENTITY vandelay.queue.type "Queue Type">
@@ -60,7 +61,7 @@
<!ENTITY vandelay.refresh "Refresh">
<!ENTITY vandelay.remove.advanced "Remove (advanced)">
<!ENTITY vandelay.remove "Remove">
-<!ENTITY vandelay.results.per.page "Results Per Page">
+<!ENTITY vandelay.results.per.page "Records Per Page">
<!ENTITY vandelay.retrieve.queue "Retrieve Queue">
<!ENTITY vandelay.return "Return">
<!ENTITY vandelay.select.cols "Select Columns">
@@ -106,7 +107,7 @@
<!ENTITY vandelay.export.field_no_hint "(starting from 0)">
<!ENTITY vandelay.export.bucket "Record Bucket ID">
<!ENTITY vandelay.select_actions "-- Actions --">
-<!ENTITY vandelay.queue.total "Total:">
-<!ENTITY vandelay.queue.imported "Imported:">
+<!ENTITY vandelay.queue.total "Records in Queue:">
+<!ENTITY vandelay.queue.imported "Records Imported:">
<!ENTITY vandelay.queue.column_picker.title "Column Picker">
<!ENTITY vandelay.import.bib_sources "Select a Record Source">
diff --git a/Open-ILS/web/templates/default/vandelay/inc/queue.tt2 b/Open-ILS/web/templates/default/vandelay/inc/queue.tt2
index 4308898..25e22a2 100644
--- a/Open-ILS/web/templates/default/vandelay/inc/queue.tt2
+++ b/Open-ILS/web/templates/default/vandelay/inc/queue.tt2
@@ -1,66 +1,109 @@
-<div dojoType="dijit.layout.ContentPane" layoutAlign='client'>
- <table class='wide'>
- <tr>
- <td align='left'>
- <h1>&vandelay.record.queue; <span style='font-style:italic;' id='vl-queue-summary-name'/></h1><br/>
- </td>
- <td align='right'>
- &vandelay.queue.total; <span style='font-weight:bold;' id='vl-queue-summary-total-count'/>
- &vandelay.queue.imported; <span style='font-weight:bold;' id='vl-queue-summary-import-count'/>
- </td>
- </tr>
- </table>
-</div>
-
-<br/>
-
-<div jsId='queueItemsImportDialog' dojoType="dijit.Dialog" title="Import Items">
- <div dojoType="dijit.layout.ContentPane">
- <table class='form_table'>
- <tbody>
+<div dojoType="dijit.layout.ContentPane" layoutAlign='client' style='margin-top:10px;'>
+ <fieldset id='vl-queue-filter-fieldset'>
+ <legend>Queue <span style='font-style:italic;' id='vl-queue-summary-name'/></legend>
+ <table width='100%'><tr>
+ <td> <!-- big left td -->
+ <table>
<tr>
- <td>&vandelay.auto.import.noncolliding;</td>
- <td colspan='4'>
- <input jsId='vlUploadQueueAutoImport2' dojoType='dijit.form.CheckBox'/>
+ <td valign='top'>
+ <table class='queue-nav-table'>
+ <thead><tr><th colspan='2' class='queue-nav-table-label'>Queue Actions</th></tr></thead>
+ <tbody>
+ <tr><td><a href='#' onclick='vlHandleQueueItemsAction("import")'>&vandelay.import.selected;</a></td></tr>
+ <tr><td><a href='#' onclick='vlHandleQueueItemsAction("import_all")'>&vandelay.import.all;</a></td></tr>
+ <tr><td><a href='#' onclick='alert("coming soon"); return;vlHandleQueueItemsAction("item_errors")'>View Item Import Failures</a></td></tr>
+ <tr><td><a href='#' onclick='
+ if(confirm("&vandelay.sure.to.delete.queue;")) {
+ vlDeleteQueue(currentType, currentQueueId,
+ function() { displayGlobalDiv("vl-marc-upload-div"); });}'>&vandelay.delete.queue;</a></td></tr>
+ </tbody>
+ </table>
</td>
- </tr>
- <tr>
- <td>&vandelay.auto.import.auto_overlay_exact;</td>
- <td colspan='4'>
- <input jsId='vlUploadQueueAutoOverlayExact2' dojoType='dijit.form.CheckBox'/>
- </td>
- </tr>
- <tr>
- <td>&vandelay.auto.import.auto_overlay_1match;</td>
- <td colspan='4'>
- <input jsId='vlUploadQueueAutoOverlay1Match2' dojoType='dijit.form.CheckBox'/>
- </td>
- </tr>
- <tr>
- <td>&vandelay.auto.import.merge_profile;</td>
- <td colspan='4'>
- <div jsId='vlUploadMergeProfile2'
- dojoType='dijit.form.FilteringSelect' required='false' labelAttr='name' searchAttr='name'/>
- </td>
- </tr>
- <tr>
- <td>
- <button dojoType='dijit.form.Button' jsId='queueItemsImportCancelButton'>Cancel</button>
+
+ <td valign='top'>
+ <table id='vl-queue-summary-table' class='queue-nav-table'>
+ <thead><tr><th colspan='2' class='queue-nav-table-label'>Queue Summary</th></tr></thead>
+ <tbody>
+ <tr><td>&vandelay.queue.total;</td><td> <span style='font-weight:bold;' id='vl-queue-summary-total-count'/></td></tr>
+ <tr><td>&vandelay.queue.imported;</td><td> <span style='font-weight:bold;' id='vl-queue-summary-import-count'/></td></tr>
+ <tr><td>Record Import Failures</td><td> <span style='font-weight:bold;' id='vl-queue-summary-rec-error-count'/></td></tr>
+ <tr><td>Items in Queue</td><td> <span style='font-weight:bold;' id='vl-queue-summary-import-item-count'/></td></tr>
+ <tr><td>Item Import Failures</td><td> <span style='font-weight:bold;' id='vl-queue-summary-item-error-count'/></td></tr>
+ </tbody>
+ </table>
</td>
- <td>
- <button dojoType='dijit.form.Button' jsId='queueItemsImportGoButton'>Import</button>
+
+ <td valign='top'> <!-- filters -->
+ <table id='vl-queue-filter-table' class='queue-nav-table'>
+ <thead><tr><th colspan='2' class='queue-nav-table-label'>Queue Filters</th></tr></thead>
+ <tbody>
+ <tr>
+ <td>&vandelay.limit.to.collision.matches;</td>
+ <td>
+ <input dojoType='dijit.form.CheckBox'
+ jsId='vlQueueGridShowMatches' onchange='retrieveQueuedRecords();'/>
+ </td>
+ </tr>
+ <tr>
+ <td>&vandelay.limit.to.non.imported;</td>
+ <td>
+ <input dojoType='dijit.form.CheckBox'
+ jsId='vlQueueGridShowNonImport' onchange='retrieveQueuedRecords();'/>
+ </td>
+ </tr>
+ <tr>
+ <td>&vandelay.limit.to.import_error;</td>
+ <td>
+ <input dojoType='dijit.form.CheckBox'
+ jsId='vlQueueGridShowImportErrors' onchange='retrieveQueuedRecords();'/>
+ </td>
+ </tr>
+ </tbody>
+ </table>
</td>
</tr>
- </tbody>
- </table>
- </div>
+ </table>
+ </td>
+
+ <td align='right' valign='bottom'> <!-- big right td -->
+ <table id='vl-queue-paging-table' class='queue-nav-table'>
+ <tbody>
+ <tr><td valign='bottom' align='right'>
+ <span style='padding-right:5px;'>&vandelay.results.per.page;</span>
+ <span class='queue-pager-span'>
+ <select jsId='vlQueueDisplayLimit' id='vl-queue-display-limit-selector'
+ value='10' onchange='retrieveQueuedRecords();'>
+ <option value='10'>10</option>
+ <option value='20'>20</option>
+ <option value='50'>50</option>
+ <option value='100'>100</option>
+ </select>
+ </span>
+
+ <span class='queue-pager-span'>
+ <span style='padding-left:5px;'>&vandelay.page;</span>
+ <input style='width:36px;' dojoType='dijit.form.TextBox' jsId='vlQueueDisplayPage' value='1'/>
+ </span>
+
+ <span style='padding-right:8px;'>
+ <a href='javascript:void(0);' onclick='vlQueueGridPrevPage();'>&vandelay.prev.page;</a>
+ </span>
+ <span style='padding-right:10px;'>
+ <a href='javascript:void(0);' onclick='vlQueueGridNextPage();'>&vandelay.next.page;</a>
+ </span>
+ </td></tr>
+ </tbody>
+ </table>
+ </td>
+ </tr></table>
+ </fieldset>
</div>
<!-- queue grid navigation row -->
<div dojoType="dijit.layout.ContentPane" layoutAlign='client'>
-
<table width='100%' style='margin-bottom:0px;'>
<tr>
+ <!--
<td align='left' valign='bottom'>
<select id='vl-queue-actions-selector'>
<option selected='selected' disabled='disabled' value='select-actions'>&vandelay.select_actions;</option>
@@ -84,38 +127,21 @@
}
</script>
</td>
- <td align='middle' valign='bottom'>
+ <td align='right' valign='bottom'>
<style type="text/css">.filter_span { padding-right: 5px; border-right: 2px solid #e8e1cf; } </style>
- <table><tr>
- <td>
- <span>&vandelay.limit.to.collision.matches;</span>
- <span class='filter_span'>
- <input dojoType='dijit.form.CheckBox' jsId='vlQueueGridShowMatches' onchange='retrieveQueuedRecords();'/>
- </span>
-
- <span>&vandelay.limit.to.non.imported;</span>
- <span class='filter_span'>
- <input dojoType='dijit.form.CheckBox'
- jsId='vlQueueGridShowNonImport' onchange='retrieveQueuedRecords();'/>
- </span>
-
- <span>&vandelay.results.per.page;</span>
- <span class='filter_span'>
- <select jsId='vlQueueDisplayLimit' id='vl-queue-display-limit-selector'
- value='10' onchange='retrieveQueuedRecords();'>
- <option value='10'>10</option>
- <option value='20'>20</option>
- <option value='50'>50</option>
- <option value='100'>100</option>
- </select>
- </span>
+ <span>&vandelay.results.per.page;</span>
+ <span class='filter_span'>
+ <select jsId='vlQueueDisplayLimit' id='vl-queue-display-limit-selector'
+ value='10' onchange='retrieveQueuedRecords();'>
+ <option value='10'>10</option>
+ <option value='20'>20</option>
+ <option value='50'>50</option>
+ <option value='100'>100</option>
+ </select>
+ </span>
+ <span style='padding-left:5px;'>&vandelay.page;</span>
+ <input style='width:36px;' dojoType='dijit.form.TextBox' jsId='vlQueueDisplayPage' value='1'/>
- <span style='padding-left:5px;'>&vandelay.page;</span>
- <input style='width:36px;' dojoType='dijit.form.TextBox' jsId='vlQueueDisplayPage' value='1'/>
- </td>
- </tr></table>
- </td>
- <td align='right' valign='bottom'>
<span style='padding-right:4px;'>
<a href='javascript:void(0);' onclick='vlQueueGridPrevPage();'>&vandelay.prev.page;</a>
</span>
@@ -123,6 +149,7 @@
<a href='javascript:void(0);' onclick='vlQueueGridNextPage();'>&vandelay.next.page;</a>
</span>
</td>
+ -->
</tr>
</table>
</div>
@@ -158,7 +185,7 @@
get='vlGetViewErrors'
formatter='vlFormatViewErrors'
styles='text-align: center;'
- nonSelectable='true'>Import Errors</th>
+ nonSelectable='true'>Import Failures</th>
<th
field='import_time'
styles='text-align: center;'
@@ -199,7 +226,7 @@
get='vlGetViewErrors'
formatter='vlFormatViewErrors'
styles='text-align: center;'
- nonSelectable='true'>Import Errors</th>
+ nonSelectable='true'>Import Failures</th>
<th
field='import_time'
styles='text-align: center;'
@@ -210,4 +237,47 @@
<div/>
</div>
+<div jsId='queueItemsImportDialog' dojoType="dijit.Dialog" title="Import Items">
+ <div dojoType="dijit.layout.ContentPane">
+ <table class='form_table'>
+ <tbody>
+ <tr>
+ <td>&vandelay.auto.import.noncolliding;</td>
+ <td colspan='4'>
+ <input jsId='vlUploadQueueAutoImport2' dojoType='dijit.form.CheckBox'/>
+ </td>
+ </tr>
+ <tr>
+ <td>&vandelay.auto.import.auto_overlay_exact;</td>
+ <td colspan='4'>
+ <input jsId='vlUploadQueueAutoOverlayExact2' dojoType='dijit.form.CheckBox'/>
+ </td>
+ </tr>
+ <tr>
+ <td>&vandelay.auto.import.auto_overlay_1match;</td>
+ <td colspan='4'>
+ <input jsId='vlUploadQueueAutoOverlay1Match2' dojoType='dijit.form.CheckBox'/>
+ </td>
+ </tr>
+ <tr>
+ <td>&vandelay.auto.import.merge_profile;</td>
+ <td colspan='4'>
+ <div jsId='vlUploadMergeProfile2'
+ dojoType='dijit.form.FilteringSelect' required='false' labelAttr='name' searchAttr='name'/>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <button dojoType='dijit.form.Button' jsId='queueItemsImportCancelButton'>Cancel</button>
+ </td>
+ <td>
+ <button dojoType='dijit.form.Button' jsId='queueItemsImportGoButton'>Import</button>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+</div>
+
+
commit 7e245cb05b5978b19c7f7f5236cff93906e11718
Author: berick <berick at esilibrary.com>
Date: Mon Apr 25 16:33:48 2011 -0400
add error and item import/error summary info to queue summary api call
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
index b431422..7f34422 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
@@ -1128,11 +1128,41 @@ sub retrieve_queue_summary {
my $search = 'search_vandelay_queued_bib_record';
$search =~ s/bib/authority/ if $type ne 'bib';
- return {
+ my $summary = {
queue => $queue,
total => scalar(@{$e->$search({queue => $queue_id}, {idlist=>1})}),
imported => scalar(@{$e->$search({queue => $queue_id, import_time => {'!=' => undef}}, {idlist=>1})}),
};
+
+ my $class = ($type eq 'bib') ? 'vqbr' : 'vqar';
+ $summary->{rec_import_errors} = $e->json_query({
+ select => {$class => [{alias => 'count', column => 'id', transform => 'count', aggregate => 1}]},
+ from => $class,
+ where => {queue => $queue_id, import_error => {'!=' => undef}}
+ })->[0]->{count};
+
+ if($type eq 'bib') {
+
+ my $query = {
+ select => {vii => [{alias => 'count', column => 'id', transform => 'count', aggregate => 1}]},
+ from => 'vii',
+ where => {
+ record => {
+ in => {
+ select => {vqbr => ['id']},
+ from => 'vqbr',
+ where => {queue => $queue_id}
+ }
+ }
+ }
+ };
+
+ $summary->{total_items} = $e->json_query($query)->[0]->{count};
+ $query->{where}->{import_error} = {'!=' => undef};
+ $summary->{item_import_errors} = $e->json_query($query)->[0]->{count};
+ }
+
+ return $summary;
}
# --------------------------------------------------------------------------------
commit 41432f29df97e0ca44a7ac4dc7163f8ce7900803
Author: berick <berick at esilibrary.com>
Date: Mon Apr 25 14:16:35 2011 -0400
No longer limit to non-imported items by default in queue display
diff --git a/Open-ILS/web/templates/default/vandelay/inc/queue.tt2 b/Open-ILS/web/templates/default/vandelay/inc/queue.tt2
index 5c87243..4308898 100644
--- a/Open-ILS/web/templates/default/vandelay/inc/queue.tt2
+++ b/Open-ILS/web/templates/default/vandelay/inc/queue.tt2
@@ -95,8 +95,8 @@
<span>&vandelay.limit.to.non.imported;</span>
<span class='filter_span'>
- <input dojoType='dijit.form.CheckBox' jsId='vlQueueGridShowNonImport'
- checked='checked' onchange='retrieveQueuedRecords();'/>
+ <input dojoType='dijit.form.CheckBox'
+ jsId='vlQueueGridShowNonImport' onchange='retrieveQueuedRecords();'/>
</span>
<span>&vandelay.results.per.page;</span>
commit ff2ab6bfd10050306dbbb65e1134703433b6b46a
Author: berick <berick at esilibrary.com>
Date: Mon Apr 25 13:45:21 2011 -0400
hide item import error grid when not in use
misc. bug fixes
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
index 59dc39b..b431422 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
@@ -1161,6 +1161,7 @@ sub import_record_asset_list_impl {
my $item = $e->retrieve_vandelay_import_item($item_id);
$report_args{progress}++;
$report_args{import_item} = $item;
+ $report_args{e} = $e;
# --------------------------------------------------------------------------------
# Find or create the volume
@@ -1199,23 +1200,30 @@ sub import_record_asset_list_impl {
# see if a valid circ_modifier was provided
# --------------------------------------------------------------------------------
if($copy->circ_modifier and not $e->search_config_circ_modifier({code=>$item->circ_modifier})->[0]) {
- $report_args{import_error} = 'import.item.invalid.circ_modifier';
- respond_with_status(%report_args, evt => $e->die_event);
+ respond_with_status(
+ %report_args,
+ evt => $e->die_event,
+ import_error => 'import.item.invalid.circ_modifier'
+ );
next;
}
if($copy->location and not $e->retrieve_asset_copy_location($copy->location)) {
- $report_args{import_error} = 'import.item.invalid.location';
- respond_with_status(%report_args, evt => $e->die_event);
+ respond_with_status(
+ %report_args,
+ evt => $e->die_event,
+ import_error => 'import.item.invalid.location'
+ );
next;
}
if($evt = OpenILS::Application::Cat::AssetCommon->create_copy($e, $vol, $copy)) {
- try { $e->rollback } otherwise {}; # sometimes calls die_event, sometimes not
- $report_args{evt} = $evt;
- $report_args{import_error} = 'import.item.duplicate.barcode'
- if $evt->{textcode} eq 'ITEM_BARCODE_EXISTS';
- respond_with_status(%report_args);
+ respond_with_status(
+ %report_args,
+ evt => $evt,
+ import_error => ($evt->{textcode} eq 'ITEM_BARCODE_EXISTS') ?
+ 'import.item.duplicate.barcode' : undef
+ );
next;
}
@@ -1243,7 +1251,8 @@ sub import_record_asset_list_impl {
# --------------------------------------------------------------------------------
$e->commit;
$report_args{in_count}++;
- respond_with_status(%report_args, imported_as => $copy->id)
+ respond_with_status(%report_args, imported_as => $copy->id);
+ $logger->info("vl: successfully imported item " . $item->barcode);
}
}
$roe->rollback;
@@ -1253,6 +1262,7 @@ sub import_record_asset_list_impl {
sub respond_with_status {
my %args = @_;
+ my $e = $args{e};
# If the import failed, track the failure reason
@@ -1262,8 +1272,9 @@ sub respond_with_status {
if($error or $evt) {
my $item = $args{import_item};
+ $logger->info("vl: unable to import item " . $item->barcode);
- my $error ||= 'general.unknown';
+ $error ||= 'general.unknown';
$item->import_error($error);
if($evt) {
@@ -1271,7 +1282,9 @@ sub respond_with_status {
$item->error_detail($detail);
}
- my $e = new_editor(xact => 1);
+ # state of the editor is unknown at this point. Force a rollback and start over.
+ $e->rollback;
+ $e = new_editor(xact => 1);
$e->update_vandelay_import_item($item);
$e->commit;
}
diff --git a/Open-ILS/web/js/ui/default/vandelay/vandelay.js b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
index 344f2ec..490d84c 100644
--- a/Open-ILS/web/js/ui/default/vandelay/vandelay.js
+++ b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
@@ -616,9 +616,18 @@ function vlLoadErrorUI(id) {
openils.Util.hide(dojo.byId(eid).parentNode);
}
}
- )
- dojo.byId('vl-error-import-error').innerHTML = rec.import_error();
- dojo.byId('vl-error-error-detail').innerHTML = rec.error_detail();
+ );
+ var iediv = dojo.byId('vl-error-import-error');
+ var eddiv = dojo.byId('vl-error-error-detail');
+ if(rec.import_error()) {
+ openils.Util.show(iediv.parentNode, 'table-row');
+ openils.Util.show(eddiv.parentNode, 'table-row');
+ iediv.innerHTML = rec.import_error();
+ eddiv.innerHTML = rec.error_detail();
+ } else {
+ openils.Util.hide(iediv.parentNode);
+ openils.Util.hide(eddiv.parentNode);
+ }
var errorItems = rec.import_items().filter(function(i) {return i.import_error()});
if(errorItems.length) {
@@ -627,6 +636,8 @@ function vlLoadErrorUI(id) {
var store = new dojo.data.ItemFileReadStore({data:storeData});
vlImportErrorGrid.setStore(store);
vlImportErrorGrid.update();
+ } else {
+ openils.Util.hide('vl-import-error-grid-some');
}
}
commit 19bb47e04e1de3764fc1e3b93be7589bae0d0e14
Author: berick <berick at esilibrary.com>
Date: Mon Apr 25 11:38:52 2011 -0400
show rec summary and import failure reason when appropriate
diff --git a/Open-ILS/web/css/skin/default/vandelay.css b/Open-ILS/web/css/skin/default/vandelay.css
index d60ba06..7476377 100644
--- a/Open-ILS/web/css/skin/default/vandelay.css
+++ b/Open-ILS/web/css/skin/default/vandelay.css
@@ -28,3 +28,9 @@ table.dijitTooltipTable { border-collapse: separate; }
.export_tr_border td { border-top: 1px solid #808080; }
.nav_row_div {padding:1px; text-align:center; }
.toolbar_selected { border: 2px dashed #808080; text-decoration:underline; font-weight:bold;}
+
+#vl-import-error-record { margin: 10px; }
+#vl-import-error-record tr:nth-child(even) {background: #EEE}
+#vl-import-error-record td:first-child { text-decoration: underline; }
+#vl-import-error-record td { padding: 5px; }
+#vl-error-import-error { font-weight: bold; }
diff --git a/Open-ILS/web/js/ui/default/vandelay/vandelay.js b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
index 68eeb0e..344f2ec 100644
--- a/Open-ILS/web/js/ui/default/vandelay/vandelay.js
+++ b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
@@ -588,7 +588,7 @@ function vlFormatViewErrors(chunk) {
var count = chunk.split(':')[2];
var links = '';
if(rec)
- links += '<a href="javascript:void(0);" onclick="vlLoadErrorUI(' + id + ');"><b>Record</b></a><br/>'; // TODO I18N
+ links += '<a href="javascript:void(0);" onclick="vlLoadErrorUI(' + id + ');">Record</a><br/>'; // TODO I18N
if(Number(count))
links += '<a href="javascript:void(0);" onclick="vlLoadErrorUI(' + id + ');">Items ('+count+')</a>'; // TODO I18N
return links;
@@ -598,15 +598,31 @@ function vlFormatViewErrors(chunk) {
function vlLoadErrorUI(id) {
displayGlobalDiv('vl-import-error-div');
- openils.Util.show('vl-import-error-grid-some');
openils.Util.hide('vl-import-error-grid-all');
+ openils.Util.show('vl-import-error-record');
var rec = queuedRecordsMap[id];
- /* TODO: show record attrs and whether it failed import */
+ dojo.byId('vl-error-id').innerHTML = rec.id();
+ dojo.forEach( // TODO sane authority rec. fields
+ ['title', 'author', 'isbn', 'issn', 'upc'],
+ function(field) {
+ var attr = getRecAttrFromCode(rec, field);
+ var eid = 'vl-error-' + field;
+ if(attr) {
+ openils.Util.show(dojo.byId(eid).parentNode, 'table-row');
+ dojo.byId(eid).innerHTML = attr.attr_value();
+ } else {
+ openils.Util.hide(dojo.byId(eid).parentNode);
+ }
+ }
+ )
+ dojo.byId('vl-error-import-error').innerHTML = rec.import_error();
+ dojo.byId('vl-error-error-detail').innerHTML = rec.error_detail();
var errorItems = rec.import_items().filter(function(i) {return i.import_error()});
- if(errorItems) {
+ if(errorItems.length) {
+ openils.Util.show('vl-import-error-grid-some');
storeData = vqbr.toStoreData(errorItems);
var store = new dojo.data.ItemFileReadStore({data:storeData});
vlImportErrorGrid.setStore(store);
diff --git a/Open-ILS/web/templates/default/vandelay/inc/import_errors.tt2 b/Open-ILS/web/templates/default/vandelay/inc/import_errors.tt2
index 5490133..6b08db4 100644
--- a/Open-ILS/web/templates/default/vandelay/inc/import_errors.tt2
+++ b/Open-ILS/web/templates/default/vandelay/inc/import_errors.tt2
@@ -6,40 +6,56 @@
</div>
<div dojoType="dijit.layout.ContentPane" layoutAlign='client'>
- <table id='import-error-table'>
+ <table id='vl-import-error-record' class='hidden'>
+ <tbody>
+ <tr><td>ID</td><td id='vl-error-id'/></tr>
+ <tr><td>Import Error</td><td id='vl-error-import-error'/></tr>
+ <tr><td>Error Detail</td><td id='vl-error-error-detail'/></tr>
+ <tr><td>Title</td><td id='vl-error-title'/></tr>
+ <tr><td>Author</td><td id='vl-error-author'/></tr>
+ <tr><td>ISBN</td><td id='vl-error-isbn'/></tr>
+ <tr><td>ISSN</td><td id='vl-error-issn'/></tr>
+ <tr><td>UPC</td><td id='vl-error-upc'/></tr>
+ </tbody>
</table>
</div>
-<div dojoType="dijit.layout.ContentPane" layoutAlign='client' class='hidden' id='vl-import-error-grid-some'>
- <table jsId="vlImportErrorGrid"
- dojoType="openils.widget.AutoGrid"
- autoHeight='true'
- fieldOrder="['barcode', 'call_number', 'owning_lib', 'import_error', 'error_detail']"
- query="{id: '*'}"
- hidePaginator='true'
- showColumnPicker='true'
- columnPickerPrefix='"vandelay.item.import_error"'
- fmClass='vii'>
- <thead>
- <th field='owning_lib' get='vlGetOrg'/>
- <th field='circ_lib' get='vlGetOrg'/>
- </thead>
- </table>
+<div dojoType="dijit.layout.ContentPane" layoutAlign='client'>
+ <div class='hidden' id='vl-import-error-grid-some'>
+ <h3>Item Import Errors</h3>
+ <table jsId="vlImportErrorGrid"
+ dojoType="openils.widget.AutoGrid"
+ autoHeight='true'
+ fieldOrder="['barcode', 'call_number', 'owning_lib', 'import_error', 'error_detail']"
+ query="{id: '*'}"
+ hidePaginator='true'
+ showColumnPicker='true'
+ columnPickerPrefix='"vandelay.item.import_error"'
+ fmClass='vii'>
+ <thead>
+ <th field='owning_lib' get='vlGetOrg'/>
+ <th field='circ_lib' get='vlGetOrg'/>
+ </thead>
+ </table>
+ </div>
</div>
-<div dojoType="dijit.layout.ContentPane" layoutAlign='client' class='hidden' id='vl-import-error-grid-all'>
- <table jsId="vlAllImportErrorGrid"
- dojoType="openils.widget.AutoGrid"
- autoHeight='true'
- fieldOrder="['barcode', 'call_number', 'owning_lib', 'import_error', 'error_detail']"
- query="{id: '*'}"
- showPaginator='true'
- showColumnPicker='true'
- columnPickerPrefix='"vandelay.item.import_error"'
- fmClass='vii'>
- <thead>
- <th field='owning_lib' get='vlGetOrg'/>
- <th field='circ_lib' get='vlGetOrg'/>
- </thead>
- </table>
+<div dojoType="dijit.layout.ContentPane" layoutAlign='client'>
+ <div class='hidden' id='vl-import-error-grid-all'>
+ <h3>Item Import Errors</h3>
+ <table jsId="vlAllImportErrorGrid"
+ dojoType="openils.widget.AutoGrid"
+ autoHeight='true'
+ fieldOrder="['barcode', 'call_number', 'owning_lib', 'import_error', 'error_detail']"
+ query="{id: '*'}"
+ showPaginator='true'
+ showColumnPicker='true'
+ columnPickerPrefix='"vandelay.item.import_error"'
+ fmClass='vii'>
+ <thead>
+ <th field='owning_lib' get='vlGetOrg'/>
+ <th field='circ_lib' get='vlGetOrg'/>
+ </thead>
+ </table>
+ </div>
</div>
commit f44258e7f54013e6c64f1aeeb617f4b7f016a696
Author: berick <berick at esilibrary.com>
Date: Mon Apr 25 11:02:55 2011 -0400
show item import error counts and rec import error as link to error page; initial error page
diff --git a/Open-ILS/web/js/ui/default/vandelay/vandelay.js b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
index 7eece79..68eeb0e 100644
--- a/Open-ILS/web/js/ui/default/vandelay/vandelay.js
+++ b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
@@ -57,7 +57,8 @@ var globalDivs = [
'vl-attr-editor-div',
'vl-marc-export-div',
'vl-profile-editor-div',
- 'vl-item-attr-editor-div'
+ 'vl-item-attr-editor-div',
+ 'vl-import-error-div'
];
var authtoken;
@@ -587,12 +588,39 @@ function vlFormatViewErrors(chunk) {
var count = chunk.split(':')[2];
var links = '';
if(rec)
- links += '<a href="javascript:void(0);" onclick="vlLoadErrorUI(' + id + ');"><b>Record</b></a><br/>'; // XXX I18N
+ links += '<a href="javascript:void(0);" onclick="vlLoadErrorUI(' + id + ');"><b>Record</b></a><br/>'; // TODO I18N
if(Number(count))
- links += '<a href="javascript:void(0);" onclick="vlLoadErrorUI(' + id + ');"><b>Items ('+count+')</b></a>'; // XXX I18N
+ links += '<a href="javascript:void(0);" onclick="vlLoadErrorUI(' + id + ');">Items ('+count+')</a>'; // TODO I18N
return links;
}
+//var vlItemErrorColumnPicker;
+function vlLoadErrorUI(id) {
+
+ displayGlobalDiv('vl-import-error-div');
+ openils.Util.show('vl-import-error-grid-some');
+ openils.Util.hide('vl-import-error-grid-all');
+
+ var rec = queuedRecordsMap[id];
+
+ /* TODO: show record attrs and whether it failed import */
+
+ var errorItems = rec.import_items().filter(function(i) {return i.import_error()});
+ if(errorItems) {
+ storeData = vqbr.toStoreData(errorItems);
+ var store = new dojo.data.ItemFileReadStore({data:storeData});
+ vlImportErrorGrid.setStore(store);
+ vlImportErrorGrid.update();
+ }
+}
+
+function vlGetOrg(rowIdx, item) {
+ if(!item) return '';
+ var value = this.grid.store.getValue(item, this.field);
+ if(value) return fieldmapper.aou.findOrgUnit(value).shortname();
+ return '';
+}
+
function vlFormatViewMatchMARC(id) {
return '<a href="javascript:void(0);" onclick="vlLoadMARCHtml(' + id + ', true, '+
'function(){displayGlobalDiv(\'vl-match-div\');});">' + this.name + '</a>';
diff --git a/Open-ILS/web/templates/default/vandelay/inc/import_errors.tt2 b/Open-ILS/web/templates/default/vandelay/inc/import_errors.tt2
new file mode 100644
index 0000000..5490133
--- /dev/null
+++ b/Open-ILS/web/templates/default/vandelay/inc/import_errors.tt2
@@ -0,0 +1,45 @@
+<h1>Import Errors</h1><br/>
+
+<div dojoType="dijit.layout.ContentPane" layoutAlign='client'>
+ <button dojoType='dijit.form.Button'
+ onclick="displayGlobalDiv('vl-queue-div');">↖ &vandelay.back.to.import.queue;</button>
+</div>
+
+<div dojoType="dijit.layout.ContentPane" layoutAlign='client'>
+ <table id='import-error-table'>
+ </table>
+</div>
+
+<div dojoType="dijit.layout.ContentPane" layoutAlign='client' class='hidden' id='vl-import-error-grid-some'>
+ <table jsId="vlImportErrorGrid"
+ dojoType="openils.widget.AutoGrid"
+ autoHeight='true'
+ fieldOrder="['barcode', 'call_number', 'owning_lib', 'import_error', 'error_detail']"
+ query="{id: '*'}"
+ hidePaginator='true'
+ showColumnPicker='true'
+ columnPickerPrefix='"vandelay.item.import_error"'
+ fmClass='vii'>
+ <thead>
+ <th field='owning_lib' get='vlGetOrg'/>
+ <th field='circ_lib' get='vlGetOrg'/>
+ </thead>
+ </table>
+</div>
+<div dojoType="dijit.layout.ContentPane" layoutAlign='client' class='hidden' id='vl-import-error-grid-all'>
+ <table jsId="vlAllImportErrorGrid"
+ dojoType="openils.widget.AutoGrid"
+ autoHeight='true'
+ fieldOrder="['barcode', 'call_number', 'owning_lib', 'import_error', 'error_detail']"
+ query="{id: '*'}"
+ showPaginator='true'
+ showColumnPicker='true'
+ columnPickerPrefix='"vandelay.item.import_error"'
+ fmClass='vii'>
+ <thead>
+ <th field='owning_lib' get='vlGetOrg'/>
+ <th field='circ_lib' get='vlGetOrg'/>
+ </thead>
+ </table>
+</div>
+
diff --git a/Open-ILS/web/templates/default/vandelay/vandelay.tt2 b/Open-ILS/web/templates/default/vandelay/vandelay.tt2
index 2e2a2e0..4ca2f37 100644
--- a/Open-ILS/web/templates/default/vandelay/vandelay.tt2
+++ b/Open-ILS/web/templates/default/vandelay/vandelay.tt2
@@ -40,6 +40,9 @@
<div dojoType="dijit.layout.ContentPane" layoutAlign='client' id='vl-item-attr-editor-div' class='hidden content'>
[% INCLUDE 'default/vandelay/inc/item_attrs.tt2' %]
</div>
+<div dojoType="dijit.layout.ContentPane" layoutAlign='client' id='vl-import-error-div' class='hidden content'>
+ [% INCLUDE 'default/vandelay/inc/import_errors.tt2' %]
+</div>
[% END %]
commit d50e03f75c2fa5635e715dcaa8f057f577a508f1
Author: berick <berick at esilibrary.com>
Date: Mon Apr 25 09:58:19 2011 -0400
record / item import failures summar links
diff --git a/Open-ILS/web/js/ui/default/vandelay/vandelay.js b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
index a54005f..7eece79 100644
--- a/Open-ILS/web/js/ui/default/vandelay/vandelay.js
+++ b/Open-ILS/web/js/ui/default/vandelay/vandelay.js
@@ -369,7 +369,7 @@ function retrieveQueuedRecords(type, queueId, onload) {
var limit = parseInt(sel.options[sel.selectedIndex].value);
var offset = limit * parseInt(vlQueueDisplayPage.attr('value')-1);
- var params = [authtoken, queueId, {clear_marc: 1, offset: offset, limit: limit}];
+ var params = [authtoken, queueId, {clear_marc: 1, offset: offset, limit: limit, flesh_import_items:1}];
if(vlQueueGridShowNonImport.checked)
params[2].non_imported = 1;
@@ -568,6 +568,31 @@ function vlFormatViewMatches(id) {
return '<a href="javascript:void(0);" onclick="vlLoadMatchUI(' + id + ');">' + this.name + '</a>';
}
+function vlGetViewErrors(rowIdx, item) {
+ if(item) {
+ var id = this.grid.store.getValue(item, 'id');
+ var rec = queuedRecordsMap[id];
+ // id:rec_error:item_import_error_count
+ return id + ':' +
+ (rec.import_error() ? 1 : '') + ':' +
+ rec.import_items().filter(function(i) {return i.import_error()}).length;
+ }
+ return -1
+}
+
+function vlFormatViewErrors(chunk) {
+ if(chunk == -1) return '';
+ var id = chunk.split(':')[0];
+ var rec = chunk.split(':')[1];
+ var count = chunk.split(':')[2];
+ var links = '';
+ if(rec)
+ links += '<a href="javascript:void(0);" onclick="vlLoadErrorUI(' + id + ');"><b>Record</b></a><br/>'; // XXX I18N
+ if(Number(count))
+ links += '<a href="javascript:void(0);" onclick="vlLoadErrorUI(' + id + ');"><b>Items ('+count+')</b></a>'; // XXX I18N
+ return links;
+}
+
function vlFormatViewMatchMARC(id) {
return '<a href="javascript:void(0);" onclick="vlLoadMARCHtml(' + id + ', true, '+
'function(){displayGlobalDiv(\'vl-match-div\');});">' + this.name + '</a>';
diff --git a/Open-ILS/web/templates/default/vandelay/inc/queue.tt2 b/Open-ILS/web/templates/default/vandelay/inc/queue.tt2
index e7d6eaf..5c87243 100644
--- a/Open-ILS/web/templates/default/vandelay/inc/queue.tt2
+++ b/Open-ILS/web/templates/default/vandelay/inc/queue.tt2
@@ -137,7 +137,7 @@
field='+row_selector'
get='vlQueueGridDrawSelectBox'
formatter='vlQueueGridFormatSelectBox'
- styles='text-align: center;'
+ styles='text-align: center;width:30px;'
nonSelectable='true'>
<input id="vl-queue-grid-row-selector" type="checkbox" onclick="vlToggleQueueGridSelect();"></input>
</th>
@@ -154,6 +154,12 @@
styles='text-align: center;'
nonSelectable='true'>&vandelay.matches;</th>
<th
+ field='+get_errors'
+ get='vlGetViewErrors'
+ formatter='vlFormatViewErrors'
+ styles='text-align: center;'
+ nonSelectable='true'>Import Errors</th>
+ <th
field='import_time'
styles='text-align: center;'
get='vlGetDateTimeField'>&vandelay.import.time;</th>
@@ -189,6 +195,12 @@
styles='text-align: center;'
nonSelectable='true'>&vandelay.matches;</th>
<th
+ field='+get_errors'
+ get='vlGetViewErrors'
+ formatter='vlFormatViewErrors'
+ styles='text-align: center;'
+ nonSelectable='true'>Import Errors</th>
+ <th
field='import_time'
styles='text-align: center;'
get='vlGetDateTimeField'>&vandelay.import.time;</th>
commit e14a3f4e11bc91d6cc0100209be4e2147f559301
Author: berick <berick at esilibrary.com>
Date: Mon Apr 25 09:57:13 2011 -0400
added virtual field for import_items to queued record
diff --git a/Open-ILS/examples/fm_IDL.xml b/Open-ILS/examples/fm_IDL.xml
index 0c59bd4..dd522fa 100644
--- a/Open-ILS/examples/fm_IDL.xml
+++ b/Open-ILS/examples/fm_IDL.xml
@@ -327,6 +327,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
<field reporter:label="Purpose" name="purpose" reporter:datatype="text"/>
<field reporter:label="Attributes" name="attributes" oils_persist:virtual="true" reporter:datatype="link"/>
<field reporter:label="Matches" name="matches" oils_persist:virtual="true" reporter:datatype="link"/>
+ <field reporter:label="Import Items" name="import_items" oils_persist:virtual="true" reporter:datatype="link"/>
</fields>
<links>
<link field="import_error" reltype="has_a" key="code" map="" class="vie"/>
@@ -335,6 +336,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
<link field="imported_as" reltype="has_a" key="id" map="" class="bre"/>
<link field="attributes" reltype="has_many" key="record" map="" class="vqbra"/>
<link field="matches" reltype="has_many" key="queued_record" map="" class="vbm"/>
+ <link field="import_items" reltype="has_many" key="record" map="" class="vii"/>
</links>
<permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
<actions>
commit 7cca21c8c126e98a64ec8677d2981d4a472ca26a
Author: berick <berick at esilibrary.com>
Date: Mon Apr 25 09:56:58 2011 -0400
added option to flesh import items on queued record retrieval
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
index 3516fd3..59dc39b 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
@@ -457,10 +457,9 @@ sub retrieve_queued_records {
'retrieve_vandelay_queued_bib_record' : 'retrieve_vandelay_queued_authority_record';
for my $rec_id (@$record_ids) {
- my $params = {
- flesh => 1,
- flesh_fields => {$class => ['attributes', 'matches']},
- };
+ my $flesh = ['attributes', 'matches'];
+ push(@$flesh, 'import_items') if $$options{flesh_import_items};
+ my $params = {flesh => 1, flesh_fields => {$class => $flesh}};
my $rec = $e->$retrieve([$rec_id->{id}, $params]);
$rec->clear_marc if $$options{clear_marc};
$conn->respond($rec);
commit 3585f727e20b8d986e1983213fb6b6677ae169ab
Author: Mike Rylander <mrylander at gmail.com>
Date: Sat Apr 23 11:47:27 2011 -0400
Make sort order of imported item retrieval stable
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
index 9b44160..3516fd3 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
@@ -513,7 +513,7 @@ sub retrieve_queue_import_items {
}
}
},
- order_by => {'vii' => ['record']}
+ order_by => {'vii' => ['record','id']}
};
$query->{where} = {'+vii' => {import_error => {'!=' => undef}}}
commit e1a271d2525911e5c1cdcbb4bb495b6295acb5df
Author: berick <berick at esilibrary.com>
Date: Fri Apr 22 16:58:15 2011 -0400
added api call open-ils.vandelay.import_item.queue.retrieve for fetching import-items by queue, w/ optional has-import-failure filter
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
index 0180832..9b44160 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
@@ -432,7 +432,7 @@ sub retrieve_queued_records {
$query->{where}->{import_time} = undef if $$options{non_imported};
$query->{where}->{import_error} = {'!=' => undef} if $$options{with_rec_import_error};
- if($$options{with_item_import_error}) {
+ if($$options{with_item_import_error} and $type eq 'bib') {
# limit to recs that have at least 1 item import error
$query->{from} = {
$class => {
@@ -470,6 +470,63 @@ sub retrieve_queued_records {
return undef;
}
+__PACKAGE__->register_method(
+ api_name => 'open-ils.vandelay.import_item.queue.retrieve',
+ method => 'retrieve_queue_import_items',
+ api_level => 1,
+ argc => 2,
+ stream => 1,
+ authoritative => 1,
+ signature => q/
+ Returns Import Item (vii) objects for the selected queue.
+ Filter options:
+ with_import_error : only return items that failed to import
+ /
+);
+
+sub retrieve_queue_import_items {
+ my($self, $conn, $auth, $q_id, $options) = @_;
+
+ $options ||= {};
+ my $limit = $$options{limit} || 20;
+ my $offset = $$options{offset} || 0;
+
+ my $e = new_editor(authtoken => $auth);
+ return $e->event unless $e->checkauth;
+
+ my $queue = $e->retrieve_vandelay_bib_queue($q_id) or return $e->event;
+ my $evt = check_queue_perms($e, 'bib', $queue);
+ return $evt if $evt;
+
+ my $query = {
+ select => {vii => ['id']},
+ from => {
+ vii => {
+ vqbr => {
+ join => {
+ 'vbq' => {
+ field => 'id',
+ fkey => 'queue',
+ filter => {id => $q_id}
+ }
+ }
+ }
+ }
+ },
+ order_by => {'vii' => ['record']}
+ };
+
+ $query->{where} = {'+vii' => {import_error => {'!=' => undef}}}
+ if $$options{with_import_error};
+
+ my $items = $e->json_query($query);
+ for my $item (@$items) {
+ $conn->respond($e->retrieve_vandelay_import_item($item->{id}));
+ }
+
+ return undef;
+}
+
sub check_queue_perms {
my($e, $type, $queue) = @_;
if ($type eq 'bib') {
commit 06e1fa2563792748dcebdabbd0a32efa11d559b4
Author: berick <berick at esilibrary.com>
Date: Fri Apr 22 16:14:47 2011 -0400
added with_rec_import_error and with_item_import_error filters to records-by-queue retrieval
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
index 1b48e9a..0180832 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
@@ -396,18 +396,19 @@ __PACKAGE__->register_method(
signature => {
desc => q/Only retrieve queued authority records that have matches against existing records/
}
-
);
sub retrieve_queued_records {
my($self, $conn, $auth, $queue_id, $options) = @_;
- my $e = new_editor(authtoken => $auth, xact => 1);
- return $e->die_event unless $e->checkauth;
+
$options ||= {};
my $limit = $$options{limit} || 20;
my $offset = $$options{offset} || 0;
-
my $type = $self->{record_type};
+
+ my $e = new_editor(authtoken => $auth, xact => 1);
+ return $e->die_event unless $e->checkauth;
+
my $queue;
if($type eq 'bib') {
$queue = $e->retrieve_vandelay_bib_queue($queue_id) or return $e->die_event;
@@ -418,37 +419,53 @@ sub retrieve_queued_records {
return $evt if ($evt);
my $class = ($type eq 'bib') ? 'vqbr' : 'vqar';
- my $search = ($type eq 'bib') ?
- 'search_vandelay_queued_bib_record' : 'search_vandelay_queued_authority_record';
- my $retrieve = ($type eq 'bib') ?
- 'retrieve_vandelay_queued_bib_record' : 'retrieve_vandelay_queued_authority_record';
+ my $query = {
+ select => {$class => ['id']},
+ from => $class,
+ where => {queue => $queue_id},
+ distinct => 1,
+ order_by => {$class => ['id']},
+ limit => $limit,
+ offset => $offset,
+ };
- my $filter = ($$options{non_imported}) ? {import_time => undef} : {};
+ $query->{where}->{import_time} = undef if $$options{non_imported};
+ $query->{where}->{import_error} = {'!=' => undef} if $$options{with_rec_import_error};
+
+ if($$options{with_item_import_error}) {
+ # limit to recs that have at least 1 item import error
+ $query->{from} = {
+ $class => {
+ vii => {
+ field => 'record',
+ fkey => 'id',
+ filter => {import_error => {'!=' => undef}}
+ }
+ }
+ };
+ }
- my $record_ids;
if($self->api_name =~ /matches/) {
- # fetch only matched records
- $record_ids = queued_records_with_matches($e, $type, $queue_id, $limit, $offset, $filter);
- } else {
- # fetch all queue records
- $record_ids = $e->$search([
- {queue => $queue_id, %$filter},
- {order_by => {$class => 'id'}, limit => $limit, offset => $offset}
- ],
- {idlist => 1}
- );
- }
+ # find only records that have matches
+ my $mclass = $type eq 'bib' ? 'vbm' : 'vam';
+ $query->{from} = {$class => {$mclass => {type => 'right'}}};
+ }
+
+ my $record_ids = $e->json_query($query);
+ my $retrieve = ($type eq 'bib') ?
+ 'retrieve_vandelay_queued_bib_record' : 'retrieve_vandelay_queued_authority_record';
for my $rec_id (@$record_ids) {
my $params = {
flesh => 1,
flesh_fields => {$class => ['attributes', 'matches']},
};
- my $rec = $e->$retrieve([$rec_id, $params]);
+ my $rec = $e->$retrieve([$rec_id->{id}, $params]);
$rec->clear_marc if $$options{clear_marc};
$conn->respond($rec);
}
+
$e->rollback;
return undef;
}
commit b61162301e6c81b2be3b0def8438535d2fb4c28b
Author: berick <berick at esilibrary.com>
Date: Fri Apr 22 13:42:08 2011 -0400
rec import bug error capturing bug fixes
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
index 0ea5798..1b48e9a 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
@@ -606,59 +606,6 @@ sub queued_records_with_matches {
return [ map {$_->{queued_record}} @$data ];
}
-# tracks any import errors, commits the current xact, responds to the client
-sub finish_rec_import_attempt {
- my %args = @_;
- my $error = $args{import_error} || 'general.unknown';
- my $evt = $args{evt};
- my $rec = $args{rec};
- my $e = $args{e};
-
- # error tracking
- if($rec) {
-
- if($error or $evt) {
- # since an error occurred, there's no guarantee the transaction wasn't
- # rolled back. force a rollback and create a new editor.
- $e->rollback;
- $e = new_editor(xact => 1);
- $rec->import_error($error);
-
- if($evt) {
- my $detail = sprintf("%s : %s", $evt->{textcode}, substr($evt->{desc}, 0, 140));
- $rec->error_detail($detail);
- }
-
- my $method = 'update_vandelay_queued_bib_record';
- $method =~ s/bib/authority/ if $args{type} eq 'auth';
- $e->$method($rec) and $e->commit or $e->rollback;
-
- } else {
- # successful import
- $e->commit;
- }
-
- } else {
- # requested queued record was not found
- $e->rollback;
- }
-
- # respond to client
- if($args{report_all} or ($args{progress} % $args{step}) == 0) {
-
- $args{conn}->respond({
- total => $args{total},
- progress => $args{progress},
- imported => ($rec) ? $rec->id : undef,
- err_event => $evt
- });
-
- # report often at first, climb quickly, then hold steady
- $args{step} *= 2 unless $args{step} == 256;
- }
-}
-
-
sub import_record_list_impl {
my($self, $conn, $rec_ids, $requestor, $args) = @_;
@@ -822,6 +769,8 @@ sub import_record_list_impl {
if($res->{$auto_overlay_func} eq 't') {
$logger->info("vl: $type auto-overlay succeeded for queued rec " . $rec->id);
$imported = 1;
+ } else {
+ $logger->info("vl: $type auto-overlay failed for queued rec " . $rec->id);
}
} else {
@@ -894,6 +843,66 @@ sub import_record_list_impl {
return undef;
}
+# tracks any import errors, commits the current xact, responds to the client
+sub finish_rec_import_attempt {
+ my %args = @_;
+ my $evt = $args{evt};
+ my $rec = $args{rec};
+ my $e = $args{e};
+
+ my $error = $args{import_error};
+ $error = 'general.unknown' if $evt and not $error;
+
+ # error tracking
+ if($rec) {
+
+ if($error or $evt) {
+ # failed import
+ # since an error occurred, there's no guarantee the transaction wasn't
+ # rolled back. force a rollback and create a new editor.
+ $e->rollback;
+ $e = new_editor(xact => 1);
+ $rec->import_error($error);
+
+ if($evt) {
+ my $detail = sprintf("%s : %s", $evt->{textcode}, substr($evt->{desc}, 0, 140));
+ $rec->error_detail($detail);
+ }
+
+ my $method = 'update_vandelay_queued_bib_record';
+ $method =~ s/bib/authority/ if $args{type} eq 'auth';
+ $e->$method($rec) and $e->commit or $e->rollback;
+
+ } else {
+ # successful import
+ $rec->clear_import_error;
+ $rec->clear_error_detail;
+ $e->commit;
+ }
+
+ } else {
+ # requested queued record was not found
+ $e->rollback;
+ }
+
+ # respond to client
+ if($args{report_all} or ($args{progress} % $args{step}) == 0) {
+
+ $args{conn}->respond({
+ total => $args{total},
+ progress => $args{progress},
+ imported => ($rec) ? $rec->id : undef,
+ err_event => $evt
+ });
+
+ # report often at first, climb quickly, then hold steady
+ $args{step} *= 2 unless $args{step} == 256;
+ }
+}
+
+
+
+
__PACKAGE__->register_method(
api_name => "open-ils.vandelay.bib_queue.owner.retrieve",
commit 2620862d7ebafed7a86c26c682a01dcc2d11f705
Author: Mike Rylander <mrylander at gmail.com>
Date: Fri Apr 22 13:19:22 2011 -0400
remove unused match_attr and actually capture eg_record into eg_id
diff --git a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
index 61b49c2..c5740d7 100644
--- a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
+++ b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
@@ -1234,7 +1234,6 @@ DECLARE
eg_marc TEXT;
v_marc TEXT;
replace_rule TEXT;
- match_count INT;
BEGIN
SELECT q.marc INTO v_marc
@@ -1280,8 +1279,6 @@ $$ LANGUAGE PLPGSQL;
CREATE OR REPLACE FUNCTION vandelay.auto_overlay_bib_record_with_best ( import_id BIGINT, merge_profile_id INT, lwm_ratio_value NUMERIC ) RETURNS BOOL AS $$
DECLARE
eg_id BIGINT;
- match_count INT;
- match_attr vandelay.bib_attr_definition%ROWTYPE;
BEGIN
IF lwm_ratio_value IS NULL THEN
@@ -1323,7 +1320,6 @@ CREATE OR REPLACE FUNCTION vandelay.auto_overlay_bib_record ( import_id BIGINT,
DECLARE
eg_id BIGINT;
match_count INT;
- match_attr vandelay.bib_attr_definition%ROWTYPE;
BEGIN
PERFORM * FROM vandelay.queued_bib_record WHERE import_time IS NOT NULL AND id = import_id;
@@ -1341,14 +1337,14 @@ BEGIN
END IF;
-- Check that the one match is on the first 901c
- PERFORM *
+ SELECT m.eg_record INTO eg_id
FROM vandelay.queued_bib_record q
JOIN vandelay.bib_match m ON (m.queued_record = q.id)
WHERE q.id = import_id
AND m.eg_record = oils_xpath_string('//*[@tag="901"]/*[@code="c"][1]',marc)::BIGINT;
IF NOT FOUND THEN
- -- RAISE NOTICE 'not a 901c match: %', match_attr.xpath;
+ -- RAISE NOTICE 'not a 901c match';
RETURN FALSE;
END IF;
commit d5c786e515791eaf53992dac8a6bd11520a661d6
Author: Mike Rylander <mrylander at gmail.com>
Date: Fri Apr 22 12:55:37 2011 -0400
Secondary sort by quality ratio (higher means incoming is more "good" than existing) instead of simple incoming quality, which is a no-op (all the same)
diff --git a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
index f98f6ca..61b49c2 100644
--- a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
+++ b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
@@ -1301,7 +1301,10 @@ BEGIN
WHERE m.queued_record = import_id
AND r.id = m.eg_record
AND m.quality::NUMERIC / COALESCE(NULLIF(vandelay.incoming_record_quality(r.marc),0),1)::NUMERIC >= lwm_ratio_value
- ORDER BY m.match_score DESC, m.quality DESC, id limit 1;
+ ORDER BY m.match_score DESC,
+ m.quality::NUMERIC / COALESCE(NULLIF(vandelay.incoming_record_quality(r.marc),0),1)::NUMERIC DESC,
+ id
+ LIMIT 1;
IF eg_id IS NULL THEN
-- RAISE NOTICE 'incoming record is not of hight enough quality';
commit 1aaf8a040116c614eb014fd2582e6bbc702b5e92
Author: Mike Rylander <mrylander at gmail.com>
Date: Fri Apr 22 12:33:16 2011 -0400
functions for performing queue-wide vandelay.auto_overlay_bib_record_with_best
diff --git a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
index eb66bd5..f98f6ca 100644
--- a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
+++ b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
@@ -698,10 +698,10 @@ BEGIN
vandelay.match_set_test_marcxml(my_bib_queue.match_set, NEW.marc) LOOP
INSERT INTO vandelay.bib_match (
- matched_set, queued_record, eg_record, quality
+ matched_set, queued_record, eg_record, match_score, quality
) VALUES (
my_bib_queue.match_set, NEW.id, test_result.record,
- test_result.quality
+ test_result.quality, vandelay.incoming_record_quality(NEW.marc)
);
END LOOP;
@@ -1281,12 +1281,9 @@ CREATE OR REPLACE FUNCTION vandelay.auto_overlay_bib_record_with_best ( import_i
DECLARE
eg_id BIGINT;
match_count INT;
- existing_qual INT;
match_attr vandelay.bib_attr_definition%ROWTYPE;
BEGIN
- existing_qual := COALESCE(NULLIF(vandelay.incoming_record_quality(r.marc),0),1);
-
IF lwm_ratio_value IS NULL THEN
lwm_ratio_value := 0.0;
END IF;
@@ -1303,7 +1300,7 @@ BEGIN
JOIN biblio.record_entry r
WHERE m.queued_record = import_id
AND r.id = m.eg_record
- AND m.quality::NUMERIC / existing_qual::NUMERIC >= lwm_ratio_value
+ AND m.quality::NUMERIC / COALESCE(NULLIF(vandelay.incoming_record_quality(r.marc),0),1)::NUMERIC >= lwm_ratio_value
ORDER BY m.match_score DESC, m.quality DESC, id limit 1;
IF eg_id IS NULL THEN
@@ -1374,6 +1371,28 @@ BEGIN
END;
$$ LANGUAGE PLPGSQL;
+CREATE OR REPLACE FUNCTION vandelay.auto_overlay_bib_queue_with_best ( queue_id BIGINT, merge_profile_id INT, lwm_ratio_value NUMERIC ) RETURNS SETOF BIGINT AS $$
+DECLARE
+ queued_record vandelay.queued_bib_record%ROWTYPE;
+BEGIN
+
+ FOR queued_record IN SELECT * FROM vandelay.queued_bib_record WHERE queue = queue_id AND import_time IS NULL LOOP
+
+ IF vandelay.auto_overlay_bib_record_with_best( queued_record.id, merge_profile_id, lwm_ratio_value ) THEN
+ RETURN NEXT queued_record.id;
+ END IF;
+
+ END LOOP;
+
+ RETURN;
+
+END;
+$$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION vandelay.auto_overlay_bib_queue_with_best ( import_id BIGINT, merge_profile_id INT ) RETURNS SETOF BIGINT AS $$
+ SELECT vandelay.auto_overlay_bib_queue_with_best( $1, $2, p.lwm_ratio ) FROM vandelay.merge_profile p WHERE id = $2;
+$$ LANGUAGE SQL;
+
CREATE OR REPLACE FUNCTION vandelay.auto_overlay_bib_queue ( queue_id BIGINT ) RETURNS SETOF BIGINT AS $$
SELECT * FROM vandelay.auto_overlay_bib_queue( $1, NULL );
$$ LANGUAGE SQL;
commit ca861020320e5a412114655eba10efe120a668a7
Author: Mike Rylander <mrylander at gmail.com>
Date: Fri Apr 22 12:30:17 2011 -0400
match_score column for recording matchiness; functions for auto-overlay based on "bestness"; low-water-mark boundary for best-auto-overlay
diff --git a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
index 14a7e14..eb66bd5 100644
--- a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
+++ b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
@@ -144,7 +144,8 @@ CREATE TABLE vandelay.bib_match (
matched_set INT REFERENCES vandelay.match_set (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
queued_record BIGINT REFERENCES vandelay.queued_bib_record (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
eg_record BIGINT REFERENCES biblio.record_entry (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
- quality INT NOT NULL DEFAULT 0
+ quality INT NOT NULL DEFAULT 0,
+ match_score INT NOT NULL DEFAULT 0
);
CREATE TABLE vandelay.import_item (
@@ -189,6 +190,7 @@ CREATE TABLE vandelay.merge_profile (
replace_spec TEXT,
strip_spec TEXT,
preserve_spec TEXT,
+ lwm_ratio NUMERIC,
CONSTRAINT vand_merge_prof_owner_name_idx UNIQUE (owner,name),
CONSTRAINT add_replace_strip_or_preserve CHECK ((preserve_spec IS NOT NULL OR replace_spec IS NOT NULL) OR (preserve_spec IS NULL AND replace_spec IS NULL))
);
@@ -1275,6 +1277,48 @@ BEGIN
END;
$$ LANGUAGE PLPGSQL;
+CREATE OR REPLACE FUNCTION vandelay.auto_overlay_bib_record_with_best ( import_id BIGINT, merge_profile_id INT, lwm_ratio_value NUMERIC ) RETURNS BOOL AS $$
+DECLARE
+ eg_id BIGINT;
+ match_count INT;
+ existing_qual INT;
+ match_attr vandelay.bib_attr_definition%ROWTYPE;
+BEGIN
+
+ existing_qual := COALESCE(NULLIF(vandelay.incoming_record_quality(r.marc),0),1);
+
+ IF lwm_ratio_value IS NULL THEN
+ lwm_ratio_value := 0.0;
+ END IF;
+
+ PERFORM * FROM vandelay.queued_bib_record WHERE import_time IS NOT NULL AND id = import_id;
+
+ IF FOUND THEN
+ -- RAISE NOTICE 'already imported, cannot auto-overlay'
+ RETURN FALSE;
+ END IF;
+
+ SELECT m.eg_record INTO eg_id
+ FROM vandelay.bib_match m
+ JOIN biblio.record_entry r
+ WHERE m.queued_record = import_id
+ AND r.id = m.eg_record
+ AND m.quality::NUMERIC / existing_qual::NUMERIC >= lwm_ratio_value
+ ORDER BY m.match_score DESC, m.quality DESC, id limit 1;
+
+ IF eg_id IS NULL THEN
+ -- RAISE NOTICE 'incoming record is not of hight enough quality';
+ RETURN FALSE;
+ END IF;
+
+ RETURN vandelay.overlay_bib_record( import_id, eg_id, merge_profile_id );
+END;
+$$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION vandelay.auto_overlay_bib_record_with_best ( import_id BIGINT, merge_profile_id INT ) RETURNS BOOL AS $$
+ SELECT vandelay.auto_overlay_bib_record_with_best( $1, $2, p.lwm_ratio ) FROM vandelay.merge_profile p WHERE id = $2;
+$$ LANGUAGE SQL;
+
CREATE OR REPLACE FUNCTION vandelay.auto_overlay_bib_record ( import_id BIGINT, merge_profile_id INT ) RETURNS BOOL AS $$
DECLARE
eg_id BIGINT;
commit 4de86d2c97b9117db2808681d091f85c79279373
Author: senator <lebbeous at esilibrary.com>
Date: Fri Apr 22 12:12:30 2011 -0400
Bugfix for negative matches
diff --git a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
index aee60a6..14a7e14 100644
--- a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
+++ b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
@@ -664,9 +664,7 @@ BEGIN
IF node.bool_op IS NOT NULL THEN
RETURN node.bool_op;
ELSE
- RETURN '(n' || node.id::TEXT || '.id IS ' ||
- (CASE WHEN node.negate THEN '' ELSE 'NOT ' END) || -- sic!
- 'NULL)';
+ RETURN '(n' || node.id::TEXT || '.id IS NOT NULL)';
END IF;
END;
$$ LANGUAGE PLPGSQL;
commit b2f78352b012820c1bbf4a6caa49d2380d9a3145
Author: senator <lebbeous at esilibrary.com>
Date: Fri Apr 22 11:45:49 2011 -0400
some changes in the UI to reflect DB side changes
Negation and quality are now ignored for operator nodes, and are not
settable in the UI.
Also in the UI, you can no longer replace the root node of the tree with
a non-op node, meaning the root of a tree is always AND or OR.
This is due to some bug that hangs the UI now when you try to save a
single-non-op-node tree, and it's not worth debugging: just remove the
feature.
diff --git a/Open-ILS/web/js/dojo/openils/vandelay/TreeDndSource.js b/Open-ILS/web/js/dojo/openils/vandelay/TreeDndSource.js
index c0586b5..7dd9fa5 100644
--- a/Open-ILS/web/js/dojo/openils/vandelay/TreeDndSource.js
+++ b/Open-ILS/web/js/dojo/openils/vandelay/TreeDndSource.js
@@ -9,12 +9,9 @@ dojo.declare(
"openils.vandelay.TreeDndSource", dijit._tree.dndSource, {
"_is_replaceable": function(spoint, dpoint, disroot) {
/* An OP can replace anything, but non-OPs can only replace other
- * non-OPs, EXCEPT when the dest is the root node (this allows
- * for simple "trees" with only a single non-OP node.
+ * non-OPs.
*/
- if (disroot)
- return true;
- else if (spoint.bool_op())
+ if (spoint.bool_op())
return true;
else if (!dpoint.bool_op())
return true;
diff --git a/Open-ILS/web/js/ui/default/conify/global/vandelay/match_set.js b/Open-ILS/web/js/ui/default/conify/global/vandelay/match_set.js
index dfcfc44..5128bd2 100644
--- a/Open-ILS/web/js/ui/default/conify/global/vandelay/match_set.js
+++ b/Open-ILS/web/js/ui/default/conify/global/vandelay/match_set.js
@@ -205,7 +205,8 @@ function NodeEditor() {
var nodes = _factories_by_type[type]();
for (var i = 0; i < nodes.length; i++) dojo.place(nodes[i], table);
- this._add_consistent_controls(table);
+ if (type != "bool_op")
+ this._add_consistent_controls(table);
dojo.create(
"input", {
@@ -231,13 +232,11 @@ function NodeEditor() {
}
function render_vmsp_label(point, minimal) {
- /* "minimal" mode has two implications:
- * 1) for svf, only show the code, not the longer label.
- * 2) for bool ops, completely ingore negation
+ /* "minimal" has this implication:
+ * for svf, only show the code, not the longer label.
*/
if (point.bool_op()) {
- return (!minimal && openils.Util.isTrue(point.negate()) ? "N" : "") +
- point.bool_op();
+ return point.bool_op();
} else if (point.svf()) {
return (openils.Util.isTrue(point.negate()) ? "NOT " : "") + (
minimal ? point.svf() :
@@ -364,9 +363,8 @@ function redraw_expression_preview() {
function render_expression_preview(r) {
if (r.children().length) {
- return (openils.Util.isTrue(r.negate()) ? "NOT " : "") +
- "(" + r.children().map(render_expression_preview).join(
- " " + render_vmsp_label(r, true /* minimal */) + " "
+ return "(" + r.children().map(render_expression_preview).join(
+ " " + render_vmsp_label(r) + " "
) + ")";
} else if (!r.bool_op()) {
return render_vmsp_label(r, true /* minimal */);
commit c7b99f8d90aa0b3a2be4fc609bfa83e5da261431
Author: senator <lebbeous at esilibrary.com>
Date: Fri Apr 22 11:29:24 2011 -0400
Replace vandelay.match_bib_record() with the new tree-y version
diff --git a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
index f64cc06..aee60a6 100644
--- a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
+++ b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
@@ -473,23 +473,216 @@ CREATE OR REPLACE FUNCTION vandelay.extract_rec_attrs ( xml TEXT ) RETURNS hstor
SELECT vandelay.extract_rec_attrs( $1, (SELECT ARRAY_ACCUM(name) FROM config.record_attr_definition));
$_$ LANGUAGE SQL;
-CREATE OR REPLACE FUNCTION vandelay.match_bib_record ( ) RETURNS TRIGGER AS $func$
+-- Everything between this comment and the beginning of the definition of
+-- vandelay.match_bib_record() is strictly in service of that function.
+CREATE TYPE vandelay.match_set_test_result AS (record BIGINT, quality INTEGER);
+
+CREATE OR REPLACE FUNCTION vandelay.match_set_test_marcxml(
+ match_set_id INTEGER, record_xml TEXT
+) RETURNS SETOF vandelay.match_set_test_result AS $$
+DECLARE
+ tags_rstore HSTORE;
+ svf_rstore HSTORE;
+ coal TEXT;
+ joins TEXT;
+ query_ TEXT;
+ wq TEXT;
+ qvalue INTEGER;
+ rec RECORD;
+BEGIN
+ tags_rstore := vandelay.flatten_marc_hstore(record_xml);
+ svf_rstore := vandelay.extract_rec_attrs(record_xml);
+
+ CREATE TEMPORARY TABLE _vandelay_tmp_qrows (q INTEGER);
+ CREATE TEMPORARY TABLE _vandelay_tmp_jrows (j TEXT);
+
+ -- generate the where clause and return that directly (into wq), and as
+ -- a side-effect, populate the _vandelay_tmp_[qj]rows tables.
+ wq := vandelay.get_expr_from_match_set(match_set_id);
+
+ query_ := 'SELECT bre.id AS record, ';
+
+ -- qrows table is for the quality bits we add to the SELECT clause
+ SELECT ARRAY_TO_STRING(
+ ARRAY_ACCUM('COALESCE(n' || q::TEXT || '.quality, 0)'), ' + '
+ ) INTO coal FROM _vandelay_tmp_qrows;
+
+ -- our query string so far is the SELECT clause and the inital FROM.
+ -- no JOINs yet nor the WHERE clause
+ query_ := query_ || coal || ' AS quality ' || E'\n' ||
+ 'FROM biblio.record_entry bre ';
+
+ -- jrows table is for the joins we must make (and the real text conditions)
+ SELECT ARRAY_TO_STRING(ARRAY_ACCUM(j), E'\n') INTO joins
+ FROM _vandelay_tmp_jrows;
+
+ -- add those joins and the where clause to our query.
+ query_ := query_ || joins || E'\n' || 'WHERE ' || wq;
+
+ -- this will return rows of record,quality
+ FOR rec IN EXECUTE query_ USING tags_rstore, svf_rstore LOOP
+ RETURN NEXT rec;
+ END LOOP;
+
+ DROP TABLE _vandelay_tmp_qrows;
+ DROP TABLE _vandelay_tmp_jrows;
+ RETURN;
+END;
+
+$$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION vandelay.flatten_marc_hstore(
+ record_xml TEXT
+) RETURNS HSTORE AS $$
+BEGIN
+ RETURN (SELECT
+ HSTORE(
+ ARRAY_ACCUM(tag || (COALESCE(subfield, ''))),
+ ARRAY_ACCUM(value)
+ )
+ FROM (
+ SELECT tag, subfield, ARRAY_ACCUM(value)::TEXT AS value
+ FROM vandelay.flatten_marc(record_xml)
+ GROUP BY tag, subfield ORDER BY tag, subfield
+ ) subquery
+ );
+END;
+$$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION vandelay.get_expr_from_match_set(
+ match_set_id INTEGER
+) RETURNS TEXT AS $$
+DECLARE
+ root vandelay.match_set_point;
+BEGIN
+ SELECT * INTO root FROM vandelay.match_set_point
+ WHERE parent IS NULL AND match_set = match_set_id;
+
+ RETURN vandelay.get_expr_from_match_set_point(root);
+END;
+$$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION vandelay.get_expr_from_match_set_point(
+ node vandelay.match_set_point
+) RETURNS TEXT AS $$
+DECLARE
+ q TEXT;
+ i INTEGER;
+ this_op TEXT;
+ children INTEGER[];
+ child vandelay.match_set_point;
+BEGIN
+ SELECT ARRAY_ACCUM(id) INTO children FROM vandelay.match_set_point
+ WHERE parent = node.id;
+
+ IF ARRAY_LENGTH(children, 1) > 0 THEN
+ this_op := vandelay._get_expr_render_one(node);
+ q := '(';
+ i := 1;
+ WHILE children[i] IS NOT NULL LOOP
+ SELECT * INTO child FROM vandelay.match_set_point
+ WHERE id = children[i];
+ IF i > 1 THEN
+ q := q || ' ' || this_op || ' ';
+ END IF;
+ i := i + 1;
+ q := q || vandelay.get_expr_from_match_set_point(child);
+ END LOOP;
+ q := q || ')';
+ RETURN q;
+ ELSIF node.bool_op IS NULL THEN
+ PERFORM vandelay._get_expr_push_qrow(node);
+ PERFORM vandelay._get_expr_push_jrow(node);
+ RETURN vandelay._get_expr_render_one(node);
+ ELSE
+ RETURN '';
+ END IF;
+END;
+$$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION vandelay._get_expr_push_qrow(
+ node vandelay.match_set_point
+) RETURNS VOID AS $$
+DECLARE
+BEGIN
+ INSERT INTO _vandelay_tmp_qrows (q) VALUES (node.id);
+END;
+$$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION vandelay._get_expr_push_jrow(
+ node vandelay.match_set_point
+) RETURNS VOID AS $$
+DECLARE
+ jrow TEXT;
+ my_alias TEXT;
+ op TEXT;
+ tagkey TEXT;
+BEGIN
+ IF node.negate THEN
+ op := '<>';
+ ELSE
+ op := '=';
+ END IF;
+
+ IF node.tag IS NOT NULL THEN
+ tagkey := node.tag;
+ IF node.subfield IS NOT NULL THEN
+ tagkey := tagkey || node.subfield;
+ END IF;
+ END IF;
+
+ my_alias := 'n' || node.id::TEXT;
+
+ jrow := 'LEFT JOIN (SELECT *, ' || node.quality ||
+ ' AS quality FROM metabib.';
+ IF node.tag IS NOT NULL THEN
+ jrow := jrow || 'full_rec) ' || my_alias || ' ON (' ||
+ my_alias || '.record = bre.id AND ' || my_alias || '.tag = ''' ||
+ node.tag || '''';
+ IF node.subfield IS NOT NULL THEN
+ jrow := jrow || ' AND ' || my_alias || '.subfield = ''' ||
+ node.subfield || '''';
+ END IF;
+ jrow := jrow || ' AND (' || my_alias || '.value ' || op ||
+ ' ANY(($1->''' || tagkey || ''')::TEXT[])))';
+ ELSE -- svf
+ jrow := jrow || 'record_attr) ' || my_alias || ' ON (' ||
+ my_alias || '.id = bre.id AND (' ||
+ my_alias || '.attrs->''' || node.svf ||
+ ''' ' || op || ' $2->''' || node.svf || '''))';
+ END IF;
+ INSERT INTO _vandelay_tmp_jrows (j) VALUES (jrow);
+END;
+$$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION vandelay._get_expr_render_one(
+ node vandelay.match_set_point
+) RETURNS TEXT AS $$
+DECLARE
+ s TEXT;
+BEGIN
+ IF node.bool_op IS NOT NULL THEN
+ RETURN node.bool_op;
+ ELSE
+ RETURN '(n' || node.id::TEXT || '.id IS ' ||
+ (CASE WHEN node.negate THEN '' ELSE 'NOT ' END) || -- sic!
+ 'NULL)';
+ END IF;
+END;
+$$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION vandelay.match_bib_record() RETURNS TRIGGER AS $func$
DECLARE
incoming_existing_id TEXT;
my_bib_queue vandelay.bib_queue%ROWTYPE;
- my_match_set vandelay.match_set%ROWTYPE;
- test vandelay.match_set_point%ROWTYPE;
- potential_matches BIGINT[];
- matches BIGINT[];
- rvalue TEXT;
- quality_set hstore;
+ test_result vandelay.match_set_test_result%ROWTYPE;
tmp_rec BIGINT;
- tmp_quality INT;
- first_round BOOL;
BEGIN
DELETE FROM vandelay.bib_match WHERE queued_record = NEW.id;
- incoming_existing_id := oils_xpath_string('//*[@tag="901"]/*[@code="c"][1]',NEW.marc);
+ -- Perfect matches on 901$c exit early with a match with high quality.
+ incoming_existing_id :=
+ oils_xpath_string('//*[@tag="901"]/*[@code="c"][1]', NEW.marc);
IF incoming_existing_id IS NOT NULL AND incoming_existing_id != '' THEN
SELECT id INTO tmp_rec FROM biblio.record_entry WHERE id = incoming_existing_id::bigint;
@@ -501,64 +694,17 @@ BEGIN
SELECT * INTO my_bib_queue FROM vandelay.bib_queue WHERE id = NEW.queue;
- first_round := TRUE;
- -- whew ... here we go ...
-
-
- -- Commented out until replaced by tree-ish version
-/*
- FOR test IN SELECT * FROM vandelay.match_set_point WHERE match_set = my_bib_queue.match_set ORDER BY required DESC LOOP
- IF test.tag IS NOT NULL THEN
- FOR rvalue IN SELECT value FROM vandelay.flatten_marc( xml ) WHERE tag = test.tag AND subfield = test.subfield LOOP
- SELECT ARRAY_ACCUM(DISTINCT record) INTO potential_matches FROM metabib.real_full_rec WHERE tag = test.tag AND subfield = test.subfield AND value = rvalue;
-
- IF first_round THEN
- matches := potential_matches;
- first_round := FALSE;
- ELSIF test.required THEN
- FOR tmp_rec IN SELECT * FROM UNNEST(matches) LOOP
- IF tmp_rec NOT IN (SELECT * FROM UNNEST(potential_matches)) THEN
- matches := evergreen.array_remove_item_by_value(matches, tmp_rec);
- potential_matches := evergreen.array_remove_item_by_value(potential_matches, tmp_rec);
- END IF;
- END LOOP;
- END IF;
+ FOR test_result IN SELECT * FROM
+ vandelay.match_set_test_marcxml(my_bib_queue.match_set, NEW.marc) LOOP
- -- add the quality for this match
- FOR tmp_rec IN SELECT * FROM UNNEST(potential_matches) LOOP
- tmp_quality := COALESCE((quality_set -> tmp_rec::TEXT)::INT, 0);
- quality_set := quality_set || hstore(tmp_rec::TEXT, (tmp_quality + test.quality)::TEXT);
- END LOOP;
-
- END LOOP;
- ELSE
- rvalue := vandelay.vandelay.extract_rec_attrs(xml, ARRAY[test.svf]);
-
- IF first_round THEN
- matches := potential_matches;
- first_round := FALSE;
- ELSIF test.required THEN
- FOR tmp_rec IN SELECT * FROM UNNEST(matches) LOOP
- IF tmp_rec NOT IN (SELECT * FROM UNNEST(potential_matches)) THEN
- matches := evergreen.array_remove_item_by_value(matches, tmp_rec);
- potential_matches := evergreen.array_remove_item_by_value(potential_matches, tmp_rec);
- END IF;
- END LOOP;
- END IF;
-
- -- add the quality for this match
- FOR tmp_rec IN SELECT * FROM UNNEST(potential_matches) LOOP
- tmp_quality := COALESCE((quality_set -> tmp_rec::TEXT)::INT, 0);
- quality_set := quality_set || hstore(tmp_rec::TEXT, (tmp_quality + test.quality)::TEXT);
- END LOOP;
-
- END IF;
- END LOOP;
+ INSERT INTO vandelay.bib_match (
+ matched_set, queued_record, eg_record, quality
+ ) VALUES (
+ my_bib_queue.match_set, NEW.id, test_result.record,
+ test_result.quality
+ );
- FOR tmp_rec IN SELECT * FROM UNNEST(matches) LOOP
- INSERT INTO vandelay.bib_match (matched_set, queued_record, eg_record, quality) VALUES (my_bib_queue.match_set, NEW.id, tmp_rec, (quality_set -> tmp_rec::TEXT));
END LOOP;
-*/
RETURN NEW;
END;
commit 813ac365b8ebf1e4d2e4434002ab248a0160833e
Author: Mike Rylander <mrylander at gmail.com>
Date: Fri Apr 22 11:14:21 2011 -0400
We don't have a matched_attr column anymore, because we're using the fancy expression tree, so test for 901c match directly
diff --git a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
index 3a69144..f64cc06 100644
--- a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
+++ b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
@@ -1152,26 +1152,18 @@ BEGIN
RETURN FALSE;
END IF;
- SELECT d.* INTO match_attr
- FROM vandelay.bib_attr_definition d
- JOIN vandelay.queued_bib_record_attr a ON (a.field = d.id)
- JOIN vandelay.bib_match m ON (m.matched_attr = a.id)
- WHERE m.queued_record = import_id;
+ -- Check that the one match is on the first 901c
+ PERFORM *
+ FROM vandelay.queued_bib_record q
+ JOIN vandelay.bib_match m ON (m.queued_record = q.id)
+ WHERE q.id = import_id
+ AND m.eg_record = oils_xpath_string('//*[@tag="901"]/*[@code="c"][1]',marc)::BIGINT;
- IF NOT (match_attr.xpath ~ '@tag="901"' AND match_attr.xpath ~ '@code="c"') THEN
+ IF NOT FOUND THEN
-- RAISE NOTICE 'not a 901c match: %', match_attr.xpath;
RETURN FALSE;
END IF;
- SELECT m.eg_record INTO eg_id
- FROM vandelay.bib_match m
- WHERE m.queued_record = import_id
- LIMIT 1;
-
- IF eg_id IS NULL THEN
- RETURN FALSE;
- END IF;
-
RETURN vandelay.overlay_bib_record( import_id, eg_id, merge_profile_id );
END;
$$ LANGUAGE PLPGSQL;
commit a02e77558027149e5a8d405daba583baa394c796
Author: berick <berick at commidore64.esilibrary.com>
Date: Fri Apr 22 10:38:38 2011 -0400
initial cut of capturing bib/auth import errors
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
index ef02b02..0ea5798 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
@@ -606,22 +606,79 @@ sub queued_records_with_matches {
return [ map {$_->{queued_record}} @$data ];
}
+# tracks any import errors, commits the current xact, responds to the client
+sub finish_rec_import_attempt {
+ my %args = @_;
+ my $error = $args{import_error} || 'general.unknown';
+ my $evt = $args{evt};
+ my $rec = $args{rec};
+ my $e = $args{e};
+
+ # error tracking
+ if($rec) {
+
+ if($error or $evt) {
+ # since an error occurred, there's no guarantee the transaction wasn't
+ # rolled back. force a rollback and create a new editor.
+ $e->rollback;
+ $e = new_editor(xact => 1);
+ $rec->import_error($error);
+
+ if($evt) {
+ my $detail = sprintf("%s : %s", $evt->{textcode}, substr($evt->{desc}, 0, 140));
+ $rec->error_detail($detail);
+ }
+
+ my $method = 'update_vandelay_queued_bib_record';
+ $method =~ s/bib/authority/ if $args{type} eq 'auth';
+ $e->$method($rec) and $e->commit or $e->rollback;
+
+ } else {
+ # successful import
+ $e->commit;
+ }
+
+ } else {
+ # requested queued record was not found
+ $e->rollback;
+ }
+
+ # respond to client
+ if($args{report_all} or ($args{progress} % $args{step}) == 0) {
+
+ $args{conn}->respond({
+ total => $args{total},
+ progress => $args{progress},
+ imported => ($rec) ? $rec->id : undef,
+ err_event => $evt
+ });
+
+ # report often at first, climb quickly, then hold steady
+ $args{step} *= 2 unless $args{step} == 256;
+ }
+}
+
+
+
sub import_record_list_impl {
my($self, $conn, $rec_ids, $requestor, $args) = @_;
my $overlay_map = $args->{overlay_map} || {};
my $type = $self->{record_type};
- my $total = @$rec_ids;
- my $count = 0;
my %queues;
- my $step = 1;
+ my %report_args = (
+ progress => 0,
+ step => 1,
+ conn => $conn,
+ total => scalar(@$rec_ids),
+ report_all => $$args{report_all}
+ );
my $auto_overlay_exact = $$args{auto_overlay_exact};
my $auto_overlay_1match = $$args{auto_overlay_1match};
my $merge_profile = $$args{merge_profile};
my $bib_source = $$args{bib_source};
- my $report_all = $$args{report_all};
my $overlay_func = 'vandelay.overlay_bib_record';
my $auto_overlay_func = 'vandelay.auto_overlay_bib_record';
@@ -632,13 +689,11 @@ sub import_record_list_impl {
my $update_queue_func = 'update_vandelay_bib_queue';
my $rec_class = 'vqbr';
- my %bib_sources;
my $editor = new_editor();
- my $sources = $editor->search_config_bib_source({id => {'!=' => undef}});
- foreach my $src (@$sources) {
- $bib_sources{$src->id} = $src->source;
- }
+ my %bib_sources;
+ my $sources = $editor->search_config_bib_source({id => {'!=' => undef}});
+ $bib_sources{$_->id} = $_->source for @$sources;
if($type eq 'auth') {
$overlay_func =~ s/bib/auth/o;
@@ -654,12 +709,15 @@ sub import_record_list_impl {
my @success_rec_ids;
for my $rec_id (@$rec_ids) {
+ my $error = 0;
my $overlay_target = $overlay_map->{$rec_id};
- my $error = 0;
my $e = new_editor(xact => 1);
$e->requestor($requestor);
+ $report_args{progress}++;
+ $report_args{e} = $e;
+
my $rec = $e->$retrieve_func([
$rec_id,
{ flesh => 1,
@@ -668,11 +726,12 @@ sub import_record_list_impl {
]);
unless($rec) {
- $conn->respond({total => $total, progress => ++$count, imported => $rec_id, err_event => $e->event});
- $e->rollback;
+ finish_rec_import_attempt(%report_args, evt => $e->event);
next;
}
+ $report_args{rec} = $rec;
+
if($rec->import_time) {
$e->rollback;
next;
@@ -784,9 +843,8 @@ sub import_record_list_impl {
}
if($U->event_code($record)) {
-
- $e->event($record);
- $e->rollback;
+ my $import_error = 'import.duplicate.tcn' if $record->{textcode} eq 'TCN_EXISTS';
+ finish_rec_import_attempt(%report_args, import_error => $import_error, evt => $record);
} else {
@@ -801,16 +859,11 @@ sub import_record_list_impl {
if($imported) {
push @success_rec_ids, $rec_id;
- $e->commit;
+ finish_rec_import_attempt(%report_args);
+
} else {
# Send an update whenever there's an error
- $conn->respond({total => $total, progress => ++$count, imported => $rec_id, err_event => $e->event});
- }
-
- if($report_all or (++$count % $step) == 0) {
- $conn->respond({total => $total, progress => $count, imported => $rec_id});
- # report often at first, climb quickly, then hold steady
- $step *= 2 unless $step == 256;
+ finish_rec_import_attempt(%report_args, evt => $e->event);
}
}
@@ -834,9 +887,10 @@ sub import_record_list_impl {
$e->rollback;
}
+ # import the copies
import_record_asset_list_impl($conn, \@success_rec_ids, $requestor);
- $conn->respond({total => $total, progress => $count});
+ $conn->respond({total => $report_args{total}, progress => $report_args{progress}});
return undef;
}
@@ -1062,8 +1116,14 @@ sub import_record_asset_list_impl {
# --------------------------------------------------------------------------------
# see if a valid circ_modifier was provided
# --------------------------------------------------------------------------------
- #if($copy->circ_modifier and not $e->retrieve_config_circ_modifier($item->circ_modifier)) {
if($copy->circ_modifier and not $e->search_config_circ_modifier({code=>$item->circ_modifier})->[0]) {
+ $report_args{import_error} = 'import.item.invalid.circ_modifier';
+ respond_with_status(%report_args, evt => $e->die_event);
+ next;
+ }
+
+ if($copy->location and not $e->retrieve_asset_copy_location($copy->location)) {
+ $report_args{import_error} = 'import.item.invalid.location';
respond_with_status(%report_args, evt => $e->die_event);
next;
}
@@ -1071,6 +1131,8 @@ sub import_record_asset_list_impl {
if($evt = OpenILS::Application::Cat::AssetCommon->create_copy($e, $vol, $copy)) {
try { $e->rollback } otherwise {}; # sometimes calls die_event, sometimes not
$report_args{evt} = $evt;
+ $report_args{import_error} = 'import.item.duplicate.barcode'
+ if $evt->{textcode} eq 'ITEM_BARCODE_EXISTS';
respond_with_status(%report_args);
next;
}
@@ -1115,7 +1177,7 @@ sub respond_with_status {
my $error = $args{import_error};
my $evt = $args{evt};
- if($error || $evt) {
+ if($error or $evt) {
my $item = $args{import_item};
@@ -1123,7 +1185,7 @@ sub respond_with_status {
$item->import_error($error);
if($evt) {
- my $detail = sprintf("%s : %s", $evt->{textcode}, substr($evt->{desc}, 0, 120));
+ my $detail = sprintf("%s : %s", $evt->{textcode}, substr($evt->{desc}, 0, 140));
$item->error_detail($detail);
}
@@ -1136,7 +1198,8 @@ sub respond_with_status {
$args{step} *= 2 unless $args{step} == 256;
$args{conn}->respond({
- map { $_ => $args{$_} } qw/total progress success_count/
+ map { $_ => $args{$_} } qw/total progress success_count/,
+ err_event => $evt
});
}
diff --git a/Open-ILS/src/sql/Pg/950.data.seed-values.sql b/Open-ILS/src/sql/Pg/950.data.seed-values.sql
index 25e9c1d..e45999d 100644
--- a/Open-ILS/src/sql/Pg/950.data.seed-values.sql
+++ b/Open-ILS/src/sql/Pg/950.data.seed-values.sql
@@ -8657,6 +8657,17 @@ INSERT INTO action_trigger.environment (event_def, path) VALUES
(37, 'circ_lib.billing_address')
;
+INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'general.unknown', oils_i18n_gettext('general.unknown', 'Import or Overlay failed', 'vie', 'description') );
+INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'import.item.duplicate.barcode', oils_i18n_gettext('import.item.duplicate.barcode', 'Import failed due to barcode collision', 'vie', 'description') );
+INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'import.item.invalid.circ_modifier', oils_i18n_gettext('import.item.invalid.circ_modifier', 'Import failed due to invalid circulation modifier', 'vie', 'description') );
+INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'import.item.invalid.location', oils_i18n_gettext('import.item.invalid.location', 'Import failed due to invalid copy location', 'vie', 'description') );
+INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'import.duplicate.sysid', oils_i18n_gettext('import.duplicate.sysid', 'Import failed due to system id collision', 'vie', 'description') );
+INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'import.duplicate.tcn', oils_i18n_gettext('import.duplicate.sysid', 'Import failed due to system id collision', 'vie', 'description') );
+INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'overlay.missing.sysid', oils_i18n_gettext('overlay.missing.sysid', 'Overlay failed due to missing system id', 'vie', 'description') );
+INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'import.auth.duplicate.acn', oils_i18n_gettext('import.auth.duplicate.acn', 'Import failed due to Accession Number collision', 'vie', 'description') );
+INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'import.xml.malformed', oils_i18n_gettext('import.xml.malformed', 'Malformed record cause Import failure', 'vie', 'description') );
+INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'overlay.xml.malformed', oils_i18n_gettext('overlay.xml.malformed', 'Malformed record cause Overlay failure', 'vie', 'description') );
+
INSERT INTO config.org_unit_setting_type ( name, label, description, datatype ) VALUES (
'ui.cat.volume_copy_editor.horizontal',
oils_i18n_gettext(
commit a2a99fc7368401e56c0ff331b39f800ff320ca60
Author: berick <berick at commidore64.esilibrary.com>
Date: Thu Apr 21 16:55:26 2011 -0400
initial item-import-failure reporting; needs testing
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
index 4d3049a..ef02b02 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
@@ -775,6 +775,7 @@ sub import_record_list_impl {
# No overlay / merge occurred. Do a traditional record import by creating a new record
+ $logger->info("vl: creating new $type record for queued record $rec_id");
if($type eq 'bib') {
$record = OpenILS::Application::Cat::BibCommon->biblio_record_xml_import($e, $rec->marc, $bib_sources{$rec->bib_source});
} else {
@@ -1004,11 +1005,16 @@ sub retrieve_queue_summary {
sub import_record_asset_list_impl {
my($conn, $rec_ids, $requestor) = @_;
- my $total = @$rec_ids;
- my $try_count = 0;
- my $in_count = 0;
my $roe = new_editor(xact=> 1, requestor => $requestor);
+ my %report_args = (
+ conn => $conn,
+ total => scalar(@$rec_ids),
+ step => 1, # how often to respond
+ progress => 0,
+ in_count => 0,
+ );
+
for my $rec_id (@$rec_ids) {
my $rec = $roe->retrieve_vandelay_queued_bib_record($rec_id);
next unless $rec and $rec->import_time;
@@ -1017,7 +1023,8 @@ sub import_record_asset_list_impl {
for my $item_id (@$item_ids) {
my $e = new_editor(requestor => $requestor, xact => 1);
my $item = $e->retrieve_vandelay_import_item($item_id);
- $try_count++;
+ $report_args{progress}++;
+ $report_args{import_item} = $item;
# --------------------------------------------------------------------------------
# Find or create the volume
@@ -1027,7 +1034,7 @@ sub import_record_asset_list_impl {
$e, $item->call_number, $rec->imported_as, $item->owning_lib);
if($evt) {
- respond_with_status($conn, $total, $try_count, $in_count, $evt);
+ respond_with_status(%report_args, evt => $evt);
next;
}
@@ -1057,13 +1064,14 @@ sub import_record_asset_list_impl {
# --------------------------------------------------------------------------------
#if($copy->circ_modifier and not $e->retrieve_config_circ_modifier($item->circ_modifier)) {
if($copy->circ_modifier and not $e->search_config_circ_modifier({code=>$item->circ_modifier})->[0]) {
- respond_with_status($conn, $total, $try_count, $in_count, $e->die_event);
+ respond_with_status(%report_args, evt => $e->die_event);
next;
}
if($evt = OpenILS::Application::Cat::AssetCommon->create_copy($e, $vol, $copy)) {
try { $e->rollback } otherwise {}; # sometimes calls die_event, sometimes not
- respond_with_status($conn, $total, $try_count, $in_count, $evt);
+ $report_args{evt} = $evt;
+ respond_with_status(%report_args);
next;
}
@@ -1074,7 +1082,7 @@ sub import_record_asset_list_impl {
$e, $copy, '', $item->pub_note, 1) if $item->pub_note;
if($evt) {
- respond_with_status($conn, $total, $try_count, $in_count, $evt);
+ respond_with_status(%report_args, evt => $evt);
next;
}
@@ -1082,7 +1090,7 @@ sub import_record_asset_list_impl {
$e, $copy, '', $item->priv_note, 1) if $item->priv_note;
if($evt) {
- respond_with_status($conn, $total, $try_count, $in_count, $evt);
+ respond_with_status(%report_args, evt => $evt);
next;
}
@@ -1090,7 +1098,8 @@ sub import_record_asset_list_impl {
# Item import succeeded
# --------------------------------------------------------------------------------
$e->commit;
- respond_with_status($conn, $total, $try_count, ++$in_count, undef, imported_as => $copy->id);
+ $report_args{in_count}++;
+ respond_with_status(%report_args, imported_as => $copy->id)
}
}
$roe->rollback;
@@ -1099,12 +1108,36 @@ sub import_record_asset_list_impl {
sub respond_with_status {
- my($conn, $total, $try_count, $success_count, $err, %args) = @_;
- $conn->respond({
- total => $total,
- progress => $try_count,
- err_event => $err,
- success_count => $success_count, %args }) if $err or ($try_count % 5 == 0);
+ my %args = @_;
+
+ # If the import failed, track the failure reason
+
+ my $error = $args{import_error};
+ my $evt = $args{evt};
+
+ if($error || $evt) {
+
+ my $item = $args{import_item};
+
+ my $error ||= 'general.unknown';
+ $item->import_error($error);
+
+ if($evt) {
+ my $detail = sprintf("%s : %s", $evt->{textcode}, substr($evt->{desc}, 0, 120));
+ $item->error_detail($detail);
+ }
+
+ my $e = new_editor(xact => 1);
+ $e->update_vandelay_import_item($item);
+ $e->commit;
+ }
+
+ return unless $args{report_all} or ($args{progress} % $args{step}) == 0;
+ $args{step} *= 2 unless $args{step} == 256;
+
+ $args{conn}->respond({
+ map { $_ => $args{$_} } qw/total progress success_count/
+ });
}
__PACKAGE__->register_method(
commit 8aa208b2796b05c74d2a4efa126b71514448e4fc
Author: berick <berick at commidore64.esilibrary.com>
Date: Thu Apr 21 14:27:41 2011 -0400
previous cast solution didn't work. casting inline instead
diff --git a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
index f95c4f1..3a69144 100644
--- a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
+++ b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
@@ -492,10 +492,9 @@ BEGIN
incoming_existing_id := oils_xpath_string('//*[@tag="901"]/*[@code="c"][1]',NEW.marc);
IF incoming_existing_id IS NOT NULL AND incoming_existing_id != '' THEN
- incoming_existing_id := incoming_existing_id::bigint;
- SELECT id INTO tmp_rec FROM biblio.record_entry WHERE id = incoming_existing_id;
+ SELECT id INTO tmp_rec FROM biblio.record_entry WHERE id = incoming_existing_id::bigint;
IF tmp_rec IS NOT NULL THEN
- INSERT INTO vandelay.bib_match (queued_record, eg_record, quality) VALUES ( NEW.id, incoming_existing_id, 9999);
+ INSERT INTO vandelay.bib_match (queued_record, eg_record, quality) VALUES ( NEW.id, incoming_existing_id::bigint, 9999);
RETURN NEW;
END IF;
END IF;
commit 091e82590d2d7b63fa4e882cbc9681b470ba97e2
Author: berick <berick at commidore64.esilibrary.com>
Date: Thu Apr 21 13:52:49 2011 -0400
repaired some thinko's in vandelay.match_bib_record stored proc
diff --git a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
index 7b4ba02..f95c4f1 100644
--- a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
+++ b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
@@ -491,10 +491,11 @@ BEGIN
incoming_existing_id := oils_xpath_string('//*[@tag="901"]/*[@code="c"][1]',NEW.marc);
- IF incoming_existing_id IS NOT NULL THEN
- SELECT id INTO tmp_rec FROM biblio.record_entry WHERE id = exact_id;
+ IF incoming_existing_id IS NOT NULL AND incoming_existing_id != '' THEN
+ incoming_existing_id := incoming_existing_id::bigint;
+ SELECT id INTO tmp_rec FROM biblio.record_entry WHERE id = incoming_existing_id;
IF tmp_rec IS NOT NULL THEN
- INSERT INTO vandelay.bib_match (queued_record, eg_record, quality) VALUES ( NEW.id, exact_id, 9999);
+ INSERT INTO vandelay.bib_match (queued_record, eg_record, quality) VALUES ( NEW.id, incoming_existing_id, 9999);
RETURN NEW;
END IF;
END IF;
commit c9ee753591520129794452347403801545894caf
Author: berick <berick at commidore64.esilibrary.com>
Date: Thu Apr 21 13:51:51 2011 -0400
cleaned out some non-existent fields from vandelay classes
diff --git a/Open-ILS/examples/fm_IDL.xml b/Open-ILS/examples/fm_IDL.xml
index c89957b..0c59bd4 100644
--- a/Open-ILS/examples/fm_IDL.xml
+++ b/Open-ILS/examples/fm_IDL.xml
@@ -278,7 +278,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
<field reporter:label="Name" name="name" reporter:datatype="text" oils_persist:i18n="true"/>
<field reporter:label="Complete" name="complete" reporter:datatype="bool"/>
<field reporter:label="Type" name="queue_type" reporter:datatype="text"/>
- <field reporter:label="Quality" name="quality" reporter:datatype="int"/>
<field reporter:label="Match Set" name="match_set" reporter:datatype="link"/>
<field reporter:label="Item Import Attribute Definition" name="item_attr_def" reporter:datatype="link"/>
</fields>
@@ -417,7 +416,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
<field reporter:label="Name" name="name" reporter:datatype="text" oils_persist:i18n="true"/>
<field reporter:label="Complete" name="complete" reporter:datatype="bool"/>
<field reporter:label="Type" name="queue_type" reporter:datatype="text"/>
- <field reporter:label="Quality" name="quality" reporter:datatype="int"/>
<field reporter:label="Match Set" name="match_set" reporter:datatype="link"/>
</fields>
<links>
@@ -472,7 +470,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
<field reporter:label="Description" name="description" reporter:datatype="text" oils_persist:i18n="true"/>
<field reporter:label="XPath" name="xpath" reporter:datatype="text"/>
<field reporter:label="Remove RegExp" name="remove" reporter:datatype="text"/>
- <field reporter:label="Is Identifier?" name="ident" reporter:datatype="bool"/>
</fields>
<links/>
<permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
commit a050890c67f43f989810bcb76695ff4f13eea938
Author: senator <lebbeous at esilibrary.com>
Date: Mon Apr 18 13:53:13 2011 -0400
Working ML method to update a tree
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
index aa830ad..4d3049a 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
@@ -1111,7 +1111,12 @@ __PACKAGE__->register_method(
api_name => "open-ils.vandelay.match_set.get_tree",
method => "match_set_get_tree",
api_level => 1,
- argc => 1
+ argc => 2,
+ signature => {
+ desc => q/For a given vms object, return a tree of match set points
+ represented by a vmsp object with recursively fleshed
+ children./
+ }
);
sub match_set_get_tree {
@@ -1137,4 +1142,62 @@ sub match_set_get_tree {
}
+__PACKAGE__->register_method(
+ api_name => "open-ils.vandelay.match_set.update",
+ method => "match_set_update_tree",
+ api_level => 1,
+ argc => 3,
+ signature => {
+ desc => q/Replace any vmsp objects associated with a given (by ID) vms
+ with the given objects (recursively fleshed vmsp tree)./
+ }
+);
+
+sub _walk_new_vmsp {
+ my ($e, $match_set_id, $node, $parent_id) = @_;
+
+ my $point = new Fieldmapper::vandelay::match_set_point;
+ $point->parent($parent_id);
+ $point->match_set($match_set_id);
+ $point->$_($node->$_) for (qw/bool_op svf tag subfield negate quality/);
+
+ $e->create_vandelay_match_set_point($point) or return $e->die_event;
+
+ $parent_id = $e->data->id;
+ if ($node->children && @{$node->children}) {
+ for (@{$node->children}) {
+ return $e->die_event if
+ _walk_new_vmsp($e, $match_set_id, $_, $parent_id);
+ }
+ }
+
+ return;
+}
+
+sub match_set_update_tree {
+ my ($self, $conn, $authtoken, $match_set_id, $tree) = @_;
+
+ my $e = new_editor("xact" => 1, "authtoken" => $authtoken);
+ $e->checkauth or return $e->die_event;
+
+ my $set = $e->retrieve_vandelay_match_set($match_set_id) or
+ return $e->die_event;
+
+ $e->allowed("ADMIN_IMPORT_MATCH_SET", $set->owner) or
+ return $e->die_event;
+
+ my $existing = $e->search_vandelay_match_set_point([
+ {"match_set" => $match_set_id},
+ {"order_by" => {"vmsp" => "id DESC"}}
+ ]) or return $e->die_event;
+
+ foreach (@$existing) {
+ $e->delete_vandelay_match_set_point($_) or return $e->die_event;
+ }
+
+ _walk_new_vmsp($e, $match_set_id, $tree);
+
+ $e->commit or return $e->die_event;
+}
+
1;
commit bae118889863f9fa37fbafd195c5d8ed86404f11
Author: senator <lebbeous at esilibrary.com>
Date: Mon Apr 18 11:20:28 2011 -0400
Terminology change, more consitent with existing crad editor
diff --git a/Open-ILS/web/js/dojo/openils/vandelay/nls/match_set.js b/Open-ILS/web/js/dojo/openils/vandelay/nls/match_set.js
index 4d92442..7e76613 100644
--- a/Open-ILS/web/js/dojo/openils/vandelay/nls/match_set.js
+++ b/Open-ILS/web/js/dojo/openils/vandelay/nls/match_set.js
@@ -8,5 +8,6 @@
"OK": "Ok",
"POINT_NEEDS_ONE": "A match point must be exactly one of the following: boolean operator, MARC tag/subfield pair, single-value-field.",
"FAULTY_MARC": "A MARC tag must be identified by three digits, and the subfield must be one non-whitespace, non-control character.",
- "WORKING_MP_HERE": "Choose from among the three buttons above to add a new match point."
+ "WORKING_MP_HERE": "Choose from among the three buttons above to add a new match point.",
+ "SVF": "Record Attribute"
}
diff --git a/Open-ILS/web/js/ui/default/conify/global/vandelay/match_set.js b/Open-ILS/web/js/ui/default/conify/global/vandelay/match_set.js
index 0c58528..dfcfc44 100644
--- a/Open-ILS/web/js/ui/default/conify/global/vandelay/match_set.js
+++ b/Open-ILS/web/js/ui/default/conify/global/vandelay/match_set.js
@@ -44,7 +44,7 @@ function NodeEditor() {
dojo.attr(select, "id", "svf-select");
var label = dojo.create(
"label", {
- "for": "svf-select", "innerHTML": "Single-Value-Field:"
+ "for": "svf-select", "innerHTML": localeStrings.SVF + ":"
}
);
diff --git a/Open-ILS/web/templates/default/conify/global/vandelay/match_set_tree.tt2 b/Open-ILS/web/templates/default/conify/global/vandelay/match_set_tree.tt2
index de7c838..4290e0b 100644
--- a/Open-ILS/web/templates/default/conify/global/vandelay/match_set_tree.tt2
+++ b/Open-ILS/web/templates/default/conify/global/vandelay/match_set_tree.tt2
@@ -76,7 +76,7 @@
</div>
<div id="vmsp-buttons">
Add new
- <button onclick="node_editor.add('svf');">Single-Value-Field</button>
+ <button onclick="node_editor.add('svf');">Record Attribute</button>
<button onclick="node_editor.add('tag');">MARC Tag and Subfield</button>
<button onclick="node_editor.add('bool_op');">Boolean Operator</button>
</div>
commit fe0c574d0fd474cf1145786ed959ceb4df840874
Author: senator <lebbeous at esilibrary.com>
Date: Mon Apr 18 11:15:20 2011 -0400
make the "Your Expression" preview more accurate by
showing "NOT (a OR b OR c)" instead of "(a NOR b NOR c)".
This really only matters in the case of a single clause inside the
negated expression:
Now such a thing shows up as "NOT (a)" versus "(a)"
diff --git a/Open-ILS/web/js/ui/default/conify/global/vandelay/match_set.js b/Open-ILS/web/js/ui/default/conify/global/vandelay/match_set.js
index 2212dcd..0c58528 100644
--- a/Open-ILS/web/js/ui/default/conify/global/vandelay/match_set.js
+++ b/Open-ILS/web/js/ui/default/conify/global/vandelay/match_set.js
@@ -231,9 +231,12 @@ function NodeEditor() {
}
function render_vmsp_label(point, minimal) {
- /* quick and dirty */
+ /* "minimal" mode has two implications:
+ * 1) for svf, only show the code, not the longer label.
+ * 2) for bool ops, completely ingore negation
+ */
if (point.bool_op()) {
- return (openils.Util.isTrue(point.negate()) ? "N" : "") +
+ return (!minimal && openils.Util.isTrue(point.negate()) ? "N" : "") +
point.bool_op();
} else if (point.svf()) {
return (openils.Util.isTrue(point.negate()) ? "NOT " : "") + (
@@ -361,8 +364,9 @@ function redraw_expression_preview() {
function render_expression_preview(r) {
if (r.children().length) {
- return "(" + r.children().map(render_expression_preview).join(
- " " + render_vmsp_label(r) + " "
+ return (openils.Util.isTrue(r.negate()) ? "NOT " : "") +
+ "(" + r.children().map(render_expression_preview).join(
+ " " + render_vmsp_label(r, true /* minimal */) + " "
) + ")";
} else if (!r.bool_op()) {
return render_vmsp_label(r, true /* minimal */);
commit 3a406e5cb384a22ade99069a69cec8d9091073c6
Author: senator <lebbeous at esilibrary.com>
Date: Fri Apr 15 18:01:22 2011 -0400
Admin -> Server Administration -> Import Match Sets
That's where you'll find the interface for the match set expression
editor in the staff client.
diff --git a/Open-ILS/web/opac/locale/en-US/lang.dtd b/Open-ILS/web/opac/locale/en-US/lang.dtd
index 4043024..6352be9 100644
--- a/Open-ILS/web/opac/locale/en-US/lang.dtd
+++ b/Open-ILS/web/opac/locale/en-US/lang.dtd
@@ -730,6 +730,7 @@
<!ENTITY staff.main.menu.admin.server_admin.conify.z3950_source.label "Z39.50 Servers">
<!ENTITY staff.main.menu.admin.server_admin.conify.circulation_modifier.label "Circulation Modifiers">
<!ENTITY staff.main.menu.admin.server_admin.conify.org_unit_setting_type "Organization Unit Setting Types">
+<!ENTITY staff.main.menu.admin.server_admin.conify.import_match_set "Import Match Sets">
<!ENTITY staff.main.menu.admin.server_admin.conify.usr_setting_type "User Setting Types">
<!ENTITY staff.main.menu.admin.server_admin.conify.config_hard_due_date "Hard Due Date Changes">
<!ENTITY staff.main.menu.admin.server_admin.conify.config_rule_circ_duration "Circulation Duration Rules">
diff --git a/Open-ILS/xul/staff_client/chrome/content/main/menu.js b/Open-ILS/xul/staff_client/chrome/content/main/menu.js
index fc85a8f..79949f4 100644
--- a/Open-ILS/xul/staff_client/chrome/content/main/menu.js
+++ b/Open-ILS/xul/staff_client/chrome/content/main/menu.js
@@ -951,6 +951,10 @@ main.menu.prototype = {
['oncommand'],
function(event) { open_eg_web_page('conify/global/config/org_unit_setting_type', null, event); }
],
+ 'cmd_server_admin_import_match_set' : [
+ ['oncommand'],
+ function(event) { open_eg_web_page('conify/global/vandelay/match_set', null, event); }
+ ],
'cmd_server_admin_usr_setting_type' : [
['oncommand'],
function(event) { open_eg_web_page('conify/global/config/usr_setting_type', null, event); }
diff --git a/Open-ILS/xul/staff_client/chrome/content/main/menu_frame_menus.xul b/Open-ILS/xul/staff_client/chrome/content/main/menu_frame_menus.xul
index 8c79bbf..741c0ce 100644
--- a/Open-ILS/xul/staff_client/chrome/content/main/menu_frame_menus.xul
+++ b/Open-ILS/xul/staff_client/chrome/content/main/menu_frame_menus.xul
@@ -182,6 +182,7 @@
perm="ADMIN_GLOBAL_FLAG"
/>
<command id="cmd_server_admin_org_unit_setting_type" />
+ <command id="cmd_server_admin_import_match_set" />
<command id="cmd_server_admin_usr_setting_type" />
<command id="cmd_server_admin_config_hard_due_date"
perm="CREATE_CIRC_DURATION DELETE_CIRC_DURATION UPDATE_CIRC_DURATION"
@@ -479,6 +480,7 @@
<menuitem label="&staff.main.menu.admin.server_admin.conify.z3950_source.label;" command="cmd_server_admin_z39_source"/>
<menuitem label="&staff.main.menu.admin.server_admin.conify.circulation_modifier.label;" command="cmd_server_admin_circ_mod"/>
<menuitem label="&staff.main.menu.admin.server_admin.conify.global_flag.label;" command="cmd_server_admin_global_flag"/>
+ <menuitem label="&staff.main.menu.admin.server_admin.conify.import_match_set;" command="cmd_server_admin_import_match_set"/>
<menuitem label="&staff.main.menu.admin.server_admin.conify.org_unit_setting_type;" command="cmd_server_admin_org_unit_setting_type"/>
<menuitem label="&staff.main.menu.admin.server_admin.conify.usr_setting_type;" command="cmd_server_admin_usr_setting_type"/>
<menuitem label="&staff.main.menu.admin.server_admin.conify.config_hard_due_date;" command="cmd_server_admin_config_hard_due_date"/>
commit 9e82b590abbc53e2e2059067028a25e4c25dbef2
Author: senator <lebbeous at esilibrary.com>
Date: Fri Apr 15 17:56:07 2011 -0400
move parts to conify namespace
diff --git a/Open-ILS/web/js/ui/default/vandelay/match_set.js b/Open-ILS/web/js/ui/default/conify/global/vandelay/match_set.js
similarity index 100%
rename from Open-ILS/web/js/ui/default/vandelay/match_set.js
rename to Open-ILS/web/js/ui/default/conify/global/vandelay/match_set.js
diff --git a/Open-ILS/web/templates/default/vandelay/match_set.tt2 b/Open-ILS/web/templates/default/conify/global/vandelay/match_set.tt2
similarity index 97%
rename from Open-ILS/web/templates/default/vandelay/match_set.tt2
rename to Open-ILS/web/templates/default/conify/global/vandelay/match_set.tt2
index 0d59f54..fad64db 100644
--- a/Open-ILS/web/templates/default/vandelay/match_set.tt2
+++ b/Open-ILS/web/templates/default/conify/global/vandelay/match_set.tt2
@@ -66,7 +66,7 @@
function tree_editor_link(datum) {
if (!datum) return "";
- return '<a href="[% ctx.base_path %]/vandelay/match_set_tree?match_set=' +
+ return '<a href="[% ctx.base_path %]/eg/conify/global/vandelay/match_set_tree?match_set=' +
datum.id + '">' + datum.name + '</a>';
}
diff --git a/Open-ILS/web/templates/default/vandelay/match_set_tree.tt2 b/Open-ILS/web/templates/default/conify/global/vandelay/match_set_tree.tt2
similarity index 97%
rename from Open-ILS/web/templates/default/vandelay/match_set_tree.tt2
rename to Open-ILS/web/templates/default/conify/global/vandelay/match_set_tree.tt2
index 1ebf055..de7c838 100644
--- a/Open-ILS/web/templates/default/vandelay/match_set_tree.tt2
+++ b/Open-ILS/web/templates/default/conify/global/vandelay/match_set_tree.tt2
@@ -107,5 +107,5 @@
</div>
<div jsId="progress_dialog" dojoType="openils.widget.ProgressDialog"></div>
<script type="text/javascript"
- src="[% ctx.media_prefix %]/js/ui/default/vandelay/match_set.js"></script>
+ src="[% ctx.media_prefix %]/js/ui/default/conify/global/vandelay/match_set.js"></script>
[% END %]
commit c78f3ec233c08fa7a3526621f06ea1521a47074c
Author: senator <lebbeous at esilibrary.com>
Date: Fri Apr 15 17:49:12 2011 -0400
UI perfection. it previews. it saves...
(or if it would if the ML method were done, but it will be easy now)
I just need to move things to the conify path and add staff client menu
entries
diff --git a/Open-ILS/web/js/dojo/openils/vandelay/TreeDndSource.js b/Open-ILS/web/js/dojo/openils/vandelay/TreeDndSource.js
index 0748a2f..c0586b5 100644
--- a/Open-ILS/web/js/dojo/openils/vandelay/TreeDndSource.js
+++ b/Open-ILS/web/js/dojo/openils/vandelay/TreeDndSource.js
@@ -30,6 +30,22 @@ dojo.declare(
window._tree_dnd_controllers = [];
window._tree_dnd_controllers.push(this);
+
+ dojo.connect(
+ this.tree.model.store, "onNew", this,
+ function() { this.redraw_expression_preview(); }
+ );
+ dojo.connect(
+ this.tree.model.store, "onDelete", this,
+ function() { this.redraw_expression_preview(); }
+ );
+ },
+ "redraw_expression_preview": function() {
+ if (typeof(window.redraw_expression_preview) == "function") {
+ window.redraw_expression_preview();
+ } else {
+ console.log("no redraw_expression_preview function registered");
+ }
},
"checkItemAcceptance": function(target, source, position) {
if (!source._ready || source == this) return;
@@ -101,6 +117,8 @@ dojo.declare(
);
}
+ this.redraw_expression_preview();
+
/* just because this is at the end of the default implementation: */
this.onDndCancel();
}
diff --git a/Open-ILS/web/js/dojo/openils/vandelay/TreeStoreModel.js b/Open-ILS/web/js/dojo/openils/vandelay/TreeStoreModel.js
index af26d09..e694238 100644
--- a/Open-ILS/web/js/dojo/openils/vandelay/TreeStoreModel.js
+++ b/Open-ILS/web/js/dojo/openils/vandelay/TreeStoreModel.js
@@ -10,32 +10,32 @@ dojo.require("openils.Util");
function _simple_item(model, item) {
/* Instead of model.getLabel(), could do
* model.store.getValue(item, "blah") or something like that ... */
- return {
- "label": model.getLabel(item),
- "match_point": String(model.store.getValue(item, "match_point")),
- "children": {}
- };
+ var mp = model.store.getValue(item, "match_point");
+ mp.children([]);
+ return mp;
}
dojo.declare(
"openils.vandelay.TreeStoreModel", dijit.tree.TreeStoreModel, {
"replace_mode": 0,
- "getSimpleTree": function(item, oncomplete, result) {
+ "get_simple_tree": function(item, oncomplete, result) {
var self = this;
- if (!result) result = {};
-
- var mykey = this.getIdentity(item);
- result[mykey] = _simple_item(this, item);
- var child_collector = result[mykey].children;
+ var me;
+ if (!result) {
+ me = result = _simple_item(this, item);
+ } else {
+ me = _simple_item(this, item);
+ result.push(me);
+ }
if (this.mayHaveChildren(item)) {
this.getChildren(
item, function(children) {
+ var kids_here = [];
for (var i = 0; i < children.length; i++) {
- self.getSimpleTree(
- children[i], null, child_collector
- );
+ self.get_simple_tree(children[i], null, kids_here);
}
+ me.children(kids_here);
if (oncomplete) oncomplete(result);
}
);
@@ -48,9 +48,5 @@ dojo.declare(
else
return true;
}
-// "newItem": function(args, parent) {
-// if (!this.mayHaveChildren(parent)) return;
-// return this.inherited(arguments);
-// }
}
);
diff --git a/Open-ILS/web/js/dojo/openils/vandelay/nls/match_set.js b/Open-ILS/web/js/dojo/openils/vandelay/nls/match_set.js
index ae9277e..4d92442 100644
--- a/Open-ILS/web/js/dojo/openils/vandelay/nls/match_set.js
+++ b/Open-ILS/web/js/dojo/openils/vandelay/nls/match_set.js
@@ -7,5 +7,6 @@
"NO_CAN_DO": "An error has occurred. Close this interface and try again.",
"OK": "Ok",
"POINT_NEEDS_ONE": "A match point must be exactly one of the following: boolean operator, MARC tag/subfield pair, single-value-field.",
- "FAULTY_MARC": "A MARC tag must be identified by three digits, and the subfield must be one non-whitespace, non-control character."
+ "FAULTY_MARC": "A MARC tag must be identified by three digits, and the subfield must be one non-whitespace, non-control character.",
+ "WORKING_MP_HERE": "Choose from among the three buttons above to add a new match point."
}
diff --git a/Open-ILS/web/js/ui/default/vandelay/match_set.js b/Open-ILS/web/js/ui/default/vandelay/match_set.js
index 4c32278..2212dcd 100644
--- a/Open-ILS/web/js/ui/default/vandelay/match_set.js
+++ b/Open-ILS/web/js/ui/default/vandelay/match_set.js
@@ -10,7 +10,7 @@ dojo.require("openils.Util");
dojo.require("openils.PermaCrud");
dojo.require("openils.widget.ProgressDialog");
-var localeStrings, node_editor, _crads, CGI, tree;
+var localeStrings, node_editor, _crads, CGI, tree, match_set;
function _find_crad_by_name(name) {
for (var i = 0; i < _crads.length; i++) {
@@ -120,7 +120,10 @@ function NodeEditor() {
this.clear = function() {
this.dnd_source.selectAll().deleteSelectedNodes();
- dojo.empty(this.node_editor_container);
+ dojo.create(
+ "em", {"innerHTML": localeStrings.WORKING_MP_HERE},
+ this.node_editor_container, "only"
+ );
this.dnd_source._ready = false;
};
@@ -215,21 +218,28 @@ function NodeEditor() {
);
dojo.place(table, this.node_editor_container, "only");
- /* XXX around here attach other data structures to the node */
+
this.dnd_source.insertNodes(false, [draggable]);
+
+ /* nice */
+ try { dojo.query("select, input", table)[0].focus(); }
+ catch(E) { console.log(String(E)); }
+
};
this._init.apply(this, arguments);
}
-function render_vmsp_label(point) {
+function render_vmsp_label(point, minimal) {
/* quick and dirty */
if (point.bool_op()) {
return (openils.Util.isTrue(point.negate()) ? "N" : "") +
point.bool_op();
} else if (point.svf()) {
- return (openils.Util.isTrue(point.negate()) ? "NOT " : "") +
- point.svf() + " / " + _find_crad_by_name(point.svf()).label();
+ return (openils.Util.isTrue(point.negate()) ? "NOT " : "") + (
+ minimal ? point.svf() :
+ (point.svf() + " / " + _find_crad_by_name(point.svf()).label())
+ );
} else {
return (openils.Util.isTrue(point.negate()) ? "NOT " : "") +
point.tag() + " \u2021" + point.subfield();
@@ -333,6 +343,62 @@ function render_vms_metadata(match_set) {
dojo.byId("vms-mtype").innerHTML = match_set.mtype();
}
+function redraw_expression_preview() {
+ tree.model.getRoot(
+ function(root) {
+ tree.model.get_simple_tree(
+ root, function(r) {
+ dojo.attr(
+ "expr-preview",
+ "innerHTML",
+ render_expression_preview(r)
+ );
+ }
+ );
+ }
+ );
+}
+
+function render_expression_preview(r) {
+ if (r.children().length) {
+ return "(" + r.children().map(render_expression_preview).join(
+ " " + render_vmsp_label(r) + " "
+ ) + ")";
+ } else if (!r.bool_op()) {
+ return render_vmsp_label(r, true /* minimal */);
+ } else {
+ return "()";
+ }
+}
+
+function save_tree() {
+ progress_dialog.show(true);
+
+ tree.model.getRoot(
+ function(root) {
+ tree.model.get_simple_tree(
+ root, function(r) {
+ fieldmapper.standardRequest(
+ ["open-ils.vandelay",
+ "open-ils.vandelay.match_set.update"],/* XXX TODO */{
+ "params": [
+ openils.User.authtoken, match_set.id(), r
+ ],
+ "async": true,
+ "oncomplete": function(r) {
+ progress_dialog.hide();
+ /* catch exceptions */
+ r = openils.Util.readResponse(r);
+
+ location.href = location.href;
+ }
+ }
+ );
+ }
+ );
+ }
+ );
+}
function my_init() {
progress_dialog.show(true);
@@ -348,7 +414,9 @@ function my_init() {
return;
}
- render_vms_metadata(pcrud.retrieve("vms", CGI.param("match_set")));
+ render_vms_metadata(
+ match_set = pcrud.retrieve("vms", CGI.param("match_set"))
+ );
/* No-one should have hundreds of these or anything, but theoretically
* this could be problematic with a big enough list of crad objects. */
@@ -400,6 +468,9 @@ function my_init() {
"move." */
}
);
+
+ redraw_expression_preview();
+ node_editor.clear();
progress_dialog.hide();
}
diff --git a/Open-ILS/web/templates/default/vandelay/match_set_tree.tt2 b/Open-ILS/web/templates/default/vandelay/match_set_tree.tt2
index 02ac2d4..1ebf055 100644
--- a/Open-ILS/web/templates/default/vandelay/match_set_tree.tt2
+++ b/Open-ILS/web/templates/default/vandelay/match_set_tree.tt2
@@ -12,7 +12,15 @@
#src-pane { float: left; width: 49%; }
#tree-pane { float: right; width: 50%; }
#submit-row { clear: both; text-align: center; padding-top: 1.5ex; }
- #submit-row hr { margin: 1ex 0; }
+ #submit-row hr { margin: 1.5ex 0; }
+ #expr-preview-row { margin: 2ex 0; }
+ #expr-preview {
+ font-family: monospace;
+ font-size: 125%;
+ font-weight: bold;
+ background-color: #000066;
+ color: white;
+ }
.node-editor { margin-bottom: 1.5ex; }
.node-editor td { padding: 0.5ex; }
li { background-color: #ddd; }
@@ -62,8 +70,10 @@
</tr>
</table>
<div class="outer">
- <div><!-- XXX TODO: consider a read-only display here of the query as built
- so far from the treet --></div>
+ <div id="expr-preview-row">
+ <em>Your Expression:</em>
+ <span id="expr-preview"></span>
+ </div>
<div id="vmsp-buttons">
Add new
<button onclick="node_editor.add('svf');">Single-Value-Field</button>
commit e04c57f1234925ba9acd681e2d944060a843975a
Author: senator <lebbeous at esilibrary.com>
Date: Fri Apr 15 14:28:16 2011 -0400
Match Set Tree editor improvements/cleanup
You can now replace the root node of the tree with anything,
and the children will be automatically deleted. This makes it easier to
create a single-node tree with no operators, if the user should so
desire.
comment cleanup, etc
diff --git a/Open-ILS/web/js/dojo/openils/vandelay/TreeDndSource.js b/Open-ILS/web/js/dojo/openils/vandelay/TreeDndSource.js
index 832ef6f..0748a2f 100644
--- a/Open-ILS/web/js/dojo/openils/vandelay/TreeDndSource.js
+++ b/Open-ILS/web/js/dojo/openils/vandelay/TreeDndSource.js
@@ -7,11 +7,14 @@ dojo.require("dijit._tree.dndSource");
*/
dojo.declare(
"openils.vandelay.TreeDndSource", dijit._tree.dndSource, {
- "_is_replaceable": function(spoint, dpoint) {
+ "_is_replaceable": function(spoint, dpoint, disroot) {
/* An OP can replace anything, but non-OPs can only replace other
- * non-OPs
+ * non-OPs, EXCEPT when the dest is the root node (this allows
+ * for simple "trees" with only a single non-OP node.
*/
- if (spoint.bool_op())
+ if (disroot)
+ return true;
+ else if (spoint.bool_op())
return true;
else if (!dpoint.bool_op())
return true;
@@ -32,13 +35,12 @@ dojo.declare(
if (!source._ready || source == this) return;
if (this.tree.model.replace_mode) {
+ var ditem = dijit.getEnclosingWidget(target).item;
return (
position == "over" && this._is_replaceable(
source.getAllNodes()[0].match_point,
- this.tree.model.store.getValue(
- dijit.getEnclosingWidget(target).item,
- "match_point"
- )
+ this.tree.model.store.getValue(ditem, "match_point"),
+ ditem === this.tree.model.root
)
);
} else {
@@ -82,6 +84,15 @@ dojo.declare(
if (k == "id") continue; /* can't use this / don't need it */
store.setValue(item, k, new_params[k]);
}
+ if (this.tree.model.root === item) { /* replacing root node */
+ if (!new_params.match_point.bool_op()) {
+ /* If we're here, we've replaced the root node with
+ * something that isn't a bool op, so we need to nuke
+ * any children that the item has.
+ */
+ store.setValue(item, "children", []);
+ }
+ }
if (typeof(window.render_vmsp_label) == "function") {
store.setValue(
item,
diff --git a/Open-ILS/web/js/ui/default/vandelay/match_set.js b/Open-ILS/web/js/ui/default/vandelay/match_set.js
index 990f21d..4c32278 100644
--- a/Open-ILS/web/js/ui/default/vandelay/match_set.js
+++ b/Open-ILS/web/js/ui/default/vandelay/match_set.js
@@ -222,8 +222,6 @@ function NodeEditor() {
this._init.apply(this, arguments);
}
-/* XXX replace later with code that will suit this function's purpose
- * as well as that of update_draggable. */
function render_vmsp_label(point) {
/* quick and dirty */
if (point.bool_op()) {
@@ -294,7 +292,6 @@ function new_match_set_tree() {
*
*/
function dojoize_match_set_tree(point, refgen) {
- /* XXX TODO test with deeper trees! */
var root = false;
if (!refgen) {
if (!point) {
@@ -329,7 +326,7 @@ function dojoize_match_set_tree(point, refgen) {
return results;
}
-function render_match_set_description(match_set) {
+function render_vms_metadata(match_set) {
dojo.byId("vms-name").innerHTML = match_set.name();
dojo.byId("vms-owner").innerHTML =
aou.findOrgUnit(match_set.owner()).name();
@@ -351,14 +348,11 @@ function my_init() {
return;
}
- var match_set = pcrud.retrieve("vms", CGI.param("match_set"));
- render_match_set_description(match_set);
+ render_vms_metadata(pcrud.retrieve("vms", CGI.param("match_set")));
- /* XXX No-one should have hundreds of these or anything, but theoretically
+ /* No-one should have hundreds of these or anything, but theoretically
* this could be problematic with a big enough list of crad objects. */
- _crads = pcrud.retrieveAll(
- "crad", {"order_by": {"crad": "label"}}
- );
+ _crads = pcrud.retrieveAll("crad", {"order_by": {"crad": "label"}});
var match_set_tree = fieldmapper.standardRequest(
["open-ils.vandelay", "open-ils.vandelay.match_set.get_tree"],
@@ -395,12 +389,15 @@ function my_init() {
dojo.connect(
src, "onDndDrop", null,
function(source, nodes, copy, target) {
- /* XXX because of the... interesting... characteristics of DnD
+ /* Because of the... interesting... characteristics of DnD
* design in dojo/dijit (at least as of 1.3), this callback will
* fire both for our working node dndSource and for the tree!
*/
if (source == this)
- node_editor.clear(); /* because otherwise this acts like a copy! */
+ node_editor.clear(); /* ... because otherwise this acts like a
+ copy operation no matter what the user
+ does, even though we really want a
+ "move." */
}
);
progress_dialog.hide();
commit 128554e383bafb7f9ac7b0edd3ec17ebb3ff90e0
Author: senator <lebbeous at esilibrary.com>
Date: Fri Apr 15 12:28:47 2011 -0400
make sure user can only add reasonbly valid match points to the tree
diff --git a/Open-ILS/web/js/dojo/openils/vandelay/nls/match_set.js b/Open-ILS/web/js/dojo/openils/vandelay/nls/match_set.js
index 30132e3..ae9277e 100644
--- a/Open-ILS/web/js/dojo/openils/vandelay/nls/match_set.js
+++ b/Open-ILS/web/js/dojo/openils/vandelay/nls/match_set.js
@@ -4,5 +4,8 @@
"EXACTLY_ONE": "First select exactly one node from the tree on the right side of the screen.",
"EXIT_REPLACE_MODE": "Exit Replace Mode",
"ENTER_REPLACE_MODE": "Enter Replace Mode",
- "NO_CAN_DO": "An error has occurred. Close this interface and try again."
+ "NO_CAN_DO": "An error has occurred. Close this interface and try again.",
+ "OK": "Ok",
+ "POINT_NEEDS_ONE": "A match point must be exactly one of the following: boolean operator, MARC tag/subfield pair, single-value-field.",
+ "FAULTY_MARC": "A MARC tag must be identified by three digits, and the subfield must be one non-whitespace, non-control character."
}
diff --git a/Open-ILS/web/js/ui/default/vandelay/match_set.js b/Open-ILS/web/js/ui/default/vandelay/match_set.js
index 20fb624..990f21d 100644
--- a/Open-ILS/web/js/ui/default/vandelay/match_set.js
+++ b/Open-ILS/web/js/ui/default/vandelay/match_set.js
@@ -124,6 +124,32 @@ function NodeEditor() {
this.dnd_source._ready = false;
};
+ this.is_sensible = function(mp) {
+ var need_one = 0;
+ ["tag", "svf", "bool_op"].forEach(
+ function(field) { if (mp[field]()) need_one++; }
+ );
+
+ if (need_one != 1) {
+ alert(localeStrings.POINT_NEEDS_ONE);
+ return false;
+ }
+
+ if (mp.tag()) {
+ if (
+ !mp.tag().match(/^\d{3}$/) ||
+ mp.subfield().length != 1 ||
+ !mp.subfield().match(/\S/) ||
+ mp.subfield().charCodeAt(0) < 32
+ ) {
+ alert(localeStrings.FAULTY_MARC);
+ return false;
+ }
+ }
+
+ return true;
+ };
+
this.build_vmsp = function() {
var match_point = new vmsp();
var controls = dojo.query("[fmfield]", this.node_editor_container);
@@ -132,14 +158,18 @@ function NodeEditor() {
var value = _simple_value_getter(controls[i]);
match_point[field](value);
}
- return match_point;
+
+ if (!this.is_sensible(match_point)) return null; /* will alert() */
+ else return match_point;
};
this.update_draggable = function(draggable) {
- draggable.match_point = this.build_vmsp();
- dojo.attr(
- draggable, "innerHTML", render_vmsp_label(draggable.match_point)
- );
+ var mp;
+
+ if (!(mp = this.build_vmsp())) return; /* will alert() */
+
+ draggable.match_point = mp;
+ dojo.attr(draggable, "innerHTML", render_vmsp_label(mp));
this.dnd_source._ready = true;
};
@@ -176,7 +206,7 @@ function NodeEditor() {
dojo.create(
"input", {
- "type": "submit", "value": "Ok",
+ "type": "submit", "value": localeStrings.OK,
"onclick": function() { self.update_draggable(draggable); }
}, dojo.create(
"td", {"colspan": 2, "align": "center"},
diff --git a/Open-ILS/web/templates/default/vandelay/match_set_tree.tt2 b/Open-ILS/web/templates/default/vandelay/match_set_tree.tt2
index f8572e9..02ac2d4 100644
--- a/Open-ILS/web/templates/default/vandelay/match_set_tree.tt2
+++ b/Open-ILS/web/templates/default/vandelay/match_set_tree.tt2
@@ -4,6 +4,7 @@
h1 { margin: 1ex 0; }
.outer { clear: both; margin-bottom: 1ex; }
button { margin: 0 0.5em; }
+ input[type=submit] { padding: 0 0.5em; }
#tree-here { margin-bottom: 1.5em; }
#vms-table { padding-bottom: 2ex; }
#vms-table th { text-align: right; }
commit 5e0b24e22043d49b2b87eb7157df1b97e7713b91
Author: senator <lebbeous at esilibrary.com>
Date: Fri Apr 15 12:02:07 2011 -0400
1) implemented working replace mode 2) autocreate new tree on launch if needed
diff --git a/Open-ILS/web/js/dojo/openils/vandelay/TreeDndSource.js b/Open-ILS/web/js/dojo/openils/vandelay/TreeDndSource.js
index 8ccd836..832ef6f 100644
--- a/Open-ILS/web/js/dojo/openils/vandelay/TreeDndSource.js
+++ b/Open-ILS/web/js/dojo/openils/vandelay/TreeDndSource.js
@@ -7,12 +7,15 @@ dojo.require("dijit._tree.dndSource");
*/
dojo.declare(
"openils.vandelay.TreeDndSource", dijit._tree.dndSource, {
- "_is_replaceable": function(src_item, target_item) {
+ "_is_replaceable": function(spoint, dpoint) {
/* An OP can replace anything, but non-OPs can only replace other
* non-OPs
*/
- console.log("src item: " + src_item + " target item: " + target_item);
- return true; /* XXX TODO FINISHME */
+ if (spoint.bool_op())
+ return true;
+ else if (!dpoint.bool_op())
+ return true;
+ return false;
},
"constructor": function() {
/* Given a tree object, there seems to be no way to access its
@@ -28,11 +31,14 @@ dojo.declare(
"checkItemAcceptance": function(target, source, position) {
if (!source._ready || source == this) return;
- if (this.tree.model._replace_mode) {
+ if (this.tree.model.replace_mode) {
return (
position == "over" && this._is_replaceable(
source.getAllNodes()[0].match_point,
- dijit.getEnclosingWidget(target).item.match_point
+ this.tree.model.store.getValue(
+ dijit.getEnclosingWidget(target).item,
+ "match_point"
+ )
)
);
} else {
@@ -47,12 +53,45 @@ dojo.declare(
* only when we want the item to be draggable */
},
"itemCreator": function(nodes, somethingelse) {
- console.log("gew: " + dijit.getEnclosingWidget(somethingelse).item.name);
- console.log("dojo.dnd.manager.copy: " + dojo.dnd.manager.copy);
var default_items = this.inherited(arguments);
for (var i = 0; i < default_items.length; i++)
default_items[i].match_point = nodes[i].match_point;
return default_items;
+ },
+ "onDndDrop": function(source, nodes, copy) {
+ if (
+ !this.tree.model.replace_mode ||
+ this.containerState != "Over" ||
+ this.dropPosition == "Before" ||
+ this.dropPosition == "After" ||
+ source == this
+ ) {
+ return this.inherited(arguments);
+ }
+
+ /* This method only comes into play for our "replace mode" */
+
+ var target_widget = dijit.getEnclosingWidget(this.targetAnchor);
+ var new_params = this.itemCreator(nodes, this.targetAnchor)[0];
+
+ /* Here, we morph target_widget.item into the new item */
+
+ var store = this.tree.model.store;
+ var item = target_widget.item;
+ for (var k in new_params) {
+ if (k == "id") continue; /* can't use this / don't need it */
+ store.setValue(item, k, new_params[k]);
+ }
+ if (typeof(window.render_vmsp_label) == "function") {
+ store.setValue(
+ item,
+ "name",
+ window.render_vmsp_label(new_params.match_point)
+ );
+ }
+
+ /* just because this is at the end of the default implementation: */
+ this.onDndCancel();
}
}
);
diff --git a/Open-ILS/web/js/dojo/openils/vandelay/TreeStoreModel.js b/Open-ILS/web/js/dojo/openils/vandelay/TreeStoreModel.js
index 2a35b70..af26d09 100644
--- a/Open-ILS/web/js/dojo/openils/vandelay/TreeStoreModel.js
+++ b/Open-ILS/web/js/dojo/openils/vandelay/TreeStoreModel.js
@@ -19,7 +19,7 @@ function _simple_item(model, item) {
dojo.declare(
"openils.vandelay.TreeStoreModel", dijit.tree.TreeStoreModel, {
- "_replace_mode": 0,
+ "replace_mode": 0,
"getSimpleTree": function(item, oncomplete, result) {
var self = this;
if (!result) result = {};
diff --git a/Open-ILS/web/js/dojo/openils/vandelay/nls/match_set.js b/Open-ILS/web/js/dojo/openils/vandelay/nls/match_set.js
index ceb72bb..30132e3 100644
--- a/Open-ILS/web/js/dojo/openils/vandelay/nls/match_set.js
+++ b/Open-ILS/web/js/dojo/openils/vandelay/nls/match_set.js
@@ -3,5 +3,6 @@
"LEAVE_ROOT_ALONE": "You cannot delete the root node of a tree (but you can replace it).",
"EXACTLY_ONE": "First select exactly one node from the tree on the right side of the screen.",
"EXIT_REPLACE_MODE": "Exit Replace Mode",
- "ENTER_REPLACE_MODE": "Enter Replace Mode"
+ "ENTER_REPLACE_MODE": "Enter Replace Mode",
+ "NO_CAN_DO": "An error has occurred. Close this interface and try again."
}
diff --git a/Open-ILS/web/js/ui/default/vandelay/match_set.js b/Open-ILS/web/js/ui/default/vandelay/match_set.js
index f9fa8ec..20fb624 100644
--- a/Open-ILS/web/js/ui/default/vandelay/match_set.js
+++ b/Open-ILS/web/js/ui/default/vandelay/match_set.js
@@ -208,14 +208,21 @@ function render_vmsp_label(point) {
}
}
-function replace_mode() {
- tree.model._replace_mode ^= 1;
+function replace_mode(explicit) {
+ if (typeof explicit == "undefined")
+ tree.model.replace_mode ^= 1;
+ else
+ tree.model.replace_mode = explicit;
+
dojo.attr(
"replacer", "innerHTML",
localeStrings[
- (tree.model._replace_mode ? "EXIT" : "ENTER") + "_REPLACE_MODE"
+ (tree.model.replace_mode ? "EXIT" : "ENTER") + "_REPLACE_MODE"
]
);
+ dojo[tree.model.replace_mode ? "addClass" : "removeClass"](
+ "replacer", "replace-mode"
+ );
}
function delete_selected_in_tree() {
@@ -231,6 +238,19 @@ function delete_selected_in_tree() {
);
}
+function new_match_set_tree() {
+ var point = new vmsp();
+ point.bool_op("AND");
+ return [
+ {
+ "id": "root",
+ "children": [],
+ "name": render_vmsp_label(point),
+ "match_point": point
+ }
+ ];
+}
+
/* dojoize_match_set_tree() takes an argument, "point", that is actually a
* vmsp fieldmapper object with descendants fleshed hierarchically. It turns
* that into a syntactically flat array but preserving the hierarchy
@@ -247,6 +267,9 @@ function dojoize_match_set_tree(point, refgen) {
/* XXX TODO test with deeper trees! */
var root = false;
if (!refgen) {
+ if (!point) {
+ return new_match_set_tree();
+ }
refgen = 0;
root = true;
}
@@ -292,6 +315,12 @@ function my_init() {
pcrud = new openils.PermaCrud();
CGI = new openils.CGI();
+ if (!CGI.param("match_set")) {
+ alert(localeStrings.NO_CAN_DO);
+ progress_dialog.hide();
+ return;
+ }
+
var match_set = pcrud.retrieve("vms", CGI.param("match_set"));
render_match_set_description(match_set);
@@ -331,6 +360,8 @@ function my_init() {
node_editor = new NodeEditor(src, "node-editor-container");
+ replace_mode(0);
+
dojo.connect(
src, "onDndDrop", null,
function(source, nodes, copy, target) {
diff --git a/Open-ILS/web/templates/default/vandelay/match_set_tree.tt2 b/Open-ILS/web/templates/default/vandelay/match_set_tree.tt2
index 06f1679..f8572e9 100644
--- a/Open-ILS/web/templates/default/vandelay/match_set_tree.tt2
+++ b/Open-ILS/web/templates/default/vandelay/match_set_tree.tt2
@@ -15,6 +15,7 @@
.node-editor { margin-bottom: 1.5ex; }
.node-editor td { padding: 0.5ex; }
li { background-color: #ddd; }
+ .replace-mode { background-color: #990; color: #fff; }
</style>
<h1>[% ctx.page_title %]</h1>
<table id="vms-table">
@@ -85,9 +86,7 @@
<button id="deleter" onclick="delete_selected_in_tree()">
Delete Selected Node
</button>
- <button id="replacer" onclick="replace_mode()">
- Enter Replace Mode
- </button>
+ <button id="replacer" onclick="replace_mode()"></button>
</div>
</div>
</div>
commit 6c32ca2e574f57e2eb57bc29c75b3ff506651a9e
Author: senator <lebbeous at esilibrary.com>
Date: Thu Apr 14 18:14:32 2011 -0400
lots of things here, but nearly last big UI todo is...
to implement openils.vandelay.TreeDndSource._is_replaceable() and then
make the changes to itemCreator
diff --git a/Open-ILS/web/js/dojo/openils/vandelay/TreeDndSource.js b/Open-ILS/web/js/dojo/openils/vandelay/TreeDndSource.js
index aa5f2f4..8ccd836 100644
--- a/Open-ILS/web/js/dojo/openils/vandelay/TreeDndSource.js
+++ b/Open-ILS/web/js/dojo/openils/vandelay/TreeDndSource.js
@@ -7,6 +7,13 @@ dojo.require("dijit._tree.dndSource");
*/
dojo.declare(
"openils.vandelay.TreeDndSource", dijit._tree.dndSource, {
+ "_is_replaceable": function(src_item, target_item) {
+ /* An OP can replace anything, but non-OPs can only replace other
+ * non-OPs
+ */
+ console.log("src item: " + src_item + " target item: " + target_item);
+ return true; /* XXX TODO FINISHME */
+ },
"constructor": function() {
/* Given a tree object, there seems to be no way to access its
* dndController, which seems to be the only thing that knows
@@ -19,18 +26,29 @@ dojo.declare(
window._tree_dnd_controllers.push(this);
},
"checkItemAcceptance": function(target, source, position) {
- return (
- source._ready && (
+ if (!source._ready || source == this) return;
+
+ if (this.tree.model._replace_mode) {
+ return (
+ position == "over" && this._is_replaceable(
+ source.getAllNodes()[0].match_point,
+ dijit.getEnclosingWidget(target).item.match_point
+ )
+ );
+ } else {
+ return (
position != "over" ||
this.tree.model.mayHaveChildren(
dijit.getEnclosingWidget(target).item
)
- )
- );
+ );
+ }
/* code in match_set.js makes sure that source._ready gets set true
* only when we want the item to be draggable */
},
- "itemCreator": function(nodes) {
+ "itemCreator": function(nodes, somethingelse) {
+ console.log("gew: " + dijit.getEnclosingWidget(somethingelse).item.name);
+ console.log("dojo.dnd.manager.copy: " + dojo.dnd.manager.copy);
var default_items = this.inherited(arguments);
for (var i = 0; i < default_items.length; i++)
default_items[i].match_point = nodes[i].match_point;
diff --git a/Open-ILS/web/js/dojo/openils/vandelay/TreeStoreModel.js b/Open-ILS/web/js/dojo/openils/vandelay/TreeStoreModel.js
index 61d2821..2a35b70 100644
--- a/Open-ILS/web/js/dojo/openils/vandelay/TreeStoreModel.js
+++ b/Open-ILS/web/js/dojo/openils/vandelay/TreeStoreModel.js
@@ -19,6 +19,7 @@ function _simple_item(model, item) {
dojo.declare(
"openils.vandelay.TreeStoreModel", dijit.tree.TreeStoreModel, {
+ "_replace_mode": 0,
"getSimpleTree": function(item, oncomplete, result) {
var self = this;
if (!result) result = {};
diff --git a/Open-ILS/web/js/dojo/openils/vandelay/nls/match_set.js b/Open-ILS/web/js/dojo/openils/vandelay/nls/match_set.js
index 1b9f01b..ceb72bb 100644
--- a/Open-ILS/web/js/dojo/openils/vandelay/nls/match_set.js
+++ b/Open-ILS/web/js/dojo/openils/vandelay/nls/match_set.js
@@ -1,3 +1,7 @@
{
- "DEFINE_MP": "Define this match point using the above fields, then drag me to the tree on the right."
+ "DEFINE_MP": "Define this match point using the above fields, then drag me to the tree on the right.",
+ "LEAVE_ROOT_ALONE": "You cannot delete the root node of a tree (but you can replace it).",
+ "EXACTLY_ONE": "First select exactly one node from the tree on the right side of the screen.",
+ "EXIT_REPLACE_MODE": "Exit Replace Mode",
+ "ENTER_REPLACE_MODE": "Enter Replace Mode"
}
diff --git a/Open-ILS/web/js/ui/default/vandelay/match_set.js b/Open-ILS/web/js/ui/default/vandelay/match_set.js
index 4b7dd90..f9fa8ec 100644
--- a/Open-ILS/web/js/ui/default/vandelay/match_set.js
+++ b/Open-ILS/web/js/ui/default/vandelay/match_set.js
@@ -1,7 +1,6 @@
dojo.require("dijit.Tree");
dojo.require("dijit.form.Button");
dojo.require("dojo.data.ItemFileWriteStore");
-//dojo.require("openils.vandelay.DndSource");
dojo.require("dojo.dnd.Source");
dojo.require("openils.vandelay.TreeDndSource");
dojo.require("openils.vandelay.TreeStoreModel");
@@ -122,47 +121,25 @@ function NodeEditor() {
this.clear = function() {
this.dnd_source.selectAll().deleteSelectedNodes();
dojo.empty(this.node_editor_container);
+ this.dnd_source._ready = false;
};
- this.update_draggable = function(draggable) {
- var s = "";
- draggable.match_point = new vmsp();
- var had_op = false;
- dojo.query("[fmfield]", this.node_editor_container).forEach(
- function(control) {
- var used_svf = null;
- var field = dojo.attr(control, "fmfield");
- var value = _simple_value_getter(control);
- draggable.match_point[field](value);
-
- if (field == "subfield")
- s += " \u2021";
- if (field == "svf")
- used_svf = value;
- if (field == "quality")
- return;
- if (field == "bool_op")
- had_op = true;
- if (field == "negate") {
- if (value) {
- if (had_op)
- s = "<strong>N</strong>" + s;
- else
- s = "<strong>NOT</strong> " + s;
- }
- } else {
- s += value;
- }
+ this.build_vmsp = function() {
+ var match_point = new vmsp();
+ var controls = dojo.query("[fmfield]", this.node_editor_container);
+ for (var i = 0; i < controls.length; i++) {
+ var field = dojo.attr(controls[i], "fmfield");
+ var value = _simple_value_getter(controls[i]);
+ match_point[field](value);
+ }
+ return match_point;
+ };
- if (used_svf !== null) {
- var our_crad = _find_crad_by_name(used_svf);
- /* XXX i18n, use fmtted strings */
- s += " / " + our_crad.label() + "<br /><em>" +
- (our_crad.description() || "") + "</em><br />";
- }
- }
+ this.update_draggable = function(draggable) {
+ draggable.match_point = this.build_vmsp();
+ dojo.attr(
+ draggable, "innerHTML", render_vmsp_label(draggable.match_point)
);
- dojo.attr(draggable, "innerHTML", s);
this.dnd_source._ready = true;
};
@@ -210,7 +187,6 @@ function NodeEditor() {
dojo.place(table, this.node_editor_container, "only");
/* XXX around here attach other data structures to the node */
this.dnd_source.insertNodes(false, [draggable]);
- this.dnd_source._ready = false;
};
this._init.apply(this, arguments);
@@ -218,24 +194,39 @@ function NodeEditor() {
/* XXX replace later with code that will suit this function's purpose
* as well as that of update_draggable. */
-function display_name_from_point(point) {
+function render_vmsp_label(point) {
/* quick and dirty */
if (point.bool_op()) {
- return (point.negate() == "t" ? "N" : "") + point.bool_op();
+ return (openils.Util.isTrue(point.negate()) ? "N" : "") +
+ point.bool_op();
} else if (point.svf()) {
- return (point.negate() == "t" ? "NOT " : "") + point.svf();
+ return (openils.Util.isTrue(point.negate()) ? "NOT " : "") +
+ point.svf() + " / " + _find_crad_by_name(point.svf()).label();
} else {
- return (point.negate() == "t" ? "NOT " : "") + point.tag() +
- "\u2021" + point.subfield();
+ return (openils.Util.isTrue(point.negate()) ? "NOT " : "") +
+ point.tag() + " \u2021" + point.subfield();
}
}
-function delete_selected_from_tree() {
+function replace_mode() {
+ tree.model._replace_mode ^= 1;
+ dojo.attr(
+ "replacer", "innerHTML",
+ localeStrings[
+ (tree.model._replace_mode ? "EXIT" : "ENTER") + "_REPLACE_MODE"
+ ]
+ );
+}
+
+function delete_selected_in_tree() {
/* relies on the fact that we only have one tree that would have
* registered a dnd controller. */
_tree_dnd_controllers[0].getSelectedItems().forEach(
function(item) {
- tree.model.store.deleteItem(item);
+ if (item === tree.model.root)
+ alert(localeStrings.LEAVE_ROOT_ALONE);
+ else
+ tree.model.store.deleteItem(item);
}
);
}
@@ -264,7 +255,7 @@ function dojoize_match_set_tree(point, refgen) {
point.children([]);
var item = {
"id": (root ? "root" : refgen),
- "name": display_name_from_point(point),
+ "name": render_vmsp_label(point),
"match_point": point.clone(),
"children": []
};
@@ -292,7 +283,7 @@ function render_match_set_description(match_set) {
dojo.byId("vms-mtype").innerHTML = match_set.mtype();
}
-function init_test() {
+function my_init() {
progress_dialog.show(true);
dojo.requireLocalization("openils.vandelay", "match_set");
@@ -315,19 +306,6 @@ function init_test() {
[openils.User.authtoken, CGI.param("match_set")]
);
-// {
-// "identifier": "id", "label": "name", "items": [
-// {
-// "id": "root", "name": "AND",
-// "children": [
-// {"_reference": "leaf0"}, {"_reference": "leaf1"}
-// ]
-// },
-// {"id": "leaf0", "name": "nonsense test"},
-// {"id": "leaf1", "name": "more nonsense"}
-// ]
-// }
-
var store = new dojo.data.ItemFileWriteStore({
"data": {
"identifier": "id",
@@ -336,14 +314,14 @@ function init_test() {
}
});
- var treeModel = new openils.vandelay.TreeStoreModel({
- store: store, "query": {"id": "root"}
+ var tree_model = new openils.vandelay.TreeStoreModel({
+ "store": store, "query": {"id": "root"}
});
var src = new dojo.dnd.Source("src-here");
tree = new dijit.Tree(
{
- "model": treeModel,
+ "model": tree_model,
"dndController": openils.vandelay.TreeDndSource,
"dragThreshold": 8,
"betweenThreshold": 5,
@@ -356,22 +334,15 @@ function init_test() {
dojo.connect(
src, "onDndDrop", null,
function(source, nodes, copy, target) {
- if (source == this) {
- var model = target.tree.model;
- model.getRoot(
- function(root) {
- model.getSimpleTree(
- root, function(results) { alert(js2JSON(results)); }
- );
- }
- );
+ /* XXX because of the... interesting... characteristics of DnD
+ * design in dojo/dijit (at least as of 1.3), this callback will
+ * fire both for our working node dndSource and for the tree!
+ */
+ if (source == this)
node_editor.clear(); /* because otherwise this acts like a copy! */
- } else {
- alert("XXX [src] nodes length is " + nodes.length); /* XXX DEBUG */
- }
}
);
progress_dialog.hide();
}
-openils.Util.addOnLoad(init_test);
+openils.Util.addOnLoad(my_init);
diff --git a/Open-ILS/web/templates/default/vandelay/match_set_tree.tt2 b/Open-ILS/web/templates/default/vandelay/match_set_tree.tt2
index 6796406..06f1679 100644
--- a/Open-ILS/web/templates/default/vandelay/match_set_tree.tt2
+++ b/Open-ILS/web/templates/default/vandelay/match_set_tree.tt2
@@ -2,14 +2,16 @@
[% ctx.page_title = 'Vandelay Match Set Editor' %]
<style type="text/css">
h1 { margin: 1ex 0; }
- .outer { clear: both; }
- #vmsp-buttons button { margin: 0 0.5em; }
+ .outer { clear: both; margin-bottom: 1ex; }
+ button { margin: 0 0.5em; }
#tree-here { margin-bottom: 1.5em; }
#vms-table { padding-bottom: 2ex; }
#vms-table th { text-align: right; }
#vms-table td { padding-left: 1em; }
#src-pane { float: left; width: 49%; }
#tree-pane { float: right; width: 50%; }
+ #submit-row { clear: both; text-align: center; padding-top: 1.5ex; }
+ #submit-row hr { margin: 1ex 0; }
.node-editor { margin-bottom: 1.5ex; }
.node-editor td { padding: 0.5ex; }
li { background-color: #ddd; }
@@ -61,7 +63,7 @@
<div><!-- XXX TODO: consider a read-only display here of the query as built
so far from the treet --></div>
<div id="vmsp-buttons">
- New
+ Add new
<button onclick="node_editor.add('svf');">Single-Value-Field</button>
<button onclick="node_editor.add('tag');">MARC Tag and Subfield</button>
<button onclick="node_editor.add('bool_op');">Boolean Operator</button>
@@ -69,6 +71,7 @@
</div>
<div class="outer" style="margin-top: 2ex;">
<div id="src-pane">
+ <div><big>Working Match Point</big></div>
<div>
<form id="node-editor-container" onsubmit="return false;"></form>
</div>
@@ -78,11 +81,20 @@
<div id="tree-pane">
<div><big>Your Expression</big></div>
<div id="tree-here"></div>
- <button id="deleter" onclick="delete_selected_from_tree()">
- Deleted Selected Node
- </button>
+ <div>
+ <button id="deleter" onclick="delete_selected_in_tree()">
+ Delete Selected Node
+ </button>
+ <button id="replacer" onclick="replace_mode()">
+ Enter Replace Mode
+ </button>
+ </div>
</div>
</div>
+<div id="submit-row">
+ <hr />
+ <button onclick="save_tree()">Save Changes</button>
+</div>
<div jsId="progress_dialog" dojoType="openils.widget.ProgressDialog"></div>
<script type="text/javascript"
src="[% ctx.media_prefix %]/js/ui/default/vandelay/match_set.js"></script>
commit 18f70edb704e984ff70b7182d4795f5e28ef4168
Author: senator <lebbeous at esilibrary.com>
Date: Thu Apr 14 11:45:43 2011 -0400
Ability to delete nodes from working tree. Show metadata about match_set.
diff --git a/Open-ILS/web/js/dojo/openils/vandelay/TreeDndSource.js b/Open-ILS/web/js/dojo/openils/vandelay/TreeDndSource.js
index 6438132..aa5f2f4 100644
--- a/Open-ILS/web/js/dojo/openils/vandelay/TreeDndSource.js
+++ b/Open-ILS/web/js/dojo/openils/vandelay/TreeDndSource.js
@@ -7,6 +7,17 @@ dojo.require("dijit._tree.dndSource");
*/
dojo.declare(
"openils.vandelay.TreeDndSource", dijit._tree.dndSource, {
+ "constructor": function() {
+ /* Given a tree object, there seems to be no way to access its
+ * dndController, which seems to be the only thing that knows
+ * about a tree's selected nodes. So we register instances
+ * in a global variable in order to find them later. :-(
+ */
+ if (!window._tree_dnd_controllers)
+ window._tree_dnd_controllers = [];
+
+ window._tree_dnd_controllers.push(this);
+ },
"checkItemAcceptance": function(target, source, position) {
return (
source._ready && (
diff --git a/Open-ILS/web/js/ui/default/vandelay/match_set.js b/Open-ILS/web/js/ui/default/vandelay/match_set.js
index 7d6a74f..4b7dd90 100644
--- a/Open-ILS/web/js/ui/default/vandelay/match_set.js
+++ b/Open-ILS/web/js/ui/default/vandelay/match_set.js
@@ -11,10 +11,7 @@ dojo.require("openils.Util");
dojo.require("openils.PermaCrud");
dojo.require("openils.widget.ProgressDialog");
-var localeStrings;
-var node_editor;
-var _crads;
-var CGI;
+var localeStrings, node_editor, _crads, CGI, tree;
function _find_crad_by_name(name) {
for (var i = 0; i < _crads.length; i++) {
@@ -233,6 +230,16 @@ function display_name_from_point(point) {
}
}
+function delete_selected_from_tree() {
+ /* relies on the fact that we only have one tree that would have
+ * registered a dnd controller. */
+ _tree_dnd_controllers[0].getSelectedItems().forEach(
+ function(item) {
+ tree.model.store.deleteItem(item);
+ }
+ );
+}
+
/* dojoize_match_set_tree() takes an argument, "point", that is actually a
* vmsp fieldmapper object with descendants fleshed hierarchically. It turns
* that into a syntactically flat array but preserving the hierarchy
@@ -278,17 +285,28 @@ function dojoize_match_set_tree(point, refgen) {
return results;
}
+function render_match_set_description(match_set) {
+ dojo.byId("vms-name").innerHTML = match_set.name();
+ dojo.byId("vms-owner").innerHTML =
+ aou.findOrgUnit(match_set.owner()).name();
+ dojo.byId("vms-mtype").innerHTML = match_set.mtype();
+}
+
function init_test() {
progress_dialog.show(true);
dojo.requireLocalization("openils.vandelay", "match_set");
localeStrings = dojo.i18n.getLocalization("openils.vandelay", "match_set");
+ pcrud = new openils.PermaCrud();
CGI = new openils.CGI();
+ var match_set = pcrud.retrieve("vms", CGI.param("match_set"));
+ render_match_set_description(match_set);
+
/* XXX No-one should have hundreds of these or anything, but theoretically
* this could be problematic with a big enough list of crad objects. */
- _crads = new openils.PermaCrud().retrieveAll(
+ _crads = pcrud.retrieveAll(
"crad", {"order_by": {"crad": "label"}}
);
@@ -322,15 +340,15 @@ function init_test() {
store: store, "query": {"id": "root"}
});
- var src = new dojo.dnd.Source("src_here");
- var tree = new dijit.Tree(
+ var src = new dojo.dnd.Source("src-here");
+ tree = new dijit.Tree(
{
"model": treeModel,
"dndController": openils.vandelay.TreeDndSource,
"dragThreshold": 8,
"betweenThreshold": 5,
"persist": false
- }, "tree_here"
+ }, "tree-here"
);
node_editor = new NodeEditor(src, "node-editor-container");
diff --git a/Open-ILS/web/templates/default/vandelay/match_set_tree.tt2 b/Open-ILS/web/templates/default/vandelay/match_set_tree.tt2
index 0cec41c..6796406 100644
--- a/Open-ILS/web/templates/default/vandelay/match_set_tree.tt2
+++ b/Open-ILS/web/templates/default/vandelay/match_set_tree.tt2
@@ -1,14 +1,37 @@
[% WRAPPER 'default/base.tt2' %]
[% ctx.page_title = 'Vandelay Match Set Editor' %]
<style type="text/css">
- h1 { margin: 0.5em 0; }
+ h1 { margin: 1ex 0; }
.outer { clear: both; }
- #vmsp-buttons button { padding: 0 1.5em; }
- .node-editor { margin-bottom: 2em; }
+ #vmsp-buttons button { margin: 0 0.5em; }
+ #tree-here { margin-bottom: 1.5em; }
+ #vms-table { padding-bottom: 2ex; }
+ #vms-table th { text-align: right; }
+ #vms-table td { padding-left: 1em; }
+ #src-pane { float: left; width: 49%; }
+ #tree-pane { float: right; width: 50%; }
+ .node-editor { margin-bottom: 1.5ex; }
.node-editor td { padding: 0.5ex; }
li { background-color: #ddd; }
</style>
<h1>[% ctx.page_title %]</h1>
+<table id="vms-table">
+ <tbody>
+ <tr>
+ <th>Match set name:</th>
+ <td><strong id="vms-name"></strong></td>
+ </tr>
+ <tr>
+ <th>Owning Library:</th>
+ <td id="vms-owner"></td>
+ </tr>
+ <tr>
+ <th>Type:</th>
+ <td id="vms-mtype"></td>
+ </tr>
+ </tbody>
+</table>
+<hr />
<!-- XXX TODO
give some indication of which match set we're editing the tree for
-->
@@ -38,22 +61,26 @@
<div><!-- XXX TODO: consider a read-only display here of the query as built
so far from the treet --></div>
<div id="vmsp-buttons">
- <button onclick="node_editor.add('svf');">New Single-Value-Field</button>
- <button onclick="node_editor.add('tag');">New MARC Tag and Subfield</button>
- <button onclick="node_editor.add('bool_op');">New Boolean Operator</button>
+ New
+ <button onclick="node_editor.add('svf');">Single-Value-Field</button>
+ <button onclick="node_editor.add('tag');">MARC Tag and Subfield</button>
+ <button onclick="node_editor.add('bool_op');">Boolean Operator</button>
</div>
</div>
<div class="outer" style="margin-top: 2ex;">
- <div style="float: left; width: 49%">
+ <div id="src-pane">
<div>
<form id="node-editor-container" onsubmit="return false;"></form>
</div>
- <ul id="src_here"></ul>
+ <ul id="src-here"></ul>
</div>
- <div style="float: right; width: 50%">
+ <div id="tree-pane">
<div><big>Your Expression</big></div>
- <div id="tree_here"></div>
+ <div id="tree-here"></div>
+ <button id="deleter" onclick="delete_selected_from_tree()">
+ Deleted Selected Node
+ </button>
</div>
</div>
<div jsId="progress_dialog" dojoType="openils.widget.ProgressDialog"></div>
commit 752e696bba75275c8e6330ff8fe7444318b9e21f
Author: senator <lebbeous at esilibrary.com>
Date: Wed Apr 13 18:04:10 2011 -0400
Add an autogrid-based interface for CRUD ops on vms objects, with links to the tree editor
diff --git a/Open-ILS/web/js/dojo/openils/widget/AutoGrid.js b/Open-ILS/web/js/dojo/openils/widget/AutoGrid.js
index ecbdf95..9e5be71 100644
--- a/Open-ILS/web/js/dojo/openils/widget/AutoGrid.js
+++ b/Open-ILS/web/js/dojo/openils/widget/AutoGrid.js
@@ -640,6 +640,13 @@ if(!dojo._hasResource['openils.widget.AutoGrid']) {
*/
return autoWidget.getDisplayString();
- }
+ };
+
+ openils.widget.AutoGrid.orgUnitGetter = function(rowIndex, item) {
+ if (!item) return "";
+ return fieldmapper.aou.findOrgUnit(
+ this.grid.store.getValue(item, this.field)
+ ).shortname();
+ };
}
diff --git a/Open-ILS/web/templates/default/vandelay/match_set.tt2 b/Open-ILS/web/templates/default/vandelay/match_set.tt2
index fe5def0..0d59f54 100644
--- a/Open-ILS/web/templates/default/vandelay/match_set.tt2
+++ b/Open-ILS/web/templates/default/vandelay/match_set.tt2
@@ -1,59 +1,94 @@
-[% WRAPPER 'default/base.tt2' %]
-[% ctx.page_title = 'Vandelay Match Set' %]
-<style type="text/css">
- h1 { margin: 0.5em 0; }
- .outer { clear: both; }
- #vmsp-buttons button { padding: 0 1.5em; }
- .node-editor { margin-bottom: 2em; }
- .node-editor td { padding: 0.5ex; }
- li { background-color: #ddd; }
-</style>
-<h1>[% ctx.page_title %]</h1>
-<table class="hidden">
- <tr consistent-controls="1">
- <td>
- <label for="quality-input"
- title="A relative number representing the impact of this expression on the quality of the overall record match"><!-- XXX tooltipize -->
- Quality:
- </label>
- </td>
- <td>
- <input id="quality-input" type="text" value="1"
- size="4" maxlength="3" fmfield="quality" />
- </td>
- </tr>
- <tr consistent-controls="1">
- <td>
- <label for="negate-input">Negate?</label>
- </td>
- <td>
- <input id="negate-input" type="checkbox" fmfield="negate" />
- </td>
- </tr>
-</table>
-<div class="outer">
- <div><!-- XXX TODO: consider a read-only display here of the query as built
- so far from the treet --></div>
- <div id="vmsp-buttons">
- <button onclick="node_editor.add('svf');">New Single-Value-Field</button>
- <button onclick="node_editor.add('tag');">New MARC Tag and Subfield</button>
- <button onclick="node_editor.add('bool_op');">New Boolean Operator</button>
- </div>
-</div>
-<div class="outer" style="margin-top: 2ex;">
- <div style="float: left; width: 49%">
+[% WRAPPER default/base.tt2 %]
+[% ctx.page_title = 'Vandelay Match Sets' %]
+<div dojoType="dijit.layout.ContentPane" layoutAlign="client">
+ <div dojoType="dijit.layout.ContentPane" layoutAlign="top" class="oils-header-panel">
+ <div>[% ctx.page_title %]</div>
<div>
- <form id="node-editor-container" onsubmit="return false;"></form>
+ <button dojoType="dijit.form.Button"
+ onClick="vms_grid.showCreateDialog()">New Match Set</button>
+ <button dojoType="dijit.form.Button"
+ onClick="vms_grid.deleteSelected()">Delete Selected</button>
</div>
- <ul id="src_here"></ul>
</div>
-
- <div style="float: right; width: 50%">
- <div><big>Your Expression</big></div>
- <div id="tree_here"></div>
+ <div>
+ Show sets owned at or below:
+ <select dojoType="openils.widget.OrgUnitFilteringSelect"
+ jsId="context_org_selector"></select>
</div>
+ <table jsId="vms_grid"
+ dojoType="openils.widget.AutoGrid"
+ query="{id: '*'}"
+ defaultCellWidth="'16em'"
+ fmClass="vms"
+ fieldorder="['name', 'owner']"
+ suppressEditFields="['id']"
+ showPaginator="true"
+ editOnEnter="true">
+ <thead>
+ <tr>
+ <th field="name" get="field_plus_id" formatter="tree_editor_link"></th>
+ <th field="owner" get="openils.widget.AutoGrid.orgUnitGetter">
+ </th>
+ </tr>
+ </thead>
+ </table>
</div>
-<div jsId="progress_dialog" dojoType="openils.widget.ProgressDialog"></div>
-<script type="text/javascript"
- src="[% ctx.media_prefix %]/js/ui/default/vandelay/match_set.js"></script>
+<div class="hidden">
+ <select dojoType="dijit.form.FilteringSelect" jsId="mtype_selector">
+ [%# for the origin of these hard coded options, see the definition
+ of vandelay.match_set.mtype in 012.schema.vandelay.sql %]
+ <option value="biblio">biblio</option>
+ <option value="authority">authority</option>
+ <!-- XXX: nah <option value="mfhd">mfhd</option> -->
+ </select>
+</div>
+
+<script type="text/javascript">
+ dojo.require("dijit.form.FilteringSelect");
+ dojo.require("openils.widget.AutoGrid");
+ dojo.require("openils.widget.OrgUnitFilteringSelect");
+
+ var context_org;
+
+ function load_grid(search) {
+ if (!search) search = {"id": {"!=": null}};
+
+ vms_grid.loadAll({"order_by": {"vms": "name"}}, search);
+ }
+
+ function field_plus_id(rowIndex, item) {
+ if (!item) return null;
+ var datum = {};
+ datum[this.field] = this.grid.store.getValue(item, this.field);
+ datum.id = this.grid.store.getValue(item, "id");
+ return datum;
+ }
+
+ function tree_editor_link(datum) {
+ if (!datum) return "";
+ return '<a href="[% ctx.base_path %]/vandelay/match_set_tree?match_set=' +
+ datum.id + '">' + datum.name + '</a>';
+ }
+
+ openils.Util.addOnLoad(
+ function() {
+ new openils.User().buildPermOrgSelector(
+ "ADMIN_IMPORT_MATCH_SET", context_org_selector,
+ null, function() {
+ context_org_selector.onChange = function() {
+ context_org = this.attr("value");
+ vms_grid.resetStore();
+ load_grid({
+ "owner": aou.descendantNodeList(context_org, true)
+ });
+ };
+ }
+ );
+
+ vms_grid.overrideEditWidgets.mtype = mtype_selector;
+ vms_grid.overrideEditWidgets.mtype.shove = {"create": "biblio"};
+ load_grid();
+ }
+ );
+</script>
[% END %]
diff --git a/Open-ILS/web/templates/default/vandelay/match_set.tt2 b/Open-ILS/web/templates/default/vandelay/match_set_tree.tt2
similarity index 93%
copy from Open-ILS/web/templates/default/vandelay/match_set.tt2
copy to Open-ILS/web/templates/default/vandelay/match_set_tree.tt2
index fe5def0..0cec41c 100644
--- a/Open-ILS/web/templates/default/vandelay/match_set.tt2
+++ b/Open-ILS/web/templates/default/vandelay/match_set_tree.tt2
@@ -1,5 +1,5 @@
[% WRAPPER 'default/base.tt2' %]
-[% ctx.page_title = 'Vandelay Match Set' %]
+[% ctx.page_title = 'Vandelay Match Set Editor' %]
<style type="text/css">
h1 { margin: 0.5em 0; }
.outer { clear: both; }
@@ -9,6 +9,9 @@
li { background-color: #ddd; }
</style>
<h1>[% ctx.page_title %]</h1>
+<!-- XXX TODO
+ give some indication of which match set we're editing the tree for
+ -->
<table class="hidden">
<tr consistent-controls="1">
<td>
commit 55bd5e663a1a7d3e611d124fea3aee68f54daeba
Author: Mike Rylander <mrylander at gmail.com>
Date: Tue Apr 12 13:41:19 2011 -0400
Corrected merge from trunk
diff --git a/Open-ILS/src/sql/Pg/000.functions.general.sql b/Open-ILS/src/sql/Pg/000.functions.general.sql
index 52301a4..40ab727 100644
--- a/Open-ILS/src/sql/Pg/000.functions.general.sql
+++ b/Open-ILS/src/sql/Pg/000.functions.general.sql
@@ -15,6 +15,8 @@ $$ LANGUAGE plpgsql;
SELECT evergreen.change_db_setting('search_path', ARRAY['evergreen','public','pg_catalog']);
+CREATE OR REPLACE FUNCTION evergreen.array_remove_item_by_value(inp ANYARRAY, el ANYELEMENT) RETURNS anyarray AS $$ SELECT ARRAY_ACCUM(x.e) FROM UNNEST( $1 ) x(e) WHERE x.e <> $2; $$ LANGUAGE SQL;
+
CREATE OR REPLACE FUNCTION evergreen.lowercase( TEXT ) RETURNS TEXT AS $$
return lc(shift);
$$ LANGUAGE PLPERLU STRICT IMMUTABLE;
diff --git a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
index a9506d1..7b4ba02 100644
--- a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
+++ b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
@@ -2,8 +2,6 @@ DROP SCHEMA IF EXISTS vandelay CASCADE;
BEGIN;
-CREATE OR REPLACE FUNCTION array_remove_item_by_value(inp ANYARRAY, el ANYELEMENT) RETURNS anyarray AS $$ SELECT ARRAY_ACCUM(x.e) FROM UNNEST( $1 ) x(e) WHERE x.e <> $2; $$ LANGUAGE SQL;
-
CREATE SCHEMA vandelay;
CREATE TABLE vandelay.match_set (
@@ -520,8 +518,8 @@ BEGIN
ELSIF test.required THEN
FOR tmp_rec IN SELECT * FROM UNNEST(matches) LOOP
IF tmp_rec NOT IN (SELECT * FROM UNNEST(potential_matches)) THEN
- matches := array_remove_item_by_value(matches, tmp_rec);
- potential_matches := array_remove_item_by_value(potential_matches, tmp_rec);
+ matches := evergreen.array_remove_item_by_value(matches, tmp_rec);
+ potential_matches := evergreen.array_remove_item_by_value(potential_matches, tmp_rec);
END IF;
END LOOP;
END IF;
@@ -542,8 +540,8 @@ BEGIN
ELSIF test.required THEN
FOR tmp_rec IN SELECT * FROM UNNEST(matches) LOOP
IF tmp_rec NOT IN (SELECT * FROM UNNEST(potential_matches)) THEN
- matches := array_remove_item_by_value(matches, tmp_rec);
- potential_matches := array_remove_item_by_value(potential_matches, tmp_rec);
+ matches := evergreen.array_remove_item_by_value(matches, tmp_rec);
+ potential_matches := evergreen.array_remove_item_by_value(potential_matches, tmp_rec);
END IF;
END LOOP;
END IF;
commit 6795405f13dead5dff39cf884fa727c01d6f4636
Author: Lebbeous Fogle-Weekley <lebbeous at esilibrary.com>
Date: Fri Apr 8 17:48:57 2011 -0400
Initial vmsp tree editor
__ notes __
now we can retrieve a tree from the server and use it as the basis of
our dijit.Tree widget. Still work to be done. Can't save anything yet.
Note to self: borrow dojo dnd's "copy" operation (as opposed to move) to
mean replacing a node in the tree, rather than adding to the tree.
Re the permissions I changed, actual users of Evergreen hate having as
much granularity as there was before, and it just confuses people trying
to figure out what perms to give to whom.
Note to self 2: add ADMIN_IMPORT_MATCH_SET to ppl
Usability
1) the tree editor will only let bool_op nodes have children
2) you can't put the unset "dummy" node from the leftside onto the tree
incidentally, gave fm objects a toString method that identifies their
classname hint, as an aid to debugging in general
diff --git a/Open-ILS/examples/fm_IDL.xml b/Open-ILS/examples/fm_IDL.xml
index 4070fa3..c89957b 100644
--- a/Open-ILS/examples/fm_IDL.xml
+++ b/Open-ILS/examples/fm_IDL.xml
@@ -541,10 +541,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
</links>
<permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
<actions>
- <create permission="CREATE_IMPORT_MATCH_SET ADMIN_IMPORT_IMPORT_MATCH_SET" context_field="owner"/>
- <retrieve permission="CREATE_IMPORT_MATCH_SET UPDATE_IMPORT_MATCH_SET DELETE_IMPORT_MATCH_SET" context_field="owner"/>
- <update permission="UPDATE_IMPORT_MATCH_SET" context_field="owner"/>
- <delete permission="DELETE_IMPORT_MATCH_SET" context_field="owner"/>
+ <create permission="ADMIN_IMPORT_MATCH_SET" context_field="owner"/>
+ <retrieve permission="ADMIN_IMPORT_MATCH_SET" context_field="owner"/>
+ <update permission="ADMIN_IMPORT_MATCH_SET" context_field="owner"/>
+ <delete permission="ADMIN_IMPORT_MATCH_SET" context_field="owner"/>
</actions>
</permacrud>
</class>
@@ -558,25 +558,28 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
<field reporter:label="Coded Field" name="svf" reporter:datatype="link"/>
<field reporter:label="Tag" name="tag" reporter:datatype="text"/>
<field reporter:label="Subfield" name="subfield" reporter:datatype="text"/>
+ <field reporter:label="Negate" name="negate" reporter:datatype="bool"/>
<field reporter:label="Importance" name="quality" reporter:datatype="int"/>
+ <field reporter:label="Expression Tree Children" name="children" oils_persist:virtual="true" reporter:datatype="link"/>
</fields>
<links>
<link field="parent" reltype="has_a" key="id" map="" class="vmsp"/>
<link field="match_set" reltype="has_a" key="id" map="" class="vms"/>
<link field="svf" reltype="has_a" key="id" map="" class="crad"/>
+ <link field="children" reltype="has_many" key="parent" map="" class="vmsp"/>
</links>
<permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
<actions>
- <create permission="CREATE_IMPORT_MATCH_SET ADMIN_IMPORT_IMPORT_MATCH_SET">
+ <create permission="ADMIN_IMPORT_MATCH_SET">
<context link="match_set" field="owner"/>
</create>
- <retrieve permission="CREATE_IMPORT_MATCH_SET UPDATE_IMPORT_MATCH_SET DELETE_IMPORT_MATCH_SET">
+ <retrieve permission="ADMIN_IMPORT_MATCH_SET">
<context link="match_set" field="owner"/>
</retrieve>
- <update permission="UPDATE_IMPORT_MATCH_SET">
+ <update permission="ADMIN_IMPORT_MATCH_SET">
<context link="match_set" field="owner"/>
</update>
- <delete permission="DELETE_IMPORT_MATCH_SET">
+ <delete permission="ADMIN_IMPORT_MATCH_SET">
<context link="match_set" field="owner"/>
</delete>
</actions>
@@ -598,10 +601,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
</links>
<permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
<actions>
- <create permission="CREATE_IMPORT_MATCH_SET ADMIN_IMPORT_IMPORT_MATCH_SET" context_field="owner"/>
- <retrieve permission="CREATE_IMPORT_MATCH_SET UPDATE_IMPORT_MATCH_SET DELETE_IMPORT_MATCH_SET" context_field="owner"/>
- <update permission="UPDATE_IMPORT_MATCH_SET" context_field="owner"/>
- <delete permission="DELETE_IMPORT_MATCH_SET" context_field="owner"/>
+ <create permission="ADMIN_IMPORT_MATCH_SET" context_field="owner"/>
+ <retrieve permission="ADMIN_IMPORT_MATCH_SET" context_field="owner"/>
+ <update permission="ADMIN_IMPORT_MATCH_SET" context_field="owner"/>
+ <delete permission="ADMIN_IMPORT_MATCH_SET" context_field="owner"/>
</actions>
</permacrud>
</class>
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
index 5c48282..aa830ad 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
@@ -1107,5 +1107,34 @@ sub respond_with_status {
success_count => $success_count, %args }) if $err or ($try_count % 5 == 0);
}
+__PACKAGE__->register_method(
+ api_name => "open-ils.vandelay.match_set.get_tree",
+ method => "match_set_get_tree",
+ api_level => 1,
+ argc => 1
+);
+
+sub match_set_get_tree {
+ my ($self, $conn, $authtoken, $match_set_id) = @_;
+
+ $match_set_id = int($match_set_id) or return;
+
+ my $e = new_editor("authtoken" => $authtoken);
+ $e->checkauth or return $e->die_event;
+
+ my $set = $e->retrieve_vandelay_match_set($match_set_id) or
+ return $e->die_event;
+
+ $e->allowed("ADMIN_IMPORT_MATCH_SET", $set->owner) or
+ return $e->die_event;
+
+ my $tree = $e->search_vandelay_match_set_point([
+ {"match_set" => $match_set_id, "parent" => undef},
+ {"flesh" => -1, "flesh_fields" => {"vmsp" => ["children"]}}
+ ]) or return $e->die_event;
+
+ return pop @$tree;
+}
+
1;
diff --git a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
index fd3f818..a9506d1 100644
--- a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
+++ b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
@@ -23,6 +23,7 @@ CREATE TABLE vandelay.match_set_point (
svf TEXT REFERENCES config.record_attr_definition (name),
tag TEXT,
subfield TEXT,
+ negate BOOL DEFAULT FALSE,
quality INT NOT NULL DEFAULT 1, -- higher is better
CONSTRAINT vmsp_need_a_subfield_with_a_tag CHECK ((tag IS NOT NULL AND subfield IS NOT NULL) OR tag IS NULL),
CONSTRAINT vmsp_need_a_tag_or_a_ff_or_a_bo CHECK (
diff --git a/Open-ILS/web/js/dojo/fieldmapper/Fieldmapper.js b/Open-ILS/web/js/dojo/fieldmapper/Fieldmapper.js
index bb369c6..df8b73b 100644
--- a/Open-ILS/web/js/dojo/fieldmapper/Fieldmapper.js
+++ b/Open-ILS/web/js/dojo/fieldmapper/Fieldmapper.js
@@ -87,6 +87,14 @@ if(!dojo._hasResource["fieldmapper.Fieldmapper"]){
return true;
}
return;
+ },
+
+ toString : function() {
+ /* ever so slightly aid debugging */
+ if (this.classname)
+ return "[object fieldmapper." + this.classname + "]";
+ else
+ return Object.prototype.toString();
}
});
diff --git a/Open-ILS/web/js/dojo/openils/vandelay/TreeDndSource.js b/Open-ILS/web/js/dojo/openils/vandelay/TreeDndSource.js
new file mode 100644
index 0000000..6438132
--- /dev/null
+++ b/Open-ILS/web/js/dojo/openils/vandelay/TreeDndSource.js
@@ -0,0 +1,29 @@
+dojo.provide("openils.vandelay.TreeDndSource");
+dojo.require("dijit._tree.dndSource");
+
+/* This class specifically serves the eg/vandelay/match_set interface
+ * for editing Vandelay Match Set trees. It should probably have a more
+ * specific name that reflects that.
+ */
+dojo.declare(
+ "openils.vandelay.TreeDndSource", dijit._tree.dndSource, {
+ "checkItemAcceptance": function(target, source, position) {
+ return (
+ source._ready && (
+ position != "over" ||
+ this.tree.model.mayHaveChildren(
+ dijit.getEnclosingWidget(target).item
+ )
+ )
+ );
+ /* code in match_set.js makes sure that source._ready gets set true
+ * only when we want the item to be draggable */
+ },
+ "itemCreator": function(nodes) {
+ var default_items = this.inherited(arguments);
+ for (var i = 0; i < default_items.length; i++)
+ default_items[i].match_point = nodes[i].match_point;
+ return default_items;
+ }
+ }
+);
diff --git a/Open-ILS/web/js/dojo/openils/vandelay/TreeStoreModel.js b/Open-ILS/web/js/dojo/openils/vandelay/TreeStoreModel.js
new file mode 100644
index 0000000..61d2821
--- /dev/null
+++ b/Open-ILS/web/js/dojo/openils/vandelay/TreeStoreModel.js
@@ -0,0 +1,55 @@
+dojo.provide("openils.vandelay.TreeStoreModel");
+dojo.require("dijit.tree.TreeStoreModel");
+dojo.require("openils.Util");
+
+/* This class specifically serves the eg/vandelay/match_set interface
+ * for editing Vandelay Match Set trees. It should probably have a more
+ * specific name that reflects that.
+ */
+
+function _simple_item(model, item) {
+ /* Instead of model.getLabel(), could do
+ * model.store.getValue(item, "blah") or something like that ... */
+ return {
+ "label": model.getLabel(item),
+ "match_point": String(model.store.getValue(item, "match_point")),
+ "children": {}
+ };
+}
+
+dojo.declare(
+ "openils.vandelay.TreeStoreModel", dijit.tree.TreeStoreModel, {
+ "getSimpleTree": function(item, oncomplete, result) {
+ var self = this;
+ if (!result) result = {};
+
+ var mykey = this.getIdentity(item);
+ result[mykey] = _simple_item(this, item);
+ var child_collector = result[mykey].children;
+
+ if (this.mayHaveChildren(item)) {
+ this.getChildren(
+ item, function(children) {
+ for (var i = 0; i < children.length; i++) {
+ self.getSimpleTree(
+ children[i], null, child_collector
+ );
+ }
+ if (oncomplete) oncomplete(result);
+ }
+ );
+ }
+ },
+ "mayHaveChildren": function(item) {
+ var match_point = this.store.getValue(item, "match_point");
+ if (match_point)
+ return openils.Util.isTrue(match_point.bool_op());
+ else
+ return true;
+ }
+// "newItem": function(args, parent) {
+// if (!this.mayHaveChildren(parent)) return;
+// return this.inherited(arguments);
+// }
+ }
+);
diff --git a/Open-ILS/web/js/dojo/openils/vandelay/nls/match_set.js b/Open-ILS/web/js/dojo/openils/vandelay/nls/match_set.js
new file mode 100644
index 0000000..1b9f01b
--- /dev/null
+++ b/Open-ILS/web/js/dojo/openils/vandelay/nls/match_set.js
@@ -0,0 +1,3 @@
+{
+ "DEFINE_MP": "Define this match point using the above fields, then drag me to the tree on the right."
+}
diff --git a/Open-ILS/web/js/ui/default/vandelay/match_set.js b/Open-ILS/web/js/ui/default/vandelay/match_set.js
new file mode 100644
index 0000000..7d6a74f
--- /dev/null
+++ b/Open-ILS/web/js/ui/default/vandelay/match_set.js
@@ -0,0 +1,359 @@
+dojo.require("dijit.Tree");
+dojo.require("dijit.form.Button");
+dojo.require("dojo.data.ItemFileWriteStore");
+//dojo.require("openils.vandelay.DndSource");
+dojo.require("dojo.dnd.Source");
+dojo.require("openils.vandelay.TreeDndSource");
+dojo.require("openils.vandelay.TreeStoreModel");
+dojo.require("openils.CGI");
+dojo.require("openils.User");
+dojo.require("openils.Util");
+dojo.require("openils.PermaCrud");
+dojo.require("openils.widget.ProgressDialog");
+
+var localeStrings;
+var node_editor;
+var _crads;
+var CGI;
+
+function _find_crad_by_name(name) {
+ for (var i = 0; i < _crads.length; i++) {
+ if (_crads[i].name() == name)
+ return _crads[i];
+ }
+ return null;
+}
+
+function NodeEditor() {
+ var self = this;
+
+ var _svf_select_template = null;
+ var _factories_by_type = {
+ "svf": function() {
+ if (!_svf_select_template) {
+ _svf_select_template = dojo.create(
+ "select", {"fmfield": "svf"}
+ );
+ for (var i=0; i<_crads.length; i++) {
+ dojo.create(
+ "option", {
+ "value": _crads[i].name(),
+ "innerHTML": _crads[i].label()
+ }, _svf_select_template
+ );
+ }
+ }
+
+ var select = dojo.clone(_svf_select_template);
+ dojo.attr(select, "id", "svf-select");
+ var label = dojo.create(
+ "label", {
+ "for": "svf-select", "innerHTML": "Single-Value-Field:"
+ }
+ );
+
+ var tr = dojo.create("tr");
+ dojo.place(label, dojo.create("td", null, tr));
+ dojo.place(select, dojo.create("td", null, tr));
+
+ return [tr];
+ },
+ "tag": function() {
+ var rows = [dojo.create("tr"), dojo.create("tr")];
+ dojo.create(
+ "label", {
+ "for": "tag-input", "innerHTML": "Tag:"
+ }, dojo.create("td", null, rows[0])
+ );
+ dojo.create(
+ "input", {
+ "id": "tag-input",
+ "type": "text",
+ "size": 4,
+ "maxlength": 3,
+ "fmfield": "tag"
+ }, dojo.create("td", null, rows[0])
+ );
+ dojo.create(
+ "label", {
+ "for": "subfield-input", "innerHTML": "Subfield: \u2021"
+ }, dojo.create("td", null, rows[1])
+ );
+ dojo.create(
+ "input", {
+ "id": "subfield-input",
+ "type": "text",
+ "size": 2,
+ "maxlength": 1,
+ "fmfield": "subfield"
+ }, dojo.create("td", null, rows[1])
+ );
+ return rows;
+ },
+ "bool_op": function() {
+ var tr = dojo.create("tr");
+ dojo.create(
+ "label",
+ {"for": "operator-select", "innerHTML": "Operator:"},
+ dojo.create("td", null, tr)
+ );
+ var select = dojo.create(
+ "select", {"fmfield": "bool_op", "id": "operator-select"},
+ dojo.create("td", null, tr)
+ );
+ dojo.create("option", {"value": "AND", "innerHTML": "AND"}, select);
+ dojo.create("option", {"value": "OR", "innerHTML": "OR"}, select);
+
+ return [tr];
+ }
+ };
+
+ function _simple_value_getter(control) {
+ if (typeof control.selectedIndex != "undefined")
+ return control.options[control.selectedIndex].value;
+ else if (dojo.attr(control, "type") == "checkbox")
+ return control.checked;
+ else
+ return control.value;
+ };
+
+ this._init = function(dnd_source, node_editor_container) {
+ this.dnd_source = dnd_source;
+ this.node_editor_container = dojo.byId(node_editor_container);
+ };
+
+ this.clear = function() {
+ this.dnd_source.selectAll().deleteSelectedNodes();
+ dojo.empty(this.node_editor_container);
+ };
+
+ this.update_draggable = function(draggable) {
+ var s = "";
+ draggable.match_point = new vmsp();
+ var had_op = false;
+ dojo.query("[fmfield]", this.node_editor_container).forEach(
+ function(control) {
+ var used_svf = null;
+ var field = dojo.attr(control, "fmfield");
+ var value = _simple_value_getter(control);
+ draggable.match_point[field](value);
+
+ if (field == "subfield")
+ s += " \u2021";
+ if (field == "svf")
+ used_svf = value;
+ if (field == "quality")
+ return;
+ if (field == "bool_op")
+ had_op = true;
+ if (field == "negate") {
+ if (value) {
+ if (had_op)
+ s = "<strong>N</strong>" + s;
+ else
+ s = "<strong>NOT</strong> " + s;
+ }
+ } else {
+ s += value;
+ }
+
+ if (used_svf !== null) {
+ var our_crad = _find_crad_by_name(used_svf);
+ /* XXX i18n, use fmtted strings */
+ s += " / " + our_crad.label() + "<br /><em>" +
+ (our_crad.description() || "") + "</em><br />";
+ }
+ }
+ );
+ dojo.attr(draggable, "innerHTML", s);
+ this.dnd_source._ready = true;
+ };
+
+ this._add_consistent_controls = function(tgt) {
+ if (!this._consistent_controls) {
+ var trs = dojo.query("[consistent-controls]");
+ this._consistent_controls = [];
+ for (var i = 0; i < trs.length; i++)
+ this._consistent_controls[i] = dojo.clone(trs[i]);
+ dojo.empty(trs[0].parentNode);
+ }
+
+ this._consistent_controls.forEach(
+ function(node) { dojo.place(dojo.clone(node), tgt); }
+ );
+ };
+
+ this.add = function(type) {
+ this.clear();
+
+ /* a representation, not the editing widgets, but will also carry
+ * the fieldmapper object when dragged to the tree */
+ var draggable = dojo.create(
+ "li", {"innerHTML": localeStrings.DEFINE_MP}
+ );
+
+ /* these are the editing widgets */
+ var table = dojo.create("table", {"className": "node-editor"});
+
+ var nodes = _factories_by_type[type]();
+ for (var i = 0; i < nodes.length; i++) dojo.place(nodes[i], table);
+
+ this._add_consistent_controls(table);
+
+ dojo.create(
+ "input", {
+ "type": "submit", "value": "Ok",
+ "onclick": function() { self.update_draggable(draggable); }
+ }, dojo.create(
+ "td", {"colspan": 2, "align": "center"},
+ dojo.create("tr", null, table)
+ )
+ );
+
+ dojo.place(table, this.node_editor_container, "only");
+ /* XXX around here attach other data structures to the node */
+ this.dnd_source.insertNodes(false, [draggable]);
+ this.dnd_source._ready = false;
+ };
+
+ this._init.apply(this, arguments);
+}
+
+/* XXX replace later with code that will suit this function's purpose
+ * as well as that of update_draggable. */
+function display_name_from_point(point) {
+ /* quick and dirty */
+ if (point.bool_op()) {
+ return (point.negate() == "t" ? "N" : "") + point.bool_op();
+ } else if (point.svf()) {
+ return (point.negate() == "t" ? "NOT " : "") + point.svf();
+ } else {
+ return (point.negate() == "t" ? "NOT " : "") + point.tag() +
+ "\u2021" + point.subfield();
+ }
+}
+
+/* dojoize_match_set_tree() takes an argument, "point", that is actually a
+ * vmsp fieldmapper object with descendants fleshed hierarchically. It turns
+ * that into a syntactically flat array but preserving the hierarchy
+ * semantically in the language used by dojo data stores, i.e.,
+ *
+ * [
+ * {'id': 'root', children:[{'_reference': '0'}, {'_reference': '1'}]},
+ * {'id': '0', children:[]},
+ * {'id': '1', children:[]}
+ * ],
+ *
+ */
+function dojoize_match_set_tree(point, refgen) {
+ /* XXX TODO test with deeper trees! */
+ var root = false;
+ if (!refgen) {
+ refgen = 0;
+ root = true;
+ }
+
+ var bathwater = point.children();
+ point.children([]);
+ var item = {
+ "id": (root ? "root" : refgen),
+ "name": display_name_from_point(point),
+ "match_point": point.clone(),
+ "children": []
+ };
+ point.children(bathwater);
+
+ var results = [item];
+
+ if (point.children()) {
+ for (var i = 0; i < point.children().length; i++) {
+ var child = point.children()[i];
+ item.children.push({"_reference": ++refgen});
+ results = results.concat(
+ dojoize_match_set_tree(child, refgen)
+ );
+ }
+ }
+
+ return results;
+}
+
+function init_test() {
+ progress_dialog.show(true);
+
+ dojo.requireLocalization("openils.vandelay", "match_set");
+ localeStrings = dojo.i18n.getLocalization("openils.vandelay", "match_set");
+
+ CGI = new openils.CGI();
+
+ /* XXX No-one should have hundreds of these or anything, but theoretically
+ * this could be problematic with a big enough list of crad objects. */
+ _crads = new openils.PermaCrud().retrieveAll(
+ "crad", {"order_by": {"crad": "label"}}
+ );
+
+ var match_set_tree = fieldmapper.standardRequest(
+ ["open-ils.vandelay", "open-ils.vandelay.match_set.get_tree"],
+ [openils.User.authtoken, CGI.param("match_set")]
+ );
+
+// {
+// "identifier": "id", "label": "name", "items": [
+// {
+// "id": "root", "name": "AND",
+// "children": [
+// {"_reference": "leaf0"}, {"_reference": "leaf1"}
+// ]
+// },
+// {"id": "leaf0", "name": "nonsense test"},
+// {"id": "leaf1", "name": "more nonsense"}
+// ]
+// }
+
+ var store = new dojo.data.ItemFileWriteStore({
+ "data": {
+ "identifier": "id",
+ "label": "name",
+ "items": dojoize_match_set_tree(match_set_tree)
+ }
+ });
+
+ var treeModel = new openils.vandelay.TreeStoreModel({
+ store: store, "query": {"id": "root"}
+ });
+
+ var src = new dojo.dnd.Source("src_here");
+ var tree = new dijit.Tree(
+ {
+ "model": treeModel,
+ "dndController": openils.vandelay.TreeDndSource,
+ "dragThreshold": 8,
+ "betweenThreshold": 5,
+ "persist": false
+ }, "tree_here"
+ );
+
+ node_editor = new NodeEditor(src, "node-editor-container");
+
+ dojo.connect(
+ src, "onDndDrop", null,
+ function(source, nodes, copy, target) {
+ if (source == this) {
+ var model = target.tree.model;
+ model.getRoot(
+ function(root) {
+ model.getSimpleTree(
+ root, function(results) { alert(js2JSON(results)); }
+ );
+ }
+ );
+ node_editor.clear(); /* because otherwise this acts like a copy! */
+ } else {
+ alert("XXX [src] nodes length is " + nodes.length); /* XXX DEBUG */
+ }
+ }
+ );
+ progress_dialog.hide();
+}
+
+openils.Util.addOnLoad(init_test);
diff --git a/Open-ILS/web/templates/default/vandelay/match_set.tt2 b/Open-ILS/web/templates/default/vandelay/match_set.tt2
new file mode 100644
index 0000000..fe5def0
--- /dev/null
+++ b/Open-ILS/web/templates/default/vandelay/match_set.tt2
@@ -0,0 +1,59 @@
+[% WRAPPER 'default/base.tt2' %]
+[% ctx.page_title = 'Vandelay Match Set' %]
+<style type="text/css">
+ h1 { margin: 0.5em 0; }
+ .outer { clear: both; }
+ #vmsp-buttons button { padding: 0 1.5em; }
+ .node-editor { margin-bottom: 2em; }
+ .node-editor td { padding: 0.5ex; }
+ li { background-color: #ddd; }
+</style>
+<h1>[% ctx.page_title %]</h1>
+<table class="hidden">
+ <tr consistent-controls="1">
+ <td>
+ <label for="quality-input"
+ title="A relative number representing the impact of this expression on the quality of the overall record match"><!-- XXX tooltipize -->
+ Quality:
+ </label>
+ </td>
+ <td>
+ <input id="quality-input" type="text" value="1"
+ size="4" maxlength="3" fmfield="quality" />
+ </td>
+ </tr>
+ <tr consistent-controls="1">
+ <td>
+ <label for="negate-input">Negate?</label>
+ </td>
+ <td>
+ <input id="negate-input" type="checkbox" fmfield="negate" />
+ </td>
+ </tr>
+</table>
+<div class="outer">
+ <div><!-- XXX TODO: consider a read-only display here of the query as built
+ so far from the treet --></div>
+ <div id="vmsp-buttons">
+ <button onclick="node_editor.add('svf');">New Single-Value-Field</button>
+ <button onclick="node_editor.add('tag');">New MARC Tag and Subfield</button>
+ <button onclick="node_editor.add('bool_op');">New Boolean Operator</button>
+ </div>
+</div>
+<div class="outer" style="margin-top: 2ex;">
+ <div style="float: left; width: 49%">
+ <div>
+ <form id="node-editor-container" onsubmit="return false;"></form>
+ </div>
+ <ul id="src_here"></ul>
+ </div>
+
+ <div style="float: right; width: 50%">
+ <div><big>Your Expression</big></div>
+ <div id="tree_here"></div>
+ </div>
+</div>
+<div jsId="progress_dialog" dojoType="openils.widget.ProgressDialog"></div>
+<script type="text/javascript"
+ src="[% ctx.media_prefix %]/js/ui/default/vandelay/match_set.js"></script>
+[% END %]
commit b1854026fc611c259a66b5c537af6018be981d15
Author: Mike Rylander <mrylander at gmail.com>
Date: Thu Mar 24 15:37:00 2011 -0400
Structure match set points as a tree
diff --git a/Open-ILS/examples/fm_IDL.xml b/Open-ILS/examples/fm_IDL.xml
index 4e5362b..4070fa3 100644
--- a/Open-ILS/examples/fm_IDL.xml
+++ b/Open-ILS/examples/fm_IDL.xml
@@ -552,22 +552,33 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
<class id="vmsp" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="vandelay::match_set_point" oils_persist:tablename="vandelay.match_set_point" reporter:label="Record Matching Definition">
<fields oils_persist:primary="id" oils_persist:sequence="vandelay.match_set_point_id_seq">
<field reporter:label="Match Definition ID" name="id" reporter:datatype="id"/>
+ <field reporter:label="Expression Tree Parent" name="parent" reporter:datatype="link"/>
<field reporter:label="Match Set" name="match_set" reporter:datatype="link"/>
- <field reporter:label="Coded Field" name="svf" reporter:datatype="text"/>
+ <field reporter:label="Boolean Operator" name="bool_op" reporter:datatype="text"/>
+ <field reporter:label="Coded Field" name="svf" reporter:datatype="link"/>
<field reporter:label="Tag" name="tag" reporter:datatype="text"/>
<field reporter:label="Subfield" name="subfield" reporter:datatype="text"/>
- <field reporter:label="Required?" name="required" reporter:datatype="bool"/>
<field reporter:label="Importance" name="quality" reporter:datatype="int"/>
</fields>
<links>
+ <link field="parent" reltype="has_a" key="id" map="" class="vmsp"/>
<link field="match_set" reltype="has_a" key="id" map="" class="vms"/>
+ <link field="svf" reltype="has_a" key="id" map="" class="crad"/>
</links>
<permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
<actions>
- <create permission="CREATE_IMPORT_MATCH_SET ADMIN_IMPORT_IMPORT_MATCH_SET" context_field="owner"/>
- <retrieve permission="CREATE_IMPORT_MATCH_SET UPDATE_IMPORT_MATCH_SET DELETE_IMPORT_MATCH_SET" context_field="owner"/>
- <update permission="UPDATE_IMPORT_MATCH_SET" context_field="owner"/>
- <delete permission="DELETE_IMPORT_MATCH_SET" context_field="owner"/>
+ <create permission="CREATE_IMPORT_MATCH_SET ADMIN_IMPORT_IMPORT_MATCH_SET">
+ <context link="match_set" field="owner"/>
+ </create>
+ <retrieve permission="CREATE_IMPORT_MATCH_SET UPDATE_IMPORT_MATCH_SET DELETE_IMPORT_MATCH_SET">
+ <context link="match_set" field="owner"/>
+ </retrieve>
+ <update permission="UPDATE_IMPORT_MATCH_SET">
+ <context link="match_set" field="owner"/>
+ </update>
+ <delete permission="DELETE_IMPORT_MATCH_SET">
+ <context link="match_set" field="owner"/>
+ </delete>
</actions>
</permacrud>
</class>
diff --git a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
index 5b6c0f5..fd3f818 100644
--- a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
+++ b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
@@ -17,16 +17,20 @@ CREATE TABLE vandelay.match_set (
-- Table to define match points, either FF via SVF or tag+subfield
CREATE TABLE vandelay.match_set_point (
id SERIAL PRIMARY KEY,
- match_set INT NOT NULL REFERENCES vandelay.match_set (id),
- svf TEXT REFERENCES config.record_attr_definition,
+ match_set INT REFERENCES vandelay.match_set (id),
+ parent INT REFERENCES vandelay.match_set_point (id),
+ bool_op TEXT CHECK (bool_op IS NULL OR (bool_op IN ('AND','OR','NOT'))),
+ svf TEXT REFERENCES config.record_attr_definition (name),
tag TEXT,
subfield TEXT,
- required BOOL NOT NULL DEFAULT TRUE,
quality INT NOT NULL DEFAULT 1, -- higher is better
CONSTRAINT vmsp_need_a_subfield_with_a_tag CHECK ((tag IS NOT NULL AND subfield IS NOT NULL) OR tag IS NULL),
- CONSTRAINT vmsp_need_a_tag_or_a_ff CHECK ((tag IS NOT NULL AND svf IS NULL) OR (tag IS NULL AND svf IS NOT NULL))
+ CONSTRAINT vmsp_need_a_tag_or_a_ff_or_a_bo CHECK (
+ (tag IS NOT NULL AND svf IS NULL AND bool_op IS NULL) OR
+ (tag IS NULL AND svf IS NOT NULL AND bool_op IS NULL) OR
+ (tag IS NULL AND svf IS NULL AND bool_op IS NOT NULL)
+ )
);
-CREATE UNIQUE INDEX vmsp_def_once_per_set ON vandelay.match_set_point (match_set, COALESCE(tag,''), COALESCE(subfield,''), COALESCE(svf,''));
CREATE TABLE vandelay.match_set_quality (
id SERIAL PRIMARY KEY,
@@ -500,6 +504,10 @@ BEGIN
first_round := TRUE;
-- whew ... here we go ...
+
+
+ -- Commented out until replaced by tree-ish version
+/*
FOR test IN SELECT * FROM vandelay.match_set_point WHERE match_set = my_bib_queue.match_set ORDER BY required DESC LOOP
IF test.tag IS NOT NULL THEN
FOR rvalue IN SELECT value FROM vandelay.flatten_marc( xml ) WHERE tag = test.tag AND subfield = test.subfield LOOP
@@ -551,6 +559,7 @@ BEGIN
FOR tmp_rec IN SELECT * FROM UNNEST(matches) LOOP
INSERT INTO vandelay.bib_match (matched_set, queued_record, eg_record, quality) VALUES (my_bib_queue.match_set, NEW.id, tmp_rec, (quality_set -> tmp_rec::TEXT));
END LOOP;
+*/
RETURN NEW;
END;
commit 13041c7e9aabd1f8067ad51efaa2b92b74c2f319
Author: Mike Rylander <mrylander at gmail.com>
Date: Mon Mar 14 14:47:55 2011 -0400
Protect bib matching from 901$c which has no corresponding incumbent record; also, boost the quality of an exact match
diff --git a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
index 84ca9bd..5b6c0f5 100644
--- a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
+++ b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
@@ -489,8 +489,11 @@ BEGIN
incoming_existing_id := oils_xpath_string('//*[@tag="901"]/*[@code="c"][1]',NEW.marc);
IF incoming_existing_id IS NOT NULL THEN
- INSERT INTO vandelay.bib_match (field_type, queued_record, eg_record) VALUES ('id', NEW.id, exact_id);
- RETURN NEW;
+ SELECT id INTO tmp_rec FROM biblio.record_entry WHERE id = exact_id;
+ IF tmp_rec IS NOT NULL THEN
+ INSERT INTO vandelay.bib_match (queued_record, eg_record, quality) VALUES ( NEW.id, exact_id, 9999);
+ RETURN NEW;
+ END IF;
END IF;
SELECT * INTO my_bib_queue FROM vandelay.bib_queue WHERE id = NEW.queue;
diff --git a/Open-ILS/src/sql/Pg/950.data.seed-values.sql b/Open-ILS/src/sql/Pg/950.data.seed-values.sql
index a010d07..25e9c1d 100644
--- a/Open-ILS/src/sql/Pg/950.data.seed-values.sql
+++ b/Open-ILS/src/sql/Pg/950.data.seed-values.sql
@@ -8807,6 +8807,7 @@ INSERT INTO config.org_unit_setting_type ( name, label, description, datatype )
INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'general.unknown', oils_i18n_gettext('general.unknown', 'Import or Overlay failed', 'vie', 'description') );
INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'import.item.duplicate.barcode', oils_i18n_gettext('import.item.duplicate.barcode', 'Import failed due to barcode collision', 'vie', 'description') );
INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'import.duplicate.sysid', oils_i18n_gettext('import.duplicate.sysid', 'Import failed due to system id collision', 'vie', 'description') );
+INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'overlay.missing.sysid', oils_i18n_gettext('overlay.missing.sysid', 'Overlay failed due to missing system id', 'vie', 'description') );
INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'import.auth.duplicate.acn', oils_i18n_gettext('import.auth.duplicate.acn', 'Import failed due to Accession Number collision', 'vie', 'description') );
INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'import.xml.malformed', oils_i18n_gettext('import.xml.malformed', 'Malformed record cause Import failure', 'vie', 'description') );
INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'overlay.xml.malformed', oils_i18n_gettext('overlay.xml.malformed', 'Malformed record cause Overlay failure', 'vie', 'description') );
commit e0114f18272c347795c21ac59e9c1e4520e2de65
Author: Mike Rylander <mrylander at gmail.com>
Date: Mon Mar 14 12:08:58 2011 -0400
SQL schema cleanup
diff --git a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
index bdfff7a..84ca9bd 100644
--- a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
+++ b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
@@ -24,9 +24,9 @@ CREATE TABLE vandelay.match_set_point (
required BOOL NOT NULL DEFAULT TRUE,
quality INT NOT NULL DEFAULT 1, -- higher is better
CONSTRAINT vmsp_need_a_subfield_with_a_tag CHECK ((tag IS NOT NULL AND subfield IS NOT NULL) OR tag IS NULL),
- CONSTRAINT vmsp_need_a_tag_or_a_ff CHECK (tag IS NOT NULL AND svf IS NULL) OR (tag IS NULL AND svf IS NOT NULL)),
- CONSTRAINT vmsp_def_once_per_set UNIQUE (match_set, COALESCE(tag,''), COALESCE(subfield,''), COALESCE(svf,''))
+ CONSTRAINT vmsp_need_a_tag_or_a_ff CHECK ((tag IS NOT NULL AND svf IS NULL) OR (tag IS NULL AND svf IS NOT NULL))
);
+CREATE UNIQUE INDEX vmsp_def_once_per_set ON vandelay.match_set_point (match_set, COALESCE(tag,''), COALESCE(subfield,''), COALESCE(svf,''));
CREATE TABLE vandelay.match_set_quality (
id SERIAL PRIMARY KEY,
@@ -37,9 +37,9 @@ CREATE TABLE vandelay.match_set_quality (
value TEXT NOT NULL,
quality INT NOT NULL DEFAULT 1, -- higher is better
CONSTRAINT vmsq_need_a_subfield_with_a_tag CHECK ((tag IS NOT NULL AND subfield IS NOT NULL) OR tag IS NULL),
- CONSTRAINT vmsq_need_a_tag_or_a_ff CHECK (tag IS NOT NULL AND svf IS NULL) OR (tag IS NULL AND svf IS NOT NULL)),
- CONSTRAINT vmsq_def_once_per_set UNIQUE (match_set, COALESCE(tag,''), COALESCE(subfield,''), COALESCE(svf,''))
+ CONSTRAINT vmsq_need_a_tag_or_a_ff CHECK ((tag IS NOT NULL AND svf IS NULL) OR (tag IS NULL AND svf IS NOT NULL))
);
+CREATE UNIQUE INDEX vmsq_def_once_per_set ON vandelay.match_set_quality (match_set, COALESCE(tag,''), COALESCE(subfield,''), COALESCE(svf,''));
CREATE TABLE vandelay.queue (
@@ -48,7 +48,7 @@ CREATE TABLE vandelay.queue (
name TEXT NOT NULL,
complete BOOL NOT NULL DEFAULT FALSE,
queue_type TEXT NOT NULL DEFAULT 'bib' CHECK (queue_type IN ('bib','authority')),
- match_set INT REFERENCES vandelay.match_set (id) DEFERRABLE INITIALLY DEFERRED ON UPDATE CASCADE ON DELETE SET NULL,
+ match_set INT REFERENCES vandelay.match_set (id) ON UPDATE CASCADE ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED,
CONSTRAINT vand_queue_name_once_per_owner_const UNIQUE (owner,name,queue_type)
);
@@ -122,7 +122,7 @@ CREATE TABLE vandelay.queued_bib_record (
queue INT NOT NULL REFERENCES vandelay.bib_queue (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
bib_source INT REFERENCES config.bib_source (id) DEFERRABLE INITIALLY DEFERRED,
imported_as BIGINT REFERENCES biblio.record_entry (id) DEFERRABLE INITIALLY DEFERRED,
- import_error INT REFERENCES vandelay.import_error (id) ON DELETE SET NULL ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
+ import_error TEXT REFERENCES vandelay.import_error (code) ON DELETE SET NULL ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
error_detail TEXT
) INHERITS (vandelay.queued_record);
ALTER TABLE vandelay.queued_bib_record ADD PRIMARY KEY (id);
@@ -148,7 +148,7 @@ CREATE TABLE vandelay.import_item (
id BIGSERIAL PRIMARY KEY,
record BIGINT NOT NULL REFERENCES vandelay.queued_bib_record (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
definition BIGINT NOT NULL REFERENCES vandelay.import_item_attr_definition (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
- import_error INT REFERENCES vandelay.import_error (id) ON DELETE SET NULL ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
+ import_error TEXT REFERENCES vandelay.import_error (code) ON DELETE SET NULL ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
error_detail TEXT,
owning_lib INT,
circ_lib INT,
@@ -311,7 +311,7 @@ BEGIN
END;
$func$ LANGUAGE PLPGSQL;
-CREAT TYPE vandelay.flat_marc AS ( tag CHAR(3), ind1 TEXT, ind2 TEXT, subfield TEXT, value TEXT );
+CREATE TYPE vandelay.flat_marc AS ( tag CHAR(3), ind1 TEXT, ind2 TEXT, subfield TEXT, value TEXT );
CREATE OR REPLACE FUNCTION vandelay.flay_marc ( TEXT ) RETURNS SETOF vandelay.flat_marc AS $func$
use MARC::Record;
@@ -515,9 +515,9 @@ BEGIN
END IF;
-- add the quality for this match
- FOR tmp_rec IN SELECT * FROM UNNEST(potential_matches);
+ FOR tmp_rec IN SELECT * FROM UNNEST(potential_matches) LOOP
tmp_quality := COALESCE((quality_set -> tmp_rec::TEXT)::INT, 0);
- quality := quality || hstore(tmp_rec::TEXT, (tmp_quality + test.quality)::TEXT);
+ quality_set := quality_set || hstore(tmp_rec::TEXT, (tmp_quality + test.quality)::TEXT);
END LOOP;
END LOOP;
@@ -537,9 +537,9 @@ BEGIN
END IF;
-- add the quality for this match
- FOR tmp_rec IN SELECT * FROM UNNEST(potential_matches);
+ FOR tmp_rec IN SELECT * FROM UNNEST(potential_matches) LOOP
tmp_quality := COALESCE((quality_set -> tmp_rec::TEXT)::INT, 0);
- quality := quality || hstore(tmp_rec::TEXT, (tmp_quality + test.quality)::TEXT);
+ quality_set := quality_set || hstore(tmp_rec::TEXT, (tmp_quality + test.quality)::TEXT);
END LOOP;
END IF;
@@ -1657,7 +1657,7 @@ ALTER TABLE vandelay.authority_queue ADD PRIMARY KEY (id);
CREATE TABLE vandelay.queued_authority_record (
queue INT NOT NULL REFERENCES vandelay.authority_queue (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
imported_as INT REFERENCES authority.record_entry (id) DEFERRABLE INITIALLY DEFERRED,
- import_error INT REFERENCES vandelay.import_error (id) ON DELETE SET NULL ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
+ import_error TEXT REFERENCES vandelay.import_error (code) ON DELETE SET NULL ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
error_detail TEXT
) INHERITS (vandelay.queued_record);
ALTER TABLE vandelay.queued_authority_record ADD PRIMARY KEY (id);
diff --git a/Open-ILS/src/sql/Pg/950.data.seed-values.sql b/Open-ILS/src/sql/Pg/950.data.seed-values.sql
index fbe9877..a010d07 100644
--- a/Open-ILS/src/sql/Pg/950.data.seed-values.sql
+++ b/Open-ILS/src/sql/Pg/950.data.seed-values.sql
@@ -3186,13 +3186,13 @@ INSERT INTO vandelay.bib_attr_definition ( id, code, description, xpath ) VALUES
INSERT INTO vandelay.bib_attr_definition ( id, code, description, xpath ) VALUES (2, 'author', oils_i18n_gettext(2, 'Author of work', 'vqbrad', 'description'),'//*[@tag="100" or @tag="110" or @tag="113"]/*[contains("ad", at code)]');
INSERT INTO vandelay.bib_attr_definition ( id, code, description, xpath ) VALUES (3, 'language', oils_i18n_gettext(3, 'Language of work', 'vqbrad', 'description'),'//*[@tag="240"]/*[@code="l"][1]');
INSERT INTO vandelay.bib_attr_definition ( id, code, description, xpath ) VALUES (4, 'pagination', oils_i18n_gettext(4, 'Pagination', 'vqbrad', 'description'),'//*[@tag="300"]/*[@code="a"][1]');
-INSERT INTO vandelay.bib_attr_definition ( id, code, description, xpath, ident, remove ) VALUES (5, 'isbn',oils_i18n_gettext(5, 'ISBN', 'vqbrad', 'description'),'//*[@tag="020"]/*[@code="a"]', TRUE, $r$(?:-|\s.+$)$r$);
-INSERT INTO vandelay.bib_attr_definition ( id, code, description, xpath, ident, remove ) VALUES (6, 'issn',oils_i18n_gettext(6, 'ISSN', 'vqbrad', 'description'),'//*[@tag="022"]/*[@code="a"]', TRUE, $r$(?:-|\s.+$)$r$);
+INSERT INTO vandelay.bib_attr_definition ( id, code, description, xpath, remove ) VALUES (5, 'isbn',oils_i18n_gettext(5, 'ISBN', 'vqbrad', 'description'),'//*[@tag="020"]/*[@code="a"]', $r$(?:-|\s.+$)$r$);
+INSERT INTO vandelay.bib_attr_definition ( id, code, description, xpath, remove ) VALUES (6, 'issn',oils_i18n_gettext(6, 'ISSN', 'vqbrad', 'description'),'//*[@tag="022"]/*[@code="a"]', $r$(?:-|\s.+$)$r$);
INSERT INTO vandelay.bib_attr_definition ( id, code, description, xpath ) VALUES (7, 'price',oils_i18n_gettext(7, 'Price', 'vqbrad', 'description'),'//*[@tag="020" or @tag="022"]/*[@code="c"][1]');
-INSERT INTO vandelay.bib_attr_definition ( id, code, description, xpath, ident ) VALUES (8, 'rec_identifier',oils_i18n_gettext(8, 'Accession Number', 'vqbrad', 'description'),'//*[@tag="001"]', TRUE);
-INSERT INTO vandelay.bib_attr_definition ( id, code, description, xpath, ident ) VALUES (9, 'eg_tcn',oils_i18n_gettext(9, 'TCN Value', 'vqbrad', 'description'),'//*[@tag="901"]/*[@code="a"]', TRUE);
-INSERT INTO vandelay.bib_attr_definition ( id, code, description, xpath, ident ) VALUES (10, 'eg_tcn_source',oils_i18n_gettext(10, 'TCN Source', 'vqbrad', 'description'),'//*[@tag="901"]/*[@code="b"]', TRUE);
-INSERT INTO vandelay.bib_attr_definition ( id, code, description, xpath, ident ) VALUES (11, 'eg_identifier',oils_i18n_gettext(11, 'Internal ID', 'vqbrad', 'description'),'//*[@tag="901"]/*[@code="c"]', TRUE);
+INSERT INTO vandelay.bib_attr_definition ( id, code, description, xpath) VALUES (8, 'rec_identifier',oils_i18n_gettext(8, 'Accession Number', 'vqbrad', 'description'),'//*[@tag="001"]');
+INSERT INTO vandelay.bib_attr_definition ( id, code, description, xpath) VALUES (9, 'eg_tcn',oils_i18n_gettext(9, 'TCN Value', 'vqbrad', 'description'),'//*[@tag="901"]/*[@code="a"]');
+INSERT INTO vandelay.bib_attr_definition ( id, code, description, xpath) VALUES (10, 'eg_tcn_source',oils_i18n_gettext(10, 'TCN Source', 'vqbrad', 'description'),'//*[@tag="901"]/*[@code="b"]');
+INSERT INTO vandelay.bib_attr_definition ( id, code, description, xpath) VALUES (11, 'eg_identifier',oils_i18n_gettext(11, 'Internal ID', 'vqbrad', 'description'),'//*[@tag="901"]/*[@code="c"]');
INSERT INTO vandelay.bib_attr_definition ( id, code, description, xpath ) VALUES (12, 'publisher',oils_i18n_gettext(12, 'Publisher', 'vqbrad', 'description'),'//*[@tag="260"]/*[@code="b"][1]');
INSERT INTO vandelay.bib_attr_definition ( id, code, description, xpath, remove ) VALUES (13, 'pubdate',oils_i18n_gettext(13, 'Publication Date', 'vqbrad', 'description'),'//*[@tag="260"]/*[@code="c"][1]',$r$\D$r$);
INSERT INTO vandelay.bib_attr_definition ( id, code, description, xpath ) VALUES (14, 'edition',oils_i18n_gettext(14, 'Edition', 'vqbrad', 'description'),'//*[@tag="250"]/*[@code="a"][1]');
@@ -3246,7 +3246,7 @@ INSERT INTO vandelay.import_item_attr_definition (
'k'
);
-INSERT INTO vandelay.authority_attr_definition (id, code, description, xpath, ident ) VALUES (1, 'rec_identifier',oils_i18n_gettext(1, 'Identifier', 'vqarad', 'description'),'//*[@tag="001"]', TRUE);
+INSERT INTO vandelay.authority_attr_definition (id, code, description, xpath) VALUES (1, 'rec_identifier',oils_i18n_gettext(1, 'Identifier', 'vqarad', 'description'),'//*[@tag="001"]');
SELECT SETVAL('vandelay.authority_attr_definition_id_seq'::TEXT, 100);
commit efba3908ce39499b007161f1c25b0d5de42e10fa
Author: Mike Rylander <mrylander at gmail.com>
Date: Mon Mar 14 11:43:24 2011 -0400
Add table and columns for tracking current import/overlay errors per object
diff --git a/Open-ILS/examples/fm_IDL.xml b/Open-ILS/examples/fm_IDL.xml
index 251df7a..4e5362b 100644
--- a/Open-ILS/examples/fm_IDL.xml
+++ b/Open-ILS/examples/fm_IDL.xml
@@ -186,6 +186,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
<field reporter:label="Import Item ID" name="id" reporter:datatype="id"/>
<field reporter:label="Import Record" name="record" reporter:datatype="link"/>
<field reporter:label="Attribute Definition" name="definition" reporter:datatype="link"/>
+ <field reporter:label="Import Error" name="import_error" reporter:datatype="link"/>
+ <field reporter:label="Import Error Detail" name="error_detail" reporter:datatype="text"/>
<field reporter:label="Owning Library" name="owning_lib" reporter:datatype="int"/>
<field reporter:label="Circulating Library" name="circ_lib" reporter:datatype="int"/>
<field reporter:label="Call Number" name="call_number" reporter:datatype="text"/>
@@ -207,6 +209,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
<field reporter:label="OPAC Visible" name="opac_visible" reporter:datatype="bool"/>
</fields>
<links>
+ <link field="import_error" reltype="has_a" key="code" map="" class="vie"/>
<link field="record" reltype="has_a" key="id" map="" class="vqbr"/>
<link field="definition" reltype="has_a" key="id" map="" class="viiad"/>
</links>
@@ -294,6 +297,23 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
</permacrud>
</class>
+ <class id="vie" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="vandelay::import_error" oils_persist:tablename="vandelay.import_error" reporter:label="Import/Overlay Error Definitions">
+ <fields oils_persist:primary="code">
+ <field reporter:label="Error Code" name="code" reporter:selector="description" reporter:datatype="id"/>
+ <field reporter:label="Description" name="description" reporter:datatype="text" oils_persist:i18n="true"/>
+ </fields>
+ <links>
+ <link field="owner" reltype="has_a" key="id" map="" class="aou"/>
+ <link field="item_attr_def" reltype="has_a" key="id" map="" class="viiad"/>
+ <link field="match_set" reltype="has_a" key="id" map="" class="vms"/>
+ </links>
+ <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
+ <actions>
+ <retrieve/>
+ </actions>
+ </permacrud>
+ </class>
+
<class id="vqbr" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="vandelay::queued_bib_record" oils_persist:tablename="vandelay.queued_bib_record" reporter:label="Queued Bib Record">
<fields oils_persist:primary="id" oils_persist:sequence="vandelay.queued_record_id_seq">
<field reporter:label="Record ID" name="id" reporter:datatype="id"/>
@@ -303,11 +323,14 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
<field reporter:label="Queue" name="queue" reporter:datatype="link"/>
<field reporter:label="Bib Source" name="bib_source" reporter:datatype="link"/>
<field reporter:label="Final Target Record" name="imported_as" reporter:datatype="link"/>
+ <field reporter:label="Import Error" name="import_error" reporter:datatype="link"/>
+ <field reporter:label="Import Error Detail" name="error_detail" reporter:datatype="text"/>
<field reporter:label="Purpose" name="purpose" reporter:datatype="text"/>
<field reporter:label="Attributes" name="attributes" oils_persist:virtual="true" reporter:datatype="link"/>
<field reporter:label="Matches" name="matches" oils_persist:virtual="true" reporter:datatype="link"/>
</fields>
<links>
+ <link field="import_error" reltype="has_a" key="code" map="" class="vie"/>
<link field="queue" reltype="has_a" key="id" map="" class="vbq"/>
<link field="bib_source" reltype="has_a" key="id" map="" class="cbs"/>
<link field="imported_as" reltype="has_a" key="id" map="" class="bre"/>
@@ -419,11 +442,14 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
<field reporter:label="MARC" name="marc" reporter:datatype="text"/>
<field reporter:label="Queue" name="queue" reporter:datatype="link"/>
<field reporter:label="Final Target Record" name="imported_as" reporter:datatype="link"/>
+ <field reporter:label="Import Error" name="import_error" reporter:datatype="link"/>
+ <field reporter:label="Import Error Detail" name="error_detail" reporter:datatype="text"/>
<field reporter:label="Purpose" name="purpose" reporter:datatype="text"/>
<field reporter:label="Attributes" name="attributes" oils_persist:virtual="true" reporter:datatype="link"/>
<field reporter:label="Matches" name="matches" oils_persist:virtual="true" reporter:datatype="link"/>
</fields>
<links>
+ <link field="import_error" reltype="has_a" key="code" map="" class="vie"/>
<link field="queue" reltype="has_a" key="id" map="" class="vaq"/>
<link field="imported_as" reltype="has_a" key="id" map="" class="are"/>
<link field="attributes" reltype="has_many" key="record" map="" class="vqara"/>
diff --git a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
index c4bc1f8..bdfff7a 100644
--- a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
+++ b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
@@ -106,6 +106,11 @@ CREATE TABLE vandelay.import_item_attr_definition (
CONSTRAINT vand_import_item_attr_def_idx UNIQUE (owner,name)
);
+CREATE TABLE vandelay.import_error (
+ code TEXT PRIMARY KEY,
+ description TEXT NOT NULL -- i18n
+);
+
CREATE TABLE vandelay.bib_queue (
queue_type TEXT NOT NULL DEFAULT 'bib' CHECK (queue_type = 'bib'),
item_attr_def BIGINT REFERENCES vandelay.import_item_attr_definition (id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED,
@@ -114,9 +119,11 @@ CREATE TABLE vandelay.bib_queue (
ALTER TABLE vandelay.bib_queue ADD PRIMARY KEY (id);
CREATE TABLE vandelay.queued_bib_record (
- queue INT NOT NULL REFERENCES vandelay.bib_queue (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
- bib_source INT REFERENCES config.bib_source (id) DEFERRABLE INITIALLY DEFERRED,
- imported_as BIGINT REFERENCES biblio.record_entry (id) DEFERRABLE INITIALLY DEFERRED
+ queue INT NOT NULL REFERENCES vandelay.bib_queue (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
+ bib_source INT REFERENCES config.bib_source (id) DEFERRABLE INITIALLY DEFERRED,
+ imported_as BIGINT REFERENCES biblio.record_entry (id) DEFERRABLE INITIALLY DEFERRED,
+ import_error INT REFERENCES vandelay.import_error (id) ON DELETE SET NULL ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
+ error_detail TEXT
) INHERITS (vandelay.queued_record);
ALTER TABLE vandelay.queued_bib_record ADD PRIMARY KEY (id);
CREATE INDEX queued_bib_record_queue_idx ON vandelay.queued_bib_record (queue);
@@ -137,11 +144,12 @@ CREATE TABLE vandelay.bib_match (
quality INT NOT NULL DEFAULT 0
);
--- DROP TABLE vandelay.import_item CASCADE;
CREATE TABLE vandelay.import_item (
id BIGSERIAL PRIMARY KEY,
record BIGINT NOT NULL REFERENCES vandelay.queued_bib_record (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
definition BIGINT NOT NULL REFERENCES vandelay.import_item_attr_definition (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
+ import_error INT REFERENCES vandelay.import_error (id) ON DELETE SET NULL ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
+ error_detail TEXT,
owning_lib INT,
circ_lib INT,
call_number TEXT,
@@ -1648,7 +1656,9 @@ ALTER TABLE vandelay.authority_queue ADD PRIMARY KEY (id);
CREATE TABLE vandelay.queued_authority_record (
queue INT NOT NULL REFERENCES vandelay.authority_queue (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
- imported_as INT REFERENCES authority.record_entry (id) DEFERRABLE INITIALLY DEFERRED
+ imported_as INT REFERENCES authority.record_entry (id) DEFERRABLE INITIALLY DEFERRED,
+ import_error INT REFERENCES vandelay.import_error (id) ON DELETE SET NULL ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
+ error_detail TEXT
) INHERITS (vandelay.queued_record);
ALTER TABLE vandelay.queued_authority_record ADD PRIMARY KEY (id);
CREATE INDEX queued_authority_record_queue_idx ON vandelay.queued_authority_record (queue);
diff --git a/Open-ILS/src/sql/Pg/950.data.seed-values.sql b/Open-ILS/src/sql/Pg/950.data.seed-values.sql
index 78ed74c..fbe9877 100644
--- a/Open-ILS/src/sql/Pg/950.data.seed-values.sql
+++ b/Open-ILS/src/sql/Pg/950.data.seed-values.sql
@@ -8804,3 +8804,10 @@ INSERT INTO config.org_unit_setting_type ( name, label, description, datatype )
),
'bool'
);
+INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'general.unknown', oils_i18n_gettext('general.unknown', 'Import or Overlay failed', 'vie', 'description') );
+INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'import.item.duplicate.barcode', oils_i18n_gettext('import.item.duplicate.barcode', 'Import failed due to barcode collision', 'vie', 'description') );
+INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'import.duplicate.sysid', oils_i18n_gettext('import.duplicate.sysid', 'Import failed due to system id collision', 'vie', 'description') );
+INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'import.auth.duplicate.acn', oils_i18n_gettext('import.auth.duplicate.acn', 'Import failed due to Accession Number collision', 'vie', 'description') );
+INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'import.xml.malformed', oils_i18n_gettext('import.xml.malformed', 'Malformed record cause Import failure', 'vie', 'description') );
+INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'overlay.xml.malformed', oils_i18n_gettext('overlay.xml.malformed', 'Malformed record cause Overlay failure', 'vie', 'description') );
+
commit 934603b401b6db47f65e3d706283f291cef8d96f
Author: Mike Rylander <mrylander at gmail.com>
Date: Fri Mar 11 16:05:07 2011 -0500
Mostly, new function(s) for bib matching based on SVF and tag+subfield; also, goodly amounts of moving things around
diff --git a/Open-ILS/examples/fm_IDL.xml b/Open-ILS/examples/fm_IDL.xml
index c268e8f..251df7a 100644
--- a/Open-ILS/examples/fm_IDL.xml
+++ b/Open-ILS/examples/fm_IDL.xml
@@ -276,11 +276,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
<field reporter:label="Complete" name="complete" reporter:datatype="bool"/>
<field reporter:label="Type" name="queue_type" reporter:datatype="text"/>
<field reporter:label="Quality" name="quality" reporter:datatype="int"/>
+ <field reporter:label="Match Set" name="match_set" reporter:datatype="link"/>
<field reporter:label="Item Import Attribute Definition" name="item_attr_def" reporter:datatype="link"/>
</fields>
<links>
<link field="owner" reltype="has_a" key="id" map="" class="aou"/>
<link field="item_attr_def" reltype="has_a" key="id" map="" class="viiad"/>
+ <link field="match_set" reltype="has_a" key="id" map="" class="vms"/>
</links>
<permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
<actions>
@@ -329,7 +331,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
<field reporter:label="Description" name="description" reporter:datatype="text" oils_persist:i18n="true"/>
<field reporter:label="XPath" name="xpath" reporter:datatype="text"/>
<field reporter:label="Remove RegExp" name="remove" reporter:datatype="text"/>
- <field reporter:label="Is Identifier?" name="ident" reporter:datatype="bool"/>
</fields>
<links/>
<permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
@@ -367,15 +368,14 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
<fields oils_persist:primary="id" oils_persist:sequence="vandelay.bib_match_id_seq">
<field reporter:label="Match ID" name="id" reporter:datatype="id"/>
<field reporter:label="Queued Record" name="queued_record" reporter:datatype="link"/>
- <field reporter:label="Matched Attribute" name="matched_attr" reporter:datatype="link"/>
+ <field reporter:label="Matched Set" name="matched_set" reporter:datatype="link"/>
<field reporter:label="Evergreen Record" name="eg_record" reporter:datatype="link"/>
- <field reporter:label="Field Type" name="field_type" reporter:datatype="text"/>
<field reporter:label="Quality" name="quality" reporter:datatype="text"/>
</fields>
<links>
<link field="queued_record" reltype="has_a" key="id" map="" class="vqbr"/>
<link field="eg_record" reltype="has_a" key="id" map="" class="bre"/>
- <link field="matched_attr" reltype="has_a" key="id" map="" class="vqbra"/>
+ <link field="matched_set" reltype="has_a" key="id" map="" class="vms"/>
</links>
<permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
<actions>
@@ -395,9 +395,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
<field reporter:label="Complete" name="complete" reporter:datatype="bool"/>
<field reporter:label="Type" name="queue_type" reporter:datatype="text"/>
<field reporter:label="Quality" name="quality" reporter:datatype="int"/>
+ <field reporter:label="Match Set" name="match_set" reporter:datatype="link"/>
</fields>
<links>
<link field="owner" reltype="has_a" key="id" map="" class="aou"/>
+ <link field="match_set" reltype="has_a" key="id" map="" class="vms"/>
</links>
<permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
<actions>
@@ -525,7 +527,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
<fields oils_persist:primary="id" oils_persist:sequence="vandelay.match_set_point_id_seq">
<field reporter:label="Match Definition ID" name="id" reporter:datatype="id"/>
<field reporter:label="Match Set" name="match_set" reporter:datatype="link"/>
- <field reporter:label="Fixed Field" name="fixed_field" reporter:datatype="text"/>
+ <field reporter:label="Coded Field" name="svf" reporter:datatype="text"/>
<field reporter:label="Tag" name="tag" reporter:datatype="text"/>
<field reporter:label="Subfield" name="subfield" reporter:datatype="text"/>
<field reporter:label="Required?" name="required" reporter:datatype="bool"/>
@@ -548,7 +550,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
<fields oils_persist:primary="id" oils_persist:sequence="vandelay.match_set_quality_id_seq">
<field reporter:label="Quality Metric ID" name="id" reporter:datatype="id"/>
<field reporter:label="Match Set" name="match_set" reporter:datatype="link"/>
- <field reporter:label="Fixed Field" name="fixed_field" reporter:datatype="text"/>
+ <field reporter:label="Coded Field" name="svf" reporter:datatype="text"/>
<field reporter:label="Tag" name="tag" reporter:datatype="text"/>
<field reporter:label="Subfield" name="subfield" reporter:datatype="text"/>
<field reporter:label="Value" name="value" reporter:datatype="text"/>
diff --git a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
index 9b3e3cf..c4bc1f8 100644
--- a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
+++ b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
@@ -2,14 +2,53 @@ DROP SCHEMA IF EXISTS vandelay CASCADE;
BEGIN;
+CREATE OR REPLACE FUNCTION array_remove_item_by_value(inp ANYARRAY, el ANYELEMENT) RETURNS anyarray AS $$ SELECT ARRAY_ACCUM(x.e) FROM UNNEST( $1 ) x(e) WHERE x.e <> $2; $$ LANGUAGE SQL;
+
CREATE SCHEMA vandelay;
+CREATE TABLE vandelay.match_set (
+ id SERIAL PRIMARY KEY,
+ name TEXT NOT NULL,
+ owner INT NOT NULL REFERENCES actor.org_unit (id) ON DELETE CASCADE,
+ mtype TEXT NOT NULL DEFAULT 'biblio', -- 'biblio','authority','mfhd'?, others?
+ CONSTRAINT name_once_per_owner_mtype UNIQUE (name, owner, mtype)
+);
+
+-- Table to define match points, either FF via SVF or tag+subfield
+CREATE TABLE vandelay.match_set_point (
+ id SERIAL PRIMARY KEY,
+ match_set INT NOT NULL REFERENCES vandelay.match_set (id),
+ svf TEXT REFERENCES config.record_attr_definition,
+ tag TEXT,
+ subfield TEXT,
+ required BOOL NOT NULL DEFAULT TRUE,
+ quality INT NOT NULL DEFAULT 1, -- higher is better
+ CONSTRAINT vmsp_need_a_subfield_with_a_tag CHECK ((tag IS NOT NULL AND subfield IS NOT NULL) OR tag IS NULL),
+ CONSTRAINT vmsp_need_a_tag_or_a_ff CHECK (tag IS NOT NULL AND svf IS NULL) OR (tag IS NULL AND svf IS NOT NULL)),
+ CONSTRAINT vmsp_def_once_per_set UNIQUE (match_set, COALESCE(tag,''), COALESCE(subfield,''), COALESCE(svf,''))
+);
+
+CREATE TABLE vandelay.match_set_quality (
+ id SERIAL PRIMARY KEY,
+ match_set INT NOT NULL REFERENCES vandelay.match_set (id),
+ svf TEXT REFERENCES config.record_attr_definition,
+ tag TEXT,
+ subfield TEXT,
+ value TEXT NOT NULL,
+ quality INT NOT NULL DEFAULT 1, -- higher is better
+ CONSTRAINT vmsq_need_a_subfield_with_a_tag CHECK ((tag IS NOT NULL AND subfield IS NOT NULL) OR tag IS NULL),
+ CONSTRAINT vmsq_need_a_tag_or_a_ff CHECK (tag IS NOT NULL AND svf IS NULL) OR (tag IS NULL AND svf IS NOT NULL)),
+ CONSTRAINT vmsq_def_once_per_set UNIQUE (match_set, COALESCE(tag,''), COALESCE(subfield,''), COALESCE(svf,''))
+);
+
+
CREATE TABLE vandelay.queue (
id BIGSERIAL PRIMARY KEY,
owner INT NOT NULL REFERENCES actor.usr (id) DEFERRABLE INITIALLY DEFERRED,
name TEXT NOT NULL,
complete BOOL NOT NULL DEFAULT FALSE,
queue_type TEXT NOT NULL DEFAULT 'bib' CHECK (queue_type IN ('bib','authority')),
+ match_set INT REFERENCES vandelay.match_set (id) DEFERRABLE INITIALLY DEFERRED ON UPDATE CASCADE ON DELETE SET NULL,
CONSTRAINT vand_queue_name_once_per_owner_const UNIQUE (owner,name,queue_type)
);
@@ -32,8 +71,7 @@ CREATE TABLE vandelay.bib_attr_definition (
code TEXT UNIQUE NOT NULL,
description TEXT,
xpath TEXT NOT NULL,
- remove TEXT NOT NULL DEFAULT '',
- ident BOOL NOT NULL DEFAULT FALSE
+ remove TEXT NOT NULL DEFAULT ''
);
-- Each TEXT field (other than 'name') should hold an XPath predicate for pulling the data needed
@@ -93,8 +131,7 @@ CREATE INDEX queued_bib_record_attr_record_idx ON vandelay.queued_bib_record_att
CREATE TABLE vandelay.bib_match (
id BIGSERIAL PRIMARY KEY,
- field_type TEXT NOT NULL CHECK (field_type in ('isbn','tcn_value','id')),
- matched_attr INT REFERENCES vandelay.queued_bib_record_attr (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
+ matched_set INT REFERENCES vandelay.match_set (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
queued_record BIGINT REFERENCES vandelay.queued_bib_record (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
eg_record BIGINT REFERENCES biblio.record_entry (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
quality INT NOT NULL DEFAULT 0
@@ -145,41 +182,6 @@ CREATE TABLE vandelay.merge_profile (
CONSTRAINT add_replace_strip_or_preserve CHECK ((preserve_spec IS NOT NULL OR replace_spec IS NOT NULL) OR (preserve_spec IS NULL AND replace_spec IS NULL))
);
-CREATE TABLE vandelay.match_set (
- id SERIAL PRIMARY KEY,
- name TEXT NOT NULL,
- owner INT NOT NULL REFERENCES actor.org_unit (id) ON DELETE CASCADE,
- mtype TEXT NOT NULL DEFAULT 'biblio', -- 'biblio','authority','mfhd'?, others?
- CONSTRAINT name_once_per_owner_mtype UNIQUE (name, owner, mtype)
-);
-
--- Table to define match points, either FF via SVF or tag+subfield
-CREATE TABLE vandelay.match_set_point (
- id SERIAL PRIMARY KEY,
- match_set INT NOT NULL REFERENCES vandelay.match_set (id),
- fixed_field TEXT, -- should exist in config.marc21_ff_pos_map.fixed_field
- tag TEXT,
- subfield TEXT,
- required BOOL NOT NULL DEFAULT TRUE,
- quality INT NOT NULL DEFAULT 1, -- higher is better
- CONSTRAINT vmsp_need_a_subfield_with_a_tag CHECK ((tag IS NOT NULL AND subfield IS NOT NULL) OR tag IS NULL),
- CONSTRAINT vmsp_need_a_tag_or_a_ff CHECK (tag IS NOT NULL AND fixed_field IS NULL) OR (tag IS NULL AND fixed_field IS NOT NULL)),
- CONSTRAINT vmsp_def_once_per_set UNIQUE (match_set, COALESCE(tag,''), COALESCE(subfield,''), COALESCE(fixed_field,''))
-);
-
-CREATE TABLE vandelay.match_set_quality (
- id SERIAL PRIMARY KEY,
- match_set INT NOT NULL REFERENCES vandelay.match_set (id),
- fixed_field TEXT, -- should exist in config.marc21_ff_pos_map.fixed_field
- tag TEXT,
- subfield TEXT,
- value TEXT NOT NULL,
- quality INT NOT NULL DEFAULT 1, -- higher is better
- CONSTRAINT vmsq_need_a_subfield_with_a_tag CHECK ((tag IS NOT NULL AND subfield IS NOT NULL) OR tag IS NULL),
- CONSTRAINT vmsq_need_a_tag_or_a_ff CHECK (tag IS NOT NULL AND fixed_field IS NULL) OR (tag IS NULL AND fixed_field IS NOT NULL)),
- CONSTRAINT vmsq_def_once_per_set UNIQUE (match_set, COALESCE(tag,''), COALESCE(subfield,''), COALESCE(fixed_field,''))
-);
-
CREATE OR REPLACE FUNCTION vandelay.marc21_record_type( marc TEXT ) RETURNS config.marc21_rec_type_map AS $func$
DECLARE
ldr TEXT;
@@ -366,6 +368,183 @@ BEGIN
END;
$func$ LANGUAGE PLPGSQL;
+CREATE OR REPLACE FUNCTION vandelay.extract_rec_attrs ( xml TEXT, attr_defs TEXT[]) RETURNS hstore AS $_$
+DECLARE
+ transformed_xml TEXT;
+ prev_xfrm TEXT;
+ normalizer RECORD;
+ xfrm config.xml_transform%ROWTYPE;
+ attr_value TEXT;
+ new_attrs HSTORE := ''::HSTORE;
+ attr_def config.record_attr_definition%ROWTYPE;
+BEGIN
+
+ FOR attr_def IN SELECT * FROM config.record_attr_definition WHERE name IN (SELECT * FROM UNNEST(attr_defs)) ORDER BY format LOOP
+
+ IF attr_def.tag IS NOT NULL THEN -- tag (and optional subfield list) selection
+ SELECT ARRAY_TO_STRING(ARRAY_ACCUM(x.value), COALESCE(attr_def.joiner,' ')) INTO attr_value
+ FROM vandelay.flatten_marc(xml) AS x
+ WHERE x.tag LIKE attr_def.tag
+ AND CASE
+ WHEN attr_def.sf_list IS NOT NULL
+ THEN POSITION(x.subfield IN attr_def.sf_list) > 0
+ ELSE TRUE
+ END
+ GROUP BY x.tag
+ ORDER BY x.tag
+ LIMIT 1;
+
+ ELSIF attr_def.fixed_field IS NOT NULL THEN -- a named fixed field, see config.marc21_ff_pos_map.fixed_field
+ attr_value := vandelay.marc21_extract_fixed_field(xml, attr_def.fixed_field);
+
+ ELSIF attr_def.xpath IS NOT NULL THEN -- and xpath expression
+
+ SELECT INTO xfrm * FROM config.xml_transform WHERE name = attr_def.format;
+
+ -- See if we can skip the XSLT ... it's expensive
+ IF prev_xfrm IS NULL OR prev_xfrm <> xfrm.name THEN
+ -- Can't skip the transform
+ IF xfrm.xslt <> '---' THEN
+ transformed_xml := oils_xslt_process(xml,xfrm.xslt);
+ ELSE
+ transformed_xml := xml;
+ END IF;
+
+ prev_xfrm := xfrm.name;
+ END IF;
+
+ IF xfrm.name IS NULL THEN
+ -- just grab the marcxml (empty) transform
+ SELECT INTO xfrm * FROM config.xml_transform WHERE xslt = '---' LIMIT 1;
+ prev_xfrm := xfrm.name;
+ END IF;
+
+ attr_value := oils_xpath_string(attr_def.xpath, transformed_xml, COALESCE(attr_def.joiner,' '), ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]]);
+
+ ELSIF attr_def.phys_char_sf IS NOT NULL THEN -- a named Physical Characteristic, see config.marc21_physical_characteristic_*_map
+ SELECT value::TEXT INTO attr_value
+ FROM vandelay.marc21_physical_characteristics(xml)
+ WHERE subfield = attr_def.phys_char_sf
+ LIMIT 1; -- Just in case ...
+
+ END IF;
+
+ -- apply index normalizers to attr_value
+ FOR normalizer IN
+ SELECT n.func AS func,
+ n.param_count AS param_count,
+ m.params AS params
+ FROM config.index_normalizer n
+ JOIN config.record_attr_index_norm_map m ON (m.norm = n.id)
+ WHERE attr = attr_def.name
+ ORDER BY m.pos LOOP
+ EXECUTE 'SELECT ' || normalizer.func || '(' ||
+ quote_literal( attr_value ) ||
+ CASE
+ WHEN normalizer.param_count > 0
+ THEN ',' || REPLACE(REPLACE(BTRIM(normalizer.params,'[]'),E'\'',E'\\\''),E'"',E'\'')
+ ELSE ''
+ END ||
+ ')' INTO attr_value;
+
+ END LOOP;
+
+ -- Add the new value to the hstore
+ new_attrs := new_attrs || hstore( attr_def.name, attr_value );
+
+ END LOOP;
+
+ RETURN new_attrs;
+END;
+$_$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION vandelay.extract_rec_attrs ( xml TEXT ) RETURNS hstore AS $_$
+ SELECT vandelay.extract_rec_attrs( $1, (SELECT ARRAY_ACCUM(name) FROM config.record_attr_definition));
+$_$ LANGUAGE SQL;
+
+CREATE OR REPLACE FUNCTION vandelay.match_bib_record ( ) RETURNS TRIGGER AS $func$
+DECLARE
+ incoming_existing_id TEXT;
+ my_bib_queue vandelay.bib_queue%ROWTYPE;
+ my_match_set vandelay.match_set%ROWTYPE;
+ test vandelay.match_set_point%ROWTYPE;
+ potential_matches BIGINT[];
+ matches BIGINT[];
+ rvalue TEXT;
+ quality_set hstore;
+ tmp_rec BIGINT;
+ tmp_quality INT;
+ first_round BOOL;
+BEGIN
+ DELETE FROM vandelay.bib_match WHERE queued_record = NEW.id;
+
+ incoming_existing_id := oils_xpath_string('//*[@tag="901"]/*[@code="c"][1]',NEW.marc);
+
+ IF incoming_existing_id IS NOT NULL THEN
+ INSERT INTO vandelay.bib_match (field_type, queued_record, eg_record) VALUES ('id', NEW.id, exact_id);
+ RETURN NEW;
+ END IF;
+
+ SELECT * INTO my_bib_queue FROM vandelay.bib_queue WHERE id = NEW.queue;
+
+ first_round := TRUE;
+ -- whew ... here we go ...
+ FOR test IN SELECT * FROM vandelay.match_set_point WHERE match_set = my_bib_queue.match_set ORDER BY required DESC LOOP
+ IF test.tag IS NOT NULL THEN
+ FOR rvalue IN SELECT value FROM vandelay.flatten_marc( xml ) WHERE tag = test.tag AND subfield = test.subfield LOOP
+ SELECT ARRAY_ACCUM(DISTINCT record) INTO potential_matches FROM metabib.real_full_rec WHERE tag = test.tag AND subfield = test.subfield AND value = rvalue;
+
+ IF first_round THEN
+ matches := potential_matches;
+ first_round := FALSE;
+ ELSIF test.required THEN
+ FOR tmp_rec IN SELECT * FROM UNNEST(matches) LOOP
+ IF tmp_rec NOT IN (SELECT * FROM UNNEST(potential_matches)) THEN
+ matches := array_remove_item_by_value(matches, tmp_rec);
+ potential_matches := array_remove_item_by_value(potential_matches, tmp_rec);
+ END IF;
+ END LOOP;
+ END IF;
+
+ -- add the quality for this match
+ FOR tmp_rec IN SELECT * FROM UNNEST(potential_matches);
+ tmp_quality := COALESCE((quality_set -> tmp_rec::TEXT)::INT, 0);
+ quality := quality || hstore(tmp_rec::TEXT, (tmp_quality + test.quality)::TEXT);
+ END LOOP;
+
+ END LOOP;
+ ELSE
+ rvalue := vandelay.vandelay.extract_rec_attrs(xml, ARRAY[test.svf]);
+
+ IF first_round THEN
+ matches := potential_matches;
+ first_round := FALSE;
+ ELSIF test.required THEN
+ FOR tmp_rec IN SELECT * FROM UNNEST(matches) LOOP
+ IF tmp_rec NOT IN (SELECT * FROM UNNEST(potential_matches)) THEN
+ matches := array_remove_item_by_value(matches, tmp_rec);
+ potential_matches := array_remove_item_by_value(potential_matches, tmp_rec);
+ END IF;
+ END LOOP;
+ END IF;
+
+ -- add the quality for this match
+ FOR tmp_rec IN SELECT * FROM UNNEST(potential_matches);
+ tmp_quality := COALESCE((quality_set -> tmp_rec::TEXT)::INT, 0);
+ quality := quality || hstore(tmp_rec::TEXT, (tmp_quality + test.quality)::TEXT);
+ END LOOP;
+
+ END IF;
+ END LOOP;
+
+ FOR tmp_rec IN SELECT * FROM UNNEST(matches) LOOP
+ INSERT INTO vandelay.bib_match (matched_set, queued_record, eg_record, quality) VALUES (my_bib_queue.match_set, NEW.id, tmp_rec, (quality_set -> tmp_rec::TEXT));
+ END LOOP;
+
+ RETURN NEW;
+END;
+$func$ LANGUAGE PLPGSQL;
+
CREATE OR REPLACE FUNCTION vandelay.incoming_record_quality ( xml TEXT, match_set_id INT ) RETURNS INT AS $_$
DECLARE
out_q INT := 0;
@@ -380,8 +559,8 @@ BEGIN
out_q := out_q + test.quality;
END IF;
END LOOP;
- ELSIF test.fixed_field IS NOT NULL THEN -- a named fixed field, see config.marc21_ff_pos_map.fixed_field
- IF test.value = vandelay.marc21_extract_fixed_field(xml, test.fixed_field) THEN
+ ELSE
+ IF test.value = vandelay.extract_rec_attrs(xml, ARRAY[test.svf]) THEN
out_q := out_q + test.quality;
END IF;
END IF;
@@ -1458,8 +1637,7 @@ CREATE TABLE vandelay.authority_attr_definition (
code TEXT UNIQUE NOT NULL,
description TEXT,
xpath TEXT NOT NULL,
- remove TEXT NOT NULL DEFAULT '',
- ident BOOL NOT NULL DEFAULT FALSE
+ remove TEXT NOT NULL DEFAULT ''
);
CREATE TABLE vandelay.authority_queue (
@@ -1485,9 +1663,10 @@ CREATE INDEX queued_authority_record_attr_record_idx ON vandelay.queued_authorit
CREATE TABLE vandelay.authority_match (
id BIGSERIAL PRIMARY KEY,
- matched_attr INT REFERENCES vandelay.queued_authority_record_attr (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
+ matched_set INT REFERENCES vandelay.match_set (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
queued_record BIGINT REFERENCES vandelay.queued_authority_record (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
- eg_record BIGINT REFERENCES authority.record_entry (id) DEFERRABLE INITIALLY DEFERRED
+ eg_record BIGINT REFERENCES authority.record_entry (id) DEFERRABLE INITIALLY DEFERRED,
+ quality INT NOT NULL DEFAULT 0
);
CREATE OR REPLACE FUNCTION vandelay.ingest_authority_marc ( ) RETURNS TRIGGER AS $$
diff --git a/Open-ILS/src/sql/Pg/030.schema.metabib.sql b/Open-ILS/src/sql/Pg/030.schema.metabib.sql
index 3cbdd49..22bc674 100644
--- a/Open-ILS/src/sql/Pg/030.schema.metabib.sql
+++ b/Open-ILS/src/sql/Pg/030.schema.metabib.sql
@@ -1116,7 +1116,7 @@ BEGIN
IF TG_OP = 'INSERT' OR OLD.deleted THEN -- initial insert OR revivication
INSERT INTO metabib.record_attr (id, attrs) VALUES (NEW.id, new_attrs);
ELSE
- UPDATE metabib.record_attr SET attrs = attrs || new_attrs WHERE id = NEW.id;
+ UPDATE metabib.record_attr SET attrs = new_attrs WHERE id = NEW.id;
END IF;
END IF;
commit efa9520b2133321b1649c92eda5db29d1d6d8ec5
Author: Mike Rylander <mrylander at gmail.com>
Date: Fri Mar 11 10:12:13 2011 -0500
Teach fieldmapper about the new vandelay classes
diff --git a/Open-ILS/examples/fm_IDL.xml b/Open-ILS/examples/fm_IDL.xml
index ce42aa3..c268e8f 100644
--- a/Open-ILS/examples/fm_IDL.xml
+++ b/Open-ILS/examples/fm_IDL.xml
@@ -275,6 +275,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
<field reporter:label="Name" name="name" reporter:datatype="text" oils_persist:i18n="true"/>
<field reporter:label="Complete" name="complete" reporter:datatype="bool"/>
<field reporter:label="Type" name="queue_type" reporter:datatype="text"/>
+ <field reporter:label="Quality" name="quality" reporter:datatype="int"/>
<field reporter:label="Item Import Attribute Definition" name="item_attr_def" reporter:datatype="link"/>
</fields>
<links>
@@ -369,6 +370,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
<field reporter:label="Matched Attribute" name="matched_attr" reporter:datatype="link"/>
<field reporter:label="Evergreen Record" name="eg_record" reporter:datatype="link"/>
<field reporter:label="Field Type" name="field_type" reporter:datatype="text"/>
+ <field reporter:label="Quality" name="quality" reporter:datatype="text"/>
</fields>
<links>
<link field="queued_record" reltype="has_a" key="id" map="" class="vqbr"/>
@@ -392,6 +394,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
<field reporter:label="Name" name="name" reporter:datatype="text" oils_persist:i18n="true"/>
<field reporter:label="Complete" name="complete" reporter:datatype="bool"/>
<field reporter:label="Type" name="queue_type" reporter:datatype="text"/>
+ <field reporter:label="Quality" name="quality" reporter:datatype="int"/>
</fields>
<links>
<link field="owner" reltype="has_a" key="id" map="" class="aou"/>
@@ -481,6 +484,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
<field reporter:label="Queued Record" name="queued_record" reporter:datatype="link"/>
<field reporter:label="Matched Attribute" name="matched_attr" reporter:datatype="link"/>
<field reporter:label="Evergreen Record" name="eg_record" reporter:datatype="link"/>
+ <field reporter:label="Quality" name="quality" reporter:datatype="int"/>
</fields>
<links>
<link field="queued_record" reltype="has_a" key="id" map="" class="vqbr"/>
@@ -497,6 +501,71 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
</permacrud>
</class>
+ <class id="vms" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="vandelay::match_set" oils_persist:tablename="vandelay.match_set" reporter:label="Record Matching Definition Set">
+ <fields oils_persist:primary="id" oils_persist:sequence="vandelay.match_set_id_seq">
+ <field reporter:label="Match Set ID" name="id" reporter:datatype="id"/>
+ <field reporter:label="Name" name="name" reporter:datatype="text"/>
+ <field reporter:label="Owning Library" name="owner" reporter:datatype="link"/>
+ <field reporter:label="Match Set Type" name="mtype" reporter:datatype="text"/>
+ </fields>
+ <links>
+ <link field="owner" reltype="has_a" key="id" map="" class="aou"/>
+ </links>
+ <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
+ <actions>
+ <create permission="CREATE_IMPORT_MATCH_SET ADMIN_IMPORT_IMPORT_MATCH_SET" context_field="owner"/>
+ <retrieve permission="CREATE_IMPORT_MATCH_SET UPDATE_IMPORT_MATCH_SET DELETE_IMPORT_MATCH_SET" context_field="owner"/>
+ <update permission="UPDATE_IMPORT_MATCH_SET" context_field="owner"/>
+ <delete permission="DELETE_IMPORT_MATCH_SET" context_field="owner"/>
+ </actions>
+ </permacrud>
+ </class>
+
+ <class id="vmsp" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="vandelay::match_set_point" oils_persist:tablename="vandelay.match_set_point" reporter:label="Record Matching Definition">
+ <fields oils_persist:primary="id" oils_persist:sequence="vandelay.match_set_point_id_seq">
+ <field reporter:label="Match Definition ID" name="id" reporter:datatype="id"/>
+ <field reporter:label="Match Set" name="match_set" reporter:datatype="link"/>
+ <field reporter:label="Fixed Field" name="fixed_field" reporter:datatype="text"/>
+ <field reporter:label="Tag" name="tag" reporter:datatype="text"/>
+ <field reporter:label="Subfield" name="subfield" reporter:datatype="text"/>
+ <field reporter:label="Required?" name="required" reporter:datatype="bool"/>
+ <field reporter:label="Importance" name="quality" reporter:datatype="int"/>
+ </fields>
+ <links>
+ <link field="match_set" reltype="has_a" key="id" map="" class="vms"/>
+ </links>
+ <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
+ <actions>
+ <create permission="CREATE_IMPORT_MATCH_SET ADMIN_IMPORT_IMPORT_MATCH_SET" context_field="owner"/>
+ <retrieve permission="CREATE_IMPORT_MATCH_SET UPDATE_IMPORT_MATCH_SET DELETE_IMPORT_MATCH_SET" context_field="owner"/>
+ <update permission="UPDATE_IMPORT_MATCH_SET" context_field="owner"/>
+ <delete permission="DELETE_IMPORT_MATCH_SET" context_field="owner"/>
+ </actions>
+ </permacrud>
+ </class>
+
+ <class id="vmsq" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="vandelay::match_set_quality" oils_persist:tablename="vandelay.match_set_quality" reporter:label="Record Quality Metric">
+ <fields oils_persist:primary="id" oils_persist:sequence="vandelay.match_set_quality_id_seq">
+ <field reporter:label="Quality Metric ID" name="id" reporter:datatype="id"/>
+ <field reporter:label="Match Set" name="match_set" reporter:datatype="link"/>
+ <field reporter:label="Fixed Field" name="fixed_field" reporter:datatype="text"/>
+ <field reporter:label="Tag" name="tag" reporter:datatype="text"/>
+ <field reporter:label="Subfield" name="subfield" reporter:datatype="text"/>
+ <field reporter:label="Value" name="value" reporter:datatype="text"/>
+ <field reporter:label="Importance" name="quality" reporter:datatype="int"/>
+ </fields>
+ <links>
+ <link field="match_set" reltype="has_a" key="id" map="" class="vms"/>
+ </links>
+ <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
+ <actions>
+ <create permission="CREATE_IMPORT_MATCH_SET ADMIN_IMPORT_IMPORT_MATCH_SET" context_field="owner"/>
+ <retrieve permission="CREATE_IMPORT_MATCH_SET UPDATE_IMPORT_MATCH_SET DELETE_IMPORT_MATCH_SET" context_field="owner"/>
+ <update permission="UPDATE_IMPORT_MATCH_SET" context_field="owner"/>
+ <delete permission="DELETE_IMPORT_MATCH_SET" context_field="owner"/>
+ </actions>
+ </permacrud>
+ </class>
<class id="auoi" controller="open-ils.cstore" oils_obj:fieldmapper="actor::usr_org_unit_opt_in" oils_persist:tablename="actor.usr_org_unit_opt_in" reporter:label="User Sharing Opt-in">
<fields oils_persist:primary="id" oils_persist:sequence="actor.usr_org_unit_opt_in_id_seq">
commit 57b7f22475b6b3cdbe3514546c82eb5b2947041c
Author: Mike Rylander <mrylander at gmail.com>
Date: Thu Mar 10 16:35:44 2011 -0500
moving functions around; tables for configuring match points and quality metrics
diff --git a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
index 7841170..9b3e3cf 100644
--- a/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
+++ b/Open-ILS/src/sql/Pg/012.schema.vandelay.sql
@@ -18,7 +18,8 @@ CREATE TABLE vandelay.queued_record (
create_time TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
import_time TIMESTAMP WITH TIME ZONE,
purpose TEXT NOT NULL DEFAULT 'import' CHECK (purpose IN ('import','overlay')),
- marc TEXT NOT NULL
+ marc TEXT NOT NULL,
+ quality INT NOT NULL DEFAULT 0
);
@@ -95,7 +96,8 @@ CREATE TABLE vandelay.bib_match (
field_type TEXT NOT NULL CHECK (field_type in ('isbn','tcn_value','id')),
matched_attr INT REFERENCES vandelay.queued_bib_record_attr (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
queued_record BIGINT REFERENCES vandelay.queued_bib_record (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
- eg_record BIGINT REFERENCES biblio.record_entry (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED
+ eg_record BIGINT REFERENCES biblio.record_entry (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
+ quality INT NOT NULL DEFAULT 0
);
-- DROP TABLE vandelay.import_item CASCADE;
@@ -143,6 +145,251 @@ CREATE TABLE vandelay.merge_profile (
CONSTRAINT add_replace_strip_or_preserve CHECK ((preserve_spec IS NOT NULL OR replace_spec IS NOT NULL) OR (preserve_spec IS NULL AND replace_spec IS NULL))
);
+CREATE TABLE vandelay.match_set (
+ id SERIAL PRIMARY KEY,
+ name TEXT NOT NULL,
+ owner INT NOT NULL REFERENCES actor.org_unit (id) ON DELETE CASCADE,
+ mtype TEXT NOT NULL DEFAULT 'biblio', -- 'biblio','authority','mfhd'?, others?
+ CONSTRAINT name_once_per_owner_mtype UNIQUE (name, owner, mtype)
+);
+
+-- Table to define match points, either FF via SVF or tag+subfield
+CREATE TABLE vandelay.match_set_point (
+ id SERIAL PRIMARY KEY,
+ match_set INT NOT NULL REFERENCES vandelay.match_set (id),
+ fixed_field TEXT, -- should exist in config.marc21_ff_pos_map.fixed_field
+ tag TEXT,
+ subfield TEXT,
+ required BOOL NOT NULL DEFAULT TRUE,
+ quality INT NOT NULL DEFAULT 1, -- higher is better
+ CONSTRAINT vmsp_need_a_subfield_with_a_tag CHECK ((tag IS NOT NULL AND subfield IS NOT NULL) OR tag IS NULL),
+ CONSTRAINT vmsp_need_a_tag_or_a_ff CHECK (tag IS NOT NULL AND fixed_field IS NULL) OR (tag IS NULL AND fixed_field IS NOT NULL)),
+ CONSTRAINT vmsp_def_once_per_set UNIQUE (match_set, COALESCE(tag,''), COALESCE(subfield,''), COALESCE(fixed_field,''))
+);
+
+CREATE TABLE vandelay.match_set_quality (
+ id SERIAL PRIMARY KEY,
+ match_set INT NOT NULL REFERENCES vandelay.match_set (id),
+ fixed_field TEXT, -- should exist in config.marc21_ff_pos_map.fixed_field
+ tag TEXT,
+ subfield TEXT,
+ value TEXT NOT NULL,
+ quality INT NOT NULL DEFAULT 1, -- higher is better
+ CONSTRAINT vmsq_need_a_subfield_with_a_tag CHECK ((tag IS NOT NULL AND subfield IS NOT NULL) OR tag IS NULL),
+ CONSTRAINT vmsq_need_a_tag_or_a_ff CHECK (tag IS NOT NULL AND fixed_field IS NULL) OR (tag IS NULL AND fixed_field IS NOT NULL)),
+ CONSTRAINT vmsq_def_once_per_set UNIQUE (match_set, COALESCE(tag,''), COALESCE(subfield,''), COALESCE(fixed_field,''))
+);
+
+CREATE OR REPLACE FUNCTION vandelay.marc21_record_type( marc TEXT ) RETURNS config.marc21_rec_type_map AS $func$
+DECLARE
+ ldr TEXT;
+ tval TEXT;
+ tval_rec RECORD;
+ bval TEXT;
+ bval_rec RECORD;
+ retval config.marc21_rec_type_map%ROWTYPE;
+BEGIN
+ ldr := oils_xpath_string( '//*[local-name()="leader"]', marc );
+
+ IF ldr IS NULL OR ldr = '' THEN
+ SELECT * INTO retval FROM config.marc21_rec_type_map WHERE code = 'BKS';
+ RETURN retval;
+ END IF;
+
+ SELECT * INTO tval_rec FROM config.marc21_ff_pos_map WHERE fixed_field = 'Type' LIMIT 1; -- They're all the same
+ SELECT * INTO bval_rec FROM config.marc21_ff_pos_map WHERE fixed_field = 'BLvl' LIMIT 1; -- They're all the same
+
+
+ tval := SUBSTRING( ldr, tval_rec.start_pos + 1, tval_rec.length );
+ bval := SUBSTRING( ldr, bval_rec.start_pos + 1, bval_rec.length );
+
+ -- RAISE NOTICE 'type %, blvl %, ldr %', tval, bval, ldr;
+
+ SELECT * INTO retval FROM config.marc21_rec_type_map WHERE type_val LIKE '%' || tval || '%' AND blvl_val LIKE '%' || bval || '%';
+
+
+ IF retval.code IS NULL THEN
+ SELECT * INTO retval FROM config.marc21_rec_type_map WHERE code = 'BKS';
+ END IF;
+
+ RETURN retval;
+END;
+$func$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION vandelay.marc21_extract_fixed_field( marc TEXT, ff TEXT ) RETURNS TEXT AS $func$
+DECLARE
+ rtype TEXT;
+ ff_pos RECORD;
+ tag_data RECORD;
+ val TEXT;
+BEGIN
+ rtype := (vandelay.marc21_record_type( marc )).code;
+ FOR ff_pos IN SELECT * FROM config.marc21_ff_pos_map WHERE fixed_field = ff AND rec_type = rtype ORDER BY tag DESC LOOP
+ FOR tag_data IN SELECT value FROM UNNEST( oils_xpath( '//*[@tag="' || UPPER(ff_pos.tag) || '"]/text()', marc ) ) x(value) LOOP
+ val := SUBSTRING( tag_data.value, ff_pos.start_pos + 1, ff_pos.length );
+ RETURN val;
+ END LOOP;
+ val := REPEAT( ff_pos.default_val, ff_pos.length );
+ RETURN val;
+ END LOOP;
+
+ RETURN NULL;
+END;
+$func$ LANGUAGE PLPGSQL;
+
+CREATE TYPE biblio.record_ff_map AS (record BIGINT, ff_name TEXT, ff_value TEXT);
+CREATE OR REPLACE FUNCTION vandelay.marc21_extract_all_fixed_fields( marc TEXT ) RETURNS SETOF biblio.record_ff_map AS $func$
+DECLARE
+ tag_data TEXT;
+ rtype TEXT;
+ ff_pos RECORD;
+ output biblio.record_ff_map%ROWTYPE;
+BEGIN
+ rtype := (vandelay.marc21_record_type( marc )).code;
+
+ FOR ff_pos IN SELECT * FROM config.marc21_ff_pos_map WHERE rec_type = rtype ORDER BY tag DESC LOOP
+ output.ff_name := ff_pos.fixed_field;
+ output.ff_value := NULL;
+
+ FOR tag_data IN SELECT value FROM UNNEST( oils_xpath( '//*[@tag="' || UPPER(tag) || '"]/text()', marc ) ) x(value) LOOP
+ output.ff_value := SUBSTRING( tag_data.value, ff_pos.start_pos + 1, ff_pos.length );
+ IF output.ff_value IS NULL THEN output.ff_value := REPEAT( ff_pos.default_val, ff_pos.length ); END IF;
+ RETURN NEXT output;
+ output.ff_value := NULL;
+ END LOOP;
+
+ END LOOP;
+
+ RETURN;
+END;
+$func$ LANGUAGE PLPGSQL;
+
+CREATE TYPE biblio.marc21_physical_characteristics AS ( id INT, record BIGINT, ptype TEXT, subfield INT, value INT );
+CREATE OR REPLACE FUNCTION vandelay.marc21_physical_characteristics( marc TEXT) RETURNS SETOF biblio.marc21_physical_characteristics AS $func$
+DECLARE
+ rowid INT := 0;
+ _007 TEXT;
+ ptype config.marc21_physical_characteristic_type_map%ROWTYPE;
+ psf config.marc21_physical_characteristic_subfield_map%ROWTYPE;
+ pval config.marc21_physical_characteristic_value_map%ROWTYPE;
+ retval biblio.marc21_physical_characteristics%ROWTYPE;
+BEGIN
+
+ _007 := oils_xpath_string( '//*[@tag="007"]', marc );
+
+ IF _007 IS NOT NULL AND _007 <> '' THEN
+ SELECT * INTO ptype FROM config.marc21_physical_characteristic_type_map WHERE ptype_key = SUBSTRING( _007, 1, 1 );
+
+ IF ptype.ptype_key IS NOT NULL THEN
+ FOR psf IN SELECT * FROM config.marc21_physical_characteristic_subfield_map WHERE ptype_key = ptype.ptype_key LOOP
+ SELECT * INTO pval FROM config.marc21_physical_characteristic_value_map WHERE ptype_subfield = psf.id AND value = SUBSTRING( _007, psf.start_pos + 1, psf.length );
+
+ IF pval.id IS NOT NULL THEN
+ rowid := rowid + 1;
+ retval.id := rowid;
+ retval.ptype := ptype.ptype_key;
+ retval.subfield := psf.id;
+ retval.value := pval.id;
+ RETURN NEXT retval;
+ END IF;
+
+ END LOOP;
+ END IF;
+ END IF;
+
+ RETURN;
+END;
+$func$ LANGUAGE PLPGSQL;
+
+CREAT TYPE vandelay.flat_marc AS ( tag CHAR(3), ind1 TEXT, ind2 TEXT, subfield TEXT, value TEXT );
+CREATE OR REPLACE FUNCTION vandelay.flay_marc ( TEXT ) RETURNS SETOF vandelay.flat_marc AS $func$
+
+use MARC::Record;
+use MARC::File::XML (BinaryEncoding => 'UTF-8');
+
+my $xml = shift;
+my $r = MARC::Record->new_from_xml( $xml );
+
+return_next( { tag => 'LDR', value => $r->leader } );
+
+for my $f ( $r->fields ) {
+ if ($f->is_control_field) {
+ return_next({ tag => $f->tag, value => $f->data });
+ } else {
+ for my $s ($f->subfields) {
+ return_next({
+ tag => $f->tag,
+ ind1 => $f->indicator(1),
+ ind2 => $f->indicator(2),
+ subfield => $s->[0],
+ value => $s->[1]
+ });
+
+ if ( $f->tag eq '245' and $s->[0] eq 'a' ) {
+ my $trim = $f->indicator(2) || 0;
+ return_next({
+ tag => 'tnf',
+ ind1 => $f->indicator(1),
+ ind2 => $f->indicator(2),
+ subfield => 'a',
+ value => substr( $s->[1], $trim )
+ });
+ }
+ }
+ }
+}
+
+return undef;
+
+$func$ LANGUAGE PLPERLU;
+
+CREATE OR REPLACE FUNCTION vandelay.flatten_marc ( marc TEXT ) RETURNS SETOF vandelay.flat_marc AS $func$
+DECLARE
+ output vandelay.flat_marc%ROWTYPE;
+ field RECORD;
+BEGIN
+ FOR field IN SELECT * FROM vandelay.flay_marc( marc ) LOOP
+ output.ind1 := field.ind1;
+ output.ind2 := field.ind2;
+ output.tag := field.tag;
+ output.subfield := field.subfield;
+ IF field.subfield IS NOT NULL AND field.tag NOT IN ('020','022','024') THEN -- exclude standard numbers and control fields
+ output.value := naco_normalize(field.value, field.subfield);
+ ELSE
+ output.value := field.value;
+ END IF;
+
+ CONTINUE WHEN output.value IS NULL;
+
+ RETURN NEXT output;
+ END LOOP;
+END;
+$func$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION vandelay.incoming_record_quality ( xml TEXT, match_set_id INT ) RETURNS INT AS $_$
+DECLARE
+ out_q INT := 0;
+ rvalue TEXT;
+ test vandelay.match_set_quality%ROWTYPE;
+BEGIN
+
+ FOR test IN SELECT * FROM vandelay.match_set_quality WHERE match_set = match_set_id LOOP
+ IF test.tag IS NOT NULL THEN
+ FOR rvalue IN SELECT value FROM vandelay.flatten_marc( xml ) WHERE tag = test.tag AND subfield = test.subfield LOOP
+ IF test.value = rvalue THEN
+ out_q := out_q + test.quality;
+ END IF;
+ END LOOP;
+ ELSIF test.fixed_field IS NOT NULL THEN -- a named fixed field, see config.marc21_ff_pos_map.fixed_field
+ IF test.value = vandelay.marc21_extract_fixed_field(xml, test.fixed_field) THEN
+ out_q := out_q + test.quality;
+ END IF;
+ END IF;
+ END LOOP;
+
+ RETURN out_q;
+END;
+$_$ LANGUAGE PLPGSQL;
CREATE TYPE vandelay.tcn_data AS (tcn TEXT, tcn_source TEXT, used BOOL);
CREATE OR REPLACE FUNCTION vandelay.find_bib_tcn_data ( xml TEXT ) RETURNS SETOF vandelay.tcn_data AS $_$
diff --git a/Open-ILS/src/sql/Pg/030.schema.metabib.sql b/Open-ILS/src/sql/Pg/030.schema.metabib.sql
index fb2c4cb..3cbdd49 100644
--- a/Open-ILS/src/sql/Pg/030.schema.metabib.sql
+++ b/Open-ILS/src/sql/Pg/030.schema.metabib.sql
@@ -417,19 +417,13 @@ DECLARE
BEGIN
SELECT INTO bib * FROM biblio.record_entry WHERE id = rid;
- FOR field IN SELECT * FROM biblio.flatten_marc( bib.marc ) LOOP
+ FOR field IN SELECT * FROM vandelay.flatten_marc( bib.marc ) LOOP
output.record := rid;
output.ind1 := field.ind1;
output.ind2 := field.ind2;
output.tag := field.tag;
output.subfield := field.subfield;
- IF field.subfield IS NOT NULL AND field.tag NOT IN ('020','022','024') THEN -- exclude standard numbers and control fields
- output.value := naco_normalize(field.value, field.subfield);
- ELSE
- output.value := field.value;
- END IF;
-
- CONTINUE WHEN output.value IS NULL;
+ output.value := field.value;
RETURN NEXT output;
END LOOP;
@@ -620,43 +614,6 @@ CREATE OR REPLACE FUNCTION biblio.marc21_extract_all_fixed_fields( rid BIGINT )
SELECT $1 AS record, ff_name, ff_value FROM vandelay.marc21_extract_all_fixed_fields( (SELECT marc FROM biblio.record_entry WHERE id = $1) );
$func$ LANGUAGE SQL;
-CREATE TYPE biblio.marc21_physical_characteristics AS ( id INT, record BIGINT, ptype TEXT, subfield INT, value INT );
-CREATE OR REPLACE FUNCTION vandelay.marc21_physical_characteristics( marc TEXT) RETURNS SETOF biblio.marc21_physical_characteristics AS $func$
-DECLARE
- rowid INT := 0;
- _007 TEXT;
- ptype config.marc21_physical_characteristic_type_map%ROWTYPE;
- psf config.marc21_physical_characteristic_subfield_map%ROWTYPE;
- pval config.marc21_physical_characteristic_value_map%ROWTYPE;
- retval biblio.marc21_physical_characteristics%ROWTYPE;
-BEGIN
-
- _007 := oils_xpath_string( '//*[@tag="007"]', marc );
-
- IF _007 IS NOT NULL AND _007 <> '' THEN
- SELECT * INTO ptype FROM config.marc21_physical_characteristic_type_map WHERE ptype_key = SUBSTRING( _007, 1, 1 );
-
- IF ptype.ptype_key IS NOT NULL THEN
- FOR psf IN SELECT * FROM config.marc21_physical_characteristic_subfield_map WHERE ptype_key = ptype.ptype_key LOOP
- SELECT * INTO pval FROM config.marc21_physical_characteristic_value_map WHERE ptype_subfield = psf.id AND value = SUBSTRING( _007, psf.start_pos + 1, psf.length );
-
- IF pval.id IS NOT NULL THEN
- rowid := rowid + 1;
- retval.id := rowid;
- retval.ptype := ptype.ptype_key;
- retval.subfield := psf.id;
- retval.value := pval.id;
- RETURN NEXT retval;
- END IF;
-
- END LOOP;
- END IF;
- END IF;
-
- RETURN;
-END;
-$func$ LANGUAGE PLPGSQL;
-
CREATE OR REPLACE FUNCTION biblio.marc21_physical_characteristics( rid BIGINT ) RETURNS SETOF biblio.marc21_physical_characteristics AS $func$
SELECT id, $1 AS record, ptype, subfield, value FROM vandelay.marc21_physical_characteristics( (SELECT marc FROM biblio.record_entry WHERE id = $1) );
$func$ LANGUAGE SQL;
commit 66144a226706c2ee8cccbcf2c5248f3c4aed404c
Author: Thomas Berezansky <tsbere at mvlc.org>
Date: Thu Jun 16 17:03:36 2011 -0400
Delete protection - Ensure you can touch group
Same protection editing a user seems to get:
If you don't have the right group_application.user perm, reject
Signed-off-by: Thomas Berezansky <tsbere at mvlc.org>
Signed-off-by: Dan Wells <dbw2 at calvin.edu>
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Actor.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Actor.pm
index 5e704b4..1f0fa93 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Actor.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Actor.pm
@@ -3515,7 +3515,13 @@ sub really_delete_user {
my $e = new_editor(authtoken => $auth, xact => 1);
return $e->die_event unless $e->checkauth;
my $user = $e->retrieve_actor_user($user_id) or return $e->die_event;
+ # No deleting yourself - UI is supposed to stop you first, though.
+ return $e->die_event unless $e->requestor->id != $user->id;
return $e->die_event unless $e->allowed('DELETE_USER', $user->home_ou);
+ # Check if you are allowed to mess with this patron permission group at all
+ my $session = OpenSRF::AppSession->create( "open-ils.storage" );
+ my $evt = group_perm_failed($session, $e->requestor, $user);
+ return $e->die_event($evt) if $evt;
my $stat = $e->json_query(
{from => ['actor.usr_delete', $user_id, $dest_user_id]})->[0]
or return $e->die_event;
-----------------------------------------------------------------------
Summary of changes:
Open-ILS/examples/fm_IDL.xml | 135 ++-
.../lib/OpenILS/Application/Trigger/Reactor.pm | 51 +
.../perlmods/lib/OpenILS/Application/Vandelay.pm | 859 +++++++++--
Open-ILS/src/sql/Pg/000.functions.general.sql | 2 +
Open-ILS/src/sql/Pg/002.schema.config.sql | 6 +-
Open-ILS/src/sql/Pg/012.schema.vandelay.sql | 1066 +++++++++-----
Open-ILS/src/sql/Pg/030.schema.metabib.sql | 72 +-
Open-ILS/src/sql/Pg/800.fkeys.sql | 2 +
Open-ILS/src/sql/Pg/950.data.seed-values.sql | 597 ++++++++-
Open-ILS/src/sql/Pg/999.functions.global.sql | 392 ++++-
.../upgrade/0526.schema.upgrade-dep-tracking.sql | 4 +-
...schema.vandelay-record-matching-and-quality.sql | 1594 ++++++++++++++++++++
Open-ILS/web/css/skin/default/vandelay.css | 20 +
Open-ILS/web/js/dojo/fieldmapper/Fieldmapper.js | 8 +
.../web/js/dojo/openils/vandelay/TreeDndSource.js | 123 ++
.../web/js/dojo/openils/vandelay/TreeStoreModel.js | 52 +
.../web/js/dojo/openils/vandelay/nls/match_set.js | 16 +
Open-ILS/web/js/dojo/openils/widget/AutoGrid.js | 9 +-
.../ui/default/conify/global/vandelay/match_set.js | 606 ++++++++
Open-ILS/web/js/ui/default/vandelay/vandelay.js | 509 ++++++--
Open-ILS/web/opac/locale/en-US/lang.dtd | 1 +
Open-ILS/web/opac/locale/en-US/vandelay.dtd | 42 +-
.../default/conify/global/vandelay/match_set.tt2 | 94 ++
.../conify/global/vandelay/match_set_tree.tt2 | 150 ++
.../web/templates/default/vandelay/inc/attrs.tt2 | 10 -
.../default/vandelay/inc/import_errors.tt2 | 77 +
.../web/templates/default/vandelay/inc/matches.tt2 | 9 +-
.../templates/default/vandelay/inc/profiles.tt2 | 9 +-
.../web/templates/default/vandelay/inc/queue.tt2 | 272 ++--
.../web/templates/default/vandelay/inc/toolbar.tt2 | 2 +
.../web/templates/default/vandelay/inc/upload.tt2 | 63 +-
.../web/templates/default/vandelay/vandelay.tt2 | 5 +
.../xul/staff_client/chrome/content/main/menu.js | 4 +
.../chrome/content/main/menu_frame_menus.xul | 2 +
34 files changed, 5998 insertions(+), 865 deletions(-)
create mode 100644 Open-ILS/src/sql/Pg/upgrade/0572.schema.vandelay-record-matching-and-quality.sql
create mode 100644 Open-ILS/web/js/dojo/openils/vandelay/TreeDndSource.js
create mode 100644 Open-ILS/web/js/dojo/openils/vandelay/TreeStoreModel.js
create mode 100644 Open-ILS/web/js/dojo/openils/vandelay/nls/match_set.js
create mode 100644 Open-ILS/web/js/ui/default/conify/global/vandelay/match_set.js
create mode 100644 Open-ILS/web/templates/default/conify/global/vandelay/match_set.tt2
create mode 100644 Open-ILS/web/templates/default/conify/global/vandelay/match_set_tree.tt2
create mode 100644 Open-ILS/web/templates/default/vandelay/inc/import_errors.tt2
hooks/post-receive
--
Evergreen ILS
More information about the open-ils-commits
mailing list