LP#1775216: Stamping upgrade script for inconsistent copy counts
[Evergreen.git] / Open-ILS / src / sql / Pg / upgrade / 1119.schema.lp1775216_consistent_avail_counts.sql
1 SELECT evergreen.upgrade_deps_block_check('1119', :eg_version);
2
3 CREATE OR REPLACE FUNCTION asset.staff_ou_record_copy_count(org integer, rid bigint)
4  RETURNS TABLE(depth integer, org_unit integer, visible bigint, available bigint, unshadow bigint, transcendant integer)
5  LANGUAGE plpgsql
6 AS $function$
7 DECLARE
8     ans RECORD;
9     trans INT;
10 BEGIN
11     SELECT 1 INTO trans FROM biblio.record_entry b JOIN config.bib_source src ON (b.source = src.id) WHERE src.transcendant AND b.id = rid;
12
13     FOR ans IN SELECT u.id, t.depth FROM actor.org_unit_ancestors(org) AS u JOIN actor.org_unit_type t ON (u.ou_type = t.id) LOOP
14         RETURN QUERY
15         WITH available_statuses AS (SELECT ARRAY_AGG(id) AS ids FROM config.copy_status WHERE is_available),
16             cp AS(
17                 SELECT  cp.id,
18                         (cp.status = ANY (available_statuses.ids))::INT as available,
19                         (cl.opac_visible AND cp.opac_visible)::INT as opac_visible
20                   FROM
21                         available_statuses,
22                         actor.org_unit_descendants(ans.id) d
23                         JOIN asset.copy cp ON (cp.circ_lib = d.id AND NOT cp.deleted)
24                         JOIN asset.copy_location cl ON (cp.location = cl.id AND NOT cl.deleted)
25                         JOIN asset.call_number cn ON (cn.record = rid AND cn.id = cp.call_number AND NOT cn.deleted)
26             ),
27             peer AS (
28                 SELECT  cp.id,
29                         (cp.status = ANY  (available_statuses.ids))::INT as available,
30                         (cl.opac_visible AND cp.opac_visible)::INT as opac_visible
31                 FROM
32                         available_statuses,
33                         actor.org_unit_descendants(ans.id) d
34                         JOIN asset.copy cp ON (cp.circ_lib = d.id AND NOT cp.deleted)
35                         JOIN asset.copy_location cl ON (cp.location = cl.id AND NOT cl.deleted)
36                         JOIN biblio.peer_bib_copy_map bp ON (bp.peer_record = rid AND bp.target_copy = cp.id)
37             )
38         SELECT ans.depth, ans.id, count(id), sum(x.available::int), sum(x.opac_visible::int), trans
39         FROM ((select * from cp) union (select * from peer)) x
40         GROUP BY 1,2,6;
41
42         IF NOT FOUND THEN
43             RETURN QUERY SELECT ans.depth, ans.id, 0::BIGINT, 0::BIGINT, 0::BIGINT, trans;
44         END IF;
45
46     END LOOP;
47     RETURN;
48 END;
49 $function$;
50
51 CREATE OR REPLACE FUNCTION asset.opac_ou_record_copy_count(org integer, rid bigint)
52  RETURNS TABLE(depth integer, org_unit integer, visible bigint, available bigint, unshadow bigint, transcendant integer)
53  LANGUAGE plpgsql
54 AS $function$
55 DECLARE
56     ans RECORD;
57     trans INT;
58 BEGIN
59     SELECT 1 INTO trans FROM biblio.record_entry b JOIN config.bib_source src ON (b.source = src.id) WHERE src.transcendant AND b.id = rid;
60
61     FOR ans IN SELECT u.id, t.depth FROM actor.org_unit_ancestors(org) AS u JOIN actor.org_unit_type t ON (u.ou_type = t.id) LOOP
62         RETURN QUERY
63         WITH org_list AS (SELECT ARRAY_AGG(id)::BIGINT[] AS orgs FROM actor.org_unit_descendants(ans.id) x),
64              available_statuses AS (SELECT ARRAY_AGG(id) AS ids FROM config.copy_status WHERE is_available),
65              mask AS (SELECT c_attrs FROM asset.patron_default_visibility_mask() x)
66         SELECT  ans.depth,
67                 ans.id,
68                 COUNT( av.id ),
69                 SUM( (cp.status = ANY (available_statuses.ids))::INT ),
70                 COUNT( av.id ),
71                 trans
72           FROM  mask,
73                 available_statuses,
74                 org_list,
75                 asset.copy_vis_attr_cache av
76                 JOIN asset.copy cp ON (cp.id = av.target_copy AND av.record = rid)
77                 JOIN asset.call_number cn ON (cp.call_number = cn.id AND not cn.deleted)
78           WHERE cp.circ_lib = ANY (org_list.orgs) AND av.vis_attr_vector @@ mask.c_attrs::query_int
79           GROUP BY 1,2,6;
80
81         IF NOT FOUND THEN
82             RETURN QUERY SELECT ans.depth, ans.id, 0::BIGINT, 0::BIGINT, 0::BIGINT, trans;
83         END IF;
84
85     END LOOP;
86
87     RETURN;
88 END;
89 $function$;
90