LP#1312699 - Add feature to allow user to edit their checkout history. user/stompro/lp1312699_history_edit_signoff
authorDan Pearl <dpearl@cwmars.org>
Tue, 20 Oct 2015 21:05:07 +0000 (17:05 -0400)
committerJosh Stompro <stomproj@larl.org>
Wed, 16 Dec 2015 14:33:26 +0000 (08:33 -0600)
In the checkout history page, a new column and action selector is provided to allow
the paton to indicate items they would just as soon not want to see again in the
history list for whatever reason.  NOTE: This is not a PURGE function; it simply
suppresses display of items in the history list (and exported history files).
Internally, the circulations are kept by Evergreen for several reasons which are
not affected by this functionality.

Signed-off-by: Dan Pearl <dpearl@cwmars.org>
Signed-off-by: Josh Stompro <stomproj@larl.org>
Open-ILS/examples/fm_IDL.xml
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Account.pm
Open-ILS/src/sql/Pg/090.schema.action.sql
Open-ILS/src/sql/Pg/upgrade/XXXX.editable_usr_circ_history.sql [new file with mode: 0644]
Open-ILS/src/templates/opac/myopac/circ_history.tt2
docs/RELEASE_NOTES_NEXT/OPAC/edit_circ_history [new file with mode: 0644]

index 8cff802..094911d 100644 (file)
@@ -4082,6 +4082,7 @@ SELECT  usr,
                        <field reporter:label="Shelving Location" name="copy_location" reporter:datatype="link"/>
                        <field reporter:label="Archived Patron Stat-Cat Entries" name="aaactsc_entries" oils_persist:virtual="true" reporter:datatype="link"/>
                        <field reporter:label="Archived Copy Stat-Cat Entries" name="aaasc_entries" oils_persist:virtual="true" reporter:datatype="link"/>
+                       <field reporter:label="Hide from User History" name="hide_from_usr_history" reporter:datatype="bool"/>
                </fields>
                <links>
                        <link field="billable_transaction" reltype="might_have" key="id" map="" class="mbt"/>
index 30e0756..154028b 100644 (file)
@@ -1522,6 +1522,10 @@ sub load_myopac_circ_history {
     my $ctx = $self->ctx;
     my $limit = $self->cgi->param('limit') || 15;
     my $offset = $self->cgi->param('offset') || 0;
+    my $action = $self->cgi->param('action') || '';
+
+    my $circ_handle_result;
+    $circ_handle_result = $self->handle_circ_update($action) if $action;
 
     $ctx->{circ_history_limit} = $limit;
     $ctx->{circ_history_offset} = $offset;
@@ -1557,7 +1561,35 @@ sub load_myopac_circ_history {
     }
 
     $ctx->{circs} = $self->fetch_user_circs(1, [map { $_->{id} } @$circ_ids]);
-    return Apache2::Const::OK;
+    return defined($circ_handle_result) ? $circ_handle_result : Apache2::Const::OK;
+}
+
+sub handle_circ_update {
+    my $self = shift;
+    my $action = shift;
+    my $circ_ids = shift;
+    my $e = $self->editor;
+    my $url;
+
+    my @circ_ids = ($circ_ids) ? @$circ_ids : $self->cgi->param('circ_id'); # for non-_all actions
+
+    my $cstore_ses = OpenSRF::AppSession->create('open-ils.cstore');
+    $cstore_ses->connect();
+    $cstore_ses->request('open-ils.cstore.transaction.begin')->gather(1);
+
+    if($action =~ /delete/) {
+        for my $circ_id (@circ_ids) {
+            my $circ = $cstore_ses->request(
+                'open-ils.cstore.direct.action.circulation.retrieve', $circ_id)->gather(1);
+            $circ->hide_from_usr_history(1);
+            my $resp = $cstore_ses->request(
+                'open-ils.cstore.direct.action.circulation.update', $circ)->gather(1);
+        }
+    }
+
+    $cstore_ses->request('open-ils.cstore.transaction.commit')->gather(1);
+    $cstore_ses->disconnect();
+    return undef;
 }
 
 # TODO: action.usr_visible_holds does not return cancelled holds.  Should it?
