[open-ils-commits] r15053 - in trunk/Open-ILS: examples src/perlmods/OpenILS/Application src/sql/Pg src/sql/Pg/upgrade (erickson)

svn at svn.open-ils.org svn at svn.open-ils.org
Wed Dec 2 09:35:07 EST 2009


Author: erickson
Date: 2009-12-02 09:35:05 -0500 (Wed, 02 Dec 2009)
New Revision: 15053

Added:
   trunk/Open-ILS/src/sql/Pg/upgrade/0101.schema.circ-chain.sql
Modified:
   trunk/Open-ILS/examples/fm_IDL.xml
   trunk/Open-ILS/src/perlmods/OpenILS/Application/Circ.pm
   trunk/Open-ILS/src/sql/Pg/002.schema.config.sql
   trunk/Open-ILS/src/sql/Pg/090.schema.action.sql
Log:
added stored proc to take a circ and determine the full chain of associated circs and companion proc to summarize the chain.  added fm class accs for action::circ_chain_summary.  add ML method to turn the stored proc output into FM objects.  added unrecoverd field to action.circulation since it was missing

Modified: trunk/Open-ILS/examples/fm_IDL.xml
===================================================================
--- trunk/Open-ILS/examples/fm_IDL.xml	2009-12-02 04:37:32 UTC (rev 15052)
+++ trunk/Open-ILS/examples/fm_IDL.xml	2009-12-02 14:35:05 UTC (rev 15053)
@@ -112,7 +112,23 @@
 		</links>
 	</class>
 
+	<class id="accs" controller="open-ils.cstore" oils_obj:fieldmapper="action::circ_chain_summary" oils_persist:virtual="true" reporter:label="Circulation Chain Summary">
+        <!-- when the time is right, turn me into a view.  -->
+		<fields>
+            <field reporter:label="Total Circs" name="num_circs" datatype="int"/>
+            <field reporter:label="Start Time" name="start_time" datatype="timestamp"/>
+            <field reporter:label="Checkout Workstation" name="checkout_workstation" datatype="text"/>
+            <field reporter:label="Last Renewal Time" name="last_renewal_time" datatype="timestamp"/>
+            <field reporter:label="Last Stop Fines" name="last_stop_fines" datatype="text"/>
+            <field reporter:label="Last Stop Fines Time" name="last_stop_fines_time" datatype="timestamp"/>
+            <field reporter:label="Last Renewal Workstation" name="last_renewal_workstation" datatype="text"/>
+            <field reporter:label="Last Checkin Workstation" name="last_checkin_workstation" datatype="text"/>
+            <field reporter:label="Last Checkin Time" name="last_checkin_time" datatype="timestamp"/>
+            <field reporter:label="Last Checkin Scan Time" name="last_checkin_scan_time" datatype="timestamp"/>
+		</fields>
+	</class>
 
+
 	<!-- Actually in the DB -->
 	<class id="vibtf" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="vandelay::import_bib_trash_fields" oils_persist:tablename="vandelay.import_bib_trash_fields" reporter:label="Import/Overlay Fields for Removal">
 		<fields oils_persist:primary="id" oils_persist:sequence="vandelay.import_bib_trash_fields_id_seq">
@@ -2174,6 +2190,7 @@
 			<field reporter:label="Circulation Type" name="circ_type" oils_persist:virtual="true" reporter:datatype="text"/>
 			<field reporter:label="Billing Totals" name="billing_total" oils_persist:virtual="true" reporter:datatype="money"/>
 			<field reporter:label="Payment Totals" name="payment_total" oils_persist:virtual="true" reporter:datatype="money"/>
+			<field reporter:label="Unrecovered Debt" name="unrecovered" reporter:datatype="bool"/>
 		</fields>
 		<links>
 			<link field="billable_transaction" reltype="might_have" key="id" map="" class="mbt"/>

Modified: trunk/Open-ILS/src/perlmods/OpenILS/Application/Circ.pm
===================================================================
--- trunk/Open-ILS/src/perlmods/OpenILS/Application/Circ.pm	2009-12-02 04:37:32 UTC (rev 15052)
+++ trunk/Open-ILS/src/perlmods/OpenILS/Application/Circ.pm	2009-12-02 14:35:05 UTC (rev 15053)
@@ -1390,44 +1390,45 @@
     }
 );
 
