<field name="copy_count" oils_persist:virtual="true" />
<field name="series" oils_persist:virtual="true" />
<field name="serials" oils_persist:virtual="true" />
+ <field name="foreign_copy_maps" oils_persist:virtual="true" />
</fields>
</class>
</permacrud>
</class>
+ <class id="bpt" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="biblio::peer_type" oils_persist:tablename="biblio.peer_type" reporter:label="Bibliographic Record Peer Type" oils_persist:field_safe="true">
+ <fields oils_persist:primary="id" oils_persist:sequence="biblio.peer_type_id_seq">
+ <field reporter:label="ID" name="id" reporter:selector="name" reporter:datatype="id"/>
+ <field reporter:label="Name" name="name" reporter:datatype="text" oils_persist:i18n="true"/>
+ </fields>
+ <links/>
+ <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
+ <actions>
+ <create permission="CREATE_BIB_PTYPE" global_required="true"/>
+ <retrieve/>
+ <update permission="UPDATE_BIB_PTYPE" global_required="true"/>
+ <delete permission="DELETE_BIB_PTYPE" global_required="true"/>
+ </actions>
+ </permacrud>
+ </class>
+
+ <class id="bpbcm" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="biblio::peer_bib_copy_map" oils_persist:tablename="biblio.peer_bib_copy_map" reporter:label="Bibliographic Record Peer Copy Map">
+ <fields oils_persist:primary="id" oils_persist:sequence="biblio.peer_bib_copy_map_id_seq">
+ <field reporter:label="ID" name="id" reporter:selector="name" reporter:datatype="id"/>
+ <field reporter:label="Peer Type" name="peer_type" reporter:datatype="link"/>
+ <field reporter:label="Peer Record" name="peer_record" reporter:datatype="link"/>
+ <field reporter:label="Target Copy" name="target_copy" reporter:datatype="link"/>
+ </fields>
+ <links>
+ <link field="peer_type" reltype="has_a" key="id" map="" class="bpt"/>
+ <link field="peer_record" reltype="has_a" key="id" map="" class="bre"/>
+ <link field="target_copy" reltype="has_a" key="id" map="" class="acp"/>
+ </links>
+ <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
+ <actions>
+ <create permission="UPDATE_COPY">
+ <context link="target_copy" field="circ_lib"/>
+ </create>
+ <retrieve/>
+ <update permission="UPDATE_COPY">
+ <context link="target_copy" field="circ_lib"/>
+ </update>
+ <delete permission="UPDATE_COPY">
+ <context link="target_copy" field="circ_lib"/>
+ </delete>
+ </actions>
+ </permacrud>
+ </class>
+
<class id="cbrebt" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="container::biblio_record_entry_bucket_type" oils_persist:tablename="container.biblio_record_entry_bucket_type" reporter:label="Bibliographic Record Bucket Type" oils_persist:field_safe="true">
<fields oils_persist:primary="code">
<field reporter:label="Code" name="code" reporter:selector="name" reporter:datatype="id"/>
<field reporter:label="Holds" name="holds" oils_persist:virtual="true" reporter:datatype="link"/>
<field reporter:label="Statistical Category Entries" name="stat_cat_entries" oils_persist:virtual="true" reporter:datatype="link"/>
<field reporter:label="Monograph Parts" name="parts" oils_persist:virtual="true" reporter:datatype="link"/>
+ <field reporter:label="Peer Record Maps" name="peer_record_maps" oils_persist:virtual="true" reporter:datatype="link"/>
+ <field reporter:label="Peer Records" name="peer_records" oils_persist:virtual="true" reporter:datatype="link"/>
</fields>
<links>
<link field="age_protect" reltype="has_a" key="id" map="" class="crahp"/>
<link field="total_circ_count" reltype="might_have" key="id" map="" class="erfcc"/>
<link field="circ_modifier" reltype="has_a" key="code" map="" class="ccm"/>
<link field="parts" reltype="has_many" key="target_copy" map="part" class="acpm"/>
+ <link field="peer_record_maps" reltype="has_many" key="target_copy" map="" class="bpbcm"/>
+ <link field="peer_records" reltype="has_many" key="target_copy" map="peer_record" class="bpbcm"/>
</links>
<permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
<actions>
{
flesh => 2,
flesh_fields => {
- acp => ['call_number','parts'],
+ acp => ['call_number','parts','peer_record_maps'],
acn => ['record','prefix','suffix','label_class']
}
}
flesh => 2,
flesh_fields => {
acp => [
- qw/ location status stat_cat_entry_copy_maps notes age_protect parts /
+ qw/ location status stat_cat_entry_copy_maps notes age_protect parts peer_record_maps /
],
ascecm => [qw/ stat_cat stat_cat_entry /],
}
api_name => 'open-ils.search.bib_id.by_barcode',
authoritative => 1,
signature => {
- desc => 'Retrieve copy object with fleshed record, given the barcode',
+ desc => 'Retrieve bib record id associated with the copy identified by the given barcode',
params => [
{ desc => 'Item barcode', type => 'string' }
],
return => {
- desc => 'Asset copy object with fleshed record and callnumber, or event on error or null set'
+ desc => 'Bib record id.'
}
}
);
+__PACKAGE__->register_method(
+ method => 'title_id_by_item_barcode',
+ api_name => 'open-ils.search.multi_home.bib_ids.by_barcode',
+ authoritative => 1,
+ signature => {
+ desc => 'Retrieve bib record ids associated with the copy identified by the given barcode. This includes peer bibs for Multi-Home items.',
+ params => [
+ { desc => 'Item barcode', type => 'string' }
+ ],
+ return => {
+ desc => 'Array of bib record ids. First element is the native bib for the item.'
+ }
+ }
+);
+
+
sub title_id_by_item_barcode {
my( $self, $conn, $barcode ) = @_;
my $e = new_editor();
);
return $e->event unless @$copies;
- return $$copies[0]->call_number->record->id;
+
+ if( $self->api_name =~ /multi_home/ ) {
+ my $multi_home_list = $e->search_biblio_peer_bib_copy_map(
+ [
+ { target_copy => $$copies[0]->id }
+ ]
+ );
+ my @temp = map { $_->peer_record } @{ $multi_home_list };
+ unshift @temp, $$copies[0]->call_number->record->id;
+ return \@temp;
+ } else {
+ return $$copies[0]->call_number->record->id;
+ }
}
+__PACKAGE__->register_method(
+ method => 'find_peer_bibs',
+ api_name => 'open-ils.search.peer_bibs.test',
+ authoritative => 1,
+ signature => {
+ desc => 'Tests to see if the specified record is a peer record.',
+ params => [
+ { desc => 'Biblio record entry Id', type => 'number' }
+ ],
+ return => {
+ desc => 'True if specified id can be found in biblio.peer_record_copy_map.peer_record.',
+ type => 'bool'
+ }
+ }
+);
+
+__PACKAGE__->register_method(
+ method => 'find_peer_bibs',
+ api_name => 'open-ils.search.peer_bibs',
+ authoritative => 1,
+ signature => {
+ desc => 'Return acps and mvrs for multi-home items linked to specified peer record.',
+ params => [
+ { desc => 'Biblio record entry Id', type => 'number' }
+ ],
+ return => {
+ desc => '{ records => Array of mvrs, items => array of acps }',
+ }
+ }
+);
+
+
+sub find_peer_bibs {
+ my( $self, $client, $doc_id ) = @_;
+ my $e = new_editor();
+
+ my $multi_home_list = $e->search_biblio_peer_bib_copy_map(
+ [
+ { peer_record => $doc_id },
+ {
+ flesh => 2,
+ flesh_fields => {
+ bpbcm => [ 'target_copy', 'peer_type' ],
+ acp => [ 'call_number', 'location', 'status', 'peer_record_maps' ]
+ }
+ }
+ ]
+ );
+
+ if ($self->api_name =~ /test/) {
+ return scalar( @{$multi_home_list} ) > 0 ? 1 : 0;
+ }
+
+ if (scalar(@{$multi_home_list})==0) {
+ return [];
+ }
+
+ # create a unique hash of the primary record MVRs for foreign copies
+ # XXX PLEASE let's change to unAPI2 (supports foreign copies) in the TT opac?!?
+ my %rec_hash = map {
+ ($_->target_copy->call_number->record, _records_to_mods( $_->target_copy->call_number->record )->[0])
+ } @$multi_home_list;
+
+ # set the foreign_copy_maps field to an empty array
+ map { $rec_hash{$_}->foreign_copy_maps([]) } keys( %rec_hash );
+
+ # push the maps onto the correct MVRs
+ for (@$multi_home_list) {
+ push(
+ @{$rec_hash{ $_->target_copy->call_number->record }->foreign_copy_maps()},
+ $_
+ );
+ }
+
+ return [sort {$a->title cmp $b->title} values(%rec_hash)];
+};
__PACKAGE__->register_method(
method => "biblio_copy_to_mods",
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
+package biblio::peer_type;
+use base qw/biblio/;
+
+biblio::peer_type->table( 'biblio_peer_type' );
+biblio::peer_type->columns( Essential => qw/id name/ );
+#-------------------------------------------------------------------------------
+
+#-------------------------------------------------------------------------------
+package biblio::peer_record_copy_map;
+use base qw/biblio/;
+
+biblio::peer_record_copy_map->table( 'biblio_peer_record_copy_map' );
+biblio::peer_record_copy_map->columns( Essential => qw/id peer_type peer_record target_copy/ );
+#-------------------------------------------------------------------------------
+
+#-------------------------------------------------------------------------------
package biblio::monograph_part;
use base qw/biblio/;
biblio::monograph_part->sequence( 'biblio.monograph_part_id_seq' );
#-------------------------------------------------------------------------------
+ package biblio::peer_record_copy_map;
+
+ biblio::peer_record_copy_map->table( 'biblio.peer_record_copy_map' );
+ biblio::peer_record_copy_map->sequence( 'biblio.peer_record_copy_map_id_seq' );
+
+ #-------------------------------------------------------------------------------
+ package biblio::peer_type;
+
+ biblio::peer_type->table( 'biblio.peer_type' );
+ biblio::peer_type->sequence( 'biblio.peer_type_id_seq' );
+
+ #-------------------------------------------------------------------------------
package container::user_bucket;
container::user_bucket->table( 'container.user_bucket' );
install_date TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
);
-INSERT INTO config.upgrade_log (version) VALUES ('0511'); -- miker
+INSERT INTO config.upgrade_log (version) VALUES ('0512'); -- miker
CREATE TABLE config.bib_source (
id SERIAL PRIMARY KEY,
CREATE INDEX biblio_record_note_creator_idx ON biblio.record_note ( creator );
CREATE INDEX biblio_record_note_editor_idx ON biblio.record_note ( editor );
+CREATE TABLE biblio.peer_type (
+ id SERIAL PRIMARY KEY,
+ name TEXT NOT NULL UNIQUE -- i18n
+);
+
+CREATE TABLE biblio.peer_bib_copy_map (
+ id SERIAL PRIMARY KEY,
+ peer_type INT NOT NULL REFERENCES biblio.peer_type (id),
+ peer_record BIGINT NOT NULL REFERENCES biblio.record_entry (id),
+ target_copy BIGINT NOT NULL -- can't use fkey because of acp subtables
+);
+CREATE INDEX peer_bib_copy_map_record_idx ON biblio.peer_bib_copy_map (peer_record);
+CREATE INDEX peer_bib_copy_map_copy_idx ON biblio.peer_bib_copy_map (target_copy);
+
CREATE TABLE biblio.monograph_part (
id SERIAL PRIMARY KEY,
record BIGINT NOT NULL REFERENCES biblio.record_entry (id),
DELETE FROM metabib.metarecord_source_map WHERE source = NEW.id; -- Rid ourselves of the search-estimate-killing linkage
DELETE FROM metabib.record_attr WHERE id = NEW.id; -- Kill the attrs hash, useless on deleted records
DELETE FROM authority.bib_linking WHERE bib = NEW.id; -- Avoid updating fields in bibs that are no longer visible
+ DELETE FROM biblio.peer_bib_copy_map WHERE peer_record = NEW.id; -- Separate any multi-homed items
RETURN NEW; -- and we're done
END IF;
CREATE UNIQUE INDEX copy_part_map_cp_part_idx ON asset.copy_part_map (target_copy, part);
CREATE TABLE asset.opac_visible_copies (
- id BIGINT primary key, -- copy id
+ id BIGSERIAL primary key,
+ copy_id BIGINT, -- copy id
record BIGINT,
circ_lib INTEGER
);
databases. Contents are maintained by a set of triggers.
$$;
CREATE INDEX opac_visible_copies_idx1 on asset.opac_visible_copies (record, circ_lib);
+CREATE INDEX opac_visible_copies_copy_id_idx on asset.opac_visible_copies (copy_id);
+CREATE UNIQUE INDEX opac_visible_copies_once_per_record_idx on asset.opac_visible_copies (copy_id, record);
CREATE OR REPLACE FUNCTION asset.acp_status_changed()
RETURNS TRIGGER AS $$
LIMIT 1;
IF NOT FOUND THEN
- -- RAISE NOTICE ' % were all status-excluded ... ', core_result.records;
- excluded_count := excluded_count + 1;
- CONTINUE;
+ PERFORM 1
+ FROM biblio.peer_bib_copy_map pr
+ JOIN asset.copy cp ON (cp.id = pr.target_copy)
+ WHERE NOT cp.deleted
+ AND cp.status IN ( SELECT * FROM search.explode_array( param_statuses ) )
+ AND pr.peer_record IN ( SELECT * FROM search.explode_array( core_result.records ) )
+ AND cp.circ_lib IN ( SELECT * FROM search.explode_array( search_org_list ) )
+ LIMIT 1;
+
+ IF NOT FOUND THEN
+ -- RAISE NOTICE ' % and multi-home linked records were all status-excluded ... ', core_result.records;
+ excluded_count := excluded_count + 1;
+ CONTINUE;
+ END IF;
END IF;
END IF;
LIMIT 1;
IF NOT FOUND THEN
- -- RAISE NOTICE ' % were all copy_location-excluded ... ', core_result.records;
- excluded_count := excluded_count + 1;
- CONTINUE;
+ PERFORM 1
+ FROM biblio.peer_bib_copy_map pr
+ JOIN asset.copy cp ON (cp.id = pr.target_copy)
+ WHERE NOT cp.deleted
+ AND cp.location IN ( SELECT * FROM search.explode_array( param_locations ) )
+ AND pr.peer_record IN ( SELECT * FROM search.explode_array( core_result.records ) )
+ AND cp.circ_lib IN ( SELECT * FROM search.explode_array( search_org_list ) )
+ LIMIT 1;
+
+ IF NOT FOUND THEN
+ -- RAISE NOTICE ' % and multi-home linked records were all copy_location-excluded ... ', core_result.records;
+ excluded_count := excluded_count + 1;
+ CONTINUE;
+ END IF;
END IF;
END IF;
LIMIT 1;
IF NOT FOUND THEN
- -- RAISE NOTICE ' % were all visibility-excluded ... ', core_result.records;
- excluded_count := excluded_count + 1;
- CONTINUE;
+ PERFORM 1
+ FROM biblio.peer_bib_copy_map pr
+ JOIN asset.opac_visible_copies cp ON (cp.copy_id = pr.target_copy)
+ WHERE cp.circ_lib IN ( SELECT * FROM search.explode_array( search_org_list ) )
+ AND pr.peer_record IN ( SELECT * FROM search.explode_array( core_result.records ) )
+ LIMIT 1;
+
+ IF NOT FOUND THEN
+
+ -- RAISE NOTICE ' % and multi-home linked records were all visibility-excluded ... ', core_result.records;
+ excluded_count := excluded_count + 1;
+ CONTINUE;
+ END IF;
END IF;
ELSE
PERFORM 1
FROM asset.call_number cn
JOIN asset.copy cp ON (cp.call_number = cn.id)
- JOIN actor.org_unit a ON (cp.circ_lib = a.id)
WHERE NOT cn.deleted
AND NOT cp.deleted
AND cp.circ_lib IN ( SELECT * FROM search.explode_array( search_org_list ) )
IF NOT FOUND THEN
PERFORM 1
- FROM asset.call_number cn
- WHERE cn.record IN ( SELECT * FROM search.explode_array( core_result.records ) )
+ FROM biblio.peer_bib_copy_map pr
+ JOIN asset.copy cp ON (cp.id = pr.target_copy)
+ WHERE NOT cp.deleted
+ AND cp.circ_lib IN ( SELECT * FROM search.explode_array( search_org_list ) )
+ AND pr.peer_record IN ( SELECT * FROM search.explode_array( core_result.records ) )
LIMIT 1;
- IF FOUND THEN
- -- RAISE NOTICE ' % were all visibility-excluded ... ', core_result.records;
- excluded_count := excluded_count + 1;
- CONTINUE;
+ IF NOT FOUND THEN
+
+ PERFORM 1
+ FROM asset.call_number cn
+ WHERE cn.record IN ( SELECT * FROM search.explode_array( core_result.records ) )
+ LIMIT 1;
+
+ IF FOUND THEN
+ -- RAISE NOTICE ' % and multi-home linked records were all visibility-excluded ... ', core_result.records;
+ excluded_count := excluded_count + 1;
+ CONTINUE;
+ END IF;
END IF;
END IF;
(3, 1, oils_i18n_gettext(3, 'Project Gutenberg', 'cbs', 'source'), TRUE);
SELECT SETVAL('config.bib_source_id_seq'::TEXT, 100);
+INSERT INTO biblio.peer_type (id,name) VALUES
+ (1,oils_i18n_gettext(1,'Bound Volume','bpt','name')),
+ (2,oils_i18n_gettext(2,'Bilingual','bpt','name')),
+ (3,oils_i18n_gettext(3,'Back-to-back','bpt','name')),
+ (4,oils_i18n_gettext(4,'Set','bpt','name')),
+ (5,oils_i18n_gettext(5,'e-Reader Preload','bpt','name'));
+SELECT SETVAL('biblio.peer_type_id_seq'::TEXT, 100);
+
INSERT INTO config.standing (id, value) VALUES (1, oils_i18n_gettext(1, 'Good', 'cst', 'value'));
INSERT INTO config.standing (id, value) VALUES (2, oils_i18n_gettext(2, 'Barred', 'cst', 'value'));
SELECT SETVAL('config.standing_id_seq'::TEXT, 100);
WHERE record_entry = $1
)x)
)
+ ELSE NULL END,
+ CASE WHEN ('acp' = ANY ($5)) THEN
+ XMLELEMENT(
+ name foreign_copies,
+ (SELECT XMLAGG(acp) FROM (
+ SELECT unapi.acp(p.target_copy,'xml','copy','{}'::TEXT[], $3, $4, $6, $7, FALSE)
+ FROM biblio.peer_bib_copy_map p
+ JOIN asset.copy c ON (p.target_copy = c.id)
+ WHERE NOT c.deleted AND peer_record = $1
+ )x)
+ )
ELSE NULL END
);
$F$ LANGUAGE SQL;
ELSE NULL
END
),
+ XMLELEMENT( name foreign_records,
+ CASE
+ WHEN ('bre' = ANY ($4)) THEN
+ XMLAGG((SELECT unapi.bre(peer_record,'marcxml','record','{}'::TEXT[], $5, $6, $7, $8, FALSE) FROM biblio.peer_bib_copy_map WHERE target_copy = cp.id))
+ ELSE NULL
+ END
+
+ ),
CASE
WHEN ('bmp' = ANY ($4)) THEN
XMLELEMENT( name monograph_parts,
TRUNCATE TABLE asset.opac_visible_copies;
- INSERT INTO asset.opac_visible_copies (id, circ_lib, record)
+ INSERT INTO asset.opac_visible_copies (copy_id, circ_lib, record)
SELECT cp.id, cp.circ_lib, cn.record
FROM asset.copy cp
JOIN asset.call_number cn ON (cn.id = cp.call_number)
AND cs.opac_visible
AND cl.opac_visible
AND cp.opac_visible
+ AND a.opac_visible
+ UNION
+ SELECT cp.id, cp.circ_lib, pbcm.peer_record AS record
+ FROM asset.copy cp
+ JOIN biblio.peer_bib_copy_map pbcm ON (pbcm.target_copy = cp.id)
+ JOIN actor.org_unit a ON (cp.circ_lib = a.id)
+ JOIN asset.copy_location cl ON (cp.location = cl.id)
+ JOIN config.copy_status cs ON (cp.status = cs.id)
+ WHERE NOT cp.deleted
+ AND cs.opac_visible
+ AND cl.opac_visible
+ AND cp.opac_visible
AND a.opac_visible;
$$ LANGUAGE SQL;
do_remove BOOLEAN := false;
BEGIN
add_query := $$
- INSERT INTO asset.opac_visible_copies (id, circ_lib, record)
- SELECT cp.id, cp.circ_lib, cn.record
+ INSERT INTO asset.opac_visible_copies (copy_id, circ_lib, record)
+ SELECT id, circ_lib, record FROM (
+ SELECT cp.id, cp.circ_lib, cn.record, cn.id AS call_number
FROM asset.copy cp
JOIN asset.call_number cn ON (cn.id = cp.call_number)
JOIN actor.org_unit a ON (cp.circ_lib = a.id)
AND cl.opac_visible
AND cp.opac_visible
AND a.opac_visible
+ UNION
+ SELECT cp.id, cp.circ_lib, pbcm.peer_record AS record, NULL AS call_number
+ FROM asset.copy cp
+ JOIN biblio.peer_bib_copy_map pbcm ON (pbcm.target_copy = cp.id)
+ JOIN actor.org_unit a ON (cp.circ_lib = a.id)
+ JOIN asset.copy_location cl ON (cp.location = cl.id)
+ JOIN config.copy_status cs ON (cp.status = cs.id)
+ WHERE NOT cp.deleted
+ AND cs.opac_visible
+ AND cl.opac_visible
+ AND cp.opac_visible
+ AND a.opac_visible
+ ) AS x
+
$$;
- remove_query := $$ DELETE FROM asset.opac_visible_copies WHERE id IN ( SELECT id FROM asset.copy WHERE $$;
+ remove_query := $$ DELETE FROM asset.opac_visible_copies WHERE copy_id IN ( SELECT id FROM asset.copy WHERE $$;
+
+ IF TG_TABLE_NAME = 'peer_bib_copy_map' THEN
+ IF TG_OP = 'INSERT' THEN
+ add_query := add_query || 'WHERE x.id = ' || NEW.target_copy || ' AND x.record = ' || NEW.peer_record || ';';
+ EXECUTE add_query;
+ RETURN NEW;
+ ELSE
+ remove_query := 'DELETE FROM asset.opac_visible_copies WHERE copy_id = ' || OLD.target_copy || ' AND record = ' || OLD.peer_record || ';';
+ EXECUTE remove_query;
+ RETURN OLD;
+ END IF;
+ END IF;
IF TG_OP = 'INSERT' THEN
IF TG_TABLE_NAME IN ('copy', 'unit') THEN
- add_query := add_query || 'AND cp.id = ' || NEW.id || ';';
+ add_query := add_query || 'WHERE x.id = ' || NEW.id || ';';
EXECUTE add_query;
END IF;
DELETE FROM asset.opac_visible_copies WHERE id = NEW.id;
END IF;
IF do_add THEN
- add_query := add_query || 'AND cp.id = ' || NEW.id || ';';
+ add_query := add_query || 'WHERE x.id = ' || NEW.id || ';';
EXECUTE add_query;
END IF;
ELSIF OLD.deleted THEN -- add rows
IF TG_TABLE_NAME IN ('copy','unit') THEN
- add_query := add_query || 'AND cp.id = ' || NEW.id || ';';
+ add_query := add_query || 'WHERE x.id = ' || NEW.id || ';';
ELSIF TG_TABLE_NAME = 'call_number' THEN
- add_query := add_query || 'AND cp.call_number = ' || NEW.id || ';';
+ add_query := add_query || 'WHERE x.call_number = ' || NEW.id || ';';
ELSIF TG_TABLE_NAME = 'record_entry' THEN
- add_query := add_query || 'AND cn.record = ' || NEW.id || ';';
+ add_query := add_query || 'WHERE x.record = ' || NEW.id || ';';
END IF;
EXECUTE add_query;
-- call number is linked to different bib
remove_query := remove_query || 'call_number = ' || NEW.id || ');';
EXECUTE remove_query;
- add_query := add_query || 'AND cp.call_number = ' || NEW.id || ';';
+ add_query := add_query || 'WHERE x.call_number = ' || NEW.id || ';';
EXECUTE add_query;
END IF;
COMMENT ON FUNCTION asset.cache_copy_visibility() IS $$
Trigger function to update the copy OPAC visiblity cache.
$$;
+CREATE TRIGGER a_opac_vis_mat_view_tgr AFTER INSERT OR DELETE ON biblio.peer_bib_copy_map FOR EACH ROW EXECUTE PROCEDURE asset.cache_copy_visibility();
CREATE TRIGGER a_opac_vis_mat_view_tgr AFTER INSERT OR UPDATE ON biblio.record_entry FOR EACH ROW EXECUTE PROCEDURE asset.cache_copy_visibility();
CREATE TRIGGER a_opac_vis_mat_view_tgr AFTER INSERT OR UPDATE ON asset.copy FOR EACH ROW EXECUTE PROCEDURE asset.cache_copy_visibility();
CREATE TRIGGER a_opac_vis_mat_view_tgr AFTER INSERT OR UPDATE ON asset.call_number FOR EACH ROW EXECUTE PROCEDURE asset.cache_copy_visibility();
--- /dev/null
+BEGIN;
+
+INSERT INTO config.upgrade_log (version) VALUES ('0512'); -- miker
+
+CREATE TABLE biblio.peer_type (
+ id SERIAL PRIMARY KEY,
+ name TEXT NOT NULL UNIQUE -- i18n
+);
+
+CREATE TABLE biblio.peer_bib_copy_map (
+ id SERIAL PRIMARY KEY,
+ peer_type INT NOT NULL REFERENCES biblio.peer_type (id),
+ peer_record BIGINT NOT NULL REFERENCES biblio.record_entry (id),
+ target_copy BIGINT NOT NULL -- can't use fkey because of acp subtables
+);
+CREATE INDEX peer_bib_copy_map_record_idx ON biblio.peer_bib_copy_map (peer_record);
+CREATE INDEX peer_bib_copy_map_copy_idx ON biblio.peer_bib_copy_map (target_copy);
+
+DROP TABLE asset.opac_visible_copies;
+CREATE TABLE asset.opac_visible_copies (
+ id BIGSERIAL primary key,
+ copy_id BIGINT,
+ record BIGINT,
+ circ_lib INTEGER
+);
+
+INSERT INTO biblio.peer_type (id,name) VALUES
+ (1,oils_i18n_gettext(1,'Bound Volume','bpt','name')),
+ (2,oils_i18n_gettext(2,'Bilingual','bpt','name')),
+ (3,oils_i18n_gettext(3,'Back-to-back','bpt','name')),
+ (4,oils_i18n_gettext(4,'Set','bpt','name')),
+ (5,oils_i18n_gettext(5,'e-Reader Preload','bpt','name'));
+
+SELECT SETVAL('biblio.peer_type_id_seq'::TEXT, 100);
+
+CREATE OR REPLACE FUNCTION search.query_parser_fts (
+
+ param_search_ou INT,
+ param_depth INT,
+ param_query TEXT,
+ param_statuses INT[],
+ param_locations INT[],
+ param_offset INT,
+ param_check INT,
+ param_limit INT,
+ metarecord BOOL,
+ staff BOOL
+
+) RETURNS SETOF search.search_result AS $func$
+DECLARE
+
+ current_res search.search_result%ROWTYPE;
+ search_org_list INT[];
+
+ check_limit INT;
+ core_limit INT;
+ core_offset INT;
+ tmp_int INT;
+
+ core_result RECORD;
+ core_cursor REFCURSOR;
+ core_rel_query TEXT;
+
+ total_count INT := 0;
+ check_count INT := 0;
+ deleted_count INT := 0;
+ visible_count INT := 0;
+ excluded_count INT := 0;
+
+BEGIN
+
+ check_limit := COALESCE( param_check, 1000 );
+ core_limit := COALESCE( param_limit, 25000 );
+ core_offset := COALESCE( param_offset, 0 );
+
+ -- core_skip_chk := COALESCE( param_skip_chk, 1 );
+
+ IF param_search_ou > 0 THEN
+ IF param_depth IS NOT NULL THEN
+ SELECT array_accum(distinct id) INTO search_org_list FROM actor.org_unit_descendants( param_search_ou, param_depth );
+ ELSE
+ SELECT array_accum(distinct id) INTO search_org_list FROM actor.org_unit_descendants( param_search_ou );
+ END IF;
+ ELSIF param_search_ou < 0 THEN
+ SELECT array_accum(distinct org_unit) INTO search_org_list FROM actor.org_lasso_map WHERE lasso = -param_search_ou;
+ ELSIF param_search_ou = 0 THEN
+ -- reserved for user lassos (ou_buckets/type='lasso') with ID passed in depth ... hack? sure.
+ END IF;
+
+ OPEN core_cursor FOR EXECUTE param_query;
+
+ LOOP
+
+ FETCH core_cursor INTO core_result;
+ EXIT WHEN NOT FOUND;
+ EXIT WHEN total_count >= core_limit;
+
+ total_count := total_count + 1;
+
+ CONTINUE WHEN total_count NOT BETWEEN core_offset + 1 AND check_limit + core_offset;
+
+ check_count := check_count + 1;
+
+ PERFORM 1 FROM biblio.record_entry b WHERE NOT b.deleted AND b.id IN ( SELECT * FROM search.explode_array( core_result.records ) );
+ IF NOT FOUND THEN
+ -- RAISE NOTICE ' % were all deleted ... ', core_result.records;
+ deleted_count := deleted_count + 1;
+ CONTINUE;
+ END IF;
+
+ PERFORM 1
+ FROM biblio.record_entry b
+ JOIN config.bib_source s ON (b.source = s.id)
+ WHERE s.transcendant
+ AND b.id IN ( SELECT * FROM search.explode_array( core_result.records ) );
+
+ IF FOUND THEN
+ -- RAISE NOTICE ' % were all transcendant ... ', core_result.records;
+ visible_count := visible_count + 1;
+
+ current_res.id = core_result.id;
+ current_res.rel = core_result.rel;
+
+ tmp_int := 1;
+ IF metarecord THEN
+ SELECT COUNT(DISTINCT s.source) INTO tmp_int FROM metabib.metarecord_source_map s WHERE s.metarecord = core_result.id;
+ END IF;
+
+ IF tmp_int = 1 THEN
+ current_res.record = core_result.records[1];
+ ELSE
+ current_res.record = NULL;
+ END IF;
+
+ RETURN NEXT current_res;
+
+ CONTINUE;
+ END IF;
+
+ PERFORM 1
+ FROM asset.call_number cn
+ JOIN asset.uri_call_number_map map ON (map.call_number = cn.id)
+ JOIN asset.uri uri ON (map.uri = uri.id)
+ WHERE NOT cn.deleted
+ AND cn.label = '##URI##'
+ AND uri.active
+ AND ( param_locations IS NULL OR array_upper(param_locations, 1) IS NULL )
+ AND cn.record IN ( SELECT * FROM search.explode_array( core_result.records ) )
+ AND cn.owning_lib IN ( SELECT * FROM search.explode_array( search_org_list ) )
+ LIMIT 1;
+
+ IF FOUND THEN
+ -- RAISE NOTICE ' % have at least one URI ... ', core_result.records;
+ visible_count := visible_count + 1;
+
+ current_res.id = core_result.id;
+ current_res.rel = core_result.rel;
+
+ tmp_int := 1;
+ IF metarecord THEN
+ SELECT COUNT(DISTINCT s.source) INTO tmp_int FROM metabib.metarecord_source_map s WHERE s.metarecord = core_result.id;
+ END IF;
+
+ IF tmp_int = 1 THEN
+ current_res.record = core_result.records[1];
+ ELSE
+ current_res.record = NULL;
+ END IF;
+
+ RETURN NEXT current_res;
+
+ CONTINUE;
+ END IF;
+
+ IF param_statuses IS NOT NULL AND array_upper(param_statuses, 1) > 0 THEN
+
+ PERFORM 1
+ FROM asset.call_number cn
+ JOIN asset.copy cp ON (cp.call_number = cn.id)
+ WHERE NOT cn.deleted
+ AND NOT cp.deleted
+ AND cp.status IN ( SELECT * FROM search.explode_array( param_statuses ) )
+ AND cn.record IN ( SELECT * FROM search.explode_array( core_result.records ) )
+ AND cp.circ_lib IN ( SELECT * FROM search.explode_array( search_org_list ) )
+ LIMIT 1;
+
+ IF NOT FOUND THEN
+ PERFORM 1
+ FROM biblio.peer_bib_copy_map pr
+ JOIN asset.copy cp ON (cp.id = pr.target_copy)
+ WHERE NOT cp.deleted
+ AND cp.status IN ( SELECT * FROM search.explode_array( param_statuses ) )
+ AND pr.peer_record IN ( SELECT * FROM search.explode_array( core_result.records ) )
+ AND cp.circ_lib IN ( SELECT * FROM search.explode_array( search_org_list ) )
+ LIMIT 1;
+
+ IF NOT FOUND THEN
+ -- RAISE NOTICE ' % and multi-home linked records were all status-excluded ... ', core_result.records;
+ excluded_count := excluded_count + 1;
+ CONTINUE;
+ END IF;
+ END IF;
+
+ END IF;
+
+ IF param_locations IS NOT NULL AND array_upper(param_locations, 1) > 0 THEN
+
+ PERFORM 1
+ FROM asset.call_number cn
+ JOIN asset.copy cp ON (cp.call_number = cn.id)
+ WHERE NOT cn.deleted
+ AND NOT cp.deleted
+ AND cp.location IN ( SELECT * FROM search.explode_array( param_locations ) )
+ AND cn.record IN ( SELECT * FROM search.explode_array( core_result.records ) )
+ AND cp.circ_lib IN ( SELECT * FROM search.explode_array( search_org_list ) )
+ LIMIT 1;
+
+ IF NOT FOUND THEN
+ PERFORM 1
+ FROM biblio.peer_bib_copy_map pr
+ JOIN asset.copy cp ON (cp.id = pr.target_copy)
+ WHERE NOT cp.deleted
+ AND cp.location IN ( SELECT * FROM search.explode_array( param_locations ) )
+ AND pr.peer_record IN ( SELECT * FROM search.explode_array( core_result.records ) )
+ AND cp.circ_lib IN ( SELECT * FROM search.explode_array( search_org_list ) )
+ LIMIT 1;
+
+ IF NOT FOUND THEN
+ -- RAISE NOTICE ' % and multi-home linked records were all copy_location-excluded ... ', core_result.records;
+ excluded_count := excluded_count + 1;
+ CONTINUE;
+ END IF;
+ END IF;
+
+ END IF;
+
+ IF staff IS NULL OR NOT staff THEN
+
+ PERFORM 1
+ FROM asset.opac_visible_copies
+ WHERE circ_lib IN ( SELECT * FROM search.explode_array( search_org_list ) )
+ AND record IN ( SELECT * FROM search.explode_array( core_result.records ) )
+ LIMIT 1;
+
+ IF NOT FOUND THEN
+ PERFORM 1
+ FROM biblio.peer_bib_copy_map pr
+ JOIN asset.opac_visible_copies cp ON (cp.copy_id = pr.target_copy)
+ WHERE cp.circ_lib IN ( SELECT * FROM search.explode_array( search_org_list ) )
+ AND pr.peer_record IN ( SELECT * FROM search.explode_array( core_result.records ) )
+ LIMIT 1;
+
+ IF NOT FOUND THEN
+
+ -- RAISE NOTICE ' % and multi-home linked records were all visibility-excluded ... ', core_result.records;
+ excluded_count := excluded_count + 1;
+ CONTINUE;
+ END IF;
+ END IF;
+
+ ELSE
+
+ PERFORM 1
+ FROM asset.call_number cn
+ JOIN asset.copy cp ON (cp.call_number = cn.id)
+ WHERE NOT cn.deleted
+ AND NOT cp.deleted
+ AND cp.circ_lib IN ( SELECT * FROM search.explode_array( search_org_list ) )
+ AND cn.record IN ( SELECT * FROM search.explode_array( core_result.records ) )
+ LIMIT 1;
+
+ IF NOT FOUND THEN
+
+ PERFORM 1
+ FROM biblio.peer_bib_copy_map pr
+ JOIN asset.copy cp ON (cp.id = pr.target_copy)
+ WHERE NOT cp.deleted
+ AND cp.circ_lib IN ( SELECT * FROM search.explode_array( search_org_list ) )
+ AND pr.peer_record IN ( SELECT * FROM search.explode_array( core_result.records ) )
+ LIMIT 1;
+
+ IF NOT FOUND THEN
+
+ PERFORM 1
+ FROM asset.call_number cn
+ WHERE cn.record IN ( SELECT * FROM search.explode_array( core_result.records ) )
+ LIMIT 1;
+
+ IF FOUND THEN
+ -- RAISE NOTICE ' % and multi-home linked records were all visibility-excluded ... ', core_result.records;
+ excluded_count := excluded_count + 1;
+ CONTINUE;
+ END IF;
+ END IF;
+
+ END IF;
+
+ END IF;
+
+ visible_count := visible_count + 1;
+
+ current_res.id = core_result.id;
+ current_res.rel = core_result.rel;
+
+ tmp_int := 1;
+ IF metarecord THEN
+ SELECT COUNT(DISTINCT s.source) INTO tmp_int FROM metabib.metarecord_source_map s WHERE s.metarecord = core_result.id;
+ END IF;
+
+ IF tmp_int = 1 THEN
+ current_res.record = core_result.records[1];
+ ELSE
+ current_res.record = NULL;
+ END IF;
+
+ RETURN NEXT current_res;
+
+ IF visible_count % 1000 = 0 THEN
+ -- RAISE NOTICE ' % visible so far ... ', visible_count;
+ END IF;
+
+ END LOOP;
+
+ current_res.id = NULL;
+ current_res.rel = NULL;
+ current_res.record = NULL;
+ current_res.total = total_count;
+ current_res.checked = check_count;
+ current_res.deleted = deleted_count;
+ current_res.visible = visible_count;
+ current_res.excluded = excluded_count;
+
+ CLOSE core_cursor;
+
+ RETURN NEXT current_res;
+
+END;
+$func$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION unapi.holdings_xml (bid BIGINT, ouid INT, org TEXT, depth INT DEFAULT NULL, includes TEXT[] DEFAULT NULL::TEXT[], slimit INT DEFAULT NULL, soffset INT DEFAULT NULL, include_xmlns BOOL DEFAULT TRUE) RETURNS XML AS $F$
+ SELECT XMLELEMENT(
+ name holdings,
+ XMLATTRIBUTES(
+ CASE WHEN $8 THEN 'http://open-ils.org/spec/holdings/v1' ELSE NULL END AS xmlns,
+ CASE WHEN ('bre' = ANY ('{acn,auri}'::TEXT[] || $5)) THEN 'tag:open-ils.org:U2@bre/' || $1 || '/' || $3 ELSE NULL END AS id
+ ),
+ XMLELEMENT(
+ name counts,
+ (SELECT XMLAGG(XMLELEMENT::XML) FROM (
+ SELECT XMLELEMENT(
+ name count,
+ XMLATTRIBUTES('public' as type, depth, org_unit, coalesce(transcendant,0) as transcendant, available, visible as count, unshadow)
+ )::text
+ FROM asset.opac_ou_record_copy_count($2, $1)
+ UNION
+ SELECT XMLELEMENT(
+ name count,
+ XMLATTRIBUTES('staff' as type, depth, org_unit, coalesce(transcendant,0) as transcendant, available, visible as count, unshadow)
+ )::text
+ FROM asset.staff_ou_record_copy_count($2, $1)
+ ORDER BY 1
+ )x)
+ ),
+ CASE
+ WHEN ('bmp' = ANY ($5)) THEN
+ XMLELEMENT( name monograph_parts,
+ XMLAGG((SELECT unapi.bmp( id, 'xml', 'monograph_part', evergreen.array_remove_item_by_value( evergreen.array_remove_item_by_value($5,'bre'), 'holdings_xml'), $3, $4, $6, $7, FALSE) FROM biblio.monograph_part WHERE record = $1))
+ )
+ ELSE NULL
+ END,
+ CASE WHEN ('acn' = ANY ('{acn,auri}'::TEXT[] || $5)) THEN
+ XMLELEMENT(
+ name volumes,
+ (SELECT XMLAGG(acn) FROM (
+ SELECT unapi.acn(acn.id,'xml','volume',evergreen.array_remove_item_by_value(evergreen.array_remove_item_by_value('{acn,auri}'::TEXT[] || $5,'holdings_xml'),'bre'), $3, $4, $6, $7, FALSE)
+ FROM asset.call_number acn
+ WHERE acn.record = $1
+ AND EXISTS (
+ SELECT 1
+ FROM asset.copy acp
+ JOIN actor.org_unit_descendants(
+ $2,
+ (COALESCE(
+ $4,
+ (SELECT aout.depth
+ FROM actor.org_unit_type aout
+ JOIN actor.org_unit aou ON (aou.ou_type = aout.id AND aou.id = $2)
+ )
+ ))
+ ) aoud ON (acp.circ_lib = aoud.id)
+ LIMIT 1
+ )
+ ORDER BY label_sortkey
+ LIMIT $6
+ OFFSET $7
+ )x)
+ )
+ ELSE NULL END,
+ CASE WHEN ('ssub' = ANY ('{acn,auri}'::TEXT[] || $5)) THEN
+ XMLELEMENT(
+ name subscriptions,
+ (SELECT XMLAGG(ssub) FROM (
+ SELECT unapi.ssub(id,'xml','subscription','{}'::TEXT[], $3, $4, $6, $7, FALSE)
+ FROM serial.subscription
+ WHERE record_entry = $1
+ )x)
+ )
+ ELSE NULL END,
+ CASE WHEN ('acp' = ANY ($5)) THEN
+ XMLELEMENT(
+ name foreign_copies,
+ (SELECT XMLAGG(acp) FROM (
+ SELECT unapi.acp(p.target_copy,'xml','copy','{}'::TEXT[], $3, $4, $6, $7, FALSE)
+ FROM biblio.peer_bib_copy_map p
+ JOIN asset.copy c ON (p.target_copy = c.id)
+ WHERE NOT c.deleted AND peer_record = $1
+ )x)
+ )
+ ELSE NULL END
+ );
+$F$ LANGUAGE SQL;
+
+CREATE OR REPLACE FUNCTION unapi.acp ( obj_id BIGINT, format TEXT, ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL, include_xmlns BOOL DEFAULT TRUE ) RETURNS XML AS $F$
+ SELECT XMLELEMENT(
+ name copy,
+ XMLATTRIBUTES(
+ CASE WHEN $9 THEN 'http://open-ils.org/spec/holdings/v1' ELSE NULL END AS xmlns,
+ 'tag:open-ils.org:U2@acp/' || id AS id,
+ create_date, edit_date, copy_number, circulate, deposit,
+ ref, holdable, deleted, deposit_amount, price, barcode,
+ circ_modifier, circ_as_type, opac_visible
+ ),
+ unapi.ccs( status, $2, 'status', evergreen.array_remove_item_by_value($4,'acp'), $5, $6, $7, $8, FALSE),
+ unapi.acl( location, $2, 'location', evergreen.array_remove_item_by_value($4,'acp'), $5, $6, $7, $8, FALSE),
+ unapi.aou( circ_lib, $2, 'circ_lib', evergreen.array_remove_item_by_value($4,'acp'), $5, $6, $7, $8),
+ unapi.aou( circ_lib, $2, 'circlib', evergreen.array_remove_item_by_value($4,'acp'), $5, $6, $7, $8),
+ CASE WHEN ('acn' = ANY ($4)) THEN unapi.acn( call_number, $2, 'call_number', evergreen.array_remove_item_by_value($4,'acp'), $5, $6, $7, $8, FALSE) ELSE NULL END,
+ XMLELEMENT( name copy_notes,
+ CASE
+ WHEN ('acpn' = ANY ($4)) THEN
+ XMLAGG((SELECT unapi.acpn( id, 'xml', 'copy_note', evergreen.array_remove_item_by_value($4,'acp'), $5, $6, $7, $8, FALSE) FROM asset.copy_note WHERE owning_copy = cp.id AND pub))
+ ELSE NULL
+ END
+ ),
+ XMLELEMENT( name statcats,
+ CASE
+ WHEN ('ascecm' = ANY ($4)) THEN
+ XMLAGG((SELECT unapi.ascecm( stat_cat_entry, 'xml', 'statcat', evergreen.array_remove_item_by_value($4,'acp'), $5, $6, $7, $8, FALSE) FROM asset.stat_cat_entry_copy_map WHERE owning_copy = cp.id))
+ ELSE NULL
+ END
+ ),
+ XMLELEMENT( name foreign_records,
+ CASE
+ WHEN ('bre' = ANY ($4)) THEN
+ XMLAGG((SELECT unapi.bre(peer_record,'marcxml','record','{}'::TEXT[], $5, $6, $7, $8, FALSE) FROM biblio.peer_bib_copy_map WHERE target_copy = cp.id))
+ ELSE NULL
+ END
+
+ ),
+ CASE
+ WHEN ('bmp' = ANY ($4)) THEN
+ XMLELEMENT( name monograph_parts,
+ XMLAGG((SELECT unapi.bmp( part, 'xml', 'monograph_part', evergreen.array_remove_item_by_value($4,'acp'), $5, $6, $7, $8, FALSE) FROM asset.copy_part_map WHERE target_copy = cp.id))
+ )
+ ELSE NULL
+ END
+ )
+ FROM asset.copy cp
+ WHERE id = $1
+ GROUP BY id, status, location, circ_lib, call_number, create_date, edit_date, copy_number, circulate, deposit, ref, holdable, deleted, deposit_amount, price, barcode, circ_modifier, circ_as_type, opac_visible;
+$F$ LANGUAGE SQL;
+
+CREATE OR REPLACE FUNCTION asset.refresh_opac_visible_copies_mat_view () RETURNS VOID AS $$
+
+ TRUNCATE TABLE asset.opac_visible_copies;
+
+ INSERT INTO asset.opac_visible_copies (copy_id, circ_lib, record)
+ SELECT cp.id, cp.circ_lib, cn.record
+ FROM asset.copy cp
+ JOIN asset.call_number cn ON (cn.id = cp.call_number)
+ JOIN actor.org_unit a ON (cp.circ_lib = a.id)
+ JOIN asset.copy_location cl ON (cp.location = cl.id)
+ JOIN config.copy_status cs ON (cp.status = cs.id)
+ JOIN biblio.record_entry b ON (cn.record = b.id)
+ WHERE NOT cp.deleted
+ AND NOT cn.deleted
+ AND NOT b.deleted
+ AND cs.opac_visible
+ AND cl.opac_visible
+ AND cp.opac_visible
+ AND a.opac_visible
+ UNION
+ SELECT cp.id, cp.circ_lib, pbcm.peer_record AS record
+ FROM asset.copy cp
+ JOIN biblio.peer_bib_copy_map pbcm ON (pbcm.target_copy = cp.id)
+ JOIN actor.org_unit a ON (cp.circ_lib = a.id)
+ JOIN asset.copy_location cl ON (cp.location = cl.id)
+ JOIN config.copy_status cs ON (cp.status = cs.id)
+ WHERE NOT cp.deleted
+ AND cs.opac_visible
+ AND cl.opac_visible
+ AND cp.opac_visible
+ AND a.opac_visible;
+
+$$ LANGUAGE SQL;
+COMMENT ON FUNCTION asset.refresh_opac_visible_copies_mat_view() IS $$
+Rebuild the copy OPAC visibility cache. Useful during migrations.
+$$;
+
+SELECT asset.refresh_opac_visible_copies_mat_view();
+CREATE INDEX opac_visible_copies_idx1 on asset.opac_visible_copies (record, circ_lib);
+CREATE INDEX opac_visible_copies_copy_id_idx on asset.opac_visible_copies (copy_id);
+CREATE UNIQUE INDEX opac_visible_copies_once_per_record_idx on asset.opac_visible_copies (copy_id, record);
+
+CREATE OR REPLACE FUNCTION asset.cache_copy_visibility () RETURNS TRIGGER as $func$
+DECLARE
+ add_query TEXT;
+ remove_query TEXT;
+ do_add BOOLEAN := false;
+ do_remove BOOLEAN := false;
+BEGIN
+ add_query := $$
+ INSERT INTO asset.opac_visible_copies (copy_id, circ_lib, record)
+ SELECT id, circ_lib, record FROM (
+ SELECT cp.id, cp.circ_lib, cn.record, cn.id AS call_number
+ FROM asset.copy cp
+ JOIN asset.call_number cn ON (cn.id = cp.call_number)
+ JOIN actor.org_unit a ON (cp.circ_lib = a.id)
+ JOIN asset.copy_location cl ON (cp.location = cl.id)
+ JOIN config.copy_status cs ON (cp.status = cs.id)
+ JOIN biblio.record_entry b ON (cn.record = b.id)
+ WHERE NOT cp.deleted
+ AND NOT cn.deleted
+ AND NOT b.deleted
+ AND cs.opac_visible
+ AND cl.opac_visible
+ AND cp.opac_visible
+ AND a.opac_visible
+ UNION
+ SELECT cp.id, cp.circ_lib, pbcm.peer_record AS record, NULL AS call_number
+ FROM asset.copy cp
+ JOIN biblio.peer_bib_copy_map pbcm ON (pbcm.target_copy = cp.id)
+ JOIN actor.org_unit a ON (cp.circ_lib = a.id)
+ JOIN asset.copy_location cl ON (cp.location = cl.id)
+ JOIN config.copy_status cs ON (cp.status = cs.id)
+ WHERE NOT cp.deleted
+ AND cs.opac_visible
+ AND cl.opac_visible
+ AND cp.opac_visible
+ AND a.opac_visible
+ ) AS x
+
+ $$;
+
+ remove_query := $$ DELETE FROM asset.opac_visible_copies WHERE copy_id IN ( SELECT id FROM asset.copy WHERE $$;
+
+ IF TG_TABLE_NAME = 'peer_bib_copy_map' THEN
+ IF TG_OP = 'INSERT' THEN
+ add_query := add_query || 'WHERE x.id = ' || NEW.target_copy || ' AND x.record = ' || NEW.peer_record || ';';
+ EXECUTE add_query;
+ RETURN NEW;
+ ELSE
+ remove_query := 'DELETE FROM asset.opac_visible_copies WHERE copy_id = ' || OLD.target_copy || ' AND record = ' || OLD.peer_record || ';';
+ EXECUTE remove_query;
+ RETURN OLD;
+ END IF;
+ END IF;
+
+ IF TG_OP = 'INSERT' THEN
+
+ IF TG_TABLE_NAME IN ('copy', 'unit') THEN
+ add_query := add_query || 'WHERE x.id = ' || NEW.id || ';';
+ EXECUTE add_query;
+ END IF;
+
+ RETURN NEW;
+
+ END IF;
+
+ -- handle items first, since with circulation activity
+ -- their statuses change frequently
+ IF TG_TABLE_NAME IN ('copy', 'unit') THEN
+
+ IF OLD.location <> NEW.location OR
+ OLD.call_number <> NEW.call_number OR
+ OLD.status <> NEW.status OR
+ OLD.circ_lib <> NEW.circ_lib THEN
+ -- any of these could change visibility, but
+ -- we'll save some queries and not try to calculate
+ -- the change directly
+ do_remove := true;
+ do_add := true;
+ ELSE
+
+ IF OLD.deleted <> NEW.deleted THEN
+ IF NEW.deleted THEN
+ do_remove := true;
+ ELSE
+ do_add := true;
+ END IF;
+ END IF;
+
+ IF OLD.opac_visible <> NEW.opac_visible THEN
+ IF OLD.opac_visible THEN
+ do_remove := true;
+ ELSIF NOT do_remove THEN -- handle edge case where deleted item
+ -- is also marked opac_visible
+ do_add := true;
+ END IF;
+ END IF;
+
+ END IF;
+
+ IF do_remove THEN
+ DELETE FROM asset.opac_visible_copies WHERE id = NEW.id;
+ END IF;
+ IF do_add THEN
+ add_query := add_query || 'WHERE x.id = ' || NEW.id || ';';
+ EXECUTE add_query;
+ END IF;
+
+ RETURN NEW;
+
+ END IF;
+
+ IF TG_TABLE_NAME IN ('call_number', 'record_entry') THEN -- these have a 'deleted' column
+
+ IF OLD.deleted AND NEW.deleted THEN -- do nothing
+
+ RETURN NEW;
+
+ ELSIF NEW.deleted THEN -- remove rows
+
+ IF TG_TABLE_NAME = 'call_number' THEN
+ DELETE FROM asset.opac_visible_copies WHERE id IN (SELECT id FROM asset.copy WHERE call_number = NEW.id);
+ ELSIF TG_TABLE_NAME = 'record_entry' THEN
+ DELETE FROM asset.opac_visible_copies WHERE record = NEW.id;
+ END IF;
+
+ RETURN NEW;
+
+ ELSIF OLD.deleted THEN -- add rows
+
+ IF TG_TABLE_NAME IN ('copy','unit') THEN
+ add_query := add_query || 'WHERE x.id = ' || NEW.id || ';';
+ ELSIF TG_TABLE_NAME = 'call_number' THEN
+ add_query := add_query || 'WHERE x.call_number = ' || NEW.id || ';';
+ ELSIF TG_TABLE_NAME = 'record_entry' THEN
+ add_query := add_query || 'WHERE x.record = ' || NEW.id || ';';
+ END IF;
+
+ EXECUTE add_query;
+ RETURN NEW;
+
+ END IF;
+
+ END IF;
+
+ IF TG_TABLE_NAME = 'call_number' THEN
+
+ IF OLD.record <> NEW.record THEN
+ -- call number is linked to different bib
+ remove_query := remove_query || 'call_number = ' || NEW.id || ');';
+ EXECUTE remove_query;
+ add_query := add_query || 'WHERE x.call_number = ' || NEW.id || ';';
+ EXECUTE add_query;
+ END IF;
+
+ RETURN NEW;
+
+ END IF;
+
+ IF TG_TABLE_NAME IN ('record_entry') THEN
+ RETURN NEW; -- don't have 'opac_visible'
+ END IF;
+
+ -- actor.org_unit, asset.copy_location, asset.copy_status
+ IF NEW.opac_visible = OLD.opac_visible THEN -- do nothing
+
+ RETURN NEW;
+
+ ELSIF NEW.opac_visible THEN -- add rows
+
+ IF TG_TABLE_NAME = 'org_unit' THEN
+ add_query := add_query || 'AND cp.circ_lib = ' || NEW.id || ';';
+ ELSIF TG_TABLE_NAME = 'copy_location' THEN
+ add_query := add_query || 'AND cp.location = ' || NEW.id || ';';
+ ELSIF TG_TABLE_NAME = 'copy_status' THEN
+ add_query := add_query || 'AND cp.status = ' || NEW.id || ';';
+ END IF;
+
+ EXECUTE add_query;
+
+ ELSE -- delete rows
+
+ IF TG_TABLE_NAME = 'org_unit' THEN
+ remove_query := 'DELETE FROM asset.opac_visible_copies WHERE circ_lib = ' || NEW.id || ';';
+ ELSIF TG_TABLE_NAME = 'copy_location' THEN
+ remove_query := remove_query || 'location = ' || NEW.id || ');';
+ ELSIF TG_TABLE_NAME = 'copy_status' THEN
+ remove_query := remove_query || 'status = ' || NEW.id || ');';
+ END IF;
+
+ EXECUTE remove_query;
+
+ END IF;
+
+ RETURN NEW;
+END;
+$func$ LANGUAGE PLPGSQL;
+COMMENT ON FUNCTION asset.cache_copy_visibility() IS $$
+Trigger function to update the copy OPAC visiblity cache.
+$$;
+
+CREATE TRIGGER a_opac_vis_mat_view_tgr AFTER INSERT OR DELETE ON biblio.peer_bib_copy_map FOR EACH ROW EXECUTE PROCEDURE asset.cache_copy_visibility();
+
+CREATE OR REPLACE FUNCTION biblio.indexing_ingest_or_delete () RETURNS TRIGGER AS $func$
+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
+
+ IF NEW.deleted IS TRUE THEN -- If this bib is deleted
+ DELETE FROM metabib.metarecord_source_map WHERE source = NEW.id; -- Rid ourselves of the search-estimate-killing linkage
+ DELETE FROM metabib.record_attr WHERE id = NEW.id; -- Kill the attrs hash, useless on deleted records
+ DELETE FROM authority.bib_linking WHERE bib = NEW.id; -- Avoid updating fields in bibs that are no longer visible
+ DELETE FROM biblio.peer_bib_copy_map WHERE peer_record = NEW.id; -- Separate any multi-homed items
+ RETURN NEW; -- and we're done
+ END IF;
+
+ IF TG_OP = 'UPDATE' THEN -- re-ingest?
+ PERFORM * FROM config.internal_flag WHERE name = 'ingest.reingest.force_on_same_marc' AND enabled;
+
+ IF NOT FOUND AND OLD.marc = NEW.marc THEN -- don't do anything if the MARC didn't change
+ RETURN NEW;
+ END IF;
+ END IF;
+
+ -- Record authority linking
+ PERFORM * FROM config.internal_flag WHERE name = 'ingest.disable_authority_linking' AND enabled;
+ IF NOT FOUND THEN
+ PERFORM biblio.map_authority_linking( NEW.id, NEW.marc );
+ END IF;
+
+ -- Flatten and insert the mfr data
+ PERFORM * FROM config.internal_flag WHERE name = 'ingest.disable_metabib_full_rec' AND enabled;
+ IF NOT FOUND THEN
+ PERFORM metabib.reingest_metabib_full_rec(NEW.id);
+
+ -- Now we pull out attribute data, which is dependent on the mfr for all but XPath-based fields
+ PERFORM * FROM config.internal_flag WHERE name = 'ingest.disable_metabib_rec_descriptor' AND enabled;
+ IF NOT FOUND THEN
+ FOR attr_def IN SELECT * FROM config.record_attr_definition ORDER BY format LOOP
+
+ IF attr_def.tag IS NOT NULL THEN -- tag (and optional subfield list) selection
+ SELECT ARRAY_TO_STRING(ARRAY_ACCUM(value), COALESCE(attr_def.joiner,' ')) INTO attr_value
+ FROM (SELECT * FROM metabib.full_rec ORDER BY tag, subfield) AS x
+ WHERE record = NEW.id
+ AND tag LIKE attr_def.tag
+ AND CASE
+ WHEN attr_def.sf_list IS NOT NULL
+ THEN POSITION(subfield IN attr_def.sf_list) > 0
+ ELSE TRUE
+ END
+ GROUP BY tag
+ ORDER BY 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 := biblio.marc21_extract_fixed_field(NEW.id, 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(NEW.marc,xfrm.xslt);
+ ELSE
+ transformed_xml := NEW.marc;
+ 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 biblio.marc21_physical_characteristics(NEW.id)
+ 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;
+
+ 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;
+ END IF;
+
+ END IF;
+ END IF;
+
+ -- Gather and insert the field entry data
+ PERFORM metabib.reingest_metabib_field_entries(NEW.id);
+
+ -- Located URI magic
+ IF TG_OP = 'INSERT' THEN
+ PERFORM * FROM config.internal_flag WHERE name = 'ingest.disable_located_uri' AND enabled;
+ IF NOT FOUND THEN
+ PERFORM biblio.extract_located_uris( NEW.id, NEW.marc, NEW.editor );
+ END IF;
+ ELSE
+ PERFORM * FROM config.internal_flag WHERE name = 'ingest.disable_located_uri' AND enabled;
+ IF NOT FOUND THEN
+ PERFORM biblio.extract_located_uris( NEW.id, NEW.marc, NEW.editor );
+ END IF;
+ END IF;
+
+ -- (re)map metarecord-bib linking
+ IF TG_OP = 'INSERT' THEN -- if not deleted and performing an insert, check for the flag
+ PERFORM * FROM config.internal_flag WHERE name = 'ingest.metarecord_mapping.skip_on_insert' AND enabled;
+ IF NOT FOUND THEN
+ PERFORM metabib.remap_metarecord_for_bib( NEW.id, NEW.fingerprint );
+ END IF;
+ ELSE -- we're doing an update, and we're not deleted, remap
+ PERFORM * FROM config.internal_flag WHERE name = 'ingest.metarecord_mapping.skip_on_update' AND enabled;
+ IF NOT FOUND THEN
+ PERFORM metabib.remap_metarecord_for_bib( NEW.id, NEW.fingerprint );
+ END IF;
+ END IF;
+
+ RETURN NEW;
+END;
+$func$ LANGUAGE PLPGSQL;
+
+COMMIT;
var FETCH_HIGHEST_PERM_ORG = 'open-ils.actor:open-ils.actor.user.perm.highest_org.batch';
var FETCH_USER_NOTES = 'open-ils.actor:open-ils.actor.note.retrieve.all';
var FETCH_ORG_BY_SHORTNAME = 'open-ils.actor:open-ils.actor.org_unit.retrieve_by_shortname';
-var FETCH_BIB_ID_BY_BARCODE = 'open-ils.search:open-ils.search.bib_id.by_barcode';
+var FETCH_BIB_IDS_BY_BARCODE = 'open-ils.search:open-ils.search.multi_home.bib_ids.by_barcode';
var FETCH_ORG_SETTING = 'open-ils.actor:open-ils.actor.ou_setting.ancestor_default';
+var TEST_PEER_BIBS = 'open-ils.search:open-ils.search.peer_bibs.test';
+var FETCH_PEER_BIBS = 'open-ils.search:open-ils.search.peer_bibs';
/* ---------------------------------------------------------------------------- */
<!ENTITY staff.cat.opac.default.label "Set bottom interface as Default">
<!ENTITY staff.cat.opac.manage_parts.accesskey "P">
<!ENTITY staff.cat.opac.manage_parts.label "Manage Parts">
+<!ENTITY staff.cat.opac.manage_multi_home_items.accesskey "F">
+<!ENTITY staff.cat.opac.manage_multi_home_items.label "Manage Foreign Items">
+<!ENTITY staff.cat.opac.mark_for_multi_home.accesskey "F">
+<!ENTITY staff.cat.opac.mark_for_multi_home.label "Mark as Target for Foreign Items">
<!ENTITY staff.cat.opac.marc_edit.accesskey "E">
<!ENTITY staff.cat.opac.marc_edit.label "MARC Edit">
<!ENTITY staff.cat.opac.marc_view.accesskey "V">
<!ENTITY staff.hold_list.cancel_hold_dialog.cancel_btn.accesskey "C">
<!ENTITY staff.hold_list.cancel_hold_dialog.apply_btn.label "Apply">
<!ENTITY staff.hold_list.cancel_hold_dialog.apply_btn.accesskey "A">
+<!ENTITY staff.cat.manage_multi_bib_items.caption "Manage Foreign Items">
+<!ENTITY staff.cat.manage_multi_bib_items.actions.menu.label "Actions for Selected Items">
+<!ENTITY staff.cat.manage_multi_bib_items.actions.menu.accesskey "f">
+<!ENTITY staff.cat.manage_multi_bib_items.actions.menu_entry.show_in_opac.label "Show in Catalog">
+<!ENTITY staff.cat.manage_multi_bib_items.actions.menu_entry.show_in_opac.accesskey "S">
+<!ENTITY staff.cat.manage_multi_bib_items.actions.menu_entry.change_peer_type.label "Change Peer Type">
+<!ENTITY staff.cat.manage_multi_bib_items.actions.menu_entry.change_peer_type.accesskey "C">
+<!ENTITY staff.cat.manage_multi_bib_items.actions.menu_entry.unlink_from_bib.label "Remove from Bib">
+<!ENTITY staff.cat.manage_multi_bib_items.actions.menu_entry.unlink_from_bib.accesskey "R">
+<!ENTITY staff.cat.manage_multi_bib_items.peer_type.menu.label "Peer Type:">
+<!ENTITY staff.cat.manage_multi_bib_items.peer_type.menu.accesskey "T">
+<!ENTITY staff.cat.manage_multi_bib_items.barcode.textbox.label "Barcode:">
+<!ENTITY staff.cat.manage_multi_bib_items.barcode.textbox.accesskey "B">
+<!ENTITY staff.cat.manage_multi_bib_items.barcode.submit.label "Link to Bib (Submit)">
+<!ENTITY staff.cat.manage_multi_bib_items.barcode.submit.accesskey "S">
<!ENTITY staff.cat.copy_browser.actions.sel_clip.label "Copy to Clipboard">
<!ENTITY staff.cat.copy_browser.actions.sel_clip.accesskey "C">
<!ENTITY staff.cat.copy_browser.actions.cmd_add_items_to_buckets.label "Add Items to Buckets">
<!ENTITY staff.cat.copy_browser.actions.cmd_edit_items.accesskey "E">
<!ENTITY staff.cat.copy_browser.actions.cmd_transfer_items.label "Transfer Items to Previously Marked Volume">
<!ENTITY staff.cat.copy_browser.actions.cmd_transfer_items.accesskey "T">
+<!ENTITY staff.cat.copy_browser.actions.cmd_link_as_multi_bib.label "Link as Foreign Items to Previously Marked Bib Record">
+<!ENTITY staff.cat.copy_browser.actions.cmd_link_as_multi_bib.accesskey "F">
<!ENTITY staff.cat.copy_browser.actions.cmd_add_volumes.label "Add Volumes">
<!ENTITY staff.cat.copy_browser.actions.cmd_add_volumes.accesskey "V">
<!ENTITY staff.cat.copy_browser.actions.cmd_mark_library.label "Mark Library as Volume Transfer Destination">
<!ENTITY rdetail.cn.less "less info">
<!ENTITY rdetail.cn.hold "place hold">
<!ENTITY rdetail.cn.reserve "book now">
+<!ENTITY rdetail.cn.multi_home "linked titles">
<!ENTITY rdetail.cn.disabled "- Disabled -">
<!ENTITY rdetail.cn.note "Copy Note">
<!ENTITY rdetail.cn.category "Copy Category">
<!ENTITY rdetail.extras.author.notes "Author Notes">
<!ENTITY rdetail.extras.annotation "Annotation">
<!ENTITY rdetail.extras.marc "MARC Record">
+<!ENTITY rdetail.extras.foreign_items "Linked Titles">
<!ENTITY rdetail.extras.call.null "There are no call numbers for this item at this location.">
<!ENTITY rdetail.extras.call.local "Local Call Numbers:">
<!ENTITY rdetail.extras.preview.fulltext "Full text">
function advFindBarcode(barcode) {
- var req = new Request(FETCH_BIB_ID_BY_BARCODE, barcode);
+ var req = new Request(FETCH_BIB_IDS_BY_BARCODE, barcode);
req.callback(advDrawBarcode);
req.request.alertEvent = false;
req.send();
}
function advDrawBarcode(r) {
- titleid = r.getResultObject();
- if(checkILSEvent(titleid)) {
+ var title_ids = r.getResultObject();
+ if(checkILSEvent(title_ids)) {
alertId('myopac.copy.not.found');
return;
}
- if(!titleid) return;
+ if(!title_ids) return;
var args = {};
- args.page = RDETAIL;
- args[PARAM_RID] = titleid;
+ if (title_ids.length == 1) {
+ args.page = RDETAIL;
+ args[PARAM_RID] = title_ids[0];
+ } else {
+ args.page = RRESULT;
+ args[PARAM_RTYPE] = RTYPE_LIST;
+ args[PARAM_RLIST] = title_ids;
+ }
location.href = buildOPACLink(args);
}
*/
var showDueTime = false;
-function cpdBuild( contextTbody, contextRow, record, callnumber, orgid, depth, copy_location ) {
+function cpdBuild( contextTbody, contextRow, record, callnumber, orgid, depth, copy_location, already_fetched_copies, peer_types ) {
var i = cpdCheckExisting(contextRow);
if(i) return i;
var print = $n(templateRow,'print');
print.onclick = function() { cpdBuildPrintPane(
contextRow, record, callnumber, orgid, depth) };
+ if (typeof callnumber == 'object') {
+ addCSSClass(print,'hide_me');
+ }
var mainTbody = $n(templateRow, 'copies_tbody');
var extrasRow = mainTbody.removeChild($n(mainTbody, 'copy_extras_row'));
- var req = new Request(FETCH_COPIES_FROM_VOLUME, record.doc_id(), callnumber, orgid);
- req.callback(cpdDrawCopies);
+ var request_args = {
+ peer_types : peer_types, /* indexed the same as already_fetched_copies */
+ contextTbody : contextTbody, /* tbody that holds the contextrow */
+ contextRow : contextRow, /* the row our new row will be inserted after */
+ record : record,
+ callnumber : callnumber,
+ orgid : orgid,
+ depth : depth,
+ templateRow : templateRow, /* contains everything */
+ copy_location : copy_location,
+ mainTbody : mainTbody, /* holds the copy rows */
+ extrasRow : extrasRow, /* wrapper row for all extras */
+ counter : counter
+ }
- req.request.args = {
- contextTbody : contextTbody, /* tbody that holds the contextrow */
- contextRow : contextRow, /* the row our new row will be inserted after */
- record : record,
- callnumber : callnumber,
- orgid : orgid,
- depth : depth,
- templateRow : templateRow, /* contains everything */
- copy_location : copy_location,
- mainTbody : mainTbody, /* holds the copy rows */
- extrasRow : extrasRow, /* wrapper row for all extras */
- counter : counter
- };
+ if (! already_fetched_copies) {
+ var req = new Request(FETCH_COPIES_FROM_VOLUME, record.doc_id(), callnumber, orgid);
+ req.callback(cpdDrawCopies);
+
+ req.request.args = request_args;
+
+ req.send();
+ } else {
+ setTimeout(
+ function() {
+ delete request_args['copy_location'];
+ cpdDrawCopies({
+ 'args' : request_args,
+ 'getResultObject' : function() { return already_fetched_copies; }
+ });
+ }, 0
+ );
+ }
if( contextRow.nextSibling )
contextTbody.insertBefore( templateRow, contextRow.nextSibling );
else
contextTbody.appendChild( templateRow );
-
- req.send();
_debug('creating new details row with id ' + templateRow.id);
cpdNodes[templateRow.id] = { templateRow : templateRow };
return templateRow.id;
for( var i = 0; i < copies.length; i++ ) {
var row = copyrow.cloneNode(true);
var copyid = copies[i];
- var req = new Request(FETCH_FLESHED_COPY, copies[i]);
- req.callback(cpdDrawCopy);
- req.request.args = r.args;
- req.request.row = row;
- req.send();
+ var pt; if (args.peer_types) pt = args.peer_types[i];
+ if (typeof copyid != 'object') {
+ var req = new Request(FETCH_FLESHED_COPY, copyid);
+ req.callback(cpdDrawCopy);
+ req.request.args = r.args;
+ req.request.row = row;
+ req.send();
+ } else {
+ setTimeout(
+ function(copy,row,pt) {
+ return function() {
+ cpdDrawCopy({
+ 'getResultObject' : function() { return copy; },
+ 'args' : r.args,
+ 'peer_type' : pt,
+ 'row' : row
+ });
+ };
+ }(copies[i],row,pt), 0
+ );
+ }
copytbody.appendChild(row);
}
}
function cpdDrawCopy(r) {
var copy = r.getResultObject();
var row = r.row;
+ var pt = r.peer_type;
var trow = r.args.templateRow;
if (r.args.copy_location && copy.location().name() != r.args.copy_location) {
return;
}
- $n(row, 'barcode').appendChild(text(copy.barcode()));
+ var b = $n(row, 'barcode').appendChild(text(copy.barcode()));
+
+ /* show the peer type*/
+ if (pt) {
+ $n(row, 'barcode').appendChild(text(' :: ' + pt));
+ }
+
$n(row, 'location').appendChild(text(copy.location().name()));
$n(row, 'status').appendChild(text(copy.status().name()));
}
}
+ /* show the other bibs link */
+ if (copy.peer_record_maps().length > 0) {
+ var l = $n(row, 'copy_multi_home');
+ unHideMe(l);
+ var link_args = {};
+ link_args.page = RRESULT;
+ link_args[PARAM_RTYPE] = RTYPE_LIST;
+ link_args[PARAM_RLIST] = new Array();
+ for (var i = 0; i < copy.peer_record_maps().length; i++) {
+ link_args[PARAM_RLIST].push( copy.peer_record_maps()[i].peer_record() );
+ }
+ l.setAttribute('href',buildOPACLink(link_args));
+ }
+
if(isXUL()) {
/* show the hold link */
var l = $n(row, 'copy_hold_link');
$('rdetail_view_marc_box').insertBefore(span, $('rdetail_view_marc_box').firstChild);
}
+function rdetailForeignItems(r,id) {
+ hideMe($('rdetail_extras_loading'));
+ var tbody = $('rdetail_foreign_items_tbody');
+
+ var robj = r.getResultObject(); /* mvr list with foreign_copy_maps fleshed */
+
+ for (var i = 0; i < robj.length; i++) {
+ var args = {};
+ args.page = RDETAIL;
+ args[PARAM_OFFSET] = 0;
+ args[PARAM_RID] = robj[i].doc_id();
+ var row = elem('tr'); tbody.appendChild(row);
+ var td1 = elem('td'); row.appendChild(td1);
+ var title = elem(
+ 'a',
+ {
+ 'href' : buildOPACLink(args),
+ 'class' : 'classic_link'
+ },
+ robj[i].title()
+ );
+ td1.appendChild(title);
+ var td2 = elem('td',{},robj[i].author()); row.appendChild(td2);
+ var td3 = elem('td'); row.appendChild(td3);
+ var details = elem(
+ 'a',
+ {
+ 'href' : 'javascript:void(0)',
+ 'class' : 'classic_link'
+ },
+ 'Copy Details'
+ );
+ details.onclick = function(idx,context_row){
+ return function() {
+ cpdBuild(
+ tbody,
+ context_row,
+ robj[idx],
+ null,
+ 1,
+ 0,
+ 1,
+ dojo.map(
+ robj[idx].foreign_copy_maps(),
+ function(x){ return x.target_copy(); }
+ ),
+ dojo.map(
+ robj[idx].foreign_copy_maps(),
+ function(x){ return x.peer_type().name(); }
+ )
+ );
+ };
+ }(i,row);
+ td3.appendChild(details);
+ }
+}
+
+
function rdetailShowLocalCopies() {
rdetailShowLocal = true;
if (novelist && currentISBN) {
unHideMe($('rdetail_novelist_link'));
}
+
+ // Multi-Home / Foreign Items / Peer Bibs
+ var req = new Request( TEST_PEER_BIBS, record.doc_id() );
+ req.callback(function(r){
+ var test = r.getResultObject();
+ if (test == "1") {
+ unHideMe($('rdetail_foreign_items_link'));
+ }
+ });
+ req.send();
}
var rdetailMarcFetched = false;
+var rdetailForeignItemsFetched = false;
function rdetailShowExtra(type, args) {
hideMe($('rdetail_copy_info_div'));
hideMe($('cn_browse'));
hideMe($('rdetail_cn_browse_div'));
hideMe($('rdetail_novelist_div'));
+ hideMe($('rdetail_foreign_items_div'));
hideMe($('rdetail_notes_div'));
removeCSSClass($('rdetail_copy_info_link'), 'rdetail_extras_selected');
removeCSSClass($('rdetail_annotation_link'), 'rdetail_extras_selected');
removeCSSClass($('rdetail_viewmarc_link'), 'rdetail_extras_selected');
removeCSSClass($('rdetail_novelist_link'), 'rdetail_extras_selected');
+ removeCSSClass($('rdetail_foreign_items_link'), 'rdetail_extras_selected');
switch(type) {
unHideMe($('rdetail_novelist_div'));
break;
+ case "foreign_items":
+ addCSSClass($('rdetail_foreign_items_link'), 'rdetail_extras_selected');
+ unHideMe($('rdetail_foreign_items_div'));
+ if(rdetailForeignItemsFetched) return;
+ unHideMe($('rdetail_extras_loading'));
+ rdetailForeignItemsFetched = true;
+ var req = new Request( FETCH_PEER_BIBS, record.doc_id() );
+ req.callback(rdetailForeignItems);
+ req.send();
+ break;
+
case 'cn':
addCSSClass($('rdetail_viewcn_link'), 'rdetail_extras_selected');
unHideMe($('rdetail_cn_browse_div'));
href='javascript:void(0);'>&rdetail.cn.hold;</a>
<a class='hide_me classic_link copy_more_info' name='copy_reserve_link'
href='javascript:void(0);'>&rdetail.cn.reserve;</a>
+ <a class='hide_me classic_link copy_more_info' name='copy_multi_home'
+ href='javascript:void(0);'>&rdetail.cn.multi_home;</a>
</td>
<td name='status'> </td>
class='classic_link'>&rdetail.extras.novelist;</a>
</td>
+ <td id='rdetail_foreign_items_link' class='hide_me rdetail_extras_td'
+ style='padding-right: 15px; padding-left: 15px;' >
+ <a href='javascript:rdetailShowExtra("foreign_items");'
+ class='classic_link'>&rdetail.extras.foreign_items;</a>
+ </td>
+
</tr>
</thead>
</table>
</div>
</div>
+ <div id='rdetail_foreign_items_div' class='rdetail_extras_div hide_me'>
+ <table width='100%' class='data_grid data_grid_center' id='rdetail_foreign_items_table'>
+ <thead>
+ <tr> <td>&common.title;</td> <td>&common.authors;</td> <td> </td></tr>
+ </thead>
+ <tbody id='rdetail_foreign_items_tbody'>
+ </tbody>
+ </table>
+ </div>
+
<div id='rdetail_cn_browse_div' style='text-align: center;' class='hide_me'>
<div id='cn_browse_none' class='hide_me color_4' style='width: 90%; text-align: center; margin: 10px;'>
this.chain.push(
function() {
var f = gen_fm_retrieval_func(
+ 'bpt',
+ [
+ api.FM_BPT_PCRUD_SEARCH.app,
+ api.FM_BPT_PCRUD_SEARCH.method,
+ [ obj.session.key, {"id":{"!=":null}}, {"order_by":{"bpt":"id"}} ],
+ false
+ ]
+ );
+ try {
+ f();
+ } catch(E) {
+ var error = 'Error: ' + js2JSON(E);
+ obj.error.sdump('D_ERROR',error);
+ throw(E);
+ }
+ }
+ );
+
+ this.chain.push(
+ function() {
+ var f = gen_fm_retrieval_func(
'csp',
[
api.FM_CSP_PCRUD_SEARCH.app,
return url;
}
+ function widget_prompt(node,args) {
+ // args is an object that may contain the following keys: title, desc, ok_label, ok_accesskey, cancel_label, cancel_accesskey, access, method
+ // access may contain 'property' or 'attribute' or 'method' for retrieving the value from the node
+ // if 'method', then the method key will reference a function that returns the value
+ try {
+ if (!node) { return false; }
+ if (!args) { args = {}; }
+ args[ 'widget' ] = node;
+
+ var url = location.protocol == 'chrome'
+ ? 'chrome://open_ils_staff_client/content/util/widget_prompt.xul'
+ : '/xul/server/util/widget_prompt.xul';
+
+ JSAN.use('util.window'); var win = new util.window();
+ var my_xulG = win.open(
+ url,
+ args.title || 'widget_prompt',
+ 'chrome,modal',
+ args
+ );
+
+ if (my_xulG.status == 'incomplete') {
+ return false;
+ } else {
+ return my_xulG.value;
+ }
+ } catch(E) {
+ alert('Error in global_utils.js, widget_prompt(): ' + E);
+ }
+ }
var marc_view_reset = true;
var marc_edit_reset = true;
var copy_browser_reset = true;
+var manage_parts_reset = true;
+var manage_multi_home_reset = true;
var hold_browser_reset = true;
var serctrl_view_reset = true;
g.data.stash('marked_record_mvr');
if (g.data.marked_record_mvr) {
alert(document.getElementById('offlineStrings').getFormattedString('cat.opac.record_marked_for_overlay.tcn.alert',[ g.data.marked_record_mvr.tcn() ]));
- xulG.set_statusbar(1, $("offlineStrings").getFormattedString('staff.cat.z3950.marked_record_for_overlay_indicator.tcn.label',[g.data.marked_record_mvr.tcn()]) );
+ xulG.set_statusbar(
+ 1,
+ $("offlineStrings").getFormattedString('staff.cat.z3950.marked_record_for_overlay_indicator.tcn.label',[g.data.marked_record_mvr.tcn()]),
+ $("offlineStrings").getFormattedString('staff.cat.z3950.marked_record_for_overlay_indicator.record_id.label',[g.data.marked_record]),
+ gen_statusbar_click_handler('marked_record')
+ );
} else {
alert(document.getElementById('offlineStrings').getFormattedString('cat.opac.record_marked_for_overlay.record_id.alert',[ g.data.marked_record ]));
- xulG.set_statusbar(1, $("offlineStrings").getFormattedString('staff.cat.z3950.marked_record_for_overlay_indicator.record_id.label',[g.data.marked_record]) );
+ xulG.set_statusbar(
+ 1,
+ $("offlineStrings").getFormattedString('staff.cat.z3950.marked_record_for_overlay_indicator.record_id.label',[g.data.marked_record]),
+ '',
+ gen_statusbar_click_handler('marked_record')
+ );
}
}
g.data.stash('marked_record_for_hold_transfer_mvr');
if (g.data.marked_record_mvr) {
var m = $("offlineStrings").getFormattedString('staff.cat.opac.marked_record_for_hold_transfer_indicator.tcn.label',[g.data.marked_record_for_hold_transfer_mvr.tcn()]);
- alert(m); xulG.set_statusbar(1, m );
+ alert(m);
+ xulG.set_statusbar(
+ 3,
+ m,
+ '',
+ gen_statusbar_click_handler('marked_record_for_hold_transfer')
+ );
} else {
var m = $("offlineStrings").getFormattedString('staff.cat.opac.marked_record_for_hold_transfer_indicator.record_id.label',[g.data.marked_record_for_hold_transfer]);
- alert(m); xulG.set_statusbar(1, m );
+ alert(m);
+ xulG.set_statusbar(
+ 3,
+ m,
+ '',
+ gen_statusbar_click_handler('marked_record_for_hold_transfer')
+ );
}
}
marc_edit_reset = true;
copy_browser_reset = true;
hold_browser_reset = true;
+ manage_parts_reset = true;
+ manage_multi_home_reset = true;
+ serctrl_view_reset = true;
while(top_pane.node.lastChild) top_pane.node.removeChild( top_pane.node.lastChild );
var children = bottom_pane.node.childNodes;
for (var i = 0; i < children.length; i++) {
function manage_parts() {
try {
- var title = document.getElementById('offlineStrings').getFormattedString('staff.cat.manage_parts.title', [docid]);
+ g.view = 'manage_parts';
var loc = urls.XUL_BROWSER + "?url=" + window.escape(
window.xulG.url_prefix(urls.CONIFY_MANAGE_PARTS) + '?r=' + docid
);
- var w = xulG.new_tab(
- loc,
- { 'tab_name' : title },
- {}
- );
+ if (manage_parts_reset) {
+ bottom_pane.reset_iframe( loc,{},xulG);
+ manage_parts_reset =false;
+ } else {
+ bottom_pane.set_iframe( loc,{},xulG);
+ }
+ opac_wrapper_set_help_context();
+ bottom_pane.get_contentWindow().addEventListener('load',opac_wrapper_set_help_context,false);
} catch(E) {
alert('Error in chrome/content/cat/opac.js, manage_parts(): ' + E);
}
}
+function manage_multi_home_items() {
+ try {
+ g.view = 'manage_multi_home';
+ var loc = window.xulG.url_prefix(urls.MANAGE_MULTI_HOME_ITEMS);
+ if (manage_multi_home_reset) {
+ bottom_pane.reset_iframe( loc,{},{'docid':docid,'no_bib_summary':true,'url_prefix':xulG.url_prefix,'new_tab':xulG.new_tab});
+ manage_multi_home_reset =false;
+ } else {
+ bottom_pane.set_iframe( loc,{},{'docid':docid,'no_bib_summary':true,'url_prefix':xulG.url_prefix,'new_tab':xulG.new_tab});
+ }
+ opac_wrapper_set_help_context();
+ bottom_pane.get_contentWindow().addEventListener('load',opac_wrapper_set_help_context,false);
+ } catch(E) {
+ alert('Error in chrome/content/cat/opac.js, manage_multi_home_items(): ' + E);
+ }
+}
+
+function mark_for_multi_home() {
+ g.data.marked_multi_home_record = docid;
+ g.data.stash('marked_multi_home_record');
+ var robj = g.network.simple_request('MODS_SLIM_RECORD_RETRIEVE.authoritative',[docid]);
+ if (typeof robj.ilsevent == 'undefined') {
+ g.data.marked_multi_home_record_mvr = robj;
+ } else {
+ g.data.marked_multi_home_record_mvr = null;
+ g.error.standard_unexpected_error_alert('in mark_for_multi_home',robj);
+ }
+ g.data.stash('marked_multi_home_record_mvr');
+
+ if (g.data.marked_multi_home_record_mvr) {
+ alert(document.getElementById('offlineStrings').getFormattedString('cat.opac.record_marked_for_multi_home.tcn.alert',[ g.data.marked_multi_home_record_mvr.tcn() ]));
+ xulG.set_statusbar(
+ 2,
+ $("offlineStrings").getFormattedString('staff.cat.copy_browser.marked_record_for_multi_home_indicator.tcn.label',[g.data.marked_multi_home_record_mvr.tcn()]),
+ $("offlineStrings").getFormattedString('staff.cat.copy_browser.marked_record_for_multi_home_indicator.record_id.label',[g.data.marked_multi_home_record]),
+ gen_statusbar_click_handler('marked_multi_home_record')
+ );
+ } else {
+ alert(document.getElementById('offlineStrings').getFormattedString('cat.opac.record_marked_for_multi_home.record_id.alert',[ g.data.marked_multi_home_record ]));
+ xulG.set_statusbar(
+ 2,
+ $("offlineStrings").getFormattedString('staff.cat.copy_browser.marked_record_for_multi_home_indicator.record_id.label',[g.data.marked_multi_home_record]),
+ '',
+ gen_statusbar_click_handler('marked_multi_home_record')
+ );
+ }
+}
+
+function gen_statusbar_click_handler(data_key) {
+ return function (ev) {
+
+ if (! g.data[data_key]) {
+ return;
+ }
+
+ if (ev.button == 0 /* left click, spawn opac */) {
+ var opac_url = xulG.url_prefix( urls.opac_rdetail ) + '?r=' + g.data[data_key];
+ var content_params = {
+ 'session' : ses(),
+ 'authtime' : ses('authtime'),
+ 'opac_url' : opac_url,
+ };
+ xulG.new_tab(
+ xulG.url_prefix(urls.XUL_OPAC_WRAPPER),
+ {'tab_name':'Retrieving title...'},
+ content_params
+ );
+ }
+
+ if (ev.button == 2 /* right click, remove mark */) {
+ if ( window.confirm( document.getElementById('offlineStrings').getString('cat.opac.clear_statusbar') ) ) {
+ g.data[data_key] = null;
+ g.data.stash(data_key);
+ ev.target.setAttribute('label','');
+ if (ev.target.hasAttribute('tooltiptext')) {
+ ev.target.removeAttribute('tooltiptext');
+ }
+ }
+ }
+ }
+}
+
+
<menuitem label="&staff.cat.opac.marc_view.label;" accesskey="&staff.cat.opac.marc_view.accesskey;" id="marc_view" oncommand="set_marc_view();"/>
<menuitem label="&staff.cat.opac.marc_edit.label;" accesskey="&staff.cat.opac.marc_edit.accesskey;" id="marc_edit" oncommand="set_marc_edit();"/>
<menuitem label="&staff.cat.opac.copy_browse.label;" accesskey="&staff.cat.opac.copy_browse.accesskey;" id="copy_browse" oncommand="set_copy_browser();"/>
+ <menuitem label="&staff.cat.opac.manage_multi_home_items.label;" accesskey="&staff.cat.opac.manage_multi_home_items.accesskey;" id="manage_multi_home_items" oncommand="manage_multi_home_items();"/>
+ <menuitem label="&staff.cat.opac.manage_parts.label;" accesskey="&staff.cat.opac.manage_parts.accesskey;" id="manage_parts" oncommand="manage_parts();"/>
<menuitem label="&staff.cat.opac.view_holds.label;" accesskey="&staff.cat.opac.view_holds.accesskey;" id="view_holds" oncommand="set_hold_browser();"/>
<menuitem label="&staff.cat.opac.view_orders.label;" accesskey="&staff.cat.opac.view_orders.accesskey;" id="view_orders" oncommand="open_acq_orders();"/>
<menuseparator/>
<menuitem label="&staff.cat.copy_browser.holdings_maintenance.cmd_add_volumes.label;" accesskey="&staff.cat.copy_browser.holdings_maintenance.cmd_add_volumes.accesskey;" id="add_volumes" oncommand="add_volumes();"/>
<menuitem label="&staff.cat.opac.mark_for_hold_transfer.label;" accesskey="&staff.cat.opac.mark_for_hold_transfer.accesskey;" id="mark_for_hold_transfer" oncommand="mark_for_hold_transfer();"/>
<menuitem label="&staff.cat.opac.transfer_title_holds.label;" accesskey="&staff.cat.opac.transfer_title_holds.accesskey;" id="transfer_title_holds" oncommand="transfer_title_holds();"/>
- <menuitem label="&staff.cat.opac.manage_parts.label;" accesskey="&staff.cat.opac.manage_parts.accesskey;" id="manage_parts" oncommand="manage_parts();"/>
+ <menuitem label="&staff.cat.opac.mark_for_multi_home.label;" accesskey="&staff.cat.opac.mark_for_multi_home.accesskey;" id="mark_for_multi_home" oncommand="mark_for_multi_home();"/>
<menuseparator/>
<menuitem label="&staff.cat.opac.bib_in_new_tab.label;" id="bib_in_new_tab" oncommand="bib_in_new_tab();"/>
<menuitem label="&staff.cat.opac.remove_me.label;" id="remove_me" oncommand="remove_me();"/>
<menuseparator/>
- <menuitem label="&staff.cat.opac.default.label;" id="default" oncommand="set_default();"/>
- <menuitem label="&staff.cat.opac.refresh_me.label;" id="refresh_me" oncommand="refresh_display(docid);"/>
- <menuseparator/>
<menu id="mfhd_menu" label="&staff.serial.mfhd_menu.label;">
<menupopup id="mfhd_popup">
<menuitem id="mfhd_add" label="&staff.serial.mfhd_menu.add.label;"/>
<menuitem id="serctrl_view" label="&staff.serial.serctrl_view.label;" oncommand="set_serctrl_view();" />
<menuitem label="&staff.cat.opac.alt_serial.label;" accesskey="&staff.cat.opac.alt_serial.accesskey;" id="alt_serial" oncommand="open_alt_serial_mgmt();" />
<menuitem label="&staff.cat.opac.batch_receive.label;" accesskey="&staff.cat.opac.batch_receive.accesskey;" id="batch_receive" oncommand="batch_receive_in_new_tab();"/>
+ <menuseparator/>
+ <menuitem label="&staff.cat.opac.default.label;" id="default" oncommand="set_default();"/>
+ <menuitem label="&staff.cat.opac.refresh_me.label;" id="refresh_me" oncommand="refresh_display(docid);"/>
</menupopup>
</menu>
</menubar>
'FM_AUSP_PCRUD_UPDATE' : { 'app' : 'open-ils.pcrud', 'method' : 'open-ils.pcrud.update.ausp', 'secure' : false },
'FM_AUSP_UPDATE_NOTE' : { 'app' : 'open-ils.actor', 'method' : 'open-ils.actor.user.penalty.note.update' },
'FM_BOOKING_CREATE_BRT_AND_BRSRC' : { 'app' : 'open-ils.booking', 'method' : 'open-ils.booking.create_brt_and_brsrc_from_copies' },
+ 'FM_BPT_PCRUD_SEARCH' : { 'app' : 'open-ils.pcrud', 'method' : 'open-ils.pcrud.search.bpt.atomic', 'secure' : false },
'FM_BRESV_RETRIEVE_VIA_PCRUD' : { 'app' : 'open-ils.pcrud', 'method' : 'open-ils.pcrud.search.bresv.atomic' },
'FM_BRSRC_RETRIEVE_VIA_PCRUD' : { 'app' : 'open-ils.pcrud', 'method' : 'open-ils.pcrud.search.brsrc.atomic' },
'FM_BRT_RETRIEVE_VIA_PCRUD' : { 'app' : 'open-ils.pcrud', 'method' : 'open-ils.pcrud.search.brt.atomic' },
'AUDIO_event_ASSET_COPY_NOT_FOUND' : '/xul/server/skin/media/audio/redalert.wav',
'AUTHORITY_MANAGE' : '/eg/cat/authority/list',
+ 'MANAGE_MULTI_HOME_ITEMS' : '/xul/server/cat/manage_multi_home_items.xul',
'XUL_AUTH_SIMPLE' : '/xul/server/main/simple_auth.xul',
'XUL_BIB_BRIEF' : '/xul/server/cat/bib_brief.xul',
'XUL_BIB_BRIEF_VERTICAL' : '/xul/server/cat/bib_brief_vertical.xul',
content_params.url_prefix = function(url) { return obj.url_prefix(url); };
content_params.network_meter = obj.network_meter;
content_params.page_meter = obj.page_meter;
- content_params.set_statusbar = function(slot,text) {
+ content_params.set_statusbar = function(slot,text,tooltiptext,click_handler) {
var e = document.getElementById('statusbarpanel'+slot);
- if (e) { e.setAttribute('label',text); }
+ if (e) {
+ var p = e.parentNode;
+ var sbp = document.createElement('statusbarpanel');
+ sbp.setAttribute('id','statusbarpanel'+slot);
+ p.replaceChild(sbp,e); // destroy and replace the statusbarpanel as a poor man's way of clearing event handlers
+
+ sbp.setAttribute('label',text);
+ if (tooltiptext) {
+ sbp.setAttribute('tooltiptext',tooltiptext);
+ }
+ if (click_handler) {
+ sbp.addEventListener(
+ 'click',
+ click_handler,
+ false
+ );
+ }
+ }
};
content_params.chrome_xulG = xulG;
content_params._data = xulG._data;
'timer' : function(funcs,interval) {
var obj = this;
- if (obj._intervalId) {
- obj.clear_timer();
- window.removeEventListener('unload',obj.clear_timer,false);
- }
+ obj.clear_timer();
var intervalId = window.setInterval(
function() {
if (typeof obj.debug != 'undefined' && obj.debug) { dump('EXEC: ' + location.pathname + ': Running interval with id = ' + intervalId + '\n'); }
window.addEventListener('unload',obj.clear_timer,false);
return intervalId;
},
+ 'clear_timer' : function() {
+ var obj = this;
+ if (obj._intervalId) {
+ obj.clear_timer();
+ window.removeEventListener('unload',obj.clear_timer,false);
+ }
+ },
// This executes a series of functions, but tries to give other events/functions a chance to
// execute between each one.
'chain' : function () {
--- /dev/null
+var xulG = {};
+var widget;
+
+function my_init() {
+ try {
+ netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+ if (typeof JSAN == 'undefined') { throw( "The JSAN library object is missing."); }
+ JSAN.errorLevel = "die"; // none, warn, or die
+ JSAN.addRepository('/xul/server/');
+ JSAN.use('util.error'); g.error = new util.error();
+ g.error.sdump('D_TRACE','my_init() for widget_prompt.xul');
+
+ widget = xul_param('widget',{'modal_xulG':true});
+ if (widget) {
+ $('widget_prompt_main').appendChild(widget);
+ }
+
+ var ok_label = xul_param('ok_label',{'modal_xulG':true}) || offlineStrings.getString('common.ok.label');
+ $('ok_btn').setAttribute('label',ok_label);
+
+ var ok_accesskey = xul_param('ok_accesskey',{'modal_xulG':true}) || offlineStrings.getString('common.ok.accesskey');
+ $('ok_btn').setAttribute('accesskey',ok_accesskey);
+
+ var cancel_label = xul_param('cancel_label',{'modal_xulG':true}) || offlineStrings.getString('common.cancel.label');
+ $('cancel_btn').setAttribute('label',cancel_label);
+
+ var cancel_accesskey = xul_param('cancel_accesskey',{'modal_xulG':true}) || offlineStrings.getString('common.cancel.accesskey');
+ $('cancel_btn').setAttribute('accesskey',cancel_accesskey);
+
+ var desc = xul_param('desc',{'modal_xulG':true});
+ if (desc) {
+ $('desc').appendChild( document.createTextNode( desc ) );
+ }
+
+ $('ok_btn').addEventListener('command',widget_save,false);
+ $('cancel_btn').addEventListener('command',function(ev) { window.close(); },false);
+
+ if (xul_param('title',{'modal_xulG':true})) {
+ try { window.title = xul_param('title',{'modal_xulG':true}); } catch(E) {}
+ try { document.title = xul_param('title',{'modal_xulG':true}); } catch(E) {}
+ }
+
+ xulG[ 'status' ] = 'incomplete';
+ update_modal_xulG(xulG);
+
+ try { widget.focus(); } catch(E) {}
+
+ } catch(E) {
+ alert('Error in widget_prompt.js, my_init(): ' + E);
+ }
+}
+
+function widget_save(ev) {
+ try {
+ if (widget) {
+ switch( xul_param('access',{'modal_xulG':true}) ) {
+ case 'method' :
+ xulG[ 'value' ] = xulG[ 'method' ]();
+ break;
+ case 'attribute':
+ xulG[ 'value' ] = widget.getAttribute('value');
+ break;
+ case 'property':
+ default:
+ xulG[ 'value' ] = widget.value;
+ break;
+ }
+ }
+ xulG[ 'status' ] = 'complete';
+
+ update_modal_xulG(xulG);
+
+ window.close();
+ } catch(E) {
+ alert('Error in widget_prompt.js, widget_save(): ' + E);
+ }
+}
+
--- /dev/null
+<?xml version="1.0"?>
+<!-- Application: Evergreen Staff Client -->
+<!-- Screen: Example Template for remote xul -->
+
+<!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
+<!-- STYLESHEETS -->
+<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
+<?xml-stylesheet href="/xul/server/skin/global.css" type="text/css"?>
+<?xml-stylesheet href="/xul/server/skin/patron_display.css" type="text/css"?>
+
+<!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
+<!-- LOCALIZATION -->
+<!DOCTYPE window PUBLIC "" ""[
+ <!--#include virtual="/opac/locale/en-US/lang.dtd"-->
+]>
+
+<!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
+<!-- OVERLAYS -->
+<?xul-overlay href="/xul/server/OpenILS/util_overlay.xul"?>
+
+<window id="widget_prompt_win"
+ onload="try { my_init(); font_helper(); persist_helper( xul_param('title',{'modal_xulG':true}) ); } catch(E) { alert(E); }"
+ oils_persist="width height"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+ <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
+ <!-- BEHAVIOR -->
+ <script type="text/javascript">
+ var myPackageDir = 'open_ils_staff_client'; var IAMXUL = true; var g = {};
+ </script>
+ <scripts id="openils_util_scripts"/>
+
+ <script type="text/javascript" src="/xul/server/main/JSAN.js"/>
+ <script type="text/javascript" src="widget_prompt.js"/>
+
+ <vbox id="widget_prompt_topbar">
+ <description id="desc"/>
+ </vbox>
+ <vbox id="widget_prompt_main" flex="1" style="overflow: auto"/>
+ <vbox id="widget_prompt_bottombar">
+ <hbox id="widget_prompt_buttonbar">
+ <spacer flex="1"/>
+ <button id="ok_btn" />
+ <button id="cancel_btn" />
+ </hbox>
+ </vbox>
+
+</window>
+
common.exception=!! This software has encountered an error. Please tell your friendly system administrator or software developer the following:\n%1$s\n%2$s\n
common.jsan.missing=The JSAN library object is missing.
common.ok=Ok
+common.ok.label=Ok
+common.ok.accesskey=O
+common.cancel.label=Cancel
+common.cancel.accesskey=C
common.clear=Clear
common.confirm=Check here to confirm this message.
common.error.default=Please report that this happened.
cat.opac.record_undeleted.error=Error undeleting record #%1$s : %2$s : %3$s
cat.opac.record_marked_for_overlay.record_id.alert=Record with ID %1$s marked for overlay.
cat.opac.record_marked_for_overlay.tcn.alert=Record with TCN %1$s marked for overlay.
+cat.opac.record_marked_for_multi_home.record_id.alert=Record with ID %1$s targeted for Multi-Bib items.
+cat.opac.record_marked_for_multi_home.tcn.alert=Record with TCN %1$s targeted for Mutli-Bib items.
+cat.opac.clear_statusbar=Un-target/un-mark this record?
cat.save_record=Save Record
cat.save.failure=Record not likely updated.
cat.record.counter=Record %1$s of %2$s
staff.cat.util.copy_editor.view=View
staff.circ.copy_status.add_volumes.perm_failure=You do not have permission to add volumes to the workstation library.
staff.circ.copy_status.add_volumes.title=Add Volume/Item for Record # %1$s
-staff.cat.manage_parts.title=Manage Parts for Record # %1$s
+staff.cat.copy_browser.marked_record_for_multi_home_indicator.tcn.label=Record with TCN %1$s targeted for Multi-Bib items.
+staff.cat.copy_browser.marked_record_for_multi_home_indicator.record_id.label=Record with ID %1$s targeted for Multi-Bib items.
staff.cat.z3950.marked_record_for_overlay_indicator.tcn.label=Record with TCN %1$s marked for overlay.
staff.cat.z3950.marked_record_for_overlay_indicator.record_id.label=Record with ID %1$s marked for overlay.
staff.cat.opac.marked_record_for_hold_transfer_indicator.tcn.label=Record with TCN %1$s marked for title hold transfer.
obj.refresh_list();
}
],
+
+ 'cmd_link_as_multi_bib' : [
+ ['command'],
+ function() {
+ try {
+ obj.data.stash_retrieve();
+ if (!obj.data.marked_multi_home_record) {
+ alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.link_as_multi_bib.missing_bib'));
+ return;
+ }
+
+ JSAN.use('util.functional');
+
+ var list = util.functional.filter_list(
+ obj.sel_list,
+ function (o) {
+ return o.split(/_/)[0] == 'acp';
+ }
+ );
+
+ list = util.functional.map_list(
+ list,
+ function (o) {
+ return obj.map_acp[ o ].barcode();
+ }
+ );
+
+ xulG.new_tab(
+ window.xulG.url_prefix(urls.MANAGE_MULTI_HOME_ITEMS),
+ {},
+ { 'docid' : obj.data.marked_multi_home_record, 'barcodes' : list }
+ );
+
+ } catch(E) {
+ alert('Error in copy_browser.js, cmd_link_as_multi_bib: ' + E);
+ }
+ obj.refresh_list();
+ }
+ ]
}
}
);
<command id="cmd_edit_items"/>
<command id="cmd_delete_items"/>
<command id="cmd_transfer_items"/>
+ <command id="cmd_link_as_multi_bib"/>
<command id="cmd_print_spine_labels"/>
<command id="cmd_add_volumes"/>
<command id="cmd_edit_volumes"/>
<menuseparator/>
<menuitem command="cmd_edit_items" label="&staff.cat.copy_browser.actions.cmd_edit_items.label;" accesskey="&staff.cat.copy_browser.actions.cmd_edit_items.accesskey;"/>
<menuitem command="cmd_transfer_items" label="&staff.cat.copy_browser.actions.cmd_transfer_items.label;" accesskey="&staff.cat.copy_browser.actions.cmd_transfer_items.accesskey;"/>
+ <menuitem command="cmd_link_as_multi_bib" label="&staff.cat.copy_browser.actions.cmd_link_as_multi_bib.label;" accesskey="&staff.cat.copy_browser.actions.cmd_link_as_multi_bib.accesskey;"/>
<menuseparator/>
<menuitem command="cmd_add_volumes" label="&staff.cat.copy_browser.actions.cmd_add_volumes.label;" accesskey="&staff.cat.copy_browser.actions.cmd_add_volumes.accesskey;"/>
<menuitem command="cmd_mark_library" label="&staff.cat.copy_browser.actions.cmd_mark_library.label;" accesskey="&staff.cat.copy_browser.actions.cmd_mark_library.accesskey;"/>
<menuseparator/>
<menuitem command="cmd_edit_items" label="&staff.cat.copy_browser.holdings_maintenance.cmd_edit_items.label;" accesskey="&staff.cat.copy_browser.holdings_maintenance.cmd_edit_items.accesskey;"/>
<menuitem command="cmd_transfer_items" label="&staff.cat.copy_browser.holdings_maintenance.cmd_transfer_items.label;" accesskey="&staff.cat.copy_browser.holdings_maintenance.cmd_transfer_items.accesskey;"/>
+ <menuitem command="cmd_link_as_multi_bib" label="&staff.cat.copy_browser.actions.cmd_link_as_multi_bib.label;" accesskey="&staff.cat.copy_browser.actions.cmd_link_as_multi_bib.accesskey;"/>
<menuseparator/>
<menuitem command="cmd_add_volumes" label="&staff.cat.copy_browser.holdings_maintenance.cmd_add_volumes.label;" accesskey="&staff.cat.copy_browser.holdings_maintenance.cmd_add_volumes.accesskey;"/>
<menuitem command="cmd_mark_library" label="&staff.cat.copy_browser.holdings_maintenance.cmd_mark_library.label;" accesskey="&staff.cat.copy_browser.holdings_maintenance.cmd_mark_library.accesskey;"/>
--- /dev/null
+var data; var list; var error; var net; var sound;
+var rows = {};
+var bpbcm_barcode_map = {};
+
+var commonStrings;
+var catStrings;
+
+//// parent interfaces may call this
+function default_focus() { document.getElementById('scanbox').focus(); }
+////
+
+function my_init() {
+ try {
+ netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+
+ commonStrings = $('commonStrings');
+ catStrings = $('catStrings');
+
+ if (typeof JSAN == 'undefined') {
+ throw(
+ commonStrings.getString('common.jsan.missing')
+ );
+ }
+
+ JSAN.errorLevel = "die"; // none, warn, or die
+ JSAN.addRepository('..');
+
+ JSAN.use('util.error'); error = new util.error();
+ JSAN.use('util.sound'); sound = new util.sound();
+ JSAN.use('util.widgets');
+ JSAN.use('util.functional');
+ JSAN.use('util.list');
+ JSAN.use('OpenILS.data'); data = new OpenILS.data();
+ data.stash_retrieve();
+ JSAN.use('util.network'); net = new util.network();
+ dojo.require('openils.PermaCrud');
+ JSAN.use('cat.util');
+
+ init_menu();
+ init_list();
+ $('list_actions').appendChild( list.render_list_actions() );
+ list.set_list_actions();
+ populate_list();
+ $('submit').addEventListener('command', function() { handle_submit(true); }, false);
+ $('remove').addEventListener('command', function() { handle_remove(); }, false);
+ $('change').addEventListener('command', function() { handle_change(); }, false);
+ $('opac').addEventListener('command', function() { handle_opac(); }, false);
+ $('scanbox').addEventListener('keypress', handle_keypress, false);
+ default_focus();
+
+ if (typeof xulG.set_tab_name == 'function') {
+ xulG.set_tab_name(
+ catStrings.getFormattedString(
+ 'staff.cat.manage_multi_bib_items.tab_name',
+ [ xul_param('docid') ]
+ )
+ );
+ }
+
+ if (! xul_param('no_bib_summary')) {
+ if (typeof bib_brief_overlay == 'function') {
+ $("bib_brief_groupbox").hidden = false;
+ bib_brief_overlay( { 'mvr_id' : xul_param('docid') } );
+ }
+ }
+
+ } catch(E) {
+ alert('Error in manage_multi_home_items.js, my_init(): ' + E);
+ }
+}
+
+function init_menu() {
+ try {
+ var ml = util.widgets.make_menulist(
+ util.functional.map_list(
+ data.list.bpt.sort( function(a,b) {
+ if (a.name().toUpperCase() < b.name().toUpperCase()) return -1;
+ if (a.name().toUpperCase() > b.name().toUpperCase()) return 1;
+ return 0;
+ }),
+ function(obj) {
+ return [ obj.name(), obj.id() ];
+ }
+ )
+ );
+ ml.setAttribute('id','bpt_menu');
+ $('menu_placeholder').appendChild(ml);
+ } catch(E) {
+ alert('Error in manage_multi_home_items.js, init_menu(): ' + E);
+ }
+}
+
+function init_list() {
+ try {
+ list = new util.list( 'list' );
+ list.init(
+ {
+ 'retrieve_row' : function(params) {
+ if (params.row.my.bpbcm) {
+ params.row_node.setAttribute('retrieve_id',params.row.my.bpbcm.id());
+ }
+ params.on_retrieve(params.row);
+ return params.row;
+ },
+ 'columns' : [
+ {
+ 'id' : 'result',
+ 'label' : 'Result',
+ 'flex' : 1,
+ 'primary' : false,
+ 'hidden' : false,
+ 'editable' : false, 'render' : function(my) { return my.result; }
+ }
+ ].concat(
+ list.fm_columns('acp', {
+ '*' : { 'expanded_label' : false, 'hidden' : true },
+ 'acp_barcode' : { 'hidden' : false },
+ 'acp_opac_visible' : { 'hidden' : false },
+ 'acp_holdable' : { 'hidden' : false }
+ })
+ ).concat(
+ list.fm_columns('mvr', {
+ '*' : { 'expanded_label' : false, 'hidden' : true },
+ 'mvr_title' : { 'hidden' : false },
+ 'mvr_author' : { 'hidden' : false },
+ 'mvr_isbn' : { 'hidden' : false },
+ 'mvr_tcn' : { 'hidden' : false },
+ 'mvr_id' : { 'hidden' : false }
+ })
+ ).concat(
+ list.fm_columns('bpbcm', {
+ '*' : { 'expanded_label' : false, 'hidden' : true },
+ 'bpbcm_peer_type' : {
+ 'hidden' : false,
+ 'render' : function(my) { return my.bpbcm ? data.hash.bpt[ my.bpbcm.peer_type() ].name() : ''; }
+ }
+ })
+ )
+ }
+ );
+ } catch(E) {
+ alert('Error in manage_multi_home_items.js, init_list(): ' + E);
+ }
+}
+
+function handle_keypress(ev) {
+ try {
+ if (ev.keyCode && ev.keyCode == 13) {
+ handle_submit(true);
+ }
+ } catch(E) {
+ alert('Error in manage_multi_home_items.js, handle_keypress(): ' + E);
+ }
+}
+
+function handle_submit(create,my_bpbcm,my_barcode) {
+ try {
+ var barcode;
+ if (create) {
+ if (my_barcode) {
+ barcode = my_barcode;
+ } else {
+ barcode = $('scanbox').value;
+ $('scanbox').value = '';
+ default_focus();
+ }
+ }
+
+ var placeholder_acp = new acp();
+ placeholder_acp.barcode(barcode);
+ var row_params = {
+ 'row' : {
+ 'my' : {
+ 'acp' : placeholder_acp,
+ 'bpbcm' : my_bpbcm
+ }
+ }
+ };
+
+ if (barcode && rows[barcode]) {
+ var node = rows[barcode].my_node;
+ var parentNode = node.parentNode;
+ parentNode.removeChild( node );
+ delete(rows[barcode]);
+ }
+
+ row_params = list.append(row_params);
+ if (barcode) {
+ rows[barcode] = row_params;
+ }
+
+ function handle_req(req) {
+ try {
+ var robj = req.getResultObject();
+ row_params.row.my.result = catStrings.getString('staff.cat.manage_multi_bib_items.result.column.value.error');
+ if (typeof robj.ilsevent != 'undefined') {
+ row_params.row.my.result = robj.textcode;
+ } else {
+ rows[robj.copy.barcode()] = row_params;
+ if (row_params.row.my.bpbcm) {
+ bpbcm_barcode_map[ row_params.row.my.bpbcm.id() ] = robj.copy.barcode();
+ }
+
+ row_params.row.my.acp = robj.copy;
+ row_params.row.my.mvr = robj.mvr;
+
+ if (create && robj.mvr.doc_id() != xul_param('docid')) {
+ var new_bpbcm = new bpbcm();
+ new_bpbcm.isnew(1);
+ new_bpbcm.peer_type($('bpt_menu').value);
+ new_bpbcm.peer_record(xul_param('docid'));
+ new_bpbcm.target_copy(robj.copy.id());
+ var pcrud = new openils.PermaCrud( { authtoken :ses() });
+ pcrud.create(new_bpbcm, {
+ "onerror" : function(r) {
+ dump('onerror, r = ' + js2JSON(r) + '\n');
+ },
+ "oncomplete": function (r, objs) {
+ try {
+ var obj = objs[0];
+ if (obj) {
+ row_params.row.my.result = catStrings.getString('staff.cat.manage_multi_bib_items.result.column.value.success');
+ row_params.row.my.bpbcm = obj;
+ bpbcm_barcode_map[ obj.id() ] = robj.copy.barcode();
+ } else {
+ row_params.row.my.result = catStrings.getString('staff.cat.manage_multi_bib_items.result.column.value.failed');
+ sound.bad();
+ }
+ list.refresh_row( row_params );
+ } catch(E) {
+ alert('Error in manage_multi_home_items.js, handle_submit, pcrud create oncomplete callback: ' + E);
+ }
+ }
+ });
+ } else {
+ if (robj.mvr.doc_id() != xul_param('docid')) {
+ row_params.row.my.result = catStrings.getString('staff.cat.manage_multi_bib_items.result.column.value.item_linked_to_bib');
+ } else {
+ row_params.row.my.result = catStrings.getString('staff.cat.manage_multi_bib_items.result.column.value.item_native_to_bib');
+ }
+ }
+ }
+ list.refresh_row( row_params );
+ } catch(E) {
+ alert('Error in manage_multi_home_items.js, handle_submit, acp details callback: ' + E);
+ }
+ }
+
+ if (my_bpbcm) {
+ net.simple_request(
+ 'FM_ACP_DETAILS', // FIXME: want this to be authoritative
+ [ ses(), my_bpbcm.target_copy() ],
+ handle_req
+ );
+ } else {
+ net.simple_request(
+ 'FM_ACP_DETAILS_VIA_BARCODE.authoritative',
+ [ ses(), barcode ],
+ handle_req
+ );
+ }
+
+ } catch(E) {
+ alert('Error in manage_multi_home_items.js, handle_submit(): ' + E);
+ }
+}
+
+function populate_list() {
+ try {
+ var pcrud = new openils.PermaCrud( { authtoken :ses() });
+ pcrud.search(
+ 'bpbcm',
+ {
+ peer_record : xul_param('docid')
+ },
+ {
+ async : true,
+ streaming : true,
+ onerror : function(r) {
+ alert('Error in manage_multi_home_items.js, populate_list(), pcrud.search onerror: ' + r);
+ },
+ oncomplete : function() {
+ if (xul_param('barcodes')) { // incoming from Holdings Maintenance
+ handle_barcodes( xul_param('barcodes') );
+ }
+ },
+ onresponse : function(r) {
+ try {
+ var my_bpbcm = openils.Util.readResponse(r);
+ if (typeof my_bpbcm.ils_event != 'undefined') { throw(my_bpbcm); }
+ handle_submit(false,my_bpbcm);
+ } catch(E) {
+ alert('Error in manage_multi_home_items.js, populate_list(), pcrud.search onresponse: ' + E);
+ }
+ }
+ }
+ );
+
+ } catch(E) {
+ alert('Error in manage_multi_home_items.js, populate_list(): ' + E);
+ }
+}
+
+function handle_change() {
+ try {
+ var node_list = list.retrieve_selection();
+ var eligibles = [];
+ for (var i = 0; i < node_list.length; i++) {
+ var retrieve_id = node_list[i].getAttribute('retrieve_id');
+ if (retrieve_id && retrieve_id != 'undefined') {
+ eligibles.push( retrieve_id );
+ }
+ }
+ if (eligibles.length > 0) {
+ var new_peer_type = widget_prompt( $('bpt_menu').cloneNode(true), {
+ 'title' : catStrings.getString('staff.cat.manage_multi_bib_items.prompt.title')
+ });
+
+ if (new_peer_type) {
+ var bpbcm_list = [];
+ for (var i = 0; i < eligibles.length; i++) {
+ var obj = rows[ bpbcm_barcode_map[ eligibles[i] ] ].row.my.bpbcm;
+ obj.ischanged(1);
+ obj.peer_type( new_peer_type );
+ bpbcm_list.push( obj );
+ }
+ var pcrud = new openils.PermaCrud( { authtoken :ses() });
+ pcrud.update(
+ bpbcm_list, {
+ 'async' : false,
+ 'onerror': function(r) {
+ dump('onerror: ' + r + '\n');
+ },
+ 'onresponse': function(r) {
+ dump('onresponse: ' + r + '\n');
+ },
+ 'oncomplete': function(r,ids) {
+ dump('oncomplete: r = ' + r + '\n\tids = ' + js2JSON(ids) + '\n');
+ for (var i = 0; i < ids.length; i++) {
+ var bpbcm_id = ids[i];
+ try {
+ rows[ bpbcm_barcode_map[ bpbcm_id ] ].row.my.bpbcm.peer_type( new_peer_type );
+ rows[ bpbcm_barcode_map[ bpbcm_id ] ].row.my.result = catStrings.getString('staff.cat.manage_multi_bib_items.result.column.value.peer_type_updated');
+ list.refresh_row( rows[ bpbcm_barcode_map[ bpbcm_id ] ] );
+ } catch(E) {
+ alert('error in oncomplete: ' + E);
+ }
+ }
+ }
+ }
+ );
+ }
+ }
+
+ } catch(E) {
+ alert('Error in manage_multi_home_items.js, handle_change(): ' + E);
+ }
+}
+
+function handle_remove() {
+ try {
+ var node_list = list.retrieve_selection();
+ var eligibles = [];
+ for (var i = 0; i < node_list.length; i++) {
+ var retrieve_id = node_list[i].getAttribute('retrieve_id');
+ if (retrieve_id && retrieve_id != 'undefined') {
+ eligibles.push( retrieve_id );
+ }
+ }
+ if (eligibles.length > 0) {
+ if (window.confirm(
+ eligibles.length == 1
+ ? catStrings.getFormattedString(
+ 'staff.cat.manage_multi_bib_items.prompt.confirm.unlink_item_from_bib.singular',
+ [ xul_param('docid') ]
+ )
+ : catStrings.getFormattedString(
+ 'staff.cat.manage_multi_bib_items.prompt.confirm.unlink_item_from_bib.plural',
+ [ xul_param('docid'), eligibles.length ]
+ ))
+ ) {
+ var bpbcm_list = [];
+ for (var i = 0; i < eligibles.length; i++) {
+ var obj = rows[ bpbcm_barcode_map[ eligibles[i] ] ].row.my.bpbcm;
+ obj.isdeleted(1);
+ bpbcm_list.push( obj );
+ }
+ var pcrud = new openils.PermaCrud( { authtoken :ses() });
+ pcrud.eliminate(
+ bpbcm_list, {
+ 'async' : false,
+ 'onerror': function(r) {
+ dump('onerror: ' + r + '\n');
+ },
+ 'onresponse': function(r) {
+ dump('onresponse: ' + r + '\n');
+ },
+ 'oncomplete': function(r,ids) {
+ dump('oncomplete: r = ' + r + '\n\tids = ' + js2JSON(ids) + '\n');
+ for (var i = 0; i < ids.length; i++) {
+ var bpbcm_id = ids[i];
+ try {
+ var node = rows[ bpbcm_barcode_map[ bpbcm_id ] ].my_node;
+ var parentNode = node.parentNode;
+ parentNode.removeChild( node );
+ delete(rows[ bpbcm_barcode_map[ bpbcm_id ] ]);
+ } catch(E) {
+ alert('error in oncomplete: ' + E);
+ }
+ }
+ }
+ }
+ );
+ }
+ }
+
+ } catch(E) {
+ alert('Error in manage_multi_home_items.js, handle_remove(): ' + E);
+ }
+}
+
+function handle_opac() {
+ try {
+ var node_list = list.retrieve_selection();
+ var eligibles = [];
+ for (var i = 0; i < node_list.length; i++) {
+ var retrieve_id = node_list[i].getAttribute('retrieve_id');
+ if (retrieve_id && retrieve_id != 'undefined') {
+ eligibles.push( retrieve_id );
+ }
+ }
+ if (eligibles.length > 0) {
+ var selection_list = [];
+ for (var i = 0; i < eligibles.length; i++) {
+ selection_list.push({
+ 'barcode' : bpbcm_barcode_map[ eligibles[i] ]
+ });
+ }
+ cat.util.show_in_opac(selection_list);
+ }
+
+ } catch(E) {
+ alert('Error in manage_multi_home_items.js, handle_opac(): ' + E);
+ }
+}
+
+function handle_barcodes(barcodes) {
+ try {
+ var funcs = [];
+
+ for (var i = 0; i < barcodes.length; i++) {
+ if (typeof rows[barcodes[i]] == 'undefined') {
+ funcs.push(
+ function(barcode) {
+
+ return function() {
+ handle_submit(true,null,barcode);
+ };
+
+ }(barcodes[i])
+ )
+ }
+ }
+
+ JSAN.use('util.exec'); var exec = new util.exec();
+ exec.timer( funcs, 500 );
+
+ funcs.push(
+ function() {
+ exec.clear_timer();
+ }
+ );
+
+ } catch(E) {
+ alert('Error in manage_multi_home_items.js, handle_barcodes(): ' + E);
+ }
+}
--- /dev/null
+<?xml version="1.0"?>
+<!-- Application: Evergreen Staff Client -->
+<!-- Screen: Add Multi-Home Items to specific Bib -->
+
+<!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
+<!-- STYLESHEETS -->
+<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
+<?xml-stylesheet href="/xul/server/skin/global.css" type="text/css"?>
+
+<!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
+<!-- LOCALIZATION -->
+<!DOCTYPE window PUBLIC "" ""[
+ <!--#include virtual="/opac/locale/${locale}/lang.dtd"-->
+]>
+
+<!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
+<!-- OVERLAYS -->
+<?xul-overlay href="/xul/server/OpenILS/util_overlay.xul"?>
+<?xul-overlay href="/xul/server/cat/bib_brief_overlay.xul"?>
+
+<window id="main_win"
+ onload="try { my_init(); font_helper(); persist_helper(); } catch(E) { alert(E); }"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+ <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
+ <!-- BEHAVIOR -->
+ <script type="text/javascript">
+ var myPackageDir = 'open_ils_staff_client'; var IAMXUL = true;
+ </script>
+ <scripts id="openils_util_scripts"/>
+
+ <messagecatalog id="catStrings" src="/xul/server/locale/<!--#echo var='locale'-->/cat.properties" />
+ <messagecatalog id="circStrings" src="/xul/server/locale/<!--#echo var='locale'-->/circ.properties" />
+
+ <script type="text/javascript" src="/xul/server/main/JSAN.js"/>
+ <script type="text/javascript" src="manage_multi_home_items.js"/>
+
+ <commandset>
+ <command id="opac"
+ label="&staff.cat.manage_multi_bib_items.actions.menu_entry.show_in_opac.label;"
+ accesskey="&staff.cat.manage_multi_bib_items.actions.menu_entry.show_in_opac.accesskey;"/>
+ <command id="change"
+ label="&staff.cat.manage_multi_bib_items.actions.menu_entry.change_peer_type.label;"
+ accesskey="&staff.cat.manage_multi_bib_items.actions.menu_entry.change_peer_type.accesskey;"/>
+ <command id="remove"
+ label="&staff.cat.manage_multi_bib_items.actions.menu_entry.unlink_from_bib.label;"
+ accesskey="&staff.cat.manage_multi_bib_items.actions.menu_entry.unlink_from_bib.accesskey;"/>
+ </commandset>
+
+ <popupset>
+ <popup id="actions">
+ <menuitem command="opac" />
+ <menuitem command="change" />
+ <menuitem command="remove" />
+ </popup>
+ </popupset>
+
+ <groupbox id="bib_brief_groupbox" hidden="true">
+ <caption label="&staff.cat.bib_brief.record_summary;"/>
+ <grid id="bib_brief_grid"/>
+ </groupbox>
+ <groupbox flex="1" class="my_overflow">
+ <caption label="&staff.cat.manage_multi_bib_items.caption;"/>
+ <hbox>
+ <label control="bpt_menu"
+ value="&staff.cat.manage_multi_bib_items.peer_type.menu.label;"
+ accesskey="&staff.cat.manage_multi_bib_items.peer_type.menu.accesskey;"/>
+ <hbox id="menu_placeholder" />
+ <label control="scanbox"
+ value="&staff.cat.manage_multi_bib_items.barcode.textbox.label;"
+ accesskey="&staff.cat.manage_multi_bib_items.barcode.textbox.accesskey;"/>
+ <textbox id="scanbox"/>
+ <button id="submit"
+ label="&staff.cat.manage_multi_bib_items.barcode.submit.label;"
+ accesskey="&staff.cat.manage_multi_bib_items.barcode.submit.accesskey;"/>
+ <spacer flex="1"/>
+ <menubar>
+ <menu label="&staff.cat.manage_multi_bib_items.actions.menu.label;" accesskey="&staff.cat.manage_multi_bib_items.actions.menu.accesskey;">
+ <menupopup>
+ <menuitem command="opac" />
+ <menuitem command="change" />
+ <menuitem command="remove" />
+ </menupopup>
+ </menu>
+ </menubar>
+ </hbox>
+ <tree id="list" flex="1" enableColumnDrag="true" context="actions"/>
+ <hbox id="list_actions" />
+ </groupbox>
+
+</window>
+
staff.cat.bib_brief.inactive=(Inactive)
staff.cat.bib_brief.noncat=(Not Cataloged)
staff.cat.bib_brief.noncat.alert=Item not cataloged.
+# %1$s = Bib Record ID
+staff.cat.manage_multi_bib_items.tab_name=Manage Foreign Items for Bib %1$s
+staff.cat.manage_multi_bib_items.result.column.value.error=Error
+staff.cat.manage_multi_bib_items.result.column.value.success=Success
+staff.cat.manage_multi_bib_items.result.column.value.failed=Failed
+staff.cat.manage_multi_bib_items.result.column.value.item_linked_to_bib=Item linked to bib
+staff.cat.manage_multi_bib_items.result.column.value.item_native_to_bib=Item native to bib
+staff.cat.manage_multi_bib_items.result.column.value.peer_type_updated=Peer Type updated
+staff.cat.manage_multi_bib_items.prompt.title=Change Peer Type
+# %1$s = Bib Record ID
+staff.cat.manage_multi_bib_items.prompt.confirm.unlink_item_from_bib.singular=Unlink selected item from Bib %1$s
+# %1$s = Bib Record ID, %2$s = Number of selected items
+staff.cat.manage_multi_bib_items.prompt.confirm.unlink_item_from_bib.plural=Unlink %2$s selected items from Bib %1$s
staff.cat.copy_browser.add_item.title=Add Item
staff.cat.copy_browser.add_item.error=copy browser -> add copies
staff.cat.copy_browser.add_items_bucket.error=copy browser -> add copies to bucket
staff.cat.copy_browser.transfer.unexpected_error=All volumes not likely transferred.
staff.cat.copy_browser.transfer_items.missing_volume=Please mark a volume as the destination from within holdings maintenance and then try this again.
staff.cat.copy_browser.transfer_items.unexpected_error=All copies not likely transferred.
+staff.cat.copy_browser.link_as_multi_bib.missing_bib=Please Mark a bib record as a Target for Foreign Items and try this again.
staff.cat.copy_browser.missing_library=Missing library list.
staff.cat.copy_browser.consortial_copy_count.error=Error retrieving consortial copy count.
staff.cat.copy_browser.list_init.tree_location=Location/Barcode