return $self->load_place_hold if $path =~ m|opac/place_hold|;
return $self->load_myopac_holds if $path =~ m|opac/myopac/holds|;
return $self->load_myopac_circs if $path =~ m|opac/myopac/circs|;
+ return $self->load_myopac_messages if $path =~ m|opac/myopac/messages|;
return $self->load_myopac_payment_form if $path =~ m|opac/myopac/main_payment_form|;
return $self->load_myopac_payments if $path =~ m|opac/myopac/main_payments|;
return $self->load_myopac_pay_init if $path =~ m|opac/myopac/main_pay_init|;
return [map { {cust => $_, value => $user_set->{$_->name} } } @$opt_ins];
}
+sub load_myopac_messages {
+ my $self = shift;
+ my $e = $self->editor;
+ my $ctx = $self->ctx;
+ my $cgi = $self->cgi;
+
+ my $limit = $cgi->param('limit') || 20;
+ my $offset = $cgi->param('offset') || 0;
+
+ my $pcrud = OpenSRF::AppSession->create('open-ils.pcrud');
+ $pcrud->connect();
+
+ my $action = $cgi->param('action') || '';
+ if ($action) {
+ my ($changed, $failed) = $self->_handle_message_action($pcrud, $action);
+ if ($changed > 0 || $failed > 0) {
+ $ctx->{message_update_action} = $action;
+ $ctx->{message_update_changed} = $changed;
+ $ctx->{message_update_failed} = $failed;
+ }
+ }
+
+ my $single = $cgi->param('single') || 0;
+ my $id = $cgi->param('message_id');
+
+ my $messages;
+ my $fetch_all = 1;
+ if (!$action && $single && $id) {
+ $messages = $self->_fetch_and_mark_read_single_message($pcrud, $id);
+ if (scalar(@$messages) == 1) {
+ $ctx->{display_single_message} = 1;
+ $ctx->{patron_message_id} = $id;
+ $fetch_all = 0;
+ }
+ }
+
+ if ($fetch_all) {
+ # fetch all the messages
+ ($ctx->{patron_messages_count}, $messages) =
+ $self->_fetch_user_messages($pcrud, $offset, $limit);
+ }
+
+ $pcrud->kill_me;
+
+ foreach my $aum (@$messages) {
+
+ push @{ $ctx->{patron_messages} }, {
+ id => $aum->id,
+ title => $aum->title,
+ message => $aum->message,
+ create_date => $aum->create_date,
+ is_read => defined($aum->read_date) ? 1 : 0,
+ library => $aum->sending_lib->name,
+ };
+ }
+
+ $ctx->{patron_messages_limit} = $limit;
+ $ctx->{patron_messages_offset} = $offset;
+
+ return Apache2::Const::OK;
+}
+
+sub _fetch_and_mark_read_single_message {
+ my $self = shift;
+ my $pcrud = shift;
+ my $id = shift;
+
+ $pcrud->request('open-ils.pcrud.transaction.begin', $self->editor->authtoken)->gather(1);
+ my $messages = $pcrud->request(
+ 'open-ils.pcrud.search.aum.atomic',
+ $self->editor->authtoken,
+ {
+ usr => $self->editor->requestor->id,
+ deleted => 'f',
+ id => $id,
+ },
+ {
+ flesh => 1,
+ flesh_fields => { aum => ['sending_lib'] },
+ }
+ )->gather(1);
+ if (@$messages) {
+ $messages->[0]->read_date('now');
+ $pcrud->request(
+ 'open-ils.pcrud.update.aum',
+ $self->editor->authtoken,
+ $messages->[0]
+ )->gather(1);
+ }
+ $pcrud->request('open-ils.pcrud.transaction.commit', $self->editor->authtoken)->gather(1);
+
+ return $messages;
+}
+
+sub _fetch_user_messages {
+ my $self = shift;
+ my $pcrud = shift;
+ my $offset = shift;
+ my $limit = shift;
+
+ my %paging = ($limit or $offset) ? (limit => $limit, offset => $offset) : ();
+
+ my $all_messages = $pcrud->request(
+ 'open-ils.pcrud.id_list.aum.atomic',
+ $self->editor->authtoken,
+ {
+ usr => $self->editor->requestor->id,
+ deleted => 'f'
+ },
+ {}
+ )->gather(1);
+
+ my $messages = $pcrud->request(
+ 'open-ils.pcrud.search.aum.atomic',
+ $self->editor->authtoken,
+ {
+ usr => $self->editor->requestor->id,
+ deleted => 'f'
+ },
+ {
+ flesh => 1,
+ flesh_fields => { aum => ['sending_lib'] },
+ order_by => { aum => 'create_date DESC' },
+ %paging
+ }
+ )->gather(1);
+
+ return scalar(@$all_messages), $messages;
+}
+
+sub _handle_message_action {
+ my $self = shift;
+ my $pcrud = shift;
+ my $action = shift;
+ my $cgi = $self->cgi;
+
+ my @ids = $cgi->param('message_id');
+ return (0, 0) unless @ids;
+
+ my $changed = 0;
+ my $failed = 0;
+ $pcrud->request('open-ils.pcrud.transaction.begin', $self->editor->authtoken)->gather(1);
+ for my $id (@ids) {
+ my $aum = $pcrud->request(
+ 'open-ils.pcrud.retrieve.aum',
+ $self->editor->authtoken,
+ $id
+ )->gather(1);
+ next unless $aum;
+ if ($action eq 'mark_read') {
+ $aum->read_date('now');
+ } elsif ($action eq 'mark_unread') {
+ $aum->clear_read_date();
+ } elsif ($action eq 'mark_deleted') {
+ $aum->deleted('t');
+ }
+ $pcrud->request('open-ils.pcrud.update.aum', $self->editor->authtoken, $aum)->gather(1) ?
+ $changed++ :
+ $failed++;
+ }
+ if ($failed) {
+ $pcrud->request('open-ils.pcrud.transaction.rollback', $self->editor->authtoken)->gather(1);
+ $changed = 0;
+ $failed = scalar(@ids);
+ } else {
+ $pcrud->request('open-ils.pcrud.transaction.commit', $self->editor->authtoken)->gather(1);
+ }
+ return ($changed, $failed);
+}
+
sub _load_lists_and_settings {
my $self = shift;
my $e = $self->editor;
/*padding-left:10px;*/
}
-#acct_checked_main_header, #acct_holds_main_header, #acct_checked_hist_header, #acct_list_header, #acct_list_header_anon, #temp_list_holds {
+#acct_checked_main_header, #acct_holds_main_header, #acct_checked_hist_header, #acct_list_header, #acct_list_header_anon, #temp_list_holds, #acct_messages_main_header {
border-collapse: collapse;
}
.hold_note_title { font-weight: bold; }
-#acct_checked_main_header td, #acct_holds_main_header td, #acct_checked_hist_header td, #acct_list_header td, #acct_list_header_anon td, #temp_list_holds td {
+#acct_checked_main_header td, #acct_holds_main_header td, #acct_checked_hist_header td, #acct_list_header td, #acct_list_header_anon td, #temp_list_holds td, #acct_messages_main_header td {
background: [% css_colors.accent_lighter2 %];
padding: 10px;
}
-#acct_checked_main_header th, #acct_holds_main_header th, #acct_checked_hist_header th, #acct_list_header th, #acct_list_header_anon th, #temp_list_holds th {
+#acct_checked_main_header th, #acct_holds_main_header th, #acct_checked_hist_header th, #acct_list_header th, #acct_list_header_anon th, #temp_list_holds th, #acct_messages_main_header th {
text-align: left;
padding: 0px 10px 0px 10px;
}
padding-left: 1em;
}
#opac.result.sort { width: 160px; }
-.renew-summary { font-size: [% css_fonts.size_bigger %]; font-style: italic; margin: 0.5ex 0; }
+.renew-summary, .message-update-summary { font-size: [% css_fonts.size_bigger %]; font-style: italic; margin: 0.5ex 0; }
.failure-text { margin-left: 4em; font-style: italic; color: [% css_colors.text_alert %]; }
.refine-controls { font-size: [% css_fonts.size_bigger %]; padding: 0.5ex 0; }
#adv_search_refine input[type=text] { border: 1px inset [% css_colors.accent_light %] !important; }
.results-paginator-list { padding-left: 1em; }
.results-paginator-selected { color: [% css_colors.text_alert %]; }
.inactive-hold { background: [% css_colors.accent_lightest %]; }
+.unread-patron-message { font-weight: bold; }
#hold-items-list td { padding: 5px; margin-bottom: 20px; }
.hold-items-list-title { font-size: [% css_fonts.size_bigger %]; }
--- /dev/null
+[% PROCESS "opac/parts/header.tt2";
+ PROCESS "opac/parts/misc_util.tt2";
+ WRAPPER "opac/parts/myopac/base.tt2";
+ myopac_page = "messages";
+ limit = (ctx.patron_messages_limit.defined) ? ctx.patron_messages_limit : 20;
+ offset = (ctx.patron_messages_offset.defined) ? ctx.patron_messages_offset : 0;
+ count = (ctx.patron_messages_count.defined) ? ctx.patron_messages_count : 0;
+ display_single = (ctx.display_single_message.defined) ? ctx.display_single_message : 0;
+%]
+<h3 class="sr-only">[% l('My Messages') %]</h3>
+[% IF display_single;
+ PROCESS "opac/myopac/messages/single_message.tt2";
+ELSE;
+ PROCESS "opac/myopac/messages/list.tt2";
+END %]
+[% END %]
--- /dev/null
+<div id="myopac_messages_div">
+ <div class="header_middle">
+ <span id="acct_messages_header" style="float:left;">[% l("Messages") %]</div>
+ <span class='float-left' style='padding-left: 10px;'>
+ <a href='[% mkurl('messages', { limit => limit, offset => (offset - limit)} ) %]'
+ [% IF offset <= 0 %] class='invisible' [% END %]><span class="nav_arrow_fix">◄</span>[% l('Previous') %]</a>
+ [% IF offset > 0 || count > limit;
+ curpage = 0;
+ WHILE curpage * limit < count;
+ IF curpage * limit == offset;
+ %]
+ [% curpage + 1 %]
+ [%- ELSE %]
+ <a href='[% mkurl('messages', {limit => limit, offset => (curpage * limit)}) %]'>[% curpage + 1 %]</a>
+ [%- END;
+ curpage = curpage + 1;
+ END;
+ END %]
+ <a href='[% mkurl('messages', {limit => limit, offset => (offset + limit)}) %]'
+ [% IF count <= limit + offset %] class='invisible' [% END %] >[% l('Next') %]<span class="nav_arrow_fix">►</span></a>
+ </span>
+ </div>
+ <div class="clear-both"></div>
+ [% IF ctx.message_update_action.defined %]
+ [% IF ctx.message_update_changed > 0 %]
+ <div class="message-update-summary">
+ [% IF ctx.message_update_action == 'mark_read';
+ l('Marked [_1] message(s) as read.', ctx.message_update_changed);
+ ELSIF ctx.message_update_action == 'mark_unread';
+ l('Marked [_1] message(s) as unread.', ctx.message_update_changed);
+ ELSIF ctx.message_update_action == 'mark_unread';
+ l('Deleted [_1] message(s).', ctx.message_update_changed);
+ END
+ %]
+ </div>
+ [% END %]
+ [% IF ctx.message_update_failed > 0 %]
+ <div class="message-update-summary alert">
+ [% IF ctx.message_update_action == 'mark_read';
+ l('Failed to mark [_1] message(s) as read.', ctx.message_update_failed);
+ ELSIF ctx.message_update_action == 'mark_unread';
+ l('Failed to mark [_1] message(s) as unread.', ctx.message_update_failed);
+ ELSIF ctx.message_update_action == 'mark_unread';
+ l('Failed to delete [_1] message(s).', ctx.message_update_failed);
+ END
+ %]
+ </div>
+ [% END %]
+ [% END %]
+ <div class="clear-both"></div>
+ <div id="messages_main">
+ <form method="post" id="messages-form"
+ onsubmit="if (document.getElementById('acct_messages_actions').value == 'mark_deleted') { return confirm('[% l("Are you sure you wish to permanently delete the selected messsage(s)?") %]') } else { return true; }">
+ <div>
+ <span>
+ <select name="action" id="acct_messages_actions"
+ title="[% l('Select your action for the selected messages') %]">
+ <option id="acct_messages_actions_none" value="">
+ -- [% l('Actions for selected messages') %] --
+ </option>
+ <option value="mark_read">[% l('Mark As Read') %]</option>
+ <option value="mark_unread">[% l('Mark As Unread') %]</option>
+ <option value="mark_deleted">[% l('Delete') %]</option>
+ </select>
+ </span>
+ <span style="padding-left:9px;">
+ <input type="submit"
+ value="[% l('Go') %]"
+ title="[% l('Go') %]"
+ class="opac-button" />
+ </span>
+ <span style="padding-left:5px;">
+ <a href="#"><img
+ alt="[% l('Messages Help') %]"
+ title="[% l('Actions for messages') %]"
+ src="[% ctx.media_prefix %]/images/question-mark.png" /></a>
+ </span>
+ </div>
+ [% IF count < 1 %]
+ <div class="warning_box">[% l('No messages found.') %]</div>
+ [% ELSE %]
+ <table id="acct_messages_main_header" title="[% l('Messages') %]"
+ class="table_no_border_space table_no_cell_pad">
+ <thead>
+ <tr>
+ <th align="center">
+ <input type="checkbox" title="[% l('Select All Messages') %]"
+ onclick="var inputs=document.getElementsByTagName('input'); for (i = 0; i < inputs.length; i++) { if (inputs[i].name == 'message_id' && !inputs[i].disabled) inputs[i].checked = this.checked;}"/>
+ </th>
+ <th>[% l('Date') %]</th>
+ <th>[% l('Library') %]</th>
+ <th>[% l('Subject') %]</th>
+ </tr>
+ </thead>
+ <tbody>
+ [% FOR message IN ctx.patron_messages; %]
+ <tr name="acct_message_row"
+ [% IF !message.is_read %]class="unread-patron-message"[% END %]>
+ <td align="center" style="text-align:center;">
+ <input type="checkbox" name="message_id" value="[% message.id %]"
+ [% html_text_attr('title', l('Select message [_1]', message.title)) %]/>
+ </td>
+ <td>[% date.format(ctx.parse_datetime(message.create_date), DATE_FORMAT); %]</td>
+ <td>[% message.library | html %]</td>
+ <td><a href="[% mkurl('messages', { single => 1, message_id => message.id } ) %]">[% message.title | html %]</a></td>
+ </tr>
+ [% END %]
+ </tbody>
+ </table>
+ [% END %]
+ </form>
+ </div>
+</div>
--- /dev/null
+<div id="myopac_messages_div">
+ <div class="header_middle">
+ <span id="acct_messages_header" style="float:left;">[% l("Message") %]</div>
+ </div>
+ <div class="clear-both"></div>
+ <div id="single_message_main">
+ <form method="post" id="messages-form" action="[% ctx.opac_root %]/myopac/messages">
+ <input type="hidden" name="message_id" value="[% ctx.patron_message_id %]" />
+ <input type="hidden" name="offset" value="[% offset %]" />
+ <input type="hidden" name="limit" value="[% limit %]" />
+ <span style="padding-left:9px;">
+ <a href="[% mkurl('messages', {}, ['single', 'message_id']) %]" class="opac-button">
+ [% l('Return to Message List') %]
+ </a>
+ <button type="submit" name="action" value="mark_deleted" class="opac-button"
+ onclick="return confirm('[% l("Are you sure you wish to permanently delete this messsage?") %]')">
+ [% l('Delete') %]
+ </button>
+ <button type="submit" name="action" value="mark_unread" class="opac-button">
+ [% l('Mark Unread') %]
+ </button>
+ </span>
+ </form>
+
+ <table title="[% l('Message') %]"
+ class='light_border data_grid'>
+ <tbody id='myopac_message_tbody'>
+ </tbody>
+ <tr>
+ <td width='30%'
+ class='color_4 light_border'>[% l("Date") %]</td>
+ <td>[% date.format(ctx.parse_datetime(ctx.patron_messages.0.create_date), DATE_FORMAT); %]</td>
+ </tr>
+ <tr>
+ <td width='30%'
+ class='color_4 light_border'>[% l("Library") %]</td>
+ <td>[% ctx.patron_messages.0.library | html %]</td>
+ </tr>
+ <tr>
+ <td width='30%'
+ class='color_4 light_border'>[% l("Subject") %]</td>
+ <td>[% ctx.patron_messages.0.title | html %]</td>
+ </tr>
+ <tr>
+ <td width='30%'
+ class='color_4 light_border'>[% l("Message") %]</td>
+ <td>[% ctx.patron_messages.0.message | html %]</td>
+ </tr>
+ </table>
+ </div>
+</div>
[% myopac_pages = [
{url => "main", name => l("Account Summary")},
+ {url => "messages", name => l("Messages")},
{url => "circs", name => l("Items Checked Out")},
{url => "holds", name => l("Holds")},
{url => "prefs", name => l("Account Preferences")},