+__PACKAGE__->register_method(
+	method	=> "retrieve_circ_chain",
+	api_name	=> "open-ils.circ.renewal_chain.retrieve_by_circ.summary",
+	signature => {
+        desc => q/Given a circulation, this returns all circulation objects
+                that are part of the same chain of renewals./,
+        params => [
+            {desc => 'Authentication token', type => 'string'},
+            {desc => 'Circ ID', type => 'number'},
+        ],
+        return => {desc => q/List of circ objects, orderd by oldest circ first/}
+    }
+);
+
 sub retrieve_circ_chain {
     my($self, $conn, $auth, $circ_id) = @_;
 
     my $e = new_editor(authtoken => $auth);
     return $e->event unless $e->checkauth;
+	return $e->event unless $e->allowed('VIEW_CIRCULATIONS');
 
-    # grab the base circ and all parent (previous) circs by fleshing
-    my $base_circ = $e->retrieve_action_circulation([
-        $circ_id,
-        {
-            flesh => -1,
-            flesh_fields => {circ => [qw/parent_circ workstation checkin_workstation/]}
-        }
-    ]) or return $e->event;
+    if($self->api_name =~ /summary/) {
+        my $sum = $e->json_query({from => ['action.summarize_circ_chain', $circ_id]})->[0];
+        return undef unless $sum;
+        my $obj = Fieldmapper::action::circ_chain_summary->new;
+        $obj->$_($sum->{$_}) for keys %$sum;
+        return $obj;
 
-    return $e->event unless $e->allowed('VIEW_CIRCULATIONS', $base_circ->circ_lib);
+    } else {
 
-    # send each circ to the caller, starting with the oldest circulation
-    my @chain;
-    my $circ = $base_circ;
-    while($circ) {
-        push(@chain, $circ);
+        my $chain = $e->json_query({from => ['action.circ_chain', $circ_id]});
 
-        # unflesh for consistency
-        my $parent = $circ->parent_circ;
-        $circ->parent_circ($parent->id) if $parent; 
-
-        $circ = $parent;
+        for my $circ_info (@$chain) {
+            my $circ = Fieldmapper::action::circulation->new;
+            $circ->$_($circ_info->{$_}) for keys %$circ_info;
+            $conn->respond($circ);
+        }
     }
-    $conn->respond($_) for reverse(@chain);
 
-    # base circ may not be the end of the chain.  see if there are any subsequent circs
-    $circ = $base_circ;
-    $conn->respond($circ) while ($circ = $e->search_action_circulation([
-        {parent_circ => $circ->id},
-        {flesh => 1, flesh_fields => {circ => [qw/workstation checkin_workstation/]}}
-    ])->[0]);
-
     return undef;
 }
 

Modified: trunk/Open-ILS/src/sql/Pg/002.schema.config.sql
===================================================================
--- trunk/Open-ILS/src/sql/Pg/002.schema.config.sql	2009-12-02 04:37:32 UTC (rev 15052)
+++ trunk/Open-ILS/src/sql/Pg/002.schema.config.sql	2009-12-02 14:35:05 UTC (rev 15053)
@@ -51,7 +51,7 @@
     install_date    TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
 );
 
