]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/sql/Pg/version-upgrade/3.3.3-3.4.0-upgrade-db.sql
LP1858448 Disable inititial aged money migration
[working/Evergreen.git] / Open-ILS / src / sql / Pg / version-upgrade / 3.3.3-3.4.0-upgrade-db.sql
1 --Upgrade Script for 3.3.3 to 3.4.0
2 \set eg_version '''3.4.0'''
3 BEGIN;
4 INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.4.0', :eg_version);
5
6 SELECT evergreen.upgrade_deps_block_check('1168', :eg_version); -- csharp/khuckins/gmcharlt
7
8 UPDATE permission.perm_list 
9     SET description = oils_i18n_gettext(
10         '608',
11         'Allows a user to apply values to workstation settings',
12         'ppl', 'description')
13     WHERE code = 'APPLY_WORKSTATION_SETTING' and description = 'APPLY_WORKSTATION_SETTING';
14
15
16
17 SELECT evergreen.upgrade_deps_block_check('1169', :eg_version);
18
19 INSERT INTO config.workstation_setting_type (name, grp, datatype, label)
20 VALUES (
21     'eg.catalog.search_templates', 'gui', 'object',
22     oils_i18n_gettext(
23         'eg.catalog.search_templates',
24         'Staff Catalog Search Templates',
25         'cwst', 'label'
26     )
27 );
28
29
30
31 SELECT evergreen.upgrade_deps_block_check('1170', :eg_version);
32
33 CREATE TABLE config.hold_type (
34     id          SERIAL,
35     hold_type   TEXT UNIQUE,
36     description TEXT
37 );
38
39 INSERT INTO config.hold_type (hold_type,description) VALUES
40     ('C','Copy Hold'),
41     ('V','Volume Hold'),
42     ('T','Title Hold'),
43     ('M','Metarecord Hold'),
44     ('R','Recall Hold'),
45     ('F','Force Hold'),
46     ('I','Issuance Hold'),
47     ('P','Part Hold')
48 ;
49
50 ALTER TABLE action.hold_request ADD CONSTRAINT hold_request_hold_type_fkey FOREIGN KEY (hold_type) REFERENCES config.hold_type(hold_type) DEFERRABLE INITIALLY DEFERRED;
51
52
53 SELECT evergreen.upgrade_deps_block_check('1172', :eg_version);
54
55 INSERT INTO config.workstation_setting_type (name, grp, datatype, label) 
56 VALUES (
57     'eg.grid.admin.local.config.hold_matrix_matchpoint', 'gui', 'object',
58     oils_i18n_gettext(
59         'eg.grid.admin.local.config.hold_matrix_matchpoint',
60         'Grid Config: admin.local.config.hold_matrix_matchpoint',
61         'cwst', 'label'
62     )
63 ), (
64     'eg.grid.admin.local.actor.address_alert', 'gui', 'object',
65     oils_i18n_gettext(
66         'eg.grid.admin.local.actor.address_alert',
67         'Grid Config: admin.local.actor.address_alert',
68         'cwst', 'label'
69     )
70 ), (
71     'eg.grid.admin.local.config.barcode_completion', 'gui', 'object',
72     oils_i18n_gettext(
73         'eg.grid.admin.local.config.barcode_completion',
74         'Grid Config: admin.local.config.barcode_completion',
75         'cwst', 'label'
76     )
77 ), (
78     'eg.grid.admin.local.actor.copy_alert_suppress', 'gui', 'object',
79     oils_i18n_gettext(
80         'eg.grid.admin.local.actor.copy_alert_suppress',
81         'Grid Config: admin.local.actor.copy_alert_suppress',
82         'cwst', 'label'
83     )
84 ), (
85     'eg.grid.admin.local.asset.copy_location', 'gui', 'object',
86     oils_i18n_gettext(
87         'eg.grid.admin.local.asset.copy_location',
88         'Grid Config: admin.local.asset.copy_location',
89         'cwst', 'label'
90     )
91 ), (
92     'eg.grid.admin.local.asset.copy_tag', 'gui', 'object',
93     oils_i18n_gettext(
94         'eg.grid.admin.local.asset.copy_tag',
95         'Grid Config: admin.local.asset.copy_tag',
96         'cwst', 'label'
97     )
98 ), (
99     'eg.grid.admin.local.permission.grp_penalty_threshold', 'gui', 'object',
100     oils_i18n_gettext(
101         'eg.grid.admin.local.permission.grp_penalty_threshold',
102         'Grid Config: admin.local.permission.grp_penalty_threshold',
103         'cwst', 'label'
104     )
105 ), (
106     'eg.grid.admin.local.config.non_cataloged_type', 'gui', 'object',
107     oils_i18n_gettext(
108         'eg.grid.admin.local.config.non_cataloged_type',
109         'Grid Config: admin.local.config.non_cataloged_type',
110         'cwst', 'label'
111     )
112 );
113
114 -- eg.grid.admin.local.rating.badge already exists
115
116
117
118 SELECT evergreen.upgrade_deps_block_check('1173', :eg_version);
119
120 CREATE TABLE config.print_template (
121     id           SERIAL PRIMARY KEY,
122     name         TEXT NOT NULL, -- programatic name
123     label        TEXT NOT NULL, -- i18n
124     owner        INT NOT NULL REFERENCES actor.org_unit (id),
125     active       BOOLEAN NOT NULL DEFAULT FALSE,
126     locale       TEXT REFERENCES config.i18n_locale(code) 
127                  ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
128     content_type TEXT NOT NULL DEFAULT 'text/html',
129     template     TEXT NOT NULL,
130         CONSTRAINT   name_once_per_lib UNIQUE (owner, name),
131         CONSTRAINT   label_once_per_lib UNIQUE (owner, label)
132 );
133
134 INSERT INTO config.print_template 
135     (id, name, locale, active, owner, label, template) 
136 VALUES (
137     1, 'patron_address', 'en-US', FALSE,
138     (SELECT id FROM actor.org_unit WHERE parent_ou IS NULL),
139     oils_i18n_gettext(1, 'Address Label', 'cpt', 'label'),
140 $TEMPLATE$
141 [%-
142     SET patron = template_data.patron;
143     SET addr = template_data.address;
144 -%]
145 <div>
146   <div>
147     [% patron.first_given_name %] 
148     [% patron.second_given_name %] 
149     [% patron.family_name %]
150   </div>
151   <div>[% addr.street1 %]</div>
152   [% IF addr.street2 %]<div>[% addr.street2 %]</div>[% END %]
153   <div>
154     [% addr.city %], [% addr.state %] [% addr.post_code %]
155   </div>
156 </div>
157 $TEMPLATE$
158 );
159
160 INSERT INTO config.print_template 
161     (id, name, locale, active, owner, label, template) 
162 VALUES (
163     2, 'holds_for_bib', 'en-US', FALSE,
164     (SELECT id FROM actor.org_unit WHERE parent_ou IS NULL),
165     oils_i18n_gettext(2, 'Holds for Bib Record', 'cpt', 'label'),
166 $TEMPLATE$
167 [%-
168     USE date;
169     SET holds = template_data;
170     # template_data is an arry of wide_hold hashes.
171 -%]
172 <div>
173   <div>Holds for record: [% holds.0.title %]</div>
174   <hr/>
175   <style>#holds-for-bib-table td { padding: 5px; }</style>
176   <table id="holds-for-bib-table">
177     <thead>
178       <tr>
179         <th>Request Date</th>
180         <th>Patron Barcode</th>
181         <th>Patron Last</th>
182         <th>Patron Alias</th>
183         <th>Current Item</th>
184       </tr>
185     </thead>
186     <tbody>
187       [% FOR hold IN holds %]
188       <tr>
189         <td>[% 
190           date.format(helpers.format_date(
191             hold.request_time, staff_org_timezone), '%x %r', locale) 
192         %]</td>
193         <td>[% hold.ucard_barcode %]</td>
194         <td>[% hold.usr_family_name %]</td>
195         <td>[% hold.usr_alias %]</td>
196         <td>[% hold.cp_barcode %]</td>
197       </tr>
198       [% END %]
199     </tbody>
200   </table>
201   <hr/>
202   <div>
203     [% staff_org.shortname %] 
204     [% date.format(helpers.current_date(client_timezone), '%x %r', locale) %]
205   </div>
206   <div>Printed by [% staff.first_given_name %]</div>
207 </div>
208 <br/>
209
210 $TEMPLATE$
211 );
212
213 -- Allow for 1k stock templates
214 SELECT SETVAL('config.print_template_id_seq'::TEXT, 1000);
215
216 INSERT INTO permission.perm_list (id, code, description) 
217 VALUES (611, 'ADMIN_PRINT_TEMPLATE', 
218     oils_i18n_gettext(611, 'Modify print templates', 'ppl', 'description'));
219
220
221
222 INSERT INTO config.upgrade_log (version, applied_to) VALUES ('1174', :eg_version);
223
224 ALTER TABLE asset.copy_tag
225           ADD COLUMN url TEXT;
226
227
228 SELECT evergreen.upgrade_deps_block_check('1175', :eg_version);
229
230 CREATE TABLE config.carousel_type (
231     id                          SERIAL PRIMARY KEY,
232     name                        TEXT NOT NULL,
233     automatic                   BOOLEAN NOT NULL DEFAULT TRUE,
234     filter_by_age               BOOLEAN NOT NULL DEFAULT FALSE,
235     filter_by_copy_owning_lib   BOOLEAN NOT NULL DEFAULT FALSE,
236     filter_by_copy_location     BOOLEAN NOT NULL DEFAULT FALSE
237 );
238
239 INSERT INTO config.carousel_type
240     (id, name,                               automatic, filter_by_age, filter_by_copy_owning_lib, filter_by_copy_location)
241 VALUES
242     (1, 'Manual',                            FALSE,     FALSE,         FALSE,                     FALSE),
243     (2, 'Newly Catalogued Items',            TRUE,      TRUE,          TRUE,                      TRUE),
244     (3, 'Recently Returned Items',           TRUE,      TRUE,          TRUE,                      TRUE),
245     (4, 'Top Circulated Items',              TRUE,      TRUE,          TRUE,                      FALSE),
246     (5, 'Newest Items By Shelving Location', TRUE,      TRUE,          TRUE,                      FALSE)
247 ;
248
249 SELECT SETVAL('config.carousel_type_id_seq'::TEXT, 100);
250
251 CREATE TABLE container.carousel (
252     id                      SERIAL PRIMARY KEY,
253     type                    INTEGER NOT NULL REFERENCES config.carousel_type (id),
254     owner                   INTEGER NOT NULL REFERENCES actor.org_unit (id),
255     name                    TEXT NOT NULL,
256     bucket                  INTEGER REFERENCES container.biblio_record_entry_bucket (id),
257     creator                 INTEGER NOT NULL REFERENCES actor.usr (id),
258     editor                  INTEGER NOT NULL REFERENCES actor.usr (id),
259     create_time             TIMESTAMPTZ NOT NULL DEFAULT now(),
260     edit_time               TIMESTAMPTZ NOT NULL DEFAULT now(),
261     age_filter              INTERVAL,
262     owning_lib_filter       INT[],
263     copy_location_filter    INT[],
264     last_refresh_time       TIMESTAMPTZ,
265     active                  BOOLEAN NOT NULL DEFAULT TRUE,
266     max_items               INTEGER NOT NULL
267 );
268
269 CREATE TABLE container.carousel_org_unit (
270     id              SERIAL PRIMARY KEY,
271     carousel        INTEGER NOT NULL REFERENCES container.carousel (id) ON DELETE CASCADE,
272     override_name   TEXT,
273     org_unit        INTEGER NOT NULL REFERENCES actor.org_unit (id),
274     seq             INTEGER NOT NULL
275 );
276
277 INSERT INTO container.biblio_record_entry_bucket_type (code, label) VALUES ('carousel', 'Carousel');
278
279 INSERT INTO permission.perm_list ( id, code, description ) VALUES
280  ( 612, 'ADMIN_CAROUSEL_TYPE', oils_i18n_gettext(611,
281     'Allow a user to manage carousel types', 'ppl', 'description')),
282  ( 613, 'ADMIN_CAROUSEL', oils_i18n_gettext(612,
283     'Allow a user to manage carousels', 'ppl', 'description')),
284  ( 614, 'REFRESH_CAROUSEL', oils_i18n_gettext(613,
285     'Allow a user to refresh carousels', 'ppl', 'description'))
286 ;
287
288
289 SELECT evergreen.upgrade_deps_block_check('1176', :eg_version);
290
291 ALTER TABLE booking.reservation
292     ADD COLUMN note TEXT;
293
294
295 SELECT evergreen.upgrade_deps_block_check('1177', :eg_version);
296
297 INSERT INTO config.workstation_setting_type (name, grp, datatype, label)
298 VALUES (
299     'eg.grid.booking.manage', 'gui', 'object',
300     oils_i18n_gettext(
301         'booking.manage',
302         'Grid Config: Booking Manage Reservations',
303         'cwst', 'label')
304 ), (
305     'eg.grid.booking.pickup.ready', 'gui', 'object',
306     oils_i18n_gettext(
307         'booking.pickup.ready',
308         'Grid Config: Booking Ready to pick up grid',
309         'cwst', 'label')
310 ), (
311     'eg.grid.booking.pickup.picked_up', 'gui', 'object',
312     oils_i18n_gettext(
313         'booking.pickup.picked_up',
314         'Grid Config: Booking Already Picked Up grid',
315         'cwst', 'label')
316 ), (
317     'eg.grid.booking.return.patron.picked_up', 'gui', 'object',
318     oils_i18n_gettext(
319         'booking.return.patron.picked_up',
320         'Grid Config: Booking Return Patron tab Already Picked Up grid',
321         'cwst', 'label')
322 ), (
323     'eg.grid.booking.return.patron.returned', 'gui', 'object',
324     oils_i18n_gettext(
325         'booking.return.patron.returned',
326         'Grid Config: Booking Return Patron tab Returned Today grid',
327         'cwst', 'label')
328 ), (
329     'eg.grid.booking.return.resource.picked_up', 'gui', 'object',
330     oils_i18n_gettext(
331         'booking.return.resourcce.picked_up',
332         'Grid Config: Booking Return Resource tab Already Picked Up grid',
333         'cwst', 'label')
334 ), (
335     'eg.grid.booking.return.resource.returned', 'gui', 'object',
336     oils_i18n_gettext(
337         'booking.return.resource.returned',
338         'Grid Config: Booking Return Resource tab Returned Today grid',
339         'cwst', 'label')
340 ), (
341     'eg.booking.manage.selected_org_family', 'gui', 'object',
342     oils_i18n_gettext(
343         'booking.manage.selected_org_family',
344         'Sticky setting for pickup ou family in Manage Reservations screen',
345         'cwst', 'label')
346 ), (
347     'eg.booking.return.tab', 'gui', 'string',
348     oils_i18n_gettext(
349         'booking.return.tab',
350         'Sticky setting for tab in Booking Return',
351         'cwst', 'label')
352 ), (
353     'eg.booking.create.granularity', 'gui', 'integer',
354     oils_i18n_gettext(
355         'booking.create.granularity',
356         'Sticky setting for granularity combobox in Booking Create',
357         'cwst', 'label')
358 ), (
359     'eg.booking.create.multiday', 'gui', 'bool',
360     oils_i18n_gettext(
361         'booking.create.multiday',
362         'Default to creating multiday booking reservations',
363         'cwst', 'label')
364 ), (
365     'eg.booking.pickup.ready.only_show_captured', 'gui', 'bool',
366     oils_i18n_gettext(
367         'booking.pickup.ready.only_show_captured',
368         'Include only resources that have been captured in the Ready grid in the Pickup screen',
369         'cwst', 'label')
370 );
371
372
373 SELECT evergreen.upgrade_deps_block_check('1178', :eg_version);
374
375 INSERT INTO action_trigger.event_definition (active, owner, name, hook, validator, reactor, delay, group_field, max_delay, template) 
376     VALUES (false, 1, 'Fine Limit Exceeded', 'penalty.PATRON_EXCEEDS_FINES', 'NOOP_True', 'SendEmail', '00:05:00', 'usr', '1 day', 
377 $$
378 [%- USE date -%]
379 [%- user = target.usr -%]
380
381 To: [%- params.recipient_email || user.email %]
382 From: [%- params.sender_email || default_sender %]
383 Date: [%- date.format(date.now, '%a, %d %b %Y %T -0000', gmt => 1) %]
384 Subject: Fine Limit Exceeded
385 Auto-Submitted: auto-generated
386
387 Dear [% user.first_given_name %] [% user.family_name %],
388
389
390 Our records indicate your account has exceeded the fine limit allowed for the use of your library account.
391
392 Please visit the library to pay your fines and restore full access to your account.
393 [% END %]
394
395 $$);
396
397 INSERT INTO action_trigger.environment (event_def, path) VALUES
398     (currval('action_trigger.event_definition_id_seq'), 'usr'),
399     (currval('action_trigger.event_definition_id_seq'), 'usr.card');
400
401
402 SELECT evergreen.upgrade_deps_block_check('1179', :eg_version);
403
404 INSERT INTO config.org_unit_setting_type 
405     (grp, name, datatype, label, description)
406 VALUES (
407     'opac',
408     'opac.show_owning_lib_column', 'bool',
409     oils_i18n_gettext(
410         'opac.show_owning_lib_column',
411         'Show Owning Lib in Items Out',
412         'coust',
413         'label'
414     ),
415     oils_i18n_gettext(
416         'opac.show_owning_lib_column',
417 'If enabled, the Owning Lib will be shown in the Items Out display.' ||
418 ' This may assist in requesting additional renewals',
419         'coust',
420         'description'
421     )
422 );
423
424
425 SELECT evergreen.upgrade_deps_block_check('1180', :eg_version);
426
427 INSERT INTO permission.perm_list ( id, code, description ) VALUES
428  ( 615, 'ADMIN_REMOTEAUTH', oils_i18n_gettext( 615,
429     'Administer remote patron authentication', 'ppl', 'description' ));
430
431 CREATE TABLE config.remoteauth_profile (
432     name TEXT PRIMARY KEY,
433     description TEXT,
434     context_org INT NOT NULL REFERENCES actor.org_unit(id) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
435     enabled BOOLEAN NOT NULL DEFAULT FALSE,
436     perm INT NOT NULL REFERENCES permission.perm_list(id) ON UPDATE CASCADE ON DELETE RESTRICT DEFERRABLE INITIALLY DEFERRED,
437     restrict_to_org BOOLEAN NOT NULL DEFAULT TRUE,
438     allow_inactive BOOL NOT NULL DEFAULT FALSE,
439     allow_expired BOOL NOT NULL DEFAULT FALSE,
440     block_list TEXT,
441     usr_activity_type INT REFERENCES config.usr_activity_type(id) ON UPDATE CASCADE ON DELETE RESTRICT DEFERRABLE INITIALLY DEFERRED
442 );
443
444 CREATE OR REPLACE FUNCTION actor.permit_remoteauth (profile_name TEXT, userid BIGINT) RETURNS TEXT AS $func$
445 DECLARE
446     usr               actor.usr%ROWTYPE;
447     profile           config.remoteauth_profile%ROWTYPE;
448     perm              TEXT;
449     context_org_list  INT[];
450     home_prox         INT;
451     block             TEXT;
452     penalty_count     INT;
453 BEGIN
454
455     SELECT INTO usr * FROM actor.usr WHERE id = userid AND NOT deleted;
456     IF usr IS NULL THEN
457         RETURN 'not_found';
458     END IF;
459
460     IF usr.barred IS TRUE THEN
461         RETURN 'blocked';
462     END IF;
463
464     SELECT INTO profile * FROM config.remoteauth_profile WHERE name = profile_name;
465     SELECT INTO context_org_list ARRAY_AGG(id) FROM actor.org_unit_full_path( profile.context_org );
466
467     -- user's home library must be within the context org
468     IF profile.restrict_to_org IS TRUE AND usr.home_ou NOT IN (SELECT * FROM UNNEST(context_org_list)) THEN
469         RETURN 'not_found';
470     END IF;
471
472     SELECT INTO perm code FROM permission.perm_list WHERE id = profile.perm;
473     IF permission.usr_has_perm(usr.id, perm, profile.context_org) IS FALSE THEN
474         RETURN 'not_found';
475     END IF;
476     
477     IF usr.expire_date < NOW() AND profile.allow_expired IS FALSE THEN
478         RETURN 'expired';
479     END IF;
480
481     IF usr.active IS FALSE AND profile.allow_inactive IS FALSE THEN
482         RETURN 'blocked';
483     END IF;
484
485     -- Proximity of user's home_ou to context_org to see if penalties should be ignored.
486     SELECT INTO home_prox prox FROM actor.org_unit_proximity WHERE from_org = usr.home_ou AND to_org = profile.context_org;
487
488     -- Loop through the block list to see if the user has any matching penalties.
489     IF profile.block_list IS NOT NULL THEN
490         FOR block IN SELECT UNNEST(STRING_TO_ARRAY(profile.block_list, '|')) LOOP
491             SELECT INTO penalty_count COUNT(DISTINCT csp.*)
492                 FROM  actor.usr_standing_penalty usp
493                         JOIN config.standing_penalty csp ON (csp.id = usp.standing_penalty)
494                 WHERE usp.usr = usr.id
495                         AND usp.org_unit IN ( SELECT * FROM UNNEST(context_org_list) )
496                         AND ( usp.stop_date IS NULL or usp.stop_date > NOW() )
497                         AND ( csp.ignore_proximity IS NULL OR csp.ignore_proximity < home_prox )
498                         AND csp.block_list ~ block;
499             IF penalty_count > 0 THEN
500                 -- User has penalties that match this block, so auth is not permitted.
501                 -- Don't bother testing the rest of the block list.
502                 RETURN 'blocked';
503             END IF;
504         END LOOP;
505     END IF;
506
507     -- User has passed all tests.
508     RETURN 'success';
509
510 END;
511 $func$ LANGUAGE plpgsql;
512
513
514
515
516 SELECT evergreen.upgrade_deps_block_check('1181', :eg_version);
517
518 \qecho Migrating aged billing and payment data.  This might take a while.
519
520 CREATE TABLE money.aged_payment (LIKE money.payment INCLUDING INDEXES);
521 ALTER TABLE money.aged_payment ADD COLUMN payment_type TEXT NOT NULL;
522
523 CREATE TABLE money.aged_billing (LIKE money.billing INCLUDING INDEXES);
524
525
526 /* LP 1858448 : Disable initial aged money migration
527
528 INSERT INTO money.aged_payment 
529     SELECT  mp.* FROM money.payment_view mp
530     JOIN action.aged_circulation circ ON (circ.id = mp.xact);
531
532 INSERT INTO money.aged_billing
533     SELECT mb.* FROM money.billing mb
534     JOIN action.aged_circulation circ ON (circ.id = mb.xact);
535
536 */
537
538 CREATE OR REPLACE VIEW money.all_payments AS
539     SELECT * FROM money.payment_view 
540     UNION ALL
541     SELECT * FROM money.aged_payment;
542
543 CREATE OR REPLACE VIEW money.all_billings AS
544     SELECT * FROM money.billing
545     UNION ALL
546     SELECT * FROM money.aged_billing;
547
548 CREATE OR REPLACE FUNCTION action.age_circ_on_delete () RETURNS TRIGGER AS $$
549 DECLARE
550 found char := 'N';
551 BEGIN
552
553     -- If there are any renewals for this circulation, don't archive or delete
554     -- it yet.   We'll do so later, when we archive and delete the renewals.
555
556     SELECT 'Y' INTO found
557     FROM action.circulation
558     WHERE parent_circ = OLD.id
559     LIMIT 1;
560
561     IF found = 'Y' THEN
562         RETURN NULL;  -- don't delete
563         END IF;
564
565     -- Archive a copy of the old row to action.aged_circulation
566
567     INSERT INTO action.aged_circulation
568         (id,usr_post_code, usr_home_ou, usr_profile, usr_birth_year, copy_call_number, copy_location,
569         copy_owning_lib, copy_circ_lib, copy_bib_record, xact_start, xact_finish, target_copy,
570         circ_lib, circ_staff, checkin_staff, checkin_lib, renewal_remaining, grace_period, due_date,
571         stop_fines_time, checkin_time, create_time, duration, fine_interval, recurring_fine,
572         max_fine, phone_renewal, desk_renewal, opac_renewal, duration_rule, recurring_fine_rule,
573         max_fine_rule, stop_fines, workstation, checkin_workstation, checkin_scan_time, parent_circ)
574       SELECT
575         id,usr_post_code, usr_home_ou, usr_profile, usr_birth_year, copy_call_number, copy_location,
576         copy_owning_lib, copy_circ_lib, copy_bib_record, xact_start, xact_finish, target_copy,
577         circ_lib, circ_staff, checkin_staff, checkin_lib, renewal_remaining, grace_period, due_date,
578         stop_fines_time, checkin_time, create_time, duration, fine_interval, recurring_fine,
579         max_fine, phone_renewal, desk_renewal, opac_renewal, duration_rule, recurring_fine_rule,
580         max_fine_rule, stop_fines, workstation, checkin_workstation, checkin_scan_time, parent_circ
581         FROM action.all_circulation WHERE id = OLD.id;
582
583     -- Migrate billings and payments to aged tables
584
585 /* LP 1858448 : Disable initial aged money migration
586     INSERT INTO money.aged_billing
587         SELECT * FROM money.billing WHERE xact = OLD.id;
588
589     INSERT INTO money.aged_payment 
590         SELECT * FROM money.payment_view WHERE xact = OLD.id;
591
592     DELETE FROM money.payment WHERE xact = OLD.id;
593     DELETE FROM money.billing WHERE xact = OLD.id;
594 */
595
596     RETURN OLD;
597 END;
598 $$ LANGUAGE 'plpgsql';
599
600
601 /* LP 1858448 : Disable initial aged money migration
602
603 -- NOTE you could COMMIT here then start a new TRANSACTION if desired.
604
605 \qecho Deleting aged payments and billings from active payment/billing
606 \qecho tables.  This may take a while...
607
608 ALTER TABLE money.payment DISABLE TRIGGER mat_summary_del_tgr;
609 ALTER TABLE money.cash_payment DISABLE TRIGGER mat_summary_del_tgr;
610 ALTER TABLE money.check_payment DISABLE TRIGGER mat_summary_del_tgr;
611 ALTER TABLE money.credit_card_payment DISABLE TRIGGER mat_summary_del_tgr;
612 ALTER TABLE money.forgive_payment DISABLE TRIGGER mat_summary_del_tgr;
613 ALTER TABLE money.credit_payment DISABLE TRIGGER mat_summary_del_tgr;
614 ALTER TABLE money.goods_payment DISABLE TRIGGER mat_summary_del_tgr;
615
616 DELETE FROM money.payment WHERE id IN (SELECT id FROM money.aged_payment);
617
618 ALTER TABLE money.payment ENABLE TRIGGER mat_summary_del_tgr;
619 ALTER TABLE money.cash_payment ENABLE TRIGGER mat_summary_del_tgr;
620 ALTER TABLE money.check_payment ENABLE TRIGGER mat_summary_del_tgr;
621 ALTER TABLE money.credit_card_payment ENABLE TRIGGER mat_summary_del_tgr;
622 ALTER TABLE money.forgive_payment ENABLE TRIGGER mat_summary_del_tgr;
623 ALTER TABLE money.credit_payment ENABLE TRIGGER mat_summary_del_tgr;
624 ALTER TABLE money.goods_payment ENABLE TRIGGER mat_summary_del_tgr;
625
626 -- TODO: This approach assumes most of the money.billing rows have been
627 -- copied to money.aged_billing.  If that is not the case, which would
628 -- happen if circ anonymization is not enabled, it will be faster to
629 -- perform a simple delete instead of a truncate/rebuild.
630
631 -- Copy all money.billing rows that are not represented in money.aged_billing
632 CREATE TEMPORARY TABLE tmp_money_billing ON COMMIT DROP AS
633     SELECT mb.* FROM money.billing mb
634     LEFT JOIN money.aged_billing mab USING (id)
635     WHERE mab.id IS NULL;
636
637 ALTER TABLE money.billing DISABLE TRIGGER ALL;
638
639 -- temporarily remove the foreign key constraint to money.billing on
640 -- account adjusment.  Needed for money.billing truncate.
641 ALTER TABLE money.account_adjustment 
642     DROP CONSTRAINT account_adjustment_billing_fkey;
643
644 TRUNCATE money.billing;
645
646 INSERT INTO money.billing SELECT * FROM tmp_money_billing;
647
648 ALTER TABLE money.billing ENABLE TRIGGER ALL;
649 ALTER TABLE money.account_adjustment 
650     ADD CONSTRAINT account_adjustment_billing_fkey 
651     FOREIGN KEY (billing) REFERENCES money.billing (id);
652
653
654 -- Good to run after truncating -- OK to run after COMMIT.
655 ANALYZE money.billing;
656
657 */
658
659
660 SELECT evergreen.upgrade_deps_block_check('1182', :eg_version);
661
662 INSERT INTO permission.perm_list ( id, code, description ) VALUES
663  ( 616, 'IMPORT_USE_ORG_UNIT_COPIES', oils_i18n_gettext( 616,
664     'Allows users to import records based on the number of org unit copies attached to a record', 'ppl', 'description' )),
665  ( 617, 'IMPORT_ON_ORDER_CAT_COPY', oils_i18n_gettext( 617,
666     'Allows users to import copies based on the on-order items attached to a record', 'ppl', 'description' ));
667
668 -- function update in 1182 further updated in 1186
669
670 SELECT evergreen.upgrade_deps_block_check('1183', :eg_version);
671
672 INSERT into config.org_unit_setting_type
673 ( name, grp, label, description, datatype, fm_class ) VALUES
674 ( 'ui.patron.edit.au.ident_value.require', 'gui',
675     oils_i18n_gettext('ui.patron.edit.au.ident_value.require',
676         'require ident_value field on patron registration',
677         'coust', 'label'),
678     oils_i18n_gettext('ui.patron.edit.au.ident_value.require',
679         'The ident_value field will be required on the patron registration screen.',
680         'coust', 'description'),
681     'bool', null);
682
683
684
685 SELECT evergreen.upgrade_deps_block_check('1184', :eg_version);
686
687 INSERT INTO permission.perm_list(id, code, description)
688     VALUES (618, 'CREATE_PRECAT', 'Allows user to create a pre-catalogued copy');
689
690 -- Add this new permission to any group with Staff login perm.
691 -- Manually remove if needed
692 INSERT INTO permission.grp_perm_map(perm, grp, depth) SELECT 618, map.grp, 0 FROM permission.grp_perm_map AS map WHERE map.perm = 2;
693
694 SELECT evergreen.upgrade_deps_block_check('1185', :eg_version); -- csharp / gmcharlt / jboyer
695
696 ALTER FUNCTION permission.grp_descendants( INT ) STABLE;
697
698 SELECT evergreen.upgrade_deps_block_check('1186', :eg_version);
699
700 CREATE OR REPLACE FUNCTION vandelay.auto_overlay_org_unit_copies ( import_id BIGINT, merge_profile_id INT, lwm_ratio_value_p NUMERIC ) RETURNS BOOL AS $$
701 DECLARE
702     eg_id           BIGINT;
703     match_count     INT;
704     rec             vandelay.bib_match%ROWTYPE;
705     v_owning_lib    INT;
706     scope_org       INT;
707     scope_orgs      INT[];
708     copy_count      INT := 0;
709     max_copy_count  INT := 0;
710 BEGIN
711
712     PERFORM * FROM vandelay.queued_bib_record WHERE import_time IS NOT NULL AND id = import_id;
713
714     IF FOUND THEN
715         -- RAISE NOTICE 'already imported, cannot auto-overlay'
716         RETURN FALSE;
717     END IF;
718
719     -- Gather all the owning libs for our import items.
720     -- These are our initial scope_orgs.
721     SELECT ARRAY_AGG(DISTINCT owning_lib) INTO scope_orgs
722         FROM vandelay.import_item
723         WHERE record = import_id;
724
725     WHILE CARDINALITY(scope_orgs) > 0 LOOP
726         FOR scope_org IN SELECT * FROM UNNEST(scope_orgs) LOOP
727             -- For each match, get a count of all copies at descendants of our scope org.
728             FOR rec IN SELECT * FROM vandelay.bib_match AS vbm
729                 WHERE queued_record = import_id
730                 ORDER BY vbm.eg_record DESC
731             LOOP
732                 SELECT COUNT(acp.id) INTO copy_count
733                     FROM asset.copy AS acp
734                     INNER JOIN asset.call_number AS acn
735                         ON acp.call_number = acn.id
736                     WHERE acn.owning_lib IN (SELECT id FROM
737                         actor.org_unit_descendants(scope_org))
738                     AND acn.record = rec.eg_record
739                     AND acp.deleted = FALSE;
740                 IF copy_count > max_copy_count THEN
741                     max_copy_count := copy_count;
742                     eg_id := rec.eg_record;
743                 END IF;
744             END LOOP;
745         END LOOP;
746
747         -- If no matching bibs had holdings, gather our next set of orgs to check, and iterate.
748         IF max_copy_count = 0 THEN 
749             SELECT ARRAY_AGG(DISTINCT parent_ou) INTO scope_orgs
750                 FROM actor.org_unit
751                 WHERE id IN (SELECT * FROM UNNEST(scope_orgs))
752                 AND parent_ou IS NOT NULL;
753         END IF;
754     END LOOP;
755
756     IF eg_id IS NULL THEN
757         -- Could not determine best match via copy count
758         -- fall back to default best match
759         IF (SELECT * FROM vandelay.auto_overlay_bib_record_with_best( import_id, merge_profile_id, lwm_ratio_value_p )) THEN
760             RETURN TRUE;
761         ELSE
762             RETURN FALSE;
763         END IF;
764     END IF;
765
766     RETURN vandelay.overlay_bib_record( import_id, eg_id, merge_profile_id );
767 END;
768 $$ LANGUAGE PLPGSQL;
769
770 SELECT evergreen.upgrade_deps_block_check('1187', :eg_version);
771 SELECT evergreen.upgrade_deps_block_check('1192', :eg_version);
772
773 CREATE OR REPLACE FUNCTION action.age_circ_on_delete () RETURNS TRIGGER AS $$
774 DECLARE
775 found char := 'N';
776 BEGIN
777
778     -- If there are any renewals for this circulation, don't archive or delete
779     -- it yet.   We'll do so later, when we archive and delete the renewals.
780
781     SELECT 'Y' INTO found
782     FROM action.circulation
783     WHERE parent_circ = OLD.id
784     LIMIT 1;
785
786     IF found = 'Y' THEN
787         RETURN NULL;  -- don't delete
788         END IF;
789
790     -- Archive a copy of the old row to action.aged_circulation
791
792     INSERT INTO action.aged_circulation
793         (id,usr_post_code, usr_home_ou, usr_profile, usr_birth_year, copy_call_number, copy_location,
794         copy_owning_lib, copy_circ_lib, copy_bib_record, xact_start, xact_finish, target_copy,
795         circ_lib, circ_staff, checkin_staff, checkin_lib, renewal_remaining, grace_period, due_date,
796         stop_fines_time, checkin_time, create_time, duration, fine_interval, recurring_fine,
797         max_fine, phone_renewal, desk_renewal, opac_renewal, duration_rule, recurring_fine_rule,
798         max_fine_rule, stop_fines, workstation, checkin_workstation, checkin_scan_time, parent_circ,
799         auto_renewal, auto_renewal_remaining)
800       SELECT
801         id,usr_post_code, usr_home_ou, usr_profile, usr_birth_year, copy_call_number, copy_location,
802         copy_owning_lib, copy_circ_lib, copy_bib_record, xact_start, xact_finish, target_copy,
803         circ_lib, circ_staff, checkin_staff, checkin_lib, renewal_remaining, grace_period, due_date,
804         stop_fines_time, checkin_time, create_time, duration, fine_interval, recurring_fine,
805         max_fine, phone_renewal, desk_renewal, opac_renewal, duration_rule, recurring_fine_rule,
806         max_fine_rule, stop_fines, workstation, checkin_workstation, checkin_scan_time, parent_circ,
807         auto_renewal, auto_renewal_remaining
808         FROM action.all_circulation WHERE id = OLD.id;
809
810     -- Migrate billings and payments to aged tables
811
812 /* LP 1858448 : Disable initial aged money migration
813     INSERT INTO money.aged_billing
814         SELECT * FROM money.billing WHERE xact = OLD.id;
815
816     INSERT INTO money.aged_payment 
817         SELECT * FROM money.payment_view WHERE xact = OLD.id;
818
819     DELETE FROM money.payment WHERE xact = OLD.id;
820     DELETE FROM money.billing WHERE xact = OLD.id;
821 */
822
823     RETURN OLD;
824 END;
825 $$ LANGUAGE 'plpgsql';
826
827 SELECT evergreen.upgrade_deps_block_check('1188', :eg_version);
828
829 UPDATE action.circulation SET auto_renewal = FALSE WHERE auto_renewal IS NULL;
830 UPDATE action.aged_circulation SET auto_renewal = FALSE WHERE auto_renewal IS NULL;
831
832
833 SELECT evergreen.upgrade_deps_block_check('1189', :eg_version);
834
835 CREATE OR REPLACE VIEW action.open_circulation AS
836         SELECT  *
837           FROM  action.circulation
838           WHERE checkin_time IS NULL
839           ORDER BY due_date;
840
841 CREATE OR REPLACE VIEW action.billable_circulations AS
842         SELECT  *
843           FROM  action.circulation
844           WHERE xact_finish IS NULL;
845
846 CREATE OR REPLACE VIEW reporter.overdue_circs AS
847 SELECT  *
848   FROM  "action".circulation
849   WHERE checkin_time is null
850         AND (stop_fines NOT IN ('LOST','CLAIMSRETURNED') OR stop_fines IS NULL)
851         AND due_date < now();
852
853 CREATE OR REPLACE VIEW reporter.circ_type AS
854 SELECT  id,
855         CASE WHEN opac_renewal OR phone_renewal OR desk_renewal OR auto_renewal
856                 THEN 'RENEWAL'
857                 ELSE 'CHECKOUT'
858         END AS "type"
859   FROM  action.circulation;
860
861 SELECT evergreen.upgrade_deps_block_check('1190', :eg_version);
862
863 UPDATE action.circulation SET desk_renewal = FALSE WHERE auto_renewal IS TRUE;
864
865 UPDATE action.aged_circulation SET desk_renewal = FALSE WHERE auto_renewal IS TRUE;
866
867
868 SELECT evergreen.upgrade_deps_block_check('1191', :eg_version);
869
870 INSERT INTO permission.perm_list ( id, code, description ) SELECT DISTINCT
871   619,
872   'EDIT_SELF_IN_CLIENT',
873   oils_i18n_gettext(619,
874     'Allow a user to edit their own account in the staff client', 'ppl', 'description'
875   )
876   FROM permission.perm_list
877   WHERE NOT EXISTS (SELECT 1 FROM permission.perm_list WHERE code = 'EDIT_SELF_IN_CLIENT');
878
879 COMMIT;
880
881 -- The following two changes from 1188 cannot occur in a transaction with the
882 -- above updates because we will get an error about not being able to
883 -- alter a table with pending transactions.  They also need to occur
884 -- after the above updates or the SET NOT NULL change will fail.
885
886 ALTER TABLE action.circulation ALTER COLUMN auto_renewal SET DEFAULT FALSE;
887 ALTER TABLE action.circulation ALTER COLUMN auto_renewal SET NOT NULL;
888
889 ALTER TABLE action.aged_circulation ALTER COLUMN auto_renewal SET DEFAULT FALSE;
890 ALTER TABLE action.aged_circulation ALTER COLUMN auto_renewal SET NOT NULL;
891
892 -- Update auditor tables to catch changes to source tables.
893 --   Can be removed/skipped if there were no schema changes.
894 SELECT auditor.update_auditors();