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