"active":"t",
"deleted":"f"
}
+ "patron_has_bills" : {
+ "context_org" : "billing_ou"
}
}
<link field="usr" reltype="has_a" key="id" map="" class="au"/>
</links>
</class>
+ <class id="muspou" controller="open-ils.cstore" oils_obj:fieldmapper="money::user_summary_per_org_unit" oils_persist:tablename="money.usr_summary_per_org_unit" reporter:label="User Summary Per Org Unit">
+ <fields oils_persist:primary="usr" oils_persist:sequence="">
+ <field name="balance_owed" reporter:datatype="money" />
+ <field name="total_owed" reporter:datatype="money" />
+ <field name="total_paid" reporter:datatype="money" />
+ <field name="usr" reporter:datatype="link"/>
+ <field name="billing_ou" reporter:datatype="link"/>
+ <field name="last_payment_ts" reporter:datatype="timestamp"/>
+ </fields>
+ <links>
+ <link field="usr" reltype="has_a" key="id" map="" class="au"/>
+ <link field="billing_ou" reltype="has_a" key="id" map="" class="aou"/>
+ </links>
+ </class>
<class id="clfm" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="config::lit_form_map" oils_persist:tablename="config.lit_form_map" reporter:label="Literary Form" oils_persist:field_safe="true">
<fields oils_persist:primary="code" oils_persist:sequence="">
<field reporter:label="LitF Code" name="code" reporter:datatype="text"/>
return @$existing ? 0 : 1;
}
+# core type "muspou"
+sub PatronExceedsBills {
+ my ($self, $env) = @_;
+ my $user = $env->{target}->usr;
+ my $org = $env->{target}->billing_ou;
+ my $balance_owed = $env->{target}->balance_owed;
+
+ # beware environment fleshing
+ $user = $user->id if ref $user;
+ $org = $org->id if ref $org;
+
+ my $e = new_editor();
+ my $threshold = $U->ou_ancestor_setting_value($org, 'patron.notify_bills_when_exceeds', $e );
+ $threshold = 0 unless $threshold;
+
+ return $balance_owed > $threshold;
+}
+
1;
'coust', 'description'),
'bool', null)
+,( 'patron.notify_bills_when_exceeds', 'finance',
+ oils_i18n_gettext('patron.notify_bills_when_exceeds',
+ 'Notify Patron bill when exceeds',
+ 'coust', 'label'),
+ oils_i18n_gettext('patron.notify_bills_when_exceeds',
+ 'Notify the patron when their balance owed exceeds this setting. Default is 0. Action trigger validator "PatronExceedsBills" required',
+ 'coust', 'description'),
+ 'currency', null)
+
,( 'print.custom_js_file', 'circ',
oils_i18n_gettext('print.custom_js_file',
'Printing: Custom Javascript File',
--- /dev/null
+BEGIN;
+
+SELECT plan(4);
+
+
+-- *******************************************
+-- Create hook
+INSERT INTO action_trigger.hook (key,core_type,description,passive)
+SELECT 'patron_has_bills','muspou','Patron has bills. Usually used in conjunction with reactor SendEmail and library setting "Notify Patron bill when exceeds".','t'
+WHERE NOT EXISTS (
+ SELECT key
+ FROM action_trigger.hook
+ WHERE key = 'patron_has_bills'
+ );
+
+-- Create validator
+INSERT INTO action_trigger.validator (module,description)
+SELECT 'PatronExceedsBills','Event is valid if the library setting "Notify Patron bill when exceeds" setting threshold is exceeded'
+WHERE NOT EXISTS (
+ SELECT module
+ FROM action_trigger.validator
+ WHERE module = 'PatronExceedsBills'
+ );
+
+-- Create library setting
+INSERT into config.org_unit_setting_type (name, grp, datatype, label, description)
+SELECT
+ 'patron.notify_bills_when_exceeds',
+ 'finance', 'currency',
+ oils_i18n_gettext(
+ 'patron.notify_bills_when_exceeds',
+ 'Notify Patron bill when exceeds',
+ 'coust',
+ 'label'
+ ),
+ oils_i18n_gettext(
+ 'patron.notify_bills_when_exceeds',
+ 'Notify the patron when their balance owed exceeds this setting. Default is 0. Action trigger validator "PatronExceedsBills" required',
+ 'coust',
+ 'description'
+ )
+WHERE NOT EXISTS (
+ SELECT name
+ FROM config.org_unit_setting_type
+ WHERE name = 'patron.notify_bills_when_exceeds'
+ );
+
+
+
+-- Create view
+CREATE OR REPLACE VIEW money.usr_summary_per_org_unit AS
+ SELECT materialized_billable_xact_summary.usr,
+ money.grocery.billing_location AS billing_ou,
+ sum(materialized_billable_xact_summary.total_paid) AS total_paid,
+ sum(materialized_billable_xact_summary.total_owed) AS total_owed,
+ sum(materialized_billable_xact_summary.balance_owed) AS balance_owed,
+ -- This needs to be non-null for patron bill notification
+ COALESCE(MAX(materialized_billable_xact_summary.last_payment_ts),'0001-01-01'::TIMESTAMP) AS last_payment_ts
+ FROM money.materialized_billable_xact_summary, money.grocery
+ WHERE money.grocery.id = money.materialized_billable_xact_summary.id
+ GROUP BY materialized_billable_xact_summary.usr, money.grocery.billing_location;
+
+ALTER TABLE money.usr_summary_per_org_unit
+ OWNER TO evergreen;
+
+
+
+
+-- *******************************************
+
+
+-- Test it
+-- *******************************************
+
+
+-- Test to make sure that the hook exists
+
+
+SELECT isnt_empty(
+ 'SELECT * FROM action_trigger.hook WHERE key = $$patron_has_bills$$',
+ 'action_trigger.hook patron_has_bills exists' );
+
+SELECT isnt_empty(
+ 'SELECT * FROM action_trigger.validator WHERE module = $$PatronExceedsBills$$',
+ 'action_trigger.validator PatronExceedsBills exists' );
+
+SELECT isnt_empty(
+ 'SELECT * FROM config.org_unit_setting_type WHERE name = $$patron.notify_bills_when_exceeds$$',
+ 'Library setting patron.notify_bills_when_exceeds exists' );
+
+SELECT isnt_empty(
+ 'SELECT total_owed,balance_owed,total_paid,billing_ou,usr,last_payment_ts FROM money.usr_summary_per_org_unit limit 100',
+ 'View money.usr_summary_per_org_unit exists' );
+
+
+
+-- Finish the tests and clean up.
+SELECT * FROM finish();
+ROLLBACK;
+
--- /dev/null
+BEGIN;
+
+-- Create a new hook
+INSERT INTO action_trigger.hook (key,core_type,description,passive)
+VALUES('patron_has_bills','muspou','Patron has bills. Usually used in conjunction with reactor SendEmail and library setting "Notify Patron bill when exceeds".','t');
+
+-- Create a new validator
+INSERT INTO action_trigger.validator (module,description) VALUES('PatronExceedsBills','Event is valid if the library setting "Notify Patron bill when exceeds" setting threshold is exceeded');
+
+-- Create the library setting
+INSERT into config.org_unit_setting_type (name, grp, datatype, label, description) VALUES (
+ 'patron.notify_bills_when_exceeds',
+ 'finance', 'currency',
+ oils_i18n_gettext(
+ 'patron.notify_bills_when_exceeds',
+ 'Notify Patron bill when exceeds',
+ 'coust',
+ 'label'
+ ),
+ oils_i18n_gettext(
+ 'patron.notify_bills_when_exceeds',
+ 'Notify the patron when their balance owed exceeds this setting. Default is 0. Action trigger
+validator "PatronExceedsBills" required',
+ 'coust',
+ 'description'
+ )
+);
+
+-- Create the view
+CREATE OR REPLACE VIEW money.usr_summary_per_org_unit AS
+ SELECT materialized_billable_xact_summary.usr,
+ money.grocery.billing_location AS billing_ou,
+ sum(materialized_billable_xact_summary.total_paid) AS total_paid,
+ sum(materialized_billable_xact_summary.total_owed) AS total_owed,
+ sum(materialized_billable_xact_summary.balance_owed) AS balance_owed,
+ -- This needs to be non-null for patron bill notification
+ COALESCE(MAX(materialized_billable_xact_summary.last_payment_ts),'0001-01-01'::TIMESTAMP) AS last_payment_ts
+ FROM money.materialized_billable_xact_summary, money.grocery
+ WHERE money.grocery.id = money.materialized_billable_xact_summary.id
+ GROUP BY materialized_billable_xact_summary.usr, money.grocery.billing_location;
+
+ALTER TABLE
+money.usr_summary_per_org_unit
+ OWNER TO evergreen;
+
+
+-- Create the action trigger event definition
+INSERT INTO action_trigger.event_definition (active, owner, name, hook, validator, reactor, delay_field, repeat_delay, template)
+ VALUES ('f', '1', 'Patron recurring 30 billing notice', 'patron_has_bills', 'PatronExceedsBills', 'SendEmail', 'last_payment_ts', '30 days',
+ $$
+[%- USE date -%]
+[%- user = target.usr -%]
+To: [%- params.recipient_email || user.email %]
+From: [%- user.home_ou.name %] <[% helpers.get_org_setting(user.home_ou, 'org.bounced_emails') || lib.email || params.sender_email || default_sender %]>
+Subject: Libarary bills
+
+[%# You can use the library setting "Notify Patron bill when exceeds" to squelch this notification when the balance owed doesnt exceed your configuration %]
+Dear [% user.first_given_name %] [% user.family_name %],
+
+You have an outstanding balance at the library:
+
+[%- target.balance_owed -%]
+
+ $$
+);
+
+-- Add the environment var for usr fleshing
+INSERT INTO action_trigger.environment(event_def,path) VALUES(CURRVAL('action_trigger.event_definition_id_seq'),'usr');
+
+COMMIT;
--- /dev/null
+Patron Periodic Billing Statement Action Trigger
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+You can setup an action trigger that will notify patrons about their oustanding bills.
+A new library setting "patron.notify_bills_when_exceeds" can bet setup to only notify
+patrons who exceed a certain amount. By default, patrons will be notified if they exceed
+0.
+
+ * New Library Setting
+ ** Notify Patron bill when exceeds
+ * New Action Trigger Hook
+ ** patron_has_bills
+ * New Action Trigger Validator
+ ** PatronExceedsBills
+
+