LP#1673857: schema, IDL, library settings & perms for copy tags
authorGalen Charlton <gmc@equinoxinitiative.org>
Fri, 17 Mar 2017 21:46:37 +0000 (17:46 -0400)
committerGalen Charlton <gmc@equinoxinitiative.org>
Mon, 24 Jul 2017 15:28:55 +0000 (11:28 -0400)
Three new tables are added to store copy tags:

* config.copy_tag_type

  Defines types that can be used for distinguishing between
  classes of copy tags when searching the catalog. The
  seed data includes a 'bookplate' type by default. The new
  permission ADMIN_COPY_TAG_TYPES controls C/U/D access to this
  table.

* asset.copy_tag

  The actual copy tag values. Copy tags have both labels and values,
  and since at least one interface allows creating copy tags
  on the fly, a trigger will set the value of a new tag
  to its label if the value is null. asset.copy_tag also has a flag
  for setting whether given tag should be searchable (and visible)
  in the public catalog or not. The new permission ADMIN_COPY_TAG
  controls C/U/D access to this table.

* asset.copy_tag_copy_map

  This stores the link between copies and their tags. Only the
  UPDATE_COPY permission is required in order to set tag mappings.

The new library setting is opac.search.enable_bookplate_search, which
controls whether or not to display a "Digital Bookplate" entry in the
catalog search fields dropdowns.

Signed-off-by: Galen Charlton <gmc@equinoxinitiative.org>
Signed-off-by: Josh Stompro <stomproj@larl.org>
Signed-off-by: Galen Charlton <gmc@equinoxinitiative.org>
Conflicts:
Open-ILS/src/sql/Pg/950.data.seed-values.sql

Signed-off-by: Galen Charlton <gmc@equinoxinitiative.org>
Open-ILS/examples/fm_IDL.xml
Open-ILS/src/sql/Pg/002.schema.config.sql
Open-ILS/src/sql/Pg/040.schema.asset.sql
Open-ILS/src/sql/Pg/800.fkeys.sql
Open-ILS/src/sql/Pg/950.data.seed-values.sql
Open-ILS/src/sql/Pg/upgrade/XXXX.schema.copy_tags.sql [new file with mode: 0644]

index f84734a..bc99527 100644 (file)
@@ -6854,6 +6854,7 @@ SELECT  usr,
                        <field reporter:label="Peer Records" name="peer_records" oils_persist:virtual="true" reporter:datatype="link"/>
                        <field reporter:label="Last Captured Hold" name="last_captured_hold" oils_persist:virtual="true" reporter:datatype="link"/>
                        <field reporter:label="Has Holds" name="holds_count" oils_persist:virtual="true" reporter:datatype="link"/>
+                       <field reporter:label="Copy Tags" name="tags" oils_persist:virtual="true" reporter:datatype="link"/>
                </fields>
                <links>
                        <link field="age_protect" reltype="has_a" key="id" map="" class="crahp"/>
@@ -6879,6 +6880,7 @@ SELECT  usr,
                        <link field="last_captured_hold" reltype="has_a" key="current_copy" map="" class="alhr"/>
                        <link field="floating" reltype="has_a" key="id" map="" class="cfg"/>
                        <link field="holds_count" reltype="might_have" key="id" map="" class="hasholdscount"/>
+                       <link field="tags" reltype="has_many" key="copy" map="" class="acptcm"/>
                </links>
         <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
             <actions>
@@ -11608,6 +11610,72 @@ SELECT  usr,
                        </actions>
                </permacrud>
        </class>