index ca1e7f3..e2a9075 100644 (file)
@@ -147,7 +147,8 @@ CREATE TABLE action.circulation (
                                       ON DELETE SET NULL
                                                                   DEFERRABLE INITIALLY DEFERRED,
        copy_location   INT                             NOT NULL DEFAULT 1 REFERENCES asset.copy_location (id) DEFERRABLE INITIALLY DEFERRED,
-       checkin_scan_time   TIMESTAMP WITH TIME ZONE
+       checkin_scan_time   TIMESTAMP WITH TIME ZONE,
+       hide_from_usr_history   BOOL                            NOT NULL DEFAULT FALSE
 ) INHERITS (money.billable_xact);
 ALTER TABLE action.circulation ADD PRIMARY KEY (id);
 ALTER TABLE action.circulation
@@ -880,7 +881,8 @@ END;
 $$ LANGUAGE 'plpgsql';
 
 -- Return the list of circ chain heads in xact_start order that the user has chosen to "retain"
-CREATE OR REPLACE FUNCTION action.usr_visible_circs (usr_id INT) RETURNS SETOF action.circulation AS $func$
+CREATE OR REPLACE FUNCTION action.usr_visible_circs (usr_id INT) RETURNS SETOF action.circulation 
+AS $func$
 DECLARE
     c               action.circulation%ROWTYPE;
     view_age        INTERVAL;
@@ -911,6 +913,7 @@ BEGIN
           WHERE usr = usr_id
                 AND parent_circ IS NULL
                 AND xact_start > NOW() - view_age
+               AND NOT hide_from_usr_history
           ORDER BY xact_start DESC
     LOOP
         RETURN NEXT c;
@@ -1148,7 +1151,7 @@ BEGIN
   END LOOP;
   RETURN purged_holds;
 END;
