]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/sql/Pg/upgrade/0504.schema.parts_and_cnaffix.sql
Monograph Parts; Unified vol/copy wizard; Call Number affixes; Instant Detail
[Evergreen.git] / Open-ILS / src / sql / Pg / upgrade / 0504.schema.parts_and_cnaffix.sql
1 BEGIN;
2
3 INSERT INTO config.upgrade_log (version) VALUES ('0504'); -- miker
4
5 CREATE TABLE biblio.monograph_part (
6     id              SERIAL  PRIMARY KEY,
7     record          BIGINT  NOT NULL REFERENCES biblio.record_entry (id),
8     label           TEXT    NOT NULL,
9     label_sortkey   TEXT    NOT NULL,
10     CONSTRAINT record_label_unique UNIQUE (record,label)
11 );
12
13 CREATE OR REPLACE FUNCTION biblio.normalize_biblio_monograph_part_sortkey () RETURNS TRIGGER AS $$
14 BEGIN
15     NEW.label_sortkey := REGEXP_REPLACE(
16         lpad_number_substrings(
17             naco_normalize(NEW.label),
18             '0',
19             10
20         ),
21         E'\\s+',
22         '',
23         'g'
24     );
25     RETURN NEW;
26 END;
27 $$ LANGUAGE PLPGSQL;
28
29 CREATE TRIGGER norm_sort_label BEFORE INSERT OR UPDATE ON biblio.monograph_part FOR EACH ROW EXECUTE PROCEDURE biblio.normalize_biblio_monograph_part_sortkey();
30
31 CREATE TABLE asset.copy_part_map (
32     id          SERIAL  PRIMARY KEY,
33     target_copy BIGINT  NOT NULL, -- points o asset.copy
34     part        INT     NOT NULL REFERENCES biblio.monograph_part (id) ON DELETE CASCADE
35 );
36 CREATE UNIQUE INDEX copy_part_map_cp_part_idx ON asset.copy_part_map (target_copy, part);
37
38 CREATE OR REPLACE FUNCTION asset.normalize_affix_sortkey () RETURNS TRIGGER AS $$
39 BEGIN
40     NEW.label_sortkey := REGEXP_REPLACE(
41         lpad_number_substrings(
42             naco_normalize(NEW.label),
43             '0',
44             10
45         ),
46         E'\\s+',
47         '',
48         'g'
49     );
50     RETURN NEW;
51 END;
52 $$ LANGUAGE PLPGSQL;
53
54 CREATE TABLE asset.call_number_prefix (
55        id                      SERIAL   PRIMARY KEY,
56        owning_lib          INT                 NOT NULL REFERENCES actor.org_unit (id),
57        label               TEXT                NOT NULL, -- i18n
58        label_sortkey   TEXT
59 );
60 CREATE TRIGGER prefix_normalize_tgr BEFORE INSERT OR UPDATE ON asset.call_number_prefix FOR EACH ROW EXECUTE PROCEDURE asset.normalize_affix_sortkey();
61 CREATE UNIQUE INDEX asset_call_number_prefix_once_per_lib ON asset.call_number_prefix (label, owning_lib);
62 CREATE INDEX asset_call_number_prefix_sortkey_idx ON asset.call_number_prefix (label_sortkey);
63
64 CREATE TABLE asset.call_number_suffix (
65        id                      SERIAL   PRIMARY KEY,
66        owning_lib          INT                 NOT NULL REFERENCES actor.org_unit (id),
67        label               TEXT                NOT NULL, -- i18n
68        label_sortkey   TEXT
69 );
70 CREATE TRIGGER suffix_normalize_tgr BEFORE INSERT OR UPDATE ON asset.call_number_suffix FOR EACH ROW EXECUTE PROCEDURE asset.normalize_affix_sortkey();
71 CREATE UNIQUE INDEX asset_call_number_suffix_once_per_lib ON asset.call_number_suffix (label, owning_lib);
72 CREATE INDEX asset_call_number_suffix_sortkey_idx ON asset.call_number_suffix (label_sortkey);
73
74 INSERT INTO asset.call_number_suffix (id, owning_lib, label) VALUES (-1, 1, '');
75 INSERT INTO asset.call_number_prefix (id, owning_lib, label) VALUES (-1, 1, '');
76
77 DROP INDEX IF EXISTS asset.asset_call_number_label_once_per_lib;
78
79 ALTER TABLE asset.call_number
80     ADD COLUMN prefix INT NOT NULL DEFAULT -1 REFERENCES asset.call_number_prefix(id) DEFERRABLE INITIALLY DEFERRED,
81     ADD COLUMN suffix INT NOT NULL DEFAULT -1 REFERENCES asset.call_number_suffix(id) DEFERRABLE INITIALLY DEFERRED;
82
83 CREATE UNIQUE INDEX asset_call_number_label_once_per_lib ON asset.call_number (record, owning_lib, label, prefix, suffix) WHERE deleted = FALSE OR deleted IS FALSE;
84
85 INSERT INTO config.org_unit_setting_type ( name, label, description, datatype ) VALUES (
86     'ui.cat.volume_copy_editor.horizontal',
87     oils_i18n_gettext(
88         'ui.cat.volume_copy_editor.horizontal',
89         'GUI: Horizontal layout for Volume/Copy Creator/Editor.',
90         'coust', 'label'),
91     oils_i18n_gettext(
92         'ui.cat.volume_copy_editor.horizontal',
93         'The main entry point for this interface is in Holdings Maintenance, Actions for Selected Rows, Edit Item Attributes / Call Numbers / Replace Barcodes.  This setting changes the top and bottom panes for that interface into left and right panes.',
94         'coust', 'description'),
95     'bool'
96 );
97
98
99 CREATE OR REPLACE FUNCTION unapi.bmp ( obj_id BIGINT, format TEXT,  ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$
100         SELECT  XMLELEMENT(
101                     name monograph_part,
102                     XMLATTRIBUTES(
103                         'http://open-ils.org/spec/holdings/v1' AS xmlns,
104                         'tag:open-ils.org:U2@bmp/' || id AS id,
105                         id AS ident,
106                         label,
107                         label_sortkey,
108                         'tag:open-ils.org:U2@bre/' || record AS record
109                     ),
110                     CASE 
111                         WHEN ('acp' = ANY ($4)) THEN
112                             XMLELEMENT( name copies,
113                                 (SELECT XMLAGG(acp) FROM (
114                                     SELECT  unapi.acp( cp.id, 'xml', 'copy', array_remove_item_by_value($4,'bmp'), $5, $6, $7, $8)
115                                       FROM  asset.copy cp
116                                             JOIN asset.copy_part_map cpm ON (cpm.target_copy = cp.id)
117                                       WHERE cpm.part = $1
118                                       ORDER BY COALESCE(cp.copy_number,0), cp.barcode
119                                       LIMIT $7
120                                       OFFSET $8
121                                 )x)
122                             )
123                         ELSE NULL
124                     END,
125                     CASE WHEN ('bre' = ANY ($4)) THEN unapi.bre( record, 'marcxml', 'record', array_remove_item_by_value($4,'bmp'), $5, $6, $7, $8) ELSE NULL END
126                 )
127           FROM  biblio.monograph_part
128           WHERE id = $1
129           GROUP BY id, label, label_sortkey, record;
130 $F$ LANGUAGE SQL;
131
132 CREATE OR REPLACE FUNCTION unapi.acnp ( obj_id BIGINT, format TEXT,  ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$
133         SELECT  XMLELEMENT(
134                     name call_number_prefix,
135                     XMLATTRIBUTES(
136                         'http://open-ils.org/spec/holdings/v1' AS xmlns,
137                         id AS ident,
138                         label,
139                         label_sortkey
140                     ),
141                     unapi.aou( owning_lib, $2, 'owning_lib', array_remove_item_by_value($4,'acnp'), $5, $6, $7, $8)
142                 )
143           FROM  asset.call_number_prefix
144           WHERE id = $1;
145 $F$ LANGUAGE SQL;
146
147 CREATE OR REPLACE FUNCTION unapi.acns ( obj_id BIGINT, format TEXT,  ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$
148         SELECT  XMLELEMENT(
149                     name call_number_suffix,
150                     XMLATTRIBUTES(
151                         'http://open-ils.org/spec/holdings/v1' AS xmlns,
152                         id AS ident,
153                         label,
154                         label_sortkey
155                     ),
156                     unapi.aou( owning_lib, $2, 'owning_lib', array_remove_item_by_value($4,'acns'), $5, $6, $7, $8)
157                 )
158           FROM  asset.call_number_suffix
159           WHERE id = $1;
160 $F$ LANGUAGE SQL;
161
162 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) RETURNS XML AS $F$
163      SELECT  XMLELEMENT(
164                  name holdings,
165                  XMLATTRIBUTES(
166                     'http://open-ils.org/spec/holdings/v1' AS xmlns,
167                     CASE WHEN ('bre' = ANY ('{acn,auri}'::TEXT[] || $5)) THEN 'tag:open-ils.org:U2@bre/' || $1 || '/' || $3 ELSE NULL END AS id
168                  ),
169                  XMLELEMENT(
170                      name counts,
171                      (SELECT  XMLAGG(XMLELEMENT::XML) FROM (
172                          SELECT  XMLELEMENT(
173                                      name count,
174                                      XMLATTRIBUTES('public' as type, depth, org_unit, coalesce(transcendant,0) as transcendant, available, visible as count, unshadow)
175                                  )::text
176                            FROM  asset.opac_ou_record_copy_count($2,  $1)
177                                      UNION
178                          SELECT  XMLELEMENT(
179                                      name count,
180                                      XMLATTRIBUTES('staff' as type, depth, org_unit, coalesce(transcendant,0) as transcendant, available, visible as count, unshadow)
181                                  )::text
182                            FROM  asset.staff_ou_record_copy_count($2, $1)
183                                      ORDER BY 1
184                      )x)
185                  ),
186                  CASE 
187                      WHEN ('bmp' = ANY ($5)) THEN
188                         XMLELEMENT( name monograph_parts,
189                             XMLAGG((SELECT unapi.bmp( id, 'xml', 'monograph_part', array_remove_item_by_value( array_remove_item_by_value($5,'bre'), 'holdings_xml'), $3, $4, $6, $7) FROM biblio.monograph_part WHERE record = $1))
190                         )
191                      ELSE NULL
192                  END,
193                  CASE WHEN ('acn' = ANY ('{acn,auri}'::TEXT[] || $5)) THEN 
194                      XMLELEMENT(
195                          name volumes,
196                          (SELECT XMLAGG(acn) FROM (
197                             SELECT  unapi.acn(acn.id,'xml','volume',array_remove_item_by_value(array_remove_item_by_value('{acn,auri}'::TEXT[] || $5,'holdings_xml'),'bre'), $3, $4, $6, $7)
198                               FROM  asset.call_number acn
199                               WHERE acn.record = $1
200                                     AND EXISTS (
201                                         SELECT  1
202                                           FROM  asset.copy acp
203                                                 JOIN actor.org_unit_descendants(
204                                                     $2,
205                                                     (COALESCE(
206                                                         $4,
207                                                         (SELECT aout.depth
208                                                           FROM  actor.org_unit_type aout
209                                                                 JOIN actor.org_unit aou ON (aou.ou_type = aout.id AND aou.id = $2)
210                                                         )
211                                                     ))
212                                                 ) aoud ON (acp.circ_lib = aoud.id)
213                                           LIMIT 1
214                                     )
215                               ORDER BY label_sortkey
216                               LIMIT $6
217                               OFFSET $7
218                          )x)
219                      )
220                  ELSE NULL END,
221                  CASE WHEN ('ssub' = ANY ('{acn,auri}'::TEXT[] || $5)) THEN 
222                      XMLELEMENT(
223                          name subscriptions,
224                          (SELECT XMLAGG(ssub) FROM (
225                             SELECT  unapi.ssub(id,'xml','subscription','{}'::TEXT[], $3, $4, $6, $7)
226                               FROM  serial.subscription
227                               WHERE record_entry = $1
228                         )x)
229                      )
230                  ELSE NULL END
231              );
232 $F$ LANGUAGE SQL;
233
234 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 ) RETURNS XML AS $F$
235         SELECT  XMLELEMENT(
236                     name copy,
237                     XMLATTRIBUTES(
238                         'http://open-ils.org/spec/holdings/v1' AS xmlns,
239                         'tag:open-ils.org:U2@acp/' || id AS id,
240                         create_date, edit_date, copy_number, circulate, deposit,
241                         ref, holdable, deleted, deposit_amount, price, barcode,
242                         circ_modifier, circ_as_type, opac_visible
243                     ),
244                     unapi.ccs( status, $2, 'status', array_remove_item_by_value($4,'acp'), $5, $6, $7, $8),
245                     unapi.acl( location, $2, 'location', array_remove_item_by_value($4,'acp'), $5, $6, $7, $8),
246                     unapi.aou( circ_lib, $2, 'circ_lib', array_remove_item_by_value($4,'acp'), $5, $6, $7, $8),
247                     unapi.aou( circ_lib, $2, 'circlib', array_remove_item_by_value($4,'acp'), $5, $6, $7, $8),
248                     CASE WHEN ('acn' = ANY ($4)) THEN unapi.acn( call_number, $2, 'call_number', array_remove_item_by_value($4,'acp'), $5, $6, $7, $8) ELSE NULL END,
249                     XMLELEMENT( name copy_notes,
250                         CASE 
251                             WHEN ('acpn' = ANY ($4)) THEN
252                                 XMLAGG((SELECT unapi.acpn( id, 'xml', 'copy_note', array_remove_item_by_value($4,'acp'), $5, $6, $7, $8) FROM asset.copy_note WHERE owning_copy = cp.id AND pub))
253                             ELSE NULL
254                         END
255                     ),
256                     XMLELEMENT( name statcats,
257                         CASE 
258                             WHEN ('ascecm' = ANY ($4)) THEN
259                                 XMLAGG((SELECT unapi.ascecm( stat_cat_entry, 'xml', 'statcat', array_remove_item_by_value($4,'acp'), $5, $6, $7, $8) FROM asset.stat_cat_entry_copy_map WHERE owning_copy = cp.id))
260                             ELSE NULL
261                         END
262                     ),
263                     CASE 
264                         WHEN ('bmp' = ANY ($4)) THEN
265                             XMLELEMENT( name monograph_parts,
266                                 XMLAGG((SELECT unapi.bmp( part, 'xml', 'monograph_part', array_remove_item_by_value($4,'acp'), $5, $6, $7, $8) FROM asset.copy_part_map WHERE target_copy = cp.id))
267                             )
268                         ELSE NULL
269                     END
270                 )
271           FROM  asset.copy cp
272           WHERE id = $1
273           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;
274 $F$ LANGUAGE SQL;
275
276 CREATE OR REPLACE FUNCTION unapi.acn ( obj_id BIGINT, format TEXT,  ename TEXT, includes TEXT[], org TEXT, depth INT DEFAULT NULL, slimit INT DEFAULT NULL, soffset INT DEFAULT NULL ) RETURNS XML AS $F$
277         SELECT  XMLELEMENT(
278                     name volume,
279                     XMLATTRIBUTES(
280                         'http://open-ils.org/spec/holdings/v1' AS xmlns,
281                         'tag:open-ils.org:U2@acn/' || acn.id AS id,
282                         o.shortname AS lib,
283                         o.opac_visible AS opac_visible,
284                         deleted, label, label_sortkey, label_class, record
285                     ),
286                     unapi.aou( owning_lib, $2, 'owning_lib', array_remove_item_by_value($4,'acn'), $5, $6, $7, $8),
287                     XMLELEMENT( name copies,
288                         CASE 
289                             WHEN ('acp' = ANY ($4)) THEN
290                                 (SELECT XMLAGG(acp) FROM (
291                                     SELECT  unapi.acp( cp.id, 'xml', 'copy', array_remove_item_by_value($4,'acn'), $5, $6, $7, $8)
292                                       FROM  asset.copy cp
293                                             JOIN actor.org_unit_descendants(
294                                                 (SELECT id FROM actor.org_unit WHERE shortname = $5),
295                                                 (COALESCE($6,(SELECT aout.depth FROM actor.org_unit_type aout JOIN actor.org_unit aou ON (aou.ou_type = aout.id AND aou.shortname = $5))))
296                                             ) aoud ON (cp.circ_lib = aoud.id)
297                                       WHERE cp.call_number = acn.id
298                                       ORDER BY COALESCE(cp.copy_number,0), cp.barcode
299                                       LIMIT $7
300                                       OFFSET $8
301                                 )x)
302                             ELSE NULL
303                         END
304                     ),
305                     XMLELEMENT(
306                         name uris,
307                         (SELECT XMLAGG(auri) FROM (SELECT unapi.auri(uri,'xml','uri', array_remove_item_by_value($4,'acn'), $5, $6, $7, $8) FROM asset.uri_call_number_map WHERE call_number = acn.id)x)
308                     ),
309                     CASE WHEN ('acnp' = ANY ($4)) THEN unapi.acnp( acn.prefix, 'marcxml', 'prefix', array_remove_item_by_value($4,'acn'), $5, $6, $7, $8) ELSE NULL END,
310                     CASE WHEN ('acns' = ANY ($4)) THEN unapi.acns( acn.suffix, 'marcxml', 'suffix', array_remove_item_by_value($4,'acn'), $5, $6, $7, $8) ELSE NULL END,
311                     CASE WHEN ('bre' = ANY ($4)) THEN unapi.bre( acn.record, 'marcxml', 'record', array_remove_item_by_value($4,'acn'), $5, $6, $7, $8) ELSE NULL END
312                 ) AS x
313           FROM  asset.call_number acn
314                 JOIN actor.org_unit o ON (o.id = acn.owning_lib)
315           WHERE acn.id = $1
316           GROUP BY acn.id, o.shortname, o.opac_visible, deleted, label, label_sortkey, label_class, owning_lib, record, acn.prefix, acn.suffix;
317 $F$ LANGUAGE SQL;
318
319
320 COMMIT;
321