+       <class id="cctt" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="config::copy_tag_type" oils_persist:tablename="config.copy_tag_type" reporter:label="Copy Tag Types" oils_persist:field_safe="true">
+               <fields oils_persist:primary="code">
+                       <field reporter:label="Code" name="code" reporter:selector="label" reporter:datatype="id" oils_obj:required="true"/>
+                       <field reporter:label="Label" name="label" reporter:datatype="text" oils_obj:required="true"/>
+                       <field reporter:label="Owner" name="owner" reporter:datatype="org_unit" oils_obj:required="true"/>
+               </fields>
+               <links>
+                       <link field="owner" reltype="has_a" key="id" map="" class="aou"/>
+               </links>
+               <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
+                       <actions>
+                               <create permission="ADMIN_COPY_TAG_TYPES" context_field="owner"/>
+                               <retrieve/>
+                               <update permission="ADMIN_COPY_TAG_TYPES" context_field="owner"/>
+                               <delete permission="ADMIN_COPY_TAG_TYPES" context_field="owner"/>
+                       </actions>
+               </permacrud>
+       </class>
+       <class id="acpt" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="asset::copy_tag" oils_persist:tablename="asset.copy_tag" reporter:label="Copy Tags" oils_persist:field_safe="true">
+               <fields oils_persist:primary="id" oils_persist:sequence="asset.copy_tag_id_seq">
+                       <field reporter:label="ID" name="id" reporter:datatype="id"/>
+                       <field reporter:label="Copy Tag Type" name="tag_type" reporter:datatype="link"/>
+                       <field reporter:label="Label" name="label" reporter:datatype="text"/>
+                       <field reporter:label="Value" name="value" reporter:datatype="text"/>
+                       <field reporter:label="Staff Note" name="staff_note" reporter:datatype="text"/>
+                       <field reporter:label="Is OPAC Visible?" name="pub" reporter:datatype="bool"/>
+                       <field reporter:label="Owner" name="owner" reporter:datatype="org_unit" oils_obj:required="true"/>
+               </fields>
+               <links>
+                       <link field="tag_type" reltype="has_a" key="code" map="" class="cctt"/>
+                       <link field="owner" reltype="has_a" key="id" map="" class="aou"/>
+               </links>
+               <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
+                       <actions>
+                               <create permission="ADMIN_COPY_TAGS" context_field="owner"/>
+                               <retrieve/>
+                               <update permission="ADMIN_COPY_TAGS" context_field="owner"/>
+                               <delete permission="ADMIN_COPY_TAGS" context_field="owner"/>
+                       </actions>
+               </permacrud>
+       </class>
+       <class id="acptcm" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="asset::copy_tag_copy_map" oils_persist:tablename="asset.copy_tag_copy_map" reporter:label="Copy Tag Copy Map" oils_persist:field_safe="true">
+               <fields oils_persist:primary="id" oils_persist:sequence="asset.copy_tag_copy_map_id_seq">
+                       <field reporter:label="ID" name="id" reporter:datatype="id"/>
+                       <field reporter:label="Copy" name="copy" reporter:datatype="link"/>
+                       <field reporter:label="Tag" name="tag" reporter:datatype="link"/>
+               </fields>
+               <links>
+                       <link field="copy" reltype="has_a" key="id" map="" class="acp"/>
+                       <link field="tag" reltype="has_a" key="id" map="" class="acpt"/>
+               </links>
+               <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
+                       <actions>
+                               <create permission="UPDATE_COPY">
+                    <context link="copy" field="circ_lib"/>
+                </create>
+                               <retrieve/>
+                               <update permission="UPDATE_COPY">
+                    <context link="copy" field="circ_lib"/>
+                </update>
+                               <delete permission="UPDATE_COPY">
+                    <context link="copy" field="circ_lib"/>
+                </delete>
+                       </actions>
+               </permacrud>
+       </class>
        <class id="hasholdscount" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="action::has_holds_count" reporter:label="Copy Has Holds Count" oils_persist:readonly="true">
         <oils_persist:source_definition>
        SELECT ahcm.target_copy AS id,count(*) AS count
index 07d491e..9edf3b1 100644 (file)
@@ -1219,4 +1219,13 @@ ALTER TABLE config.marc_subfield
            )
           );
 
+CREATE TABLE config.copy_tag_type (
+    code            TEXT NOT NULL PRIMARY KEY,
+    label           TEXT NOT NULL,
+    owner           INTEGER NOT NULL -- REFERENCES actor.org_unit (id) DEFERRABLE INITIALLY DEFERRED
+);
+
+CREATE INDEX config_copy_tag_type_owner_idx
+    ON config.copy_tag_type (owner);
+
 COMMIT;
index 283b476..267b302 100644 (file)
@@ -905,5 +905,60 @@ BEGIN
 END;
 $F$ LANGUAGE PLPGSQL;
 
