Correcting some diverging drift in the usr_merge function
[working/Evergreen.git] / Open-ILS / src / sql / Pg / upgrade / 0278.function.usr-merge-drift.sql
1 BEGIN;
2
3 INSERT INTO config.upgrade_log (version) VALUES ('0278'); -- Scott McKellar
4
5 CREATE OR REPLACE FUNCTION actor.usr_merge(
6         src_usr INT,
7         dest_usr INT,
8         del_addrs BOOLEAN,
9         del_cards BOOLEAN,
10         deactivate_cards BOOLEAN
11 ) RETURNS VOID AS $$
12 DECLARE
13         suffix TEXT;
14         bucket_row RECORD;
15         picklist_row RECORD;
16         queue_row RECORD;
17         folder_row RECORD;
18 BEGIN
19
20     -- do some initial cleanup 
21     UPDATE actor.usr SET card = NULL WHERE id = src_usr;
22     UPDATE actor.usr SET mailing_address = NULL WHERE id = src_usr;
23     UPDATE actor.usr SET billing_address = NULL WHERE id = src_usr;
24
25     -- actor.*
26     IF del_cards THEN
27         DELETE FROM actor.card where usr = src_usr;
28     ELSE
29         IF deactivate_cards THEN
30             UPDATE actor.card SET active = 'f' WHERE usr = src_usr;
31         END IF;
32         UPDATE actor.card SET usr = dest_usr WHERE usr = src_usr;
33     END IF;
34
35
36     IF del_addrs THEN
37         DELETE FROM actor.usr_address WHERE usr = src_usr;
38     ELSE
39         UPDATE actor.usr_address SET usr = dest_usr WHERE usr = src_usr;
40     END IF;
41
42     UPDATE actor.usr_note SET usr = dest_usr WHERE usr = src_usr;
43     -- dupes are technically OK in actor.usr_standing_penalty, should manually delete them...
44     UPDATE actor.usr_standing_penalty SET usr = dest_usr WHERE usr = src_usr;
45     PERFORM actor.usr_merge_rows('actor.usr_org_unit_opt_in', 'usr', src_usr, dest_usr);
46     PERFORM actor.usr_merge_rows('actor.usr_setting', 'usr', src_usr, dest_usr);
47
48     -- permission.*
49     PERFORM actor.usr_merge_rows('permission.usr_perm_map', 'usr', src_usr, dest_usr);
50     PERFORM actor.usr_merge_rows('permission.usr_object_perm_map', 'usr', src_usr, dest_usr);
51     PERFORM actor.usr_merge_rows('permission.usr_grp_map', 'usr', src_usr, dest_usr);
52     PERFORM actor.usr_merge_rows('permission.usr_work_ou_map', 'usr', src_usr, dest_usr);
53
54
55     -- container.*
56         
57         -- For each *_bucket table: transfer every bucket belonging to src_usr
58         -- into the custody of dest_usr.
59         --
60         -- In order to avoid colliding with an existing bucket owned by
61         -- the destination user, append the source user's id (in parenthesese)
62         -- to the name.  If you still get a collision, add successive
63         -- spaces to the name and keep trying until you succeed.
64         --
65         FOR bucket_row in
66                 SELECT id, name
67                 FROM   container.biblio_record_entry_bucket
68                 WHERE  owner = src_usr
69         LOOP
70                 suffix := ' (' || src_usr || ')';
71                 LOOP
72                         BEGIN
73                                 UPDATE  container.biblio_record_entry_bucket
74                                 SET     owner = dest_usr, name = name || suffix
75                                 WHERE   id = bucket_row.id;
76                         EXCEPTION WHEN unique_violation THEN
77                                 suffix := suffix || ' ';
78                                 CONTINUE;
79                         END;
80                         EXIT;
81                 END LOOP;
82         END LOOP;
83
84         FOR bucket_row in
85                 SELECT id, name
86                 FROM   container.call_number_bucket
87                 WHERE  owner = src_usr
88         LOOP
89                 suffix := ' (' || src_usr || ')';
90                 LOOP
91                         BEGIN
92                                 UPDATE  container.call_number_bucket
93                                 SET     owner = dest_usr, name = name || suffix
94                                 WHERE   id = bucket_row.id;
95                         EXCEPTION WHEN unique_violation THEN
96                                 suffix := suffix || ' ';
97                                 CONTINUE;
98                         END;
99                         EXIT;
100                 END LOOP;
101         END LOOP;
102
103         FOR bucket_row in
104                 SELECT id, name
105                 FROM   container.copy_bucket
106                 WHERE  owner = src_usr
107         LOOP
108                 suffix := ' (' || src_usr || ')';
109                 LOOP
110                         BEGIN
111                                 UPDATE  container.copy_bucket
112                                 SET     owner = dest_usr, name = name || suffix
113                                 WHERE   id = bucket_row.id;
114                         EXCEPTION WHEN unique_violation THEN
115                                 suffix := suffix || ' ';
116                                 CONTINUE;
117                         END;
118                         EXIT;
119                 END LOOP;
120         END LOOP;
121
122         FOR bucket_row in
123                 SELECT id, name
124                 FROM   container.user_bucket
125                 WHERE  owner = src_usr
126         LOOP
127                 suffix := ' (' || src_usr || ')';
128                 LOOP
129                         BEGIN
130                                 UPDATE  container.user_bucket
131                                 SET     owner = dest_usr, name = name || suffix
132                                 WHERE   id = bucket_row.id;
133                         EXCEPTION WHEN unique_violation THEN
134                                 suffix := suffix || ' ';
135                                 CONTINUE;
136                         END;
137                         EXIT;
138                 END LOOP;
139         END LOOP;
140
141         UPDATE container.user_bucket_item SET target_user = dest_usr WHERE target_user = src_usr;
142
143     -- vandelay.*
144         -- transfer queues the same way we transfer buckets (see above)
145         FOR queue_row in
146                 SELECT id, name
147                 FROM   vandelay.queue
148                 WHERE  owner = src_usr
149         LOOP
150                 suffix := ' (' || src_usr || ')';
151                 LOOP
152                         BEGIN
153                                 UPDATE  vandelay.queue
154                                 SET     owner = dest_usr, name = name || suffix
155                                 WHERE   id = queue_row.id;
156                         EXCEPTION WHEN unique_violation THEN
157                                 suffix := suffix || ' ';
158                                 CONTINUE;
159                         END;
160                         EXIT;
161                 END LOOP;
162         END LOOP;
163
164     -- money.*
165     PERFORM actor.usr_merge_rows('money.collections_tracker', 'usr', src_usr, dest_usr);
166     PERFORM actor.usr_merge_rows('money.collections_tracker', 'collector', src_usr, dest_usr);
167     UPDATE money.billable_xact SET usr = dest_usr WHERE usr = src_usr;
168     UPDATE money.billing SET voider = dest_usr WHERE voider = src_usr;
169     UPDATE money.bnm_payment SET accepting_usr = dest_usr WHERE accepting_usr = src_usr;
170
171     -- action.*
172     UPDATE action.circulation SET usr = dest_usr WHERE usr = src_usr;
173     UPDATE action.circulation SET circ_staff = dest_usr WHERE circ_staff = src_usr;
174     UPDATE action.circulation SET checkin_staff = dest_usr WHERE checkin_staff = src_usr;
175
176     UPDATE action.hold_request SET usr = dest_usr WHERE usr = src_usr;
177     UPDATE action.hold_request SET fulfillment_staff = dest_usr WHERE fulfillment_staff = src_usr;
178     UPDATE action.hold_request SET requestor = dest_usr WHERE requestor = src_usr;
179     UPDATE action.hold_notification SET notify_staff = dest_usr WHERE notify_staff = src_usr;
180
181     UPDATE action.in_house_use SET staff = dest_usr WHERE staff = src_usr;
182     UPDATE action.non_cataloged_circulation SET staff = dest_usr WHERE staff = src_usr;
183     UPDATE action.non_cataloged_circulation SET patron = dest_usr WHERE patron = src_usr;
184     UPDATE action.non_cat_in_house_use SET staff = dest_usr WHERE staff = src_usr;
185     UPDATE action.survey_response SET usr = dest_usr WHERE usr = src_usr;
186
187     -- acq.*
188     UPDATE acq.fund_allocation SET allocator = dest_usr WHERE allocator = src_usr;
189     UPDATE acq.fund_transfer SET transfer_user = dest_usr WHERE transfer_user = src_usr;
190
191         -- transfer picklists the same way we transfer buckets (see above)
192         FOR picklist_row in
193                 SELECT id, name
194                 FROM   acq.picklist
195                 WHERE  owner = src_usr
196         LOOP
197                 suffix := ' (' || src_usr || ')';
198                 LOOP
199                         BEGIN
200                                 UPDATE  acq.picklist
201                                 SET     owner = dest_usr, name = name || suffix
202                                 WHERE   id = picklist_row.id;
203                         EXCEPTION WHEN unique_violation THEN
204                                 suffix := suffix || ' ';
205                                 CONTINUE;
206                         END;
207                         EXIT;
208                 END LOOP;
209         END LOOP;
210
211     UPDATE acq.purchase_order SET owner = dest_usr WHERE owner = src_usr;
212     UPDATE acq.po_note SET creator = dest_usr WHERE creator = src_usr;
213     UPDATE acq.po_note SET editor = dest_usr WHERE editor = src_usr;
214         UPDATE acq.provider_note SET creator = dest_usr WHERE creator = src_usr;
215         UPDATE acq.provider_note SET editor = dest_usr WHERE editor = src_usr;
216     UPDATE acq.lineitem_note SET creator = dest_usr WHERE creator = src_usr;
217     UPDATE acq.lineitem_note SET editor = dest_usr WHERE editor = src_usr;
218     UPDATE acq.lineitem_usr_attr_definition SET usr = dest_usr WHERE usr = src_usr;
219
220     -- asset.*
221     UPDATE asset.copy SET creator = dest_usr WHERE creator = src_usr;
222     UPDATE asset.copy SET editor = dest_usr WHERE editor = src_usr;
223     UPDATE asset.copy_note SET creator = dest_usr WHERE creator = src_usr;
224     UPDATE asset.call_number SET creator = dest_usr WHERE creator = src_usr;
225     UPDATE asset.call_number SET editor = dest_usr WHERE editor = src_usr;
226     UPDATE asset.call_number_note SET creator = dest_usr WHERE creator = src_usr;
227
228     -- serial.*
229     UPDATE serial.record_entry SET creator = dest_usr WHERE creator = src_usr;
230     UPDATE serial.record_entry SET editor = dest_usr WHERE editor = src_usr;
231
232     -- reporter.*
233     -- It's not uncommon to define the reporter schema in a replica 
234     -- DB only, so don't assume these tables exist in the write DB.
235     BEGIN
236         UPDATE reporter.template SET owner = dest_usr WHERE owner = src_usr;
237     EXCEPTION WHEN undefined_table THEN
238         -- do nothing
239     END;
240     BEGIN
241         UPDATE reporter.report SET owner = dest_usr WHERE owner = src_usr;
242     EXCEPTION WHEN undefined_table THEN
243         -- do nothing
244     END;
245     BEGIN
246         UPDATE reporter.schedule SET runner = dest_usr WHERE runner = src_usr;
247     EXCEPTION WHEN undefined_table THEN
248         -- do nothing
249     END;
250     BEGIN
251                 -- transfer folders the same way we transfer buckets (see above)
252                 FOR folder_row in
253                         SELECT id, name
254                         FROM   reporter.template_folder
255                         WHERE  owner = src_usr
256                 LOOP
257                         suffix := ' (' || src_usr || ')';
258                         LOOP
259                                 BEGIN
260                                         UPDATE  reporter.template_folder
261                                         SET     owner = dest_usr, name = name || suffix
262                                         WHERE   id = folder_row.id;
263                                 EXCEPTION WHEN unique_violation THEN
264                                         suffix := suffix || ' ';
265                                         CONTINUE;
266                                 END;
267                                 EXIT;
268                         END LOOP;
269                 END LOOP;
270     EXCEPTION WHEN undefined_table THEN
271         -- do nothing
272     END;
273     BEGIN
274                 -- transfer folders the same way we transfer buckets (see above)
275                 FOR folder_row in
276                         SELECT id, name
277                         FROM   reporter.report_folder
278                         WHERE  owner = src_usr
279                 LOOP
280                         suffix := ' (' || src_usr || ')';
281                         LOOP
282                                 BEGIN
283                                         UPDATE  reporter.report_folder
284                                         SET     owner = dest_usr, name = name || suffix
285                                         WHERE   id = folder_row.id;
286                                 EXCEPTION WHEN unique_violation THEN
287                                         suffix := suffix || ' ';
288                                         CONTINUE;
289                                 END;
290                                 EXIT;
291                         END LOOP;
292                 END LOOP;
293     EXCEPTION WHEN undefined_table THEN
294         -- do nothing
295     END;
296     BEGIN
297                 -- transfer folders the same way we transfer buckets (see above)
298                 FOR folder_row in
299                         SELECT id, name
300                         FROM   reporter.output_folder
301                         WHERE  owner = src_usr
302                 LOOP
303                         suffix := ' (' || src_usr || ')';
304                         LOOP
305                                 BEGIN
306                                         UPDATE  reporter.output_folder
307                                         SET     owner = dest_usr, name = name || suffix
308                                         WHERE   id = folder_row.id;
309                                 EXCEPTION WHEN unique_violation THEN
310                                         suffix := suffix || ' ';
311                                         CONTINUE;
312                                 END;
313                                 EXIT;
314                         END LOOP;
315                 END LOOP;
316     EXCEPTION WHEN undefined_table THEN
317         -- do nothing
318     END;
319
320     -- Finally, delete the source user
321     DELETE FROM actor.usr WHERE id = src_usr;
322
323 END;
324 $$ LANGUAGE plpgsql;
325
326 COMMIT;