-$func$ LANGUAGE plpgsql;
+$func$ LANGUAGE 'plpgsql';
 
 CREATE OR REPLACE FUNCTION action.apply_fieldset(
        fieldset_id IN INT,        -- id from action.fieldset
@@ -1259,7 +1262,7 @@ BEGIN
        --
        RETURN msg;
 END;
-$$ LANGUAGE plpgsql;
+$$ LANGUAGE 'plpgsql';
 
 COMMENT ON FUNCTION action.apply_fieldset( INT, TEXT, TEXT, TEXT ) IS $$
 Applies a specified fieldset, using a supplied table name and primary
diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.editable_usr_circ_history.sql b/Open-ILS/src/sql/Pg/upgrade/XXXX.editable_usr_circ_history.sql
new file mode 100644 (file)
index 0000000..b966900
--- /dev/null
@@ -0,0 +1,48 @@
+BEGIN;
+
+ALTER TABLE action.circulation 
+      ADD COLUMN hide_from_usr_history boolean not null default false;
+
+CREATE OR REPLACE FUNCTION action.usr_visible_circs(usr_id integer) RETURNS SETOF action.circulation
+AS $function$
+DECLARE
+    c               action.circulation%ROWTYPE;
+    view_age        INTERVAL;
+    usr_view_age    actor.usr_setting%ROWTYPE;
+    usr_view_start  actor.usr_setting%ROWTYPE;
+BEGIN
+    SELECT * INTO usr_view_age FROM actor.usr_setting WHERE usr = usr_id AND name = 'history.circ.retention_age';
+    SELECT * INTO usr_view_start FROM actor.usr_setting WHERE usr = usr_id AND name = 'history.circ.retention_start';
+
+    IF usr_view_age.value IS NOT NULL AND usr_view_start.value IS NOT NULL THEN
+        -- User opted in and supplied a retention age
+        IF oils_json_to_text(usr_view_age.value)::INTERVAL > AGE(NOW(), oils_json_to_text(usr_view_start.value)::TIMESTAMPTZ) THEN
+            view_age := AGE(NOW(), oils_json_to_text(usr_view_start.value)::TIMESTAMPTZ);
+        ELSE
+            view_age := oils_json_to_text(usr_view_age.value)::INTERVAL;
+        END IF;
+    ELSIF usr_view_start.value IS NOT NULL THEN
+        -- User opted in
+        view_age := AGE(NOW(), oils_json_to_text(usr_view_start.value)::TIMESTAMPTZ);
+    ELSE
+        -- User did not opt in
+        RETURN;
+    END IF;
+
+    FOR c IN
+        SELECT  *
+          FROM  action.circulation
+          WHERE usr = usr_id
+                AND parent_circ IS NULL
+                AND xact_start > NOW() - view_age
+                AND NOT hide_from_usr_history
+          ORDER BY xact_start DESC
+    LOOP
+       RETURN NEXT c;
+    END LOOP;
+
+    RETURN;
+END;
+$function$ LANGUAGE plpgsql;
+
+COMMIT;
index 5339b25..e686b80 100644 (file)
     <div class="warning_box">[% l('There are no items in your circulation history.') %]</div>
     [% ELSE %]
 
+        <form method="post" id="circ-form"
+            onsubmit="return confirm('[% l("Are you sure you wish to delete the selected item(s)?") %]');">
+        <table cellpadding='0' cellspacing='0' class="item_list_padding">
+            <tr>
+                <td>
+                    <select name="action">
+                        <option value="delete">[% l('Delete Selected Titles') %]</option>
+                    </select>
+                </td>
+                <td style="padding-left:9px;">
+                    <input type="submit"
+                        value="[% l('Go') %]"
+                        alt="[% l('Go') %]" title="[% l('Go') %]"
+                        class="opac-button" />
+                </td>
+                <!--
+                <td style="padding-left:5px;">
+                    <a href="#"><img alt="[% l('Deleting Help') %]"
+                        src="[% ctx.media_prefix %]/images/question-mark.png" /></a>
+                </td>
+                -->
+            </tr>
+        </table>
     <div id='checked_main'>
         <table id="acct_checked_main_header"
             title="[% l('History of Items Checked Out') %]">
             <thead>
                 <tr>
+                    <th align="center">
+                        <input type="checkbox" onclick="var inputs=document.getElementsByTagName('input'); for (i = 0; i < inputs.length; i++) { if (inputs[i].name == 'circ_id' && !inputs[i].disabled) inputs[i].checked = this.checked;}"/>
+                    </th>
                     <th>[% sort_head("sort_title", l("Title")) %]</th>
                     <th>[% sort_head("author", l("Author")) %]</th>
                     <th>[% sort_head("checkout", l("Checkout Date")) %]</th>
 
                 FOR circ IN circ_items; %]
                     <tr>
+                       <td align="center" style="text-align:center;">
+                               <input type="checkbox" name="circ_id" value="[% circ.circ.id %]" />
+                       </td>
                         <td>
                             <a href="[% mkurl(ctx.opac_root _ '/record/' _ 
                                 circ.circ.target_copy.call_number.record.id, {}, 1) %]"
                         </td>
                         <td>[% circ.circ.target_copy.barcode | html %]</td>
                         <td>[% circ.circ.target_copy.call_number.label | html %]</td>
+        </form>
                     </tr>
                 [% END %]
             </tbody>
diff --git a/docs/RELEASE_NOTES_NEXT/OPAC/edit_circ_history b/docs/RELEASE_NOTES_NEXT/OPAC/edit_circ_history
new file mode 100644 (file)
index 0000000..ea4c60c
--- /dev/null
@@ -0,0 +1,10 @@
+Editable Borrowing History
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+You can delete titles that you do not wish to appear in your Check Out History. 
+
+ * In "My Account", click on the "Items Checked Out" tab, then the "Check Out History" sub-tab.
+ * Check off the items you wish to conceal.
+ * Click the Go button next to the "Delete Selected Titles" drop-down box.
+ * Click OK in the pop-up to confirm your deletion.  Choose carefully, as there is no "undo".
+
+Deleted titles will also not appear in the downloaded CSV file.