]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/sql/Pg/version-upgrade/2.10.0-2.10.1-upgrade-db.sql
2.10.0 - 2.10.1 schema update script
[working/Evergreen.git] / Open-ILS / src / sql / Pg / version-upgrade / 2.10.0-2.10.1-upgrade-db.sql
1 --Upgrade Script for 2.10.0 to 2.10.1
2 \set eg_version '''2.10.1'''
3 BEGIN;
4
5 INSERT INTO config.upgrade_log (version, applied_to) VALUES ('2.10.1', :eg_version);
6
7 SELECT evergreen.upgrade_deps_block_check('0975', :eg_version);
8
9 CREATE OR REPLACE FUNCTION vandelay.ingest_items ( import_id BIGINT, attr_def_id BIGINT ) RETURNS SETOF vandelay.import_item AS $$
10 DECLARE
11
12     owning_lib      TEXT;
13     circ_lib        TEXT;
14     call_number     TEXT;
15     copy_number     TEXT;
16     status          TEXT;
17     location        TEXT;
18     circulate       TEXT;
19     deposit         TEXT;
20     deposit_amount  TEXT;
21     ref             TEXT;
22     holdable        TEXT;
23     price           TEXT;
24     barcode         TEXT;
25     circ_modifier   TEXT;
26     circ_as_type    TEXT;
27     alert_message   TEXT;
28     opac_visible    TEXT;
29     pub_note        TEXT;
30     priv_note       TEXT;
31     internal_id     TEXT;
32     stat_cat_data   TEXT;
33     parts_data      TEXT;
34
35     attr_def        RECORD;
36     tmp_attr_set    RECORD;
37     attr_set        vandelay.import_item%ROWTYPE;
38
39     xpaths          TEXT[];
40     tmp_str         TEXT;
41
42 BEGIN
43
44     SELECT * INTO attr_def FROM vandelay.import_item_attr_definition WHERE id = attr_def_id;
45
46     IF FOUND THEN
47
48         attr_set.definition := attr_def.id;
49
50         -- Build the combined XPath
51
52         owning_lib :=
53             CASE
54                 WHEN attr_def.owning_lib IS NULL THEN 'null()'
55                 WHEN LENGTH( attr_def.owning_lib ) = 1 THEN '*[@code="' || attr_def.owning_lib || '"]'
56                 ELSE '*' || attr_def.owning_lib
57             END;
58
59         circ_lib :=
60             CASE
61                 WHEN attr_def.circ_lib IS NULL THEN 'null()'
62                 WHEN LENGTH( attr_def.circ_lib ) = 1 THEN '*[@code="' || attr_def.circ_lib || '"]'
63                 ELSE '*' || attr_def.circ_lib
64             END;
65
66         call_number :=
67             CASE
68                 WHEN attr_def.call_number IS NULL THEN 'null()'
69                 WHEN LENGTH( attr_def.call_number ) = 1 THEN '*[@code="' || attr_def.call_number || '"]'
70                 ELSE '*' || attr_def.call_number
71             END;
72
73         copy_number :=
74             CASE
75                 WHEN attr_def.copy_number IS NULL THEN 'null()'
76                 WHEN LENGTH( attr_def.copy_number ) = 1 THEN '*[@code="' || attr_def.copy_number || '"]'
77                 ELSE '*' || attr_def.copy_number
78             END;
79
80         status :=
81             CASE
82                 WHEN attr_def.status IS NULL THEN 'null()'
83                 WHEN LENGTH( attr_def.status ) = 1 THEN '*[@code="' || attr_def.status || '"]'
84                 ELSE '*' || attr_def.status
85             END;
86
87         location :=
88             CASE
89                 WHEN attr_def.location IS NULL THEN 'null()'
90                 WHEN LENGTH( attr_def.location ) = 1 THEN '*[@code="' || attr_def.location || '"]'
91                 ELSE '*' || attr_def.location
92             END;
93
94         circulate :=
95             CASE
96                 WHEN attr_def.circulate IS NULL THEN 'null()'
97                 WHEN LENGTH( attr_def.circulate ) = 1 THEN '*[@code="' || attr_def.circulate || '"]'
98                 ELSE '*' || attr_def.circulate
99             END;
100
101         deposit :=
102             CASE
103                 WHEN attr_def.deposit IS NULL THEN 'null()'
104                 WHEN LENGTH( attr_def.deposit ) = 1 THEN '*[@code="' || attr_def.deposit || '"]'
105                 ELSE '*' || attr_def.deposit
106             END;
107
108         deposit_amount :=
109             CASE
110                 WHEN attr_def.deposit_amount IS NULL THEN 'null()'
111                 WHEN LENGTH( attr_def.deposit_amount ) = 1 THEN '*[@code="' || attr_def.deposit_amount || '"]'
112                 ELSE '*' || attr_def.deposit_amount
113             END;
114
115         ref :=
116             CASE
117                 WHEN attr_def.ref IS NULL THEN 'null()'
118                 WHEN LENGTH( attr_def.ref ) = 1 THEN '*[@code="' || attr_def.ref || '"]'
119                 ELSE '*' || attr_def.ref
120             END;
121
122         holdable :=
123             CASE
124                 WHEN attr_def.holdable IS NULL THEN 'null()'
125                 WHEN LENGTH( attr_def.holdable ) = 1 THEN '*[@code="' || attr_def.holdable || '"]'
126                 ELSE '*' || attr_def.holdable
127             END;
128
129         price :=
130             CASE
131                 WHEN attr_def.price IS NULL THEN 'null()'
132                 WHEN LENGTH( attr_def.price ) = 1 THEN '*[@code="' || attr_def.price || '"]'
133                 ELSE '*' || attr_def.price
134             END;
135
136         barcode :=
137             CASE
138                 WHEN attr_def.barcode IS NULL THEN 'null()'
139                 WHEN LENGTH( attr_def.barcode ) = 1 THEN '*[@code="' || attr_def.barcode || '"]'
140                 ELSE '*' || attr_def.barcode
141             END;
142
143         circ_modifier :=
144             CASE
145                 WHEN attr_def.circ_modifier IS NULL THEN 'null()'
146                 WHEN LENGTH( attr_def.circ_modifier ) = 1 THEN '*[@code="' || attr_def.circ_modifier || '"]'
147                 ELSE '*' || attr_def.circ_modifier
148             END;
149
150         circ_as_type :=
151             CASE
152                 WHEN attr_def.circ_as_type IS NULL THEN 'null()'
153                 WHEN LENGTH( attr_def.circ_as_type ) = 1 THEN '*[@code="' || attr_def.circ_as_type || '"]'
154                 ELSE '*' || attr_def.circ_as_type
155             END;
156
157         alert_message :=
158             CASE
159                 WHEN attr_def.alert_message IS NULL THEN 'null()'
160                 WHEN LENGTH( attr_def.alert_message ) = 1 THEN '*[@code="' || attr_def.alert_message || '"]'
161                 ELSE '*' || attr_def.alert_message
162             END;
163
164         opac_visible :=
165             CASE
166                 WHEN attr_def.opac_visible IS NULL THEN 'null()'
167                 WHEN LENGTH( attr_def.opac_visible ) = 1 THEN '*[@code="' || attr_def.opac_visible || '"]'
168                 ELSE '*' || attr_def.opac_visible
169             END;
170
171         pub_note :=
172             CASE
173                 WHEN attr_def.pub_note IS NULL THEN 'null()'
174                 WHEN LENGTH( attr_def.pub_note ) = 1 THEN '*[@code="' || attr_def.pub_note || '"]'
175                 ELSE '*' || attr_def.pub_note
176             END;
177         priv_note :=
178             CASE
179                 WHEN attr_def.priv_note IS NULL THEN 'null()'
180                 WHEN LENGTH( attr_def.priv_note ) = 1 THEN '*[@code="' || attr_def.priv_note || '"]'
181                 ELSE '*' || attr_def.priv_note
182             END;
183
184         internal_id :=
185             CASE
186                 WHEN attr_def.internal_id IS NULL THEN 'null()'
187                 WHEN LENGTH( attr_def.internal_id ) = 1 THEN '*[@code="' || attr_def.internal_id || '"]'
188                 ELSE '*' || attr_def.internal_id
189             END;
190
191         stat_cat_data :=
192             CASE
193                 WHEN attr_def.stat_cat_data IS NULL THEN 'null()'
194                 WHEN LENGTH( attr_def.stat_cat_data ) = 1 THEN '*[@code="' || attr_def.stat_cat_data || '"]'
195                 ELSE '*' || attr_def.stat_cat_data
196             END;
197
198         parts_data :=
199             CASE
200                 WHEN attr_def.parts_data IS NULL THEN 'null()'
201                 WHEN LENGTH( attr_def.parts_data ) = 1 THEN '*[@code="' || attr_def.parts_data || '"]'
202                 ELSE '*' || attr_def.parts_data
203             END;
204
205
206
207         xpaths := ARRAY[owning_lib, circ_lib, call_number, copy_number, status, location, circulate,
208                         deposit, deposit_amount, ref, holdable, price, barcode, circ_modifier, circ_as_type,
209                         alert_message, pub_note, priv_note, internal_id, stat_cat_data, parts_data, opac_visible];
210
211         FOR tmp_attr_set IN
212                 SELECT  *
213                   FROM  oils_xpath_tag_to_table( (SELECT marc FROM vandelay.queued_bib_record WHERE id = import_id), attr_def.tag, xpaths)
214                             AS t( ol TEXT, clib TEXT, cn TEXT, cnum TEXT, cs TEXT, cl TEXT, circ TEXT,
215                                   dep TEXT, dep_amount TEXT, r TEXT, hold TEXT, pr TEXT, bc TEXT, circ_mod TEXT,
216                                   circ_as TEXT, amessage TEXT, note TEXT, pnote TEXT, internal_id TEXT,
217                                   stat_cat_data TEXT, parts_data TEXT, opac_vis TEXT )
218         LOOP
219
220             attr_set.import_error := NULL;
221             attr_set.error_detail := NULL;
222             attr_set.deposit_amount := NULL;
223             attr_set.copy_number := NULL;
224             attr_set.price := NULL;
225             attr_set.circ_modifier := NULL;
226             attr_set.location := NULL;
227             attr_set.barcode := NULL;
228             attr_set.call_number := NULL;
229
230             IF tmp_attr_set.pr != '' THEN
231                 tmp_str = REGEXP_REPLACE(tmp_attr_set.pr, E'[^0-9\\.]', '', 'g');
232                 IF tmp_str = '' THEN 
233                     attr_set.import_error := 'import.item.invalid.price';
234                     attr_set.error_detail := tmp_attr_set.pr; -- original value
235                     RETURN NEXT attr_set; CONTINUE; 
236                 END IF;
237                 attr_set.price := tmp_str::NUMERIC(8,2); 
238             END IF;
239
240             IF tmp_attr_set.dep_amount != '' THEN
241                 tmp_str = REGEXP_REPLACE(tmp_attr_set.dep_amount, E'[^0-9\\.]', '', 'g');
242                 IF tmp_str = '' THEN 
243                     attr_set.import_error := 'import.item.invalid.deposit_amount';
244                     attr_set.error_detail := tmp_attr_set.dep_amount; 
245                     RETURN NEXT attr_set; CONTINUE; 
246                 END IF;
247                 attr_set.deposit_amount := tmp_str::NUMERIC(8,2); 
248             END IF;
249
250             IF tmp_attr_set.cnum != '' THEN
251                 tmp_str = REGEXP_REPLACE(tmp_attr_set.cnum, E'[^0-9]', '', 'g');
252                 IF tmp_str = '' THEN 
253                     attr_set.import_error := 'import.item.invalid.copy_number';
254                     attr_set.error_detail := tmp_attr_set.cnum; 
255                     RETURN NEXT attr_set; CONTINUE; 
256                 END IF;
257                 attr_set.copy_number := tmp_str::INT; 
258             END IF;
259
260             IF tmp_attr_set.ol != '' THEN
261                 SELECT id INTO attr_set.owning_lib FROM actor.org_unit WHERE shortname = UPPER(tmp_attr_set.ol); -- INT
262                 IF NOT FOUND THEN
263                     attr_set.import_error := 'import.item.invalid.owning_lib';
264                     attr_set.error_detail := tmp_attr_set.ol;
265                     RETURN NEXT attr_set; CONTINUE; 
266                 END IF;
267             END IF;
268
269             IF tmp_attr_set.clib != '' THEN
270                 SELECT id INTO attr_set.circ_lib FROM actor.org_unit WHERE shortname = UPPER(tmp_attr_set.clib); -- INT
271                 IF NOT FOUND THEN
272                     attr_set.import_error := 'import.item.invalid.circ_lib';
273                     attr_set.error_detail := tmp_attr_set.clib;
274                     RETURN NEXT attr_set; CONTINUE; 
275                 END IF;
276             END IF;
277
278             IF tmp_attr_set.cs != '' THEN
279                 SELECT id INTO attr_set.status FROM config.copy_status WHERE LOWER(name) = LOWER(tmp_attr_set.cs); -- INT
280                 IF NOT FOUND THEN
281                     attr_set.import_error := 'import.item.invalid.status';
282                     attr_set.error_detail := tmp_attr_set.cs;
283                     RETURN NEXT attr_set; CONTINUE; 
284                 END IF;
285             END IF;
286
287             IF COALESCE(tmp_attr_set.circ_mod, '') = '' THEN
288
289                 -- no circ mod defined, see if we should apply a default
290                 SELECT INTO attr_set.circ_modifier TRIM(BOTH '"' FROM value) 
291                     FROM actor.org_unit_ancestor_setting(
292                         'vandelay.item.circ_modifier.default', 
293                         attr_set.owning_lib
294                     );
295
296                 -- make sure the value from the org setting is still valid
297                 PERFORM 1 FROM config.circ_modifier WHERE code = attr_set.circ_modifier;
298                 IF NOT FOUND THEN
299                     attr_set.import_error := 'import.item.invalid.circ_modifier';
300                     attr_set.error_detail := tmp_attr_set.circ_mod;
301                     RETURN NEXT attr_set; CONTINUE; 
302                 END IF;
303
304             ELSE 
305
306                 SELECT code INTO attr_set.circ_modifier FROM config.circ_modifier WHERE code = tmp_attr_set.circ_mod;
307                 IF NOT FOUND THEN
308                     attr_set.import_error := 'import.item.invalid.circ_modifier';
309                     attr_set.error_detail := tmp_attr_set.circ_mod;
310                     RETURN NEXT attr_set; CONTINUE; 
311                 END IF;
312             END IF;
313
314             IF tmp_attr_set.circ_as != '' THEN
315                 SELECT code INTO attr_set.circ_as_type FROM config.coded_value_map WHERE ctype = 'item_type' AND code = tmp_attr_set.circ_as;
316                 IF NOT FOUND THEN
317                     attr_set.import_error := 'import.item.invalid.circ_as_type';
318                     attr_set.error_detail := tmp_attr_set.circ_as;
319                     RETURN NEXT attr_set; CONTINUE; 
320                 END IF;
321             END IF;
322
323             IF COALESCE(tmp_attr_set.cl, '') = '' THEN
324                 -- no location specified, see if we should apply a default
325
326                 SELECT INTO attr_set.location TRIM(BOTH '"' FROM value) 
327                     FROM actor.org_unit_ancestor_setting(
328                         'vandelay.item.copy_location.default', 
329                         attr_set.owning_lib
330                     );
331
332                 -- make sure the value from the org setting is still valid
333                 PERFORM 1 FROM asset.copy_location 
334                     WHERE id = attr_set.location AND NOT deleted;
335                 IF NOT FOUND THEN
336                     attr_set.import_error := 'import.item.invalid.location';
337                     attr_set.error_detail := tmp_attr_set.cs;
338                     RETURN NEXT attr_set; CONTINUE; 
339                 END IF;
340             ELSE
341
342                 -- search up the org unit tree for a matching copy location
343                 WITH RECURSIVE anscestor_depth AS (
344                     SELECT  ou.id,
345                         out.depth AS depth,
346                         ou.parent_ou
347                     FROM  actor.org_unit ou
348                         JOIN actor.org_unit_type out ON (out.id = ou.ou_type)
349                     WHERE ou.id = COALESCE(attr_set.owning_lib, attr_set.circ_lib)
350                         UNION ALL
351                     SELECT  ou.id,
352                         out.depth,
353                         ou.parent_ou
354                     FROM  actor.org_unit ou
355                         JOIN actor.org_unit_type out ON (out.id = ou.ou_type)
356                         JOIN anscestor_depth ot ON (ot.parent_ou = ou.id)
357                 ) SELECT  cpl.id INTO attr_set.location
358                     FROM  anscestor_depth a
359                         JOIN asset.copy_location cpl ON (cpl.owning_lib = a.id)
360                     WHERE LOWER(cpl.name) = LOWER(tmp_attr_set.cl) 
361                         AND NOT cpl.deleted
362                     ORDER BY a.depth DESC
363                     LIMIT 1; 
364
365                 IF NOT FOUND THEN
366                     attr_set.import_error := 'import.item.invalid.location';
367                     attr_set.error_detail := tmp_attr_set.cs;
368                     RETURN NEXT attr_set; CONTINUE; 
369                 END IF;
370             END IF;
371
372             attr_set.circulate      :=
373                 LOWER( SUBSTRING( tmp_attr_set.circ, 1, 1)) IN ('t','y','1')
374                 OR LOWER(tmp_attr_set.circ) = 'circulating'; -- BOOL
375
376             attr_set.deposit        :=
377                 LOWER( SUBSTRING( tmp_attr_set.dep, 1, 1 ) ) IN ('t','y','1')
378                 OR LOWER(tmp_attr_set.dep) = 'deposit'; -- BOOL
379
380             attr_set.holdable       :=
381                 LOWER( SUBSTRING( tmp_attr_set.hold, 1, 1 ) ) IN ('t','y','1')
382                 OR LOWER(tmp_attr_set.hold) = 'holdable'; -- BOOL
383
384             attr_set.opac_visible   :=
385                 LOWER( SUBSTRING( tmp_attr_set.opac_vis, 1, 1 ) ) IN ('t','y','1')
386                 OR LOWER(tmp_attr_set.opac_vis) = 'visible'; -- BOOL
387
388             attr_set.ref            :=
389                 LOWER( SUBSTRING( tmp_attr_set.r, 1, 1 ) ) IN ('t','y','1')
390                 OR LOWER(tmp_attr_set.r) = 'reference'; -- BOOL
391
392             attr_set.call_number    := tmp_attr_set.cn; -- TEXT
393             attr_set.barcode        := tmp_attr_set.bc; -- TEXT,
394             attr_set.alert_message  := tmp_attr_set.amessage; -- TEXT,
395             attr_set.pub_note       := tmp_attr_set.note; -- TEXT,
396             attr_set.priv_note      := tmp_attr_set.pnote; -- TEXT,
397             attr_set.alert_message  := tmp_attr_set.amessage; -- TEXT,
398             attr_set.internal_id    := tmp_attr_set.internal_id::BIGINT;
399             attr_set.stat_cat_data  := tmp_attr_set.stat_cat_data; -- TEXT,
400             attr_set.parts_data     := tmp_attr_set.parts_data; -- TEXT,
401
402             RETURN NEXT attr_set;
403
404         END LOOP;
405
406     END IF;
407
408     RETURN;
409
410 END;
411 $$ LANGUAGE PLPGSQL;
412
413 COMMIT;