-INSERT INTO config.upgrade_log (version) VALUES ('0100'); -- Scott McKellar
+INSERT INTO config.upgrade_log (version) VALUES ('0101'); -- berick
 
 CREATE TABLE config.bib_source (
 	id		SERIAL	PRIMARY KEY,

Modified: trunk/Open-ILS/src/sql/Pg/090.schema.action.sql
===================================================================
--- trunk/Open-ILS/src/sql/Pg/090.schema.action.sql	2009-12-02 04:37:32 UTC (rev 15052)
+++ trunk/Open-ILS/src/sql/Pg/090.schema.action.sql	2009-12-02 14:35:05 UTC (rev 15053)
@@ -474,5 +474,101 @@
       WHERE l.count = m.min;
 
 
+-- represents a circ chain summary
+CREATE TYPE action.circ_chain_summary AS (
+    num_circs INTEGER,
+    start_time TIMESTAMP WITH TIME ZONE,
+    checkout_workstation TEXT,
+    last_renewal_time TIMESTAMP WITH TIME ZONE, -- NULL if no renewals
+    last_stop_fines TEXT,
+    last_stop_fines_time TIMESTAMP WITH TIME ZONE,
+    last_renewal_workstation TEXT, -- NULL if no renewals
+    last_checkin_workstation TEXT,
+    last_checkin_time TIMESTAMP WITH TIME ZONE,
+    last_checkin_scan_time TIMESTAMP WITH TIME ZONE
+);
+
+
+CREATE OR REPLACE FUNCTION action.circ_chain ( ctx_circ_id INTEGER ) RETURNS SETOF action.circulation AS $$
+DECLARE
+    tmp_circ action.circulation%ROWTYPE;
+    circ_0 action.circulation%ROWTYPE;
+BEGIN
+
+    SELECT INTO tmp_circ * FROM action.circulation WHERE id = ctx_circ_id;
+
+    IF tmp_circ IS NULL THEN
+        RETURN NEXT tmp_circ;
+    END IF;
+    circ_0 := tmp_circ;
+
+    -- find the front of the chain
+    WHILE TRUE LOOP
+        SELECT INTO tmp_circ * FROM action.circulation WHERE id = tmp_circ.parent_circ;
+        IF tmp_circ IS NULL THEN
+            EXIT;
+        END IF;
+        circ_0 := tmp_circ;
+    END LOOP;
+
+    -- now send the circs to the caller, oldest to newest
+    tmp_circ := circ_0;
+    WHILE TRUE LOOP
+        IF tmp_circ IS NULL THEN
+            EXIT;
+        END IF;
+        RETURN NEXT tmp_circ;
+        SELECT INTO tmp_circ * FROM action.circulation WHERE parent_circ = tmp_circ.id;
+    END LOOP;
+
+END;
+$$ LANGUAGE 'plpgsql';
+
+CREATE OR REPLACE FUNCTION action.summarize_circ_chain ( ctx_circ_id INTEGER ) RETURNS action.circ_chain_summary AS $$
+
+DECLARE
+
+    -- first circ in the chain
+    circ_0 action.circulation%ROWTYPE;
+
+    -- last circ in the chain
+    circ_n action.circulation%ROWTYPE;
+
+    -- circ chain under construction
+    chain action.circ_chain_summary;
+    tmp_circ action.circulation%ROWTYPE;
+
+BEGIN
+    
+    chain.num_circs := 0;
+    FOR tmp_circ IN SELECT * FROM action.circ_chain(ctx_circ_id) LOOP
+
+        IF chain.num_circs = 0 THEN
+            circ_0 := tmp_circ;
+        END IF;
+
+        chain.num_circs := chain.num_circs + 1;
+        circ_n := tmp_circ;
+    END LOOP;
+
+    chain.start_time := circ_0.xact_start;
+    chain.last_stop_fines := circ_n.stop_fines;
+    chain.last_stop_fines_time := circ_n.stop_fines_time;
+    chain.last_checkin_time := circ_n.checkin_time;
+    chain.last_checkin_scan_time := circ_n.checkin_scan_time;
+    SELECT INTO chain.checkout_workstation name FROM actor.workstation WHERE id = circ_0.workstation;
+    SELECT INTO chain.last_checkin_workstation name FROM actor.workstation WHERE id = circ_n.checkin_workstation;
+
+    IF chain.num_circs > 1 THEN
+        chain.last_renewal_time := circ_n.xact_start;
+        SELECT INTO chain.last_renewal_workstation name FROM actor.workstation WHERE id = circ_n.workstation;
+    END IF;
+
+    RETURN chain;
+
+END;
+$$ LANGUAGE 'plpgsql';
+
+
 COMMIT;
 

Added: trunk/Open-ILS/src/sql/Pg/upgrade/0101.schema.circ-chain.sql
===================================================================
--- trunk/Open-ILS/src/sql/Pg/upgrade/0101.schema.circ-chain.sql	                        (rev 0)
+++ trunk/Open-ILS/src/sql/Pg/upgrade/0101.schema.circ-chain.sql	2009-12-02 14:35:05 UTC (rev 15053)
@@ -0,0 +1,103 @@
+BEGIN;
+
+INSERT INTO config.upgrade_log (version) VALUES ('0101');
+
+-- represents a circ chain summary
+CREATE TYPE action.circ_chain_summary AS (
+    num_circs INTEGER,
+    start_time TIMESTAMP WITH TIME ZONE,
+    checkout_workstation TEXT,
+    last_renewal_time TIMESTAMP WITH TIME ZONE, -- NULL if no renewals
+    last_stop_fines TEXT,
+    last_stop_fines_time TIMESTAMP WITH TIME ZONE,
+    last_renewal_workstation TEXT, -- NULL if no renewals
+    last_checkin_workstation TEXT,
+    last_checkin_time TIMESTAMP WITH TIME ZONE,
+    last_checkin_scan_time TIMESTAMP WITH TIME ZONE
+);
+
+
+CREATE OR REPLACE FUNCTION action.circ_chain ( ctx_circ_id INTEGER ) RETURNS SETOF action.circulation AS $$
+DECLARE
+    tmp_circ action.circulation%ROWTYPE;
+    circ_0 action.circulation%ROWTYPE;
+BEGIN
+
+    SELECT INTO tmp_circ * FROM action.circulation WHERE id = ctx_circ_id;
+
+    IF tmp_circ IS NULL THEN
+        RETURN NEXT tmp_circ;
+    END IF;
+    circ_0 := tmp_circ;
+
+    -- find the front of the chain
+    WHILE TRUE LOOP
+        SELECT INTO tmp_circ * FROM action.circulation WHERE id = tmp_circ.parent_circ;
+        IF tmp_circ IS NULL THEN
+            EXIT;
+        END IF;
+        circ_0 := tmp_circ;
+    END LOOP;
+
+    -- now send the circs to the caller, oldest to newest
+    tmp_circ := circ_0;
+    WHILE TRUE LOOP
+        IF tmp_circ IS NULL THEN
+            EXIT;
+        END IF;
+        RETURN NEXT tmp_circ;
+        SELECT INTO tmp_circ * FROM action.circulation WHERE parent_circ = tmp_circ.id;
+    END LOOP;
+
+END;
+$$ LANGUAGE 'plpgsql';
+
+CREATE OR REPLACE FUNCTION action.summarize_circ_chain ( ctx_circ_id INTEGER ) RETURNS action.circ_chain_summary AS $$
+
+DECLARE
+
+    -- first circ in the chain
+    circ_0 action.circulation%ROWTYPE;
+
+    -- last circ in the chain
+    circ_n action.circulation%ROWTYPE;
+
+    -- circ chain under construction
+    chain action.circ_chain_summary;
+    tmp_circ action.circulation%ROWTYPE;
+
+BEGIN
+    
+    chain.num_circs := 0;
+    FOR tmp_circ IN SELECT * FROM action.circ_chain(ctx_circ_id) LOOP
+
+        IF chain.num_circs = 0 THEN
+            circ_0 := tmp_circ;
+        END IF;
+
+        chain.num_circs := chain.num_circs + 1;
+        circ_n := tmp_circ;
+    END LOOP;
+
+    chain.start_time := circ_0.xact_start;
+    chain.last_stop_fines := circ_n.stop_fines;
+    chain.last_stop_fines_time := circ_n.stop_fines_time;
+    chain.last_checkin_time := circ_n.checkin_time;
+    chain.last_checkin_scan_time := circ_n.checkin_scan_time;
+    SELECT INTO chain.checkout_workstation name FROM actor.workstation WHERE id = circ_0.workstation;
+    SELECT INTO chain.last_checkin_workstation name FROM actor.workstation WHERE id = circ_n.checkin_workstation;
+
+    IF chain.num_circs > 1 THEN
+        chain.last_renewal_time := circ_n.xact_start;
+        SELECT INTO chain.last_renewal_workstation name FROM actor.workstation WHERE id = circ_n.workstation;
+    END IF;
+
+    RETURN chain;
+
+END;
+$$ LANGUAGE 'plpgsql';
+
+
+COMMIT;
+
+



More information about the open-ils-commits mailing list