where => {id => $e->requestor->id},
limit => $limit,
offset => $offset
- });
+ });
+ }
$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?
--- /dev/null
-COMMIT;
-
-BEGIN;
-
+ BEGIN;
+
+ ALTER TABLE action.circulation
+ ADD COLUMN hide_from_usr_history boolean not null default false;
+
- RETURNS SETOF action.circulation
- LANGUAGE plpgsql
-AS $function$
+ CREATE OR REPLACE FUNCTION action.usr_visible_circs(usr_id integer)
-RETURN NEXT c;
++ 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
-$function$
++ RETURN NEXT c;
+ END LOOP;
+
+ RETURN;
+ END;
++$function$ LANGUAGE PLPGSQL;
+
+ COMMIT;
<div id='checked_main'>
<table id="acct_checked_main_header"
title="[% l('History of Items Checked Out') %]">
- <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>
<thead>
<tr>
- <th>[% l('Title / Author') %]</th>
- <th>[% l('Checkout Date') %]</th>
- <th>[% l('Due Date') %]</th>
- <th>[% l('Date Returned') %]</th>
- <th>[% l('Barcode') %]</th>
- <th>[% l('Call Number') %]</th>
++ <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>
+ <th>[% sort_head("due", l("Due Date")) %]</th>
+ <th>[% sort_head("returned", l("Date Returned")) %]</th>
+ <th>[% sort_head("barcode", l("Barcode")) %]</th>
+ <th>[% sort_head("callnum", l("Call Number")) %]</th>
</tr>
</thead>
<tbody>
- [% FOR circ IN ctx.circs;
- attrs = {marc_xml => circ.marc_xml};
- <td align="center" style="text-align:center;">
- <input type="checkbox" name="circ_id" value="[% circ.circ.id %]" />
- </td>
- PROCESS get_marc_attrs args=attrs; %]
+ [%# Copy the ctx.circs into a local array, then add a SORT field
+ that contains the value to sort on. Since we need the item attrs,
+ invoke it and save the result in ATTRS.
+ %]
+ [%
+ circ_items = ctx.circs; # Array assignment
+
+ FOR circ IN circ_items;
+ circ.ATTRS = {marc_xml => circ.marc_xml};
+ PROCESS get_marc_attrs args=circ.ATTRS;
+
+ SWITCH sort_field;
+
+ CASE "sort_title";
+ circ.SORTING = circ.ATTRS.sort_title;
+
+ CASE "author";
+ circ.SORTING = circ.ATTRS.author;
+
+ CASE "checkout";
+ circ.SORTING = circ.circ.xact_start;
+
+ CASE "due";
+ circ.SORTING = circ.circ.due_date;
+
+ CASE "returned";
+ circ.SORTING = circ.circ.checkin_time;
+
+ CASE "barcode";
+ circ.SORTING = circ.circ.target_copy.barcode;
+
+ CASE "callnum";
+ circ.SORTING = circ.circ.target_copy.call_number.label;
+
+ CASE;
+ sort_field = "";
+ END; # SWITCH
+ END; #FOR circ
+
+ IF (sort_field != "sort_title");
+ deemphasize_class = "";
+ ELSE;
+ deemphasize_class = " class=\"sort_deemphasize\"";
+ END;
+
+ # Apply sorting to circ_items
+ IF (sort_field);
+ circ_items = circ_items.sort("SORTING");
+ IF (CGI.param("sort_type") == "desc");
+ circ_items = circ_items.reverse;
+ END;
+
+ # Shorten the circ_items list per offset/limit/cout
+ hi = offset + limit - 1;
+ hi = hi > circ_items.max ? circ_items.max : hi;
+
+ circ_items = circ_items.slice(offset, hi);
+ END;
+
+ # circ_items list is now sorted. Traverse and dump the information.
+
+ 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) %]"
+ name="[% l('Catalog record') %]"><span[%- deemphasize_class -%]>
+ [%- circ.ATTRS.title.substr(0,circ.ATTRS.nonfiling_characters) | html %]</span>
+ [%- circ.ATTRS.title.substr(circ.ATTRS.nonfiling_characters) | html %]</a>
+ </td>
<td>
- <a href="[% mkurl(ctx.opac_root _ '/record/' _ circ.circ.target_copy.call_number.record.id) %]"
- [% html_text_attr('title', l('Catalog record [_1]', attrs.title)) %]>
- [% attrs.title | html %]
- </a>
- [% IF attrs.author %] /
<a href="[% mkurl(ctx.opac_root _ '/results',
- {qtype => 'author', query => attrs.author.replace('[,\.:;]', '')}
- )%]">[% attrs.author | html %]</a>
- [% END %]
+ {qtype => 'author', query => circ.ATTRS.author.replace('[,\.:;]', '')},
+ 1
+ ) %]">[% circ.ATTRS.author | html %]</a>
</td>
<td>
[% date.format(ctx.parse_datetime(circ.circ.xact_start),DATE_FORMAT); %]