]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/sql/Pg/version-upgrade/3.4.3-3.5.0-upgrade-db.sql
LP 2061136 follow-up: ng lint --fix
[Evergreen.git] / Open-ILS / src / sql / Pg / version-upgrade / 3.4.3-3.5.0-upgrade-db.sql
1 --Upgrade Script for 3.4.3 to 3.5.0
2 \set eg_version '''3.5.0'''
3 BEGIN;
4 INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.5.0', :eg_version);
5
6 SELECT evergreen.upgrade_deps_block_check('1194', :eg_version);
7
8 CREATE OR REPLACE FUNCTION public.naco_normalize( TEXT, TEXT ) RETURNS TEXT AS $func$
9
10     use strict;
11     use Unicode::Normalize;
12     use Encode;
13
14     my $str = shift;
15     my $sf = shift;
16
17     # Apply NACO normalization to input string; based on
18     # https://www.loc.gov/aba/pcc/naco/documents/SCA_PccNormalization_Final_revised.pdf
19     #
20     # Note that unlike a strict reading of the NACO normalization rules,
21     # output is returned as lowercase instead of uppercase for compatibility
22     # with previous versions of the Evergreen naco_normalize routine.
23
24     # Convert to upper-case first; even though final output will be lowercase, doing this will
25     # ensure that the German eszett (ß) and certain ligatures (ff, fi, ffl, etc.) will be handled correctly.
26     # If there are any bugs in Perl's implementation of upcasing, they will be passed through here.
27     $str = uc $str;
28
29     # remove non-filing strings
30     $str =~ s/\x{0098}.*?\x{009C}//g;
31
32
33     # Replace unicode curly single and double quote-like characters with straight
34     $str =~ s/[\x{2018}\x{2019}\x{201B}\x{FF07}\x{201A}]/\x{0027}/g;
35     $str =~ s/[\x{201C}\x{201D}\x{201F}\x{FF0C}\x{201E}\x{2E42}]/\x{0022}/g;
36
37     $str = NFKD($str);
38
39     # additional substitutions - 3.6.
40     $str =~ s/\x{00C6}/AE/g;
41     $str =~ s/\x{00DE}/TH/g;
42     $str =~ s/\x{0152}/OE/g;
43     $str =~ tr/\x{0110}\x{00D0}\x{00D8}\x{0141}\x{2113}\x{02BB}\x{02BC}]['/DDOLl/d;
44
45     # transformations based on Unicode category codes
46     $str =~ s/[\p{Cc}\p{Cf}\p{Co}\p{Cs}\p{Lm}\p{Mc}\p{Me}\p{Mn}]//g;
47
48         if ($sf && $sf =~ /^a/o) {
49                 my $commapos = index($str, ',');
50                 if ($commapos > -1) {
51                         if ($commapos != length($str) - 1) {
52                 $str =~ s/,/\x07/; # preserve first comma
53                         }
54                 }
55         }
56
57     # since we've stripped out the control characters, we can now
58     # use a few as placeholders temporarily
59     $str =~ tr/+&@\x{266D}\x{266F}#/\x01\x02\x03\x04\x05\x06/;
60     $str =~ s/[\p{Pc}\p{Pd}\p{Pe}\p{Pf}\p{Pi}\p{Po}\p{Ps}\p{Sk}\p{Sm}\p{So}\p{Zl}\p{Zp}\p{Zs}]/ /g;
61     $str =~ tr/\x01\x02\x03\x04\x05\x06\x07/+&@\x{266D}\x{266F}#,/;
62
63     # decimal digits
64     $str =~ tr/\x{0660}-\x{0669}\x{06F0}-\x{06F9}\x{07C0}-\x{07C9}\x{0966}-\x{096F}\x{09E6}-\x{09EF}\x{0A66}-\x{0A6F}\x{0AE6}-\x{0AEF}\x{0B66}-\x{0B6F}\x{0BE6}-\x{0BEF}\x{0C66}-\x{0C6F}\x{0CE6}-\x{0CEF}\x{0D66}-\x{0D6F}\x{0E50}-\x{0E59}\x{0ED0}-\x{0ED9}\x{0F20}-\x{0F29}\x{1040}-\x{1049}\x{1090}-\x{1099}\x{17E0}-\x{17E9}\x{1810}-\x{1819}\x{1946}-\x{194F}\x{19D0}-\x{19D9}\x{1A80}-\x{1A89}\x{1A90}-\x{1A99}\x{1B50}-\x{1B59}\x{1BB0}-\x{1BB9}\x{1C40}-\x{1C49}\x{1C50}-\x{1C59}\x{A620}-\x{A629}\x{A8D0}-\x{A8D9}\x{A900}-\x{A909}\x{A9D0}-\x{A9D9}\x{AA50}-\x{AA59}\x{ABF0}-\x{ABF9}\x{FF10}-\x{FF19}/0-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-9/;
65
66     # intentionally skipping step 8 of the NACO algorithm; if the string
67     # gets normalized away, that's fine.
68
69     # leading and trailing spaces
70     $str =~ s/\s+/ /g;
71     $str =~ s/^\s+//;
72     $str =~ s/\s+$//g;
73
74     return lc $str;
75 $func$ LANGUAGE 'plperlu' STRICT IMMUTABLE;
76
77 CREATE OR REPLACE FUNCTION public.search_normalize( TEXT, TEXT ) RETURNS TEXT AS $func$
78
79     use strict;
80     use Unicode::Normalize;
81     use Encode;
82
83     my $str = shift;
84     my $sf = shift;
85
86     # Apply NACO normalization to input string; based on
87     # https://www.loc.gov/aba/pcc/naco/documents/SCA_PccNormalization_Final_revised.pdf
88     #
89     # Note that unlike a strict reading of the NACO normalization rules,
90     # output is returned as lowercase instead of uppercase for compatibility
91     # with previous versions of the Evergreen naco_normalize routine.
92
93     # Convert to upper-case first; even though final output will be lowercase, doing this will
94     # ensure that the German eszett (ß) and certain ligatures (ff, fi, ffl, etc.) will be handled correctly.
95     # If there are any bugs in Perl's implementation of upcasing, they will be passed through here.
96     $str = uc $str;
97
98     # remove non-filing strings
99     $str =~ s/\x{0098}.*?\x{009C}//g;
100
101     # Replace unicode curly single and double quote-like characters with straight
102     $str =~ s/[\x{2018}\x{2019}\x{201B}\x{FF07}\x{201A}]/\x{0027}/g;
103     $str =~ s/[\x{201C}\x{201D}\x{201F}\x{FF0C}\x{201E}\x{2E42}]/\x{0022}/g;
104
105
106     $str = NFKD($str);
107
108     # additional substitutions - 3.6.
109     $str =~ s/\x{00C6}/AE/g;
110     $str =~ s/\x{00DE}/TH/g;
111     $str =~ s/\x{0152}/OE/g;
112     $str =~ tr/\x{0110}\x{00D0}\x{00D8}\x{0141}\x{2113}\x{02BB}\x{02BC}][/DDOLl/d;
113
114     # transformations based on Unicode category codes
115     $str =~ s/[\p{Cc}\p{Cf}\p{Co}\p{Cs}\p{Lm}\p{Mc}\p{Me}\p{Mn}]//g;
116
117         if ($sf && $sf =~ /^a/o) {
118                 my $commapos = index($str, ',');
119                 if ($commapos > -1) {
120                         if ($commapos != length($str) - 1) {
121                 $str =~ s/,/\x07/; # preserve first comma
122                         }
123                 }
124         }
125
126     # since we've stripped out the control characters, we can now
127     # use a few as placeholders temporarily
128     $str =~ tr/+&@\x{266D}\x{266F}#/\x01\x02\x03\x04\x05\x06/;
129     $str =~ s/[\p{Pc}\p{Pd}\p{Pe}\p{Pf}\p{Pi}\p{Po}\p{Ps}\p{Sk}\p{Sm}\p{So}\p{Zl}\p{Zp}\p{Zs}]/ /g;
130     $str =~ tr/\x01\x02\x03\x04\x05\x06\x07/+&@\x{266D}\x{266F}#,/;
131
132     # decimal digits
133     $str =~ tr/\x{0660}-\x{0669}\x{06F0}-\x{06F9}\x{07C0}-\x{07C9}\x{0966}-\x{096F}\x{09E6}-\x{09EF}\x{0A66}-\x{0A6F}\x{0AE6}-\x{0AEF}\x{0B66}-\x{0B6F}\x{0BE6}-\x{0BEF}\x{0C66}-\x{0C6F}\x{0CE6}-\x{0CEF}\x{0D66}-\x{0D6F}\x{0E50}-\x{0E59}\x{0ED0}-\x{0ED9}\x{0F20}-\x{0F29}\x{1040}-\x{1049}\x{1090}-\x{1099}\x{17E0}-\x{17E9}\x{1810}-\x{1819}\x{1946}-\x{194F}\x{19D0}-\x{19D9}\x{1A80}-\x{1A89}\x{1A90}-\x{1A99}\x{1B50}-\x{1B59}\x{1BB0}-\x{1BB9}\x{1C40}-\x{1C49}\x{1C50}-\x{1C59}\x{A620}-\x{A629}\x{A8D0}-\x{A8D9}\x{A900}-\x{A909}\x{A9D0}-\x{A9D9}\x{AA50}-\x{AA59}\x{ABF0}-\x{ABF9}\x{FF10}-\x{FF19}/0-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-90-9/;
134
135     # intentionally skipping step 8 of the NACO algorithm; if the string
136     # gets normalized away, that's fine.
137
138     # leading and trailing spaces
139     $str =~ s/\s+/ /g;
140     $str =~ s/^\s+//;
141     $str =~ s/\s+$//g;
142
143     return lc $str;
144 $func$ LANGUAGE 'plperlu' STRICT IMMUTABLE;
145
146
147 SELECT evergreen.upgrade_deps_block_check('1196', :eg_version);
148
149 INSERT into config.org_unit_setting_type
150 ( name, grp, label, description, datatype, fm_class ) VALUES
151 ( 'opac.patron.custom_css', 'opac',
152     oils_i18n_gettext('opac.patron.custom_css',
153         'Custom CSS for the OPAC',
154         'coust', 'label'),
155     oils_i18n_gettext('opac.patron.custom_css',
156         'Custom CSS for the OPAC',
157         'coust', 'description'),
158     'string', NULL);
159
160
161 SELECT evergreen.upgrade_deps_block_check('1198', :eg_version);
162
163 INSERT INTO config.workstation_setting_type (name, grp, datatype, label)
164 VALUES (
165     'eg.catalog.results.count', 'gui', 'integer',
166     oils_i18n_gettext(
167         'eg.catalog.results.count',
168         'Catalog Results Page Size',
169         'cwst', 'label'
170     )
171 );
172
173
174
175 SELECT evergreen.upgrade_deps_block_check('1199', :eg_version);
176
177 INSERT INTO action_trigger.hook
178 (key,core_type,description,passive)
179 VALUES
180 ('stgu.created','stgu','Patron requested a card using self registration','t');
181
182
183 INSERT INTO action_trigger.event_definition(active,owner,name,hook,validator,reactor,delay,max_delay,delay_field,group_field,template,retention_interval)
184 SELECT 'f',1,'Patron Registered for a card stgu.created','stgu.created','NOOP_True','SendEmail','00:01:00'::interval,'1 day'::interval,'row_date','home_ou',
185 $$[%- USE date -%]
186 [%- lib = target.0.home_ou -%]
187 To: [% lib.name %] <[% params.recipient_email || helpers.get_org_setting(target.0.home_ou.id, 'org.bounced_emails') || lib.email || default_sender %]>
188 From: [% lib.name %] <[%  helpers.get_org_setting(target.0.home_ou.id, 'org.bounced_emails') || lib.email || params.recipient_email || default_sender %]>
189 Date: [% date.format(format => '%a, %d %b %Y %H:%M:%S %Z') %]
190 Subject: Patron card requested
191 Auto-Submitted: auto-generated
192
193
194 Dear Staff Admin,
195
196 There are some pending patrons waiting for your attention.
197
198 [% FOR patron IN target %]
199     [% patron.first_given_name %]
200
201 [% END %]
202
203 These requests can be tended via the staff interface. Located "Circulation" -> "Pending Patrons"
204
205
206 $$,
207 '1 year'::interval
208
209 WHERE NOT EXISTS (SELECT 1 FROM action_trigger.event_definition WHERE name='Patron Registered for a card stgu.created');
210
211 INSERT INTO action_trigger.environment (event_def,path)
212 SELECT id,'home_ou' from action_trigger.event_definition WHERE name='Patron Registered for a card stgu.created'
213 AND NOT EXISTS (SELECT 1 FROM action_trigger.environment WHERE
214 event_def=(SELECT id FROM action_trigger.event_definition WHERE name='Patron Registered for a card stgu.created' AND owner=1 LIMIT 1)
215 AND path='home_ou');
216
217
218
219 SELECT evergreen.upgrade_deps_block_check('1200', :eg_version);
220
221 CREATE TABLE money.debit_card_payment () INHERITS (money.bnm_desk_payment);
222 ALTER TABLE money.debit_card_payment ADD PRIMARY KEY (id);
223 CREATE INDEX money_debit_card_payment_xact_idx ON money.debit_card_payment (xact);
224 CREATE INDEX money_debit_card_id_idx ON money.debit_card_payment (id);
225 CREATE INDEX money_debit_card_payment_ts_idx ON money.debit_card_payment (payment_ts);
226 CREATE INDEX money_debit_card_payment_accepting_usr_idx ON money.debit_card_payment (accepting_usr);
227 CREATE INDEX money_debit_card_payment_cash_drawer_idx ON money.debit_card_payment (cash_drawer);
228
229 CREATE TRIGGER mat_summary_add_tgr AFTER INSERT ON money.debit_card_payment FOR EACH ROW EXECUTE PROCEDURE money.materialized_summary_payment_add ('debit_card_payment');
230 CREATE TRIGGER mat_summary_upd_tgr AFTER UPDATE ON money.debit_card_payment FOR EACH ROW EXECUTE PROCEDURE money.materialized_summary_payment_update ('debit_card_payment');
231 CREATE TRIGGER mat_summary_del_tgr BEFORE DELETE ON money.debit_card_payment FOR EACH ROW EXECUTE PROCEDURE money.materialized_summary_payment_del ('debit_card_payment');
232  
233 CREATE OR REPLACE VIEW money.non_drawer_payment_view AS
234        SELECT  p.*, c.relname AS payment_type
235          FROM  money.bnm_payment p         
236                        JOIN pg_class c ON p.tableoid = c.oid
237          WHERE c.relname NOT IN ('cash_payment','check_payment','credit_card_payment','debit_card_payment');
238
239 UPDATE action_trigger.event_definition 
240     SET template = $$
241 [%- USE date -%]
242 [%- SET user = target.0.xact.usr -%]
243 To: [%- params.recipient_email || user.email %]
244 From: [%- params.sender_email || default_sender %]
245 Date: [%- date.format(date.now, '%a, %d %b %Y %T -0000', gmt => 1) %]
246 Subject: Payment Receipt
247 Auto-Submitted: auto-generated
248
249 [% date.format -%]
250 [%- SET xact_mp_hash = {} -%]
251 [%- FOR mp IN target %][%# Template is hooked around payments, but let us make the receipt focused on transactions -%]
252     [%- SET xact_id = mp.xact.id -%]
253     [%- IF ! xact_mp_hash.defined( xact_id ) -%][%- xact_mp_hash.$xact_id = { 'xact' => mp.xact, 'payments' => [] } -%][%- END -%]
254     [%- xact_mp_hash.$xact_id.payments.push(mp) -%]
255 [%- END -%]
256 [%- FOR xact_id IN xact_mp_hash.keys.sort -%]
257     [%- SET xact = xact_mp_hash.$xact_id.xact %]
258 Transaction ID: [% xact_id %]
259     [% IF xact.circulation %][% helpers.get_copy_bib_basics(xact.circulation.target_copy).title %]
260     [% ELSE %]Miscellaneous
261     [% END %]
262     Line item billings:
263         [%- SET mb_type_hash = {} -%]
264         [%- FOR mb IN xact.billings %][%# Group billings by their btype -%]
265             [%- IF mb.voided == 'f' -%]
266                 [%- SET mb_type = mb.btype.id -%]
267                 [%- IF ! mb_type_hash.defined( mb_type ) -%][%- mb_type_hash.$mb_type = { 'sum' => 0.00, 'billings' => [] } -%][%- END -%]
268                 [%- IF ! mb_type_hash.$mb_type.defined( 'first_ts' ) -%][%- mb_type_hash.$mb_type.first_ts = mb.billing_ts -%][%- END -%]
269                 [%- mb_type_hash.$mb_type.last_ts = mb.billing_ts -%]
270                 [%- mb_type_hash.$mb_type.sum = mb_type_hash.$mb_type.sum + mb.amount -%]
271                 [%- mb_type_hash.$mb_type.billings.push( mb ) -%]
272             [%- END -%]
273         [%- END -%]
274         [%- FOR mb_type IN mb_type_hash.keys.sort -%]
275             [%- IF mb_type == 1 %][%-# Consolidated view of overdue billings -%]
276                 $[% mb_type_hash.$mb_type.sum %] for [% mb_type_hash.$mb_type.billings.0.btype.name %] 
277                     on [% mb_type_hash.$mb_type.first_ts %] through [% mb_type_hash.$mb_type.last_ts %]
278             [%- ELSE -%][%# all other billings show individually %]
279                 [% FOR mb IN mb_type_hash.$mb_type.billings %]
280                     $[% mb.amount %] for [% mb.btype.name %] on [% mb.billing_ts %] [% mb.note %]
281                 [% END %]
282             [% END %]
283         [% END %]
284     Line item payments:
285         [% FOR mp IN xact_mp_hash.$xact_id.payments %]
286             Payment ID: [% mp.id %]
287                 Paid [% mp.amount %] via [% SWITCH mp.payment_type -%]
288                     [% CASE "cash_payment" %]cash
289                     [% CASE "check_payment" %]check
290                     [% CASE "credit_card_payment" %]credit card
291                     [%- IF mp.credit_card_payment.cc_number %] ([% mp.credit_card_payment.cc_number %])[% END %]
292                     [% CASE "debit_card_payment" %]debit card
293                     [% CASE "credit_payment" %]credit
294                     [% CASE "forgive_payment" %]forgiveness
295                     [% CASE "goods_payment" %]goods
296                     [% CASE "work_payment" %]work
297                 [%- END %] on [% mp.payment_ts %] [% mp.note %]
298         [% END %]
299 [% END %]
300 $$
301 WHERE id = 29 AND template = $$
302 [%- USE date -%]
303 [%- SET user = target.0.xact.usr -%]
304 To: [%- params.recipient_email || user.email %]
305 From: [%- params.sender_email || default_sender %]
306 Date: [%- date.format(date.now, '%a, %d %b %Y %T -0000', gmt => 1) %]
307 Subject: Payment Receipt
308 Auto-Submitted: auto-generated
309
310 [% date.format -%]
311 [%- SET xact_mp_hash = {} -%]
312 [%- FOR mp IN target %][%# Template is hooked around payments, but let us make the receipt focused on transactions -%]
313     [%- SET xact_id = mp.xact.id -%]
314     [%- IF ! xact_mp_hash.defined( xact_id ) -%][%- xact_mp_hash.$xact_id = { 'xact' => mp.xact, 'payments' => [] } -%][%- END -%]
315     [%- xact_mp_hash.$xact_id.payments.push(mp) -%]
316 [%- END -%]
317 [%- FOR xact_id IN xact_mp_hash.keys.sort -%]
318     [%- SET xact = xact_mp_hash.$xact_id.xact %]
319 Transaction ID: [% xact_id %]
320     [% IF xact.circulation %][% helpers.get_copy_bib_basics(xact.circulation.target_copy).title %]
321     [% ELSE %]Miscellaneous
322     [% END %]
323     Line item billings:
324         [%- SET mb_type_hash = {} -%]
325         [%- FOR mb IN xact.billings %][%# Group billings by their btype -%]
326             [%- IF mb.voided == 'f' -%]
327                 [%- SET mb_type = mb.btype.id -%]
328                 [%- IF ! mb_type_hash.defined( mb_type ) -%][%- mb_type_hash.$mb_type = { 'sum' => 0.00, 'billings' => [] } -%][%- END -%]
329                 [%- IF ! mb_type_hash.$mb_type.defined( 'first_ts' ) -%][%- mb_type_hash.$mb_type.first_ts = mb.billing_ts -%][%- END -%]
330                 [%- mb_type_hash.$mb_type.last_ts = mb.billing_ts -%]
331                 [%- mb_type_hash.$mb_type.sum = mb_type_hash.$mb_type.sum + mb.amount -%]
332                 [%- mb_type_hash.$mb_type.billings.push( mb ) -%]
333             [%- END -%]
334         [%- END -%]
335         [%- FOR mb_type IN mb_type_hash.keys.sort -%]
336             [%- IF mb_type == 1 %][%-# Consolidated view of overdue billings -%]
337                 $[% mb_type_hash.$mb_type.sum %] for [% mb_type_hash.$mb_type.billings.0.btype.name %] 
338                     on [% mb_type_hash.$mb_type.first_ts %] through [% mb_type_hash.$mb_type.last_ts %]
339             [%- ELSE -%][%# all other billings show individually %]
340                 [% FOR mb IN mb_type_hash.$mb_type.billings %]
341                     $[% mb.amount %] for [% mb.btype.name %] on [% mb.billing_ts %] [% mb.note %]
342                 [% END %]
343             [% END %]
344         [% END %]
345     Line item payments:
346         [% FOR mp IN xact_mp_hash.$xact_id.payments %]
347             Payment ID: [% mp.id %]
348                 Paid [% mp.amount %] via [% SWITCH mp.payment_type -%]
349                     [% CASE "cash_payment" %]cash
350                     [% CASE "check_payment" %]check
351                     [% CASE "credit_card_payment" %]credit card
352                     [%- IF mp.credit_card_payment.cc_number %] ([% mp.credit_card_payment.cc_number %])[% END %]
353                     [% CASE "credit_payment" %]credit
354                     [% CASE "forgive_payment" %]forgiveness
355                     [% CASE "goods_payment" %]goods
356                     [% CASE "work_payment" %]work
357                 [%- END %] on [% mp.payment_ts %] [% mp.note %]
358         [% END %]
359 [% END %]
360 $$;
361
362
363 SELECT evergreen.upgrade_deps_block_check('1201', :eg_version); -- rhamby/jboyer
364
365 INSERT INTO permission.perm_list ( id, code, description ) VALUES
366 ( 620, 'UPDATE_ORG_UNIT_SETTING.opac.patron.custom_css', oils_i18n_gettext(620,
367    'Update CSS setting for the OPAC', 'ppl', 'description'))
368 ;
369
370 UPDATE config.org_unit_setting_type SET update_perm = 620 WHERE name = 'opac.patron.custom_css';
371
372
373 SELECT evergreen.upgrade_deps_block_check('1203', :eg_version);
374
375 ALTER TABLE config.best_hold_order ADD COLUMN owning_lib_to_home_lib_prox INT; -- copy owning lib <-> user home lib prox
376
377 ALTER table config.best_hold_order DROP CONSTRAINT best_hold_order_check;
378
379 -- At least one of these columns must contain a non-null value
380 ALTER TABLE config.best_hold_order ADD CHECK ((
381     pprox IS NOT NULL OR
382     hprox IS NOT NULL OR
383     owning_lib_to_home_lib_prox IS NOT NULL OR
384     aprox IS NOT NULL OR
385     priority IS NOT NULL OR
386     cut IS NOT NULL OR
387     depth IS NOT NULL OR
388     htime IS NOT NULL OR
389     rtime IS NOT NULL
390 ));
391
392 INSERT INTO config.best_hold_order (
393     name,
394     owning_lib_to_home_lib_prox, hprox, approx, pprox, aprox, priority, cut, depth, rtime
395 ) VALUES (
396     'Traditional with Holds-chase-home-lib-patrons',
397     1, 2, 3, 4, 5, 6, 7, 8, 9
398 );
399
400 COMMIT;
401
402 -- Update auditor tables to catch changes to source tables.
403 --   Can be removed/skipped if there were no schema changes.
404 SELECT auditor.update_auditors();