+CREATE TABLE asset.copy_tag (
+    id              SERIAL PRIMARY KEY,
+    tag_type        TEXT REFERENCES config.copy_tag_type (code)
+                    ON UPDATE CASCADE ON DELETE CASCADE,
+    label           TEXT NOT NULL,
+    value           TEXT NOT NULL,
+    index_vector    tsvector NOT NULL,
+    staff_note      TEXT,
+    pub             BOOLEAN DEFAULT TRUE,
+    owner           INTEGER NOT NULL REFERENCES actor.org_unit (id)
+);
+
+CREATE INDEX asset_copy_tag_label_idx
+    ON asset.copy_tag (label);
+CREATE INDEX asset_copy_tag_label_lower_idx
+    ON asset.copy_tag (evergreen.lowercase(label));
+CREATE INDEX asset_copy_tag_index_vector_idx
+    ON asset.copy_tag
+    USING GIN(index_vector);
+CREATE INDEX asset_copy_tag_tag_type_idx
+    ON asset.copy_tag (tag_type);
+CREATE INDEX asset_copy_tag_owner_idx
+    ON asset.copy_tag (owner);
+
+CREATE OR REPLACE FUNCTION asset.set_copy_tag_value () RETURNS TRIGGER AS $$
+BEGIN
+    IF NEW.value IS NULL THEN
+        NEW.value = NEW.label;        
+    END IF;
+
+    RETURN NEW;
+END;
+$$ LANGUAGE 'plpgsql';
+
+-- name of following trigger chosen to ensure it runs first
+CREATE TRIGGER asset_copy_tag_do_value
+    BEFORE INSERT OR UPDATE ON asset.copy_tag
+    FOR EACH ROW EXECUTE PROCEDURE asset.set_copy_tag_value();
+CREATE TRIGGER asset_copy_tag_fti_trigger
+    BEFORE UPDATE OR INSERT ON asset.copy_tag
+    FOR EACH ROW EXECUTE PROCEDURE oils_tsearch2('default');
+
+CREATE TABLE asset.copy_tag_copy_map (
+    id              BIGSERIAL PRIMARY KEY,
+    copy            BIGINT REFERENCES asset.copy (id)
+                    ON UPDATE CASCADE ON DELETE CASCADE,
+    tag             INTEGER REFERENCES asset.copy_tag (id)
+                    ON UPDATE CASCADE ON DELETE CASCADE
+);
+
+CREATE INDEX asset_copy_tag_copy_map_copy_idx
+    ON asset.copy_tag_copy_map (copy);
+CREATE INDEX asset_copy_tag_copy_map_tag_idx
+    ON asset.copy_tag_copy_map (tag);
+
 COMMIT;
 
index ed2e79f..7d10125 100644 (file)
@@ -175,4 +175,6 @@ ALTER TABLE asset.copy_template ADD CONSTRAINT asset_copy_template_floating_fkey
 ALTER TABLE config.marc_field ADD CONSTRAINT config_marc_field_owner_fkey FOREIGN KEY (owner) REFERENCES actor.org_unit(id) DEFERRABLE INITIALLY DEFERRED;
 ALTER TABLE config.marc_subfield ADD CONSTRAINT config_marc_subfield_owner_fkey FOREIGN KEY (owner) REFERENCES actor.org_unit(id) DEFERRABLE INITIALLY DEFERRED;
 
+ALTER TABLE config.copy_tag_type ADD CONSTRAINT copy_tag_type_owner_fkey FOREIGN KEY (owner) REFERENCES  actor.org_unit(id) DEFERRABLE INITIALLY DEFERRED;
+
 COMMIT;
index ffa6732..eef768d 100644 (file)
@@ -1675,7 +1675,11 @@ INSERT INTO permission.perm_list ( id, code, description ) VALUES
  ( 588, 'ITEM_NOT_HOLDABLE.override', oils_i18n_gettext( 588,
     'Override the ITEM_NOT_HOLDABLE event', 'ppl', 'description' )),
  ( 589, 'ITEM_RENTAL_FEE_REQUIRED.override', oils_i18n_gettext( 589,
-    'Override the ITEM_RENTAL_FEE_REQUIRED event', 'ppl', 'description' ))
+    'Override the ITEM_RENTAL_FEE_REQUIRED event', 'ppl', 'description' )),
+ ( 590, 'ADMIN_COPY_TAG_TYPES', oils_i18n_gettext( 590,
+    'Administer copy tag types', 'ppl', 'description' )),
+ ( 591, 'ADMIN_COPY_TAG', oils_i18n_gettext( 591,
+    'Administer copy tag', 'ppl', 'description' ))
 ;
 
 SELECT SETVAL('permission.perm_list_id_seq'::TEXT, 1000);
@@ -16876,3 +16880,25 @@ INSERT into config.org_unit_setting_type (
     )
     ,'string'
 );
+
+INSERT INTO config.org_unit_setting_type
+    (name, label, description, grp, datatype)
+VALUES (
+    'opac.search.enable_bookplate_search',
+    oils_i18n_gettext(
+        'opac.search.enable_bookplate_search',
+        'Enable Digital Bookplate Search',
+        'coust',
+        'label'
+    ),
+    oils_i18n_gettext(
+        'opac.search.enable_bookplate_search',
+        'If enabled, adds a "Digital Bookplate" option to the query type selectors in the public catalog for search on copy tags.',   
+        'coust',
+        'description'
+    ),
+    'opac',
+    'bool'
+);
+
+INSERT INTO config.copy_tag_type (code, label, owner) VALUES ('bookplate', 'Digital Bookplate', 1);
diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.copy_tags.sql b/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.copy_tags.sql
new file mode 100644 (file)
index 0000000..07cabb9
--- /dev/null
@@ -0,0 +1,96 @@
+BEGIN;
+
+CREATE TABLE config.copy_tag_type (
+    code            TEXT NOT NULL PRIMARY KEY,
+    label           TEXT NOT NULL,
+    owner           INTEGER NOT NULL REFERENCES actor.org_unit (id) DEFERRABLE INITIALLY DEFERRED
+);
+
+CREATE INDEX config_copy_tag_type_owner_idx
+    ON config.copy_tag_type (owner);
+
+CREATE TABLE asset.copy_tag (
+    id              SERIAL PRIMARY KEY,
+    tag_type        TEXT REFERENCES config.copy_tag_type (code)
+                    ON UPDATE CASCADE ON DELETE CASCADE,
+    label           TEXT NOT NULL,
+    value           TEXT NOT NULL,
+    index_vector    tsvector NOT NULL,
+    staff_note      TEXT,
+    pub             BOOLEAN DEFAULT TRUE,
+    owner           INTEGER NOT NULL REFERENCES actor.org_unit (id)
+);
+
+CREATE INDEX asset_copy_tag_label_idx
+    ON asset.copy_tag (label);
+CREATE INDEX asset_copy_tag_label_lower_idx
+    ON asset.copy_tag (evergreen.lowercase(label));
+CREATE INDEX asset_copy_tag_index_vector_idx
+    ON asset.copy_tag
+    USING GIN(index_vector);
+CREATE INDEX asset_copy_tag_tag_type_idx
+    ON asset.copy_tag (tag_type);
+CREATE INDEX asset_copy_tag_owner_idx
+    ON asset.copy_tag (owner);
+
+CREATE OR REPLACE FUNCTION asset.set_copy_tag_value () RETURNS TRIGGER AS $$
+BEGIN
+    IF NEW.value IS NULL THEN
+        NEW.value = NEW.label;        
+    END IF;
+
+    RETURN NEW;
+END;
+$$ LANGUAGE 'plpgsql';
+
+-- name of following trigger chosen to ensure it runs first
+CREATE TRIGGER asset_copy_tag_do_value
+    BEFORE INSERT OR UPDATE ON asset.copy_tag
+    FOR EACH ROW EXECUTE PROCEDURE asset.set_copy_tag_value();
+CREATE TRIGGER asset_copy_tag_fti_trigger
+    BEFORE UPDATE OR INSERT ON asset.copy_tag
+    FOR EACH ROW EXECUTE PROCEDURE oils_tsearch2('default');
+
+CREATE TABLE asset.copy_tag_copy_map (
+    id              BIGSERIAL PRIMARY KEY,
+    copy            BIGINT REFERENCES asset.copy (id)
+                    ON UPDATE CASCADE ON DELETE CASCADE,
+    tag             INTEGER REFERENCES asset.copy_tag (id)
+                    ON UPDATE CASCADE ON DELETE CASCADE
+);
+
+CREATE INDEX asset_copy_tag_copy_map_copy_idx
+    ON asset.copy_tag_copy_map (copy);
+CREATE INDEX asset_copy_tag_copy_map_tag_idx
+    ON asset.copy_tag_copy_map (tag);
+
+INSERT INTO config.copy_tag_type (code, label, owner) VALUES ('bookplate', 'Digital Bookplate', 1);
+
+INSERT INTO permission.perm_list ( id, code, description ) VALUES
+ ( 590, 'ADMIN_COPY_TAG_TYPES', oils_i18n_gettext( 590,
+    'Administer copy tag types', 'ppl', 'description' )),
+ ( 591, 'ADMIN_COPY_TAG', oils_i18n_gettext( 591,
+    'Administer copy tag', 'ppl', 'description' ))
+;
+
+INSERT INTO config.org_unit_setting_type
+    (name, label, description, grp, datatype)
+VALUES (
+    'opac.search.enable_bookplate_search',
+    oils_i18n_gettext(
+        'opac.search.enable_bookplate_search',
+        'Enable Digital Bookplate Search',
+        'coust',
+        'label'
+    ),
+    oils_i18n_gettext(
+        'opac.search.enable_bookplate_search',
+        'If enabled, adds a "Digital Bookplate" option to the query type selectors in the public catalog for search on copy tags.',   
+        'coust',
+        'description'
+    ),
+    'opac',
+    'bool'
+);
+
+COMMIT;