4 INSERT INTO config.upgrade_log (version) VALUES ('0059'); -- miker
6 CREATE OR REPLACE FUNCTION action.item_user_circ_test( circ_ou INT, match_item BIGINT, match_user INT, renewal BOOL ) RETURNS SETOF action.matrix_test_result AS $func$
8 user_object actor.usr%ROWTYPE;
9 standing_penalty config.standing_penalty%ROWTYPE;
10 item_object asset.copy%ROWTYPE;
11 item_status_object config.copy_status%ROWTYPE;
12 item_location_object asset.copy_location%ROWTYPE;
13 result action.matrix_test_result;
14 circ_test config.circ_matrix_matchpoint%ROWTYPE;
15 out_by_circ_mod config.circ_matrix_circ_mod_test%ROWTYPE;
16 circ_mod_map config.circ_matrix_circ_mod_test_map%ROWTYPE;
20 context_org_list INT[];
23 result.success := TRUE;
25 -- Fail if the user is BARRED
26 SELECT INTO user_object * FROM actor.usr WHERE id = match_user;
28 -- Fail if we couldn't find a set of tests
29 IF user_object.id IS NULL THEN
30 result.fail_part := 'no_user';
31 result.success := FALSE;
37 IF user_object.barred IS TRUE THEN
38 result.fail_part := 'actor.usr.barred';
39 result.success := FALSE;
44 -- Fail if the item can't circulate
45 SELECT INTO item_object * FROM asset.copy WHERE id = match_item;
46 IF item_object.circulate IS FALSE THEN
47 result.fail_part := 'asset.copy.circulate';
48 result.success := FALSE;
53 -- Fail if the item isn't in a circulateable status on a non-renewal
54 IF NOT renewal AND item_object.status NOT IN ( 0, 7, 8 ) THEN
55 result.fail_part := 'asset.copy.status';
56 result.success := FALSE;
59 ELSIF renewal AND item_object.status <> 1 THEN
60 result.fail_part := 'asset.copy.status';
61 result.success := FALSE;
66 -- Fail if the item can't circulate because of the shelving location
67 SELECT INTO item_location_object * FROM asset.copy_location WHERE id = item_object.location;
68 IF item_location_object.circulate IS FALSE THEN
69 result.fail_part := 'asset.copy_location.circulate';
70 result.success := FALSE;
75 SELECT INTO circ_test * FROM action.find_circ_matrix_matchpoint(circ_ou, match_item, match_user, renewal);
76 result.matchpoint := circ_test.id;
78 SELECT INTO context_org_list ARRAY_ACCUM(id) FROM actor.org_unit_full_path( circ_test.org_unit );
80 -- Fail if we couldn't find a set of tests
81 IF result.matchpoint IS NULL THEN
82 result.fail_part := 'no_matchpoint';
83 result.success := FALSE;
88 -- Fail if the test is set to hard non-circulating
89 IF circ_test.circulate IS FALSE THEN
90 result.fail_part := 'config.circ_matrix_test.circulate';
91 result.success := FALSE;
97 penalty_type = '%RENEW%';
99 penalty_type = '%CIRC%';
102 FOR standing_penalty IN
103 SELECT DISTINCT csp.*
104 FROM actor.usr_standing_penalty usp
105 JOIN config.standing_penalty csp ON (csp.id = usp.standing_penalty)
106 WHERE usr = match_user
107 AND usp.org_unit IN ( SELECT * FROM explode_array(context_org_list) )
108 AND (usp.stop_date IS NULL or usp.stop_date > NOW())
109 AND csp.block_list LIKE penalty_type LOOP
111 result.fail_part := standing_penalty.name;
112 result.success := FALSE;
117 -- Fail if the user has too many items with specific circ_modifiers checked out
118 FOR out_by_circ_mod IN SELECT * FROM config.circ_matrix_circ_mod_test WHERE matchpoint = circ_test.id LOOP
119 SELECT INTO items_out COUNT(*)
120 FROM action.circulation circ
121 JOIN asset.copy cp ON (cp.id = circ.target_copy)
122 WHERE circ.usr = match_user
123 AND circ.circ_lib IN ( SELECT * FROM explode_array(context_org_list) )
124 AND circ.checkin_time IS NULL
125 AND (circ.stop_fines IN ('MAXFINES','LONGOVERDUE') OR circ.stop_fines IS NULL)
126 AND cp.circ_modifier IN (SELECT circ_mod FROM config.circ_matrix_circ_mod_test_map WHERE circ_mod_test = out_by_circ_mod.id);
127 IF items_out >= out_by_circ_mod.items_out THEN
128 result.fail_part := 'config.circ_matrix_circ_mod_test';
129 result.success := FALSE;
135 -- If we passed everything, return the successful matchpoint id
142 $func$ LANGUAGE plpgsql;