From: miker Date: Fri, 20 Mar 2009 14:28:14 +0000 (+0000) Subject: teach the penalty code how to create events for system penalties returned from actor... X-Git-Tag: sprint4-merge-nov22~10444 X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=622604fa0d5c1795d16784503194ac3b12ab8499;p=working%2FEvergreen.git teach the penalty code how to create events for system penalties returned from actor.calculate_system_penalties git-svn-id: svn://svn.open-ils.org/ILS/trunk@12625 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- diff --git a/Open-ILS/src/perlmods/OpenILS/Utils/Penalty.pm b/Open-ILS/src/perlmods/OpenILS/Utils/Penalty.pm index 4b42c4ebf0..bb5f6f0822 100644 --- a/Open-ILS/src/perlmods/OpenILS/Utils/Penalty.pm +++ b/Open-ILS/src/perlmods/OpenILS/Utils/Penalty.pm @@ -25,6 +25,10 @@ sub calculate_penalties { my $penalties = $e->json_query({from => ['actor.calculate_system_penalties',$user_id, $context_org]}); + my $user = $e->retrieve_actor_user( $user_id ); + my $ses = OpenSRF::AppSession->create('open-ils.trigger') if (@$penalties); + + my %csp; for my $pen_obj (@$penalties) { next if grep { # leave duplicate penalties in place @@ -40,6 +44,19 @@ sub calculate_penalties { } else { $e->create_actor_user_standing_penalty($pen) or return $e->die_event; + + my $csp_obj = $csp{$pen->{standing_penalty}} || + $e->retrieve_config_standing_penalty( $pen->{standing_penalty} ); + + # cache for later + $csp{$pen->{standing_penalty}} = $csp_obj; + + $ses->request( + 'open-ils.trigger.event.autocreate', + 'penalty.' . $csp_obj->name, + $user, + $pen->{org_unit} + ); } } diff --git a/Open-ILS/src/sql/Pg/002.schema.config.sql b/Open-ILS/src/sql/Pg/002.schema.config.sql index 3c088ee2b1..91221d856a 100644 --- a/Open-ILS/src/sql/Pg/002.schema.config.sql +++ b/Open-ILS/src/sql/Pg/002.schema.config.sql @@ -123,6 +123,8 @@ INSERT INTO config.standing_penalty (id,name,label,block_list) VALUES (2,'PATRON_EXCEEDS_OVERDUE_COUNT','Patron exceeds max overdue item threshold','CIRC|HOLD|RENEW'); INSERT INTO config.standing_penalty (id,name,label,block_list) VALUES (3,'PATRON_EXCEEDS_CHECKOUT_COUNT','Patron exceeds max checked out item threshold','CIRC'); +INSERT INTO config.standing_penalty (id,name,label,block_list) + VALUES (4,'PATRON_EXCEEDS_COLLECTIONS_WARNING','Patron exceeds pre-collections warning fine threshold','CIRC|HOLD|RENEW'); SELECT SETVAL('config.standing_penalty_id_seq', 100); CREATE TABLE config.xml_transform ( diff --git a/Open-ILS/src/sql/Pg/100.circ_matrix.sql b/Open-ILS/src/sql/Pg/100.circ_matrix.sql index 5d354b0ff6..20ff081524 100644 --- a/Open-ILS/src/sql/Pg/100.circ_matrix.sql +++ b/Open-ILS/src/sql/Pg/100.circ_matrix.sql @@ -362,13 +362,14 @@ $func$ LANGUAGE SQL; CREATE OR REPLACE FUNCTION actor.calculate_system_penalties( match_user INT, context_org INT ) RETURNS SETOF actor.usr_standing_penalty AS $func$ DECLARE user_object actor.usr%ROWTYPE; - new_sp_row actor.usr_standing_penalty%ROWTYPE; - existing_sp_row actor.usr_standing_penalty%ROWTYPE; + new_sp_row actor.usr_standing_penalty%ROWTYPE; + existing_sp_row actor.usr_standing_penalty%ROWTYPE; + collections_fines permission.grp_penalty_threshold%ROWTYPE; max_fines permission.grp_penalty_threshold%ROWTYPE; max_overdue permission.grp_penalty_threshold%ROWTYPE; max_items_out permission.grp_penalty_threshold%ROWTYPE; - tmp_grp INT; - items_overdue INT; + tmp_grp INT; + items_overdue INT; items_out INT; context_org_list INT[]; current_fines NUMERIC(8,2) := 0.0; @@ -419,31 +420,20 @@ BEGIN RETURN NEXT existing_sp_row; END LOOP; - FOR tmp_groc IN - SELECT * - FROM money.grocery g - JOIN actor.org_unit_full_path( max_fines.org_unit ) fp ON (g.billing_location = fp.id) - WHERE usr = match_user - AND xact_finish IS NULL - LOOP - SELECT INTO tmp_fines SUM( amount ) FROM money.billing WHERE xact = tmp_groc.id AND NOT voided; - current_fines = current_fines + COALESCE(tmp_fines, 0.0); - SELECT INTO tmp_fines SUM( amount ) FROM money.payment WHERE xact = tmp_groc.id AND NOT voided; - current_fines = current_fines - COALESCE(tmp_fines, 0.0); - END LOOP; - - FOR tmp_circ IN - SELECT * - FROM action.circulation circ - JOIN actor.org_unit_full_path( max_fines.org_unit ) fp ON (circ.circ_lib = fp.id) - WHERE usr = match_user - AND xact_finish IS NULL - LOOP - SELECT INTO tmp_fines SUM( amount ) FROM money.billing WHERE xact = tmp_circ.id AND NOT voided; - current_fines = current_fines + COALESCE(tmp_fines, 0.0); - SELECT INTO tmp_fines SUM( amount ) FROM money.payment WHERE xact = tmp_circ.id AND NOT voided; - current_fines = current_fines - COALESCE(tmp_fines, 0.0); - END LOOP; + SELECT SUM(f.balance_owed) INTO current_fines + FROM money.materialized_billable_xact_summary f + JOIN ( + SELECT g.id + FROM money.grocery g + JOIN actor.org_unit_full_path( max_fines.org_unit ) fp ON (g.billing_location = fp.id) + WHERE usr = match_user + AND xact_finish IS NULL + UNION ALL + SELECT circ.id + FROM action.circulation circ + JOIN actor.org_unit_full_path( max_fines.org_unit ) fp ON (circ.circ_lib = fp.id) + WHERE usr = match_user + AND xact_finish IS NULL ) l USING (id); IF current_fines >= max_fines.threshold THEN new_sp_row.usr := match_user; @@ -567,6 +557,70 @@ BEGIN END IF; END IF; + -- Start over for collections warning + SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org; + + -- Fail if the user has a collections-level fine balance + LOOP + tmp_grp := user_object.profile; + LOOP + SELECT * INTO max_fines FROM permission.grp_penalty_threshold WHERE grp = tmp_grp AND penalty = 4 AND org_unit = tmp_org.id; + + IF max_fines.threshold IS NULL THEN + SELECT parent INTO tmp_grp FROM permission.grp_tree WHERE id = tmp_grp; + ELSE + EXIT; + END IF; + + IF tmp_grp IS NULL THEN + EXIT; + END IF; + END LOOP; + + IF max_fines.threshold IS NOT NULL OR tmp_org.parent_ou IS NULL THEN + EXIT; + END IF; + + SELECT * INTO tmp_org FROM actor.org_unit WHERE id = tmp_org.parent_ou; + + END LOOP; + + IF max_fines.threshold IS NOT NULL THEN + + FOR existing_sp_row IN + SELECT * + FROM actor.usr_standing_penalty + WHERE usr = match_user + AND org_unit = max_fines.org_unit + AND standing_penalty = 1 + LOOP + RETURN NEXT existing_sp_row; + END LOOP; + + SELECT SUM(f.balance_owed) INTO current_fines + FROM money.materialized_billable_xact_summary f + JOIN ( + SELECT g.id + FROM money.grocery g + JOIN actor.org_unit_full_path( max_fines.org_unit ) fp ON (g.billing_location = fp.id) + WHERE usr = match_user + AND xact_finish IS NULL + UNION ALL + SELECT circ.id + FROM action.circulation circ + JOIN actor.org_unit_full_path( max_fines.org_unit ) fp ON (circ.circ_lib = fp.id) + WHERE usr = match_user + AND xact_finish IS NULL ) l USING (id); + + IF current_fines >= max_fines.threshold THEN + new_sp_row.usr := match_user; + new_sp_row.org_unit := max_fines.org_unit; + new_sp_row.standing_penalty := 1; + RETURN NEXT new_sp_row; + END IF; + END IF; + + RETURN; END; $func$ LANGUAGE plpgsql;