]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/sql/Pg/upgrade/0430.schema.strict_ou_test.sql
LP#1835085: stamp DB update
[Evergreen.git] / Open-ILS / src / sql / Pg / upgrade / 0430.schema.strict_ou_test.sql
1 BEGIN;
2
3 INSERT INTO config.upgrade_log (version) VALUES ('0430'); -- miker
4
5 ALTER TABLE config.hold_matrix_matchpoint ADD COLUMN strict_ou_match BOOL NOT NULL DEFAULT FALSE;
6
7 CREATE OR REPLACE FUNCTION action.find_hold_matrix_matchpoint( pickup_ou INT, request_ou INT, match_item BIGINT, match_user INT, match_requestor INT ) RETURNS INT AS $func$
8 DECLARE
9     current_requestor_group    permission.grp_tree%ROWTYPE;
10     requestor_object    actor.usr%ROWTYPE;
11     user_object        actor.usr%ROWTYPE;
12     item_object        asset.copy%ROWTYPE;
13     item_cn_object        asset.call_number%ROWTYPE;
14     rec_descriptor        metabib.rec_descriptor%ROWTYPE;
15     current_mp_weight    FLOAT;
16     matchpoint_weight    FLOAT;
17     tmp_weight        FLOAT;
18     current_mp        config.hold_matrix_matchpoint%ROWTYPE;
19     matchpoint        config.hold_matrix_matchpoint%ROWTYPE;
20 BEGIN
21     SELECT INTO user_object * FROM actor.usr WHERE id = match_user;
22     SELECT INTO requestor_object * FROM actor.usr WHERE id = match_requestor;
23     SELECT INTO item_object * FROM asset.copy WHERE id = match_item;
24     SELECT INTO item_cn_object * FROM asset.call_number WHERE id = item_object.call_number;
25     SELECT INTO rec_descriptor r.* FROM metabib.rec_descriptor r WHERE r.record = item_cn_object.record;
26
27     PERFORM * FROM config.internal_flag WHERE name = 'circ.holds.usr_not_requestor' AND enabled;
28
29     IF NOT FOUND THEN
30         SELECT INTO current_requestor_group * FROM permission.grp_tree WHERE id = requestor_object.profile;
31     ELSE
32         SELECT INTO current_requestor_group * FROM permission.grp_tree WHERE id = user_object.profile;
33     END IF;
34
35     LOOP 
36         -- for each potential matchpoint for this ou and group ...
37         FOR current_mp IN
38             SELECT    m.*
39               FROM    config.hold_matrix_matchpoint m
40               WHERE    m.requestor_grp = current_requestor_group.id AND m.active
41               ORDER BY    CASE WHEN m.circ_modifier    IS NOT NULL THEN 16 ELSE 0 END +
42                     CASE WHEN m.juvenile_flag    IS NOT NULL THEN 16 ELSE 0 END +
43                     CASE WHEN m.marc_type        IS NOT NULL THEN 8 ELSE 0 END +
44                     CASE WHEN m.marc_form        IS NOT NULL THEN 4 ELSE 0 END +
45                     CASE WHEN m.marc_vr_format    IS NOT NULL THEN 2 ELSE 0 END +
46                     CASE WHEN m.ref_flag        IS NOT NULL THEN 1 ELSE 0 END DESC LOOP
47
48             current_mp_weight := 5.0;
49
50             IF current_mp.circ_modifier IS NOT NULL THEN
51                 CONTINUE WHEN current_mp.circ_modifier <> item_object.circ_modifier OR item_object.circ_modifier IS NULL;
52             END IF;
53
54             IF current_mp.marc_type IS NOT NULL THEN
55                 IF item_object.circ_as_type IS NOT NULL THEN
56                     CONTINUE WHEN current_mp.marc_type <> item_object.circ_as_type;
57                 ELSE
58                     CONTINUE WHEN current_mp.marc_type <> rec_descriptor.item_type;
59                 END IF;
60             END IF;
61
62             IF current_mp.marc_form IS NOT NULL THEN
63                 CONTINUE WHEN current_mp.marc_form <> rec_descriptor.item_form;
64             END IF;
65
66             IF current_mp.marc_vr_format IS NOT NULL THEN
67                 CONTINUE WHEN current_mp.marc_vr_format <> rec_descriptor.vr_format;
68             END IF;
69
70             IF current_mp.juvenile_flag IS NOT NULL THEN
71                 CONTINUE WHEN current_mp.juvenile_flag <> user_object.juvenile;
72             END IF;
73
74             IF current_mp.ref_flag IS NOT NULL THEN
75                 CONTINUE WHEN current_mp.ref_flag <> item_object.ref;
76             END IF;
77
78
79             -- caclulate the rule match weight
80             IF current_mp.item_owning_ou IS NOT NULL THEN
81                 IF NOT current_mp.strict_ou_match THEN
82                     SELECT INTO tmp_weight 1.0 / (actor.org_unit_proximity(current_mp.item_owning_ou, item_cn_object.owning_lib)::FLOAT + 1.0)::FLOAT;
83                 ELSE
84                     tmp_weight := CASE WHEN current_mp.item_owning_ou = item_cn_object.owning_lib THEN 1.0 ELSE 0.0 END;
85                 END IF;
86                 current_mp_weight := current_mp_weight - tmp_weight;
87             END IF; 
88
89             IF current_mp.item_circ_ou IS NOT NULL THEN
90                 IF NOT current_mp.strict_ou_match THEN
91                     SELECT INTO tmp_weight 1.0 / (actor.org_unit_proximity(current_mp.item_circ_ou, item_object.circ_lib)::FLOAT + 1.0)::FLOAT;
92                 ELSE
93                     tmp_weight := CASE WHEN current_mp.item_circ_ou = item_object.circ_lib THEN 1.0 ELSE 0.0 END;
94                 END IF;
95                 current_mp_weight := current_mp_weight - tmp_weight;
96             END IF; 
97
98             IF current_mp.pickup_ou IS NOT NULL THEN
99                 IF NOT current_mp.strict_ou_match THEN
100                     SELECT INTO tmp_weight 1.0 / (actor.org_unit_proximity(current_mp.pickup_ou, pickup_ou)::FLOAT + 1.0)::FLOAT;
101                 ELSE
102                     tmp_weight := CASE WHEN current_mp.pickup_ou = pickiup_ou THEN 1.0 ELSE 0.0 END;
103                 END IF;
104                 current_mp_weight := current_mp_weight - tmp_weight;
105             END IF; 
106
107             IF current_mp.request_ou IS NOT NULL THEN
108                 IF NOT current_mp.strict_ou_match THEN
109                     SELECT INTO tmp_weight 1.0 / (actor.org_unit_proximity(current_mp.request_ou, request_ou)::FLOAT + 1.0)::FLOAT;
110                 ELSE
111                     tmp_weight := CASE WHEN current_mp.request_ou = request_ou THEN 1.0 ELSE 0.0 END;
112                 END IF;
113                 current_mp_weight := current_mp_weight - tmp_weight;
114             END IF; 
115
116             IF current_mp.user_home_ou IS NOT NULL THEN
117                 IF NOT current_mp.strict_ou_match THEN
118                     SELECT INTO tmp_weight 1.0 / (actor.org_unit_proximity(current_mp.user_home_ou, user_object.home_ou)::FLOAT + 1.0)::FLOAT;
119                 ELSE
120                     tmp_weight := CASE WHEN current_mp.user_home_ou = user_object.home_ou THEN 1.0 ELSE 0.0 END;
121                 END IF;
122                 current_mp_weight := current_mp_weight - tmp_weight;
123             END IF; 
124
125             -- set the matchpoint if we found the best one
126             IF matchpoint_weight IS NULL OR matchpoint_weight > current_mp_weight THEN
127                 matchpoint = current_mp;
128                 matchpoint_weight = current_mp_weight;
129             END IF;
130
131         END LOOP;
132
133         EXIT WHEN current_requestor_group.parent IS NULL OR matchpoint.id IS NOT NULL;
134
135         SELECT INTO current_requestor_group * FROM permission.grp_tree WHERE id = current_requestor_group.parent;
136     END LOOP;
137
138     RETURN matchpoint.id;
139 END;
140 $func$ LANGUAGE plpgsql;
141
142 COMMIT;
143