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