squash collab/phasefx/alt_patron_summary_rel_2_3_3
authorJason Etheridge <jason@esilibrary.com>
Tue, 19 Feb 2013 23:30:58 +0000 (18:30 -0500)
committerJason Etheridge <jason@esilibrary.com>
Tue, 12 Mar 2013 16:19:04 +0000 (12:19 -0400)
Signed-off-by: Jason Etheridge <jason@esilibrary.com>
25 files changed:
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader.pm
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/PatronSummary.pm [new file with mode: 0644]
Open-ILS/src/templates/base_nodojo.tt2 [new file with mode: 0644]
Open-ILS/src/templates/opac/PatronSearchSummary.tt2 [new file with mode: 0644]
Open-ILS/src/templates/opac/PatronSummary.tt2 [new file with mode: 0644]
Open-ILS/src/templates/opac/css/PatronSummary.css.tt2 [new file with mode: 0644]
Open-ILS/xul/staff_client/chrome/content/OpenILS/data.js
Open-ILS/xul/staff_client/chrome/content/main/constants.js
Open-ILS/xul/staff_client/chrome/content/main/menu.js
Open-ILS/xul/staff_client/chrome/content/util/list.js
Open-ILS/xul/staff_client/server/circ/checkin.js
Open-ILS/xul/staff_client/server/circ/checkout.js
Open-ILS/xul/staff_client/server/main/data.xul
Open-ILS/xul/staff_client/server/patron/barcode_entry.xul [changed from file to symlink]
Open-ILS/xul/staff_client/server/patron/bill2.js
Open-ILS/xul/staff_client/server/patron/display.js [deleted file]
Open-ILS/xul/staff_client/server/patron/display.xul
Open-ILS/xul/staff_client/server/patron/display_horiz.xul [changed from file to symlink]
Open-ILS/xul/staff_client/server/patron/display_horiz_overlay.xul [deleted file]
Open-ILS/xul/staff_client/server/patron/display_overlay.xul [deleted file]
Open-ILS/xul/staff_client/server/patron/holds.js
Open-ILS/xul/staff_client/server/patron/patron.js [new file with mode: 0644]
Open-ILS/xul/staff_client/server/patron/search.js [new file with mode: 0644]
Open-ILS/xul/staff_client/server/patron/search_result.js
Open-ILS/xul/staff_client/server/patron/standing_penalties.js

index ad222e5..382cd9c 100644 (file)
@@ -23,6 +23,7 @@ use OpenILS::WWW::EGCatLoader::Search;
 use OpenILS::WWW::EGCatLoader::Record;
 use OpenILS::WWW::EGCatLoader::Container;
 use OpenILS::WWW::EGCatLoader::SMS;
+use OpenILS::WWW::EGCatLoader::PatronSummary;
 
 my $U = 'OpenILS::Application::AppUtils';
 
@@ -193,6 +194,8 @@ sub load {
     return $self->load_myopac_prefs_settings if $path =~ m|opac/myopac/prefs_settings|;
     return $self->load_myopac_prefs if $path =~ m|opac/myopac/prefs|;
     return $self->load_sms_cn if $path =~ m|opac/sms_cn|;
+    return $self->load_patron_summary if $path =~ m|opac/PatronSummary|;
+    return $self->load_patron_summary if $path =~ m|opac/PatronSearchSummary|;
 
     return Apache2::Const::OK;
 }
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/PatronSummary.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/PatronSummary.pm
new file mode 100644 (file)
index 0000000..a751333
--- /dev/null
@@ -0,0 +1,186 @@
+package OpenILS::WWW::EGCatLoader;
+use strict; use warnings;
+use Apache2::Const -compile => qw(OK DECLINED FORBIDDEN HTTP_INTERNAL_SERVER_ERROR REDIRECT HTTP_BAD_REQUEST);
+use OpenSRF::Utils::Logger qw/$logger/;
+use OpenILS::Utils::CStoreEditor qw/:funcs/;
+use OpenILS::Utils::Fieldmapper;
+use OpenILS::Application::AppUtils;
+use OpenILS::Event;
+use OpenSRF::Utils::JSON;
+use Data::Dumper;
+$Data::Dumper::Indent = 0;
+use DateTime;
+my $U = 'OpenILS::Application::AppUtils';
+
+sub isTrue {
+    my $v = shift;
+    return 1 if ($v eq 't');
+    return 0;
+}
+
+sub load_patron_summary {
+    my $self = shift;
+    my $ctx = $self->ctx;
+    #my $gos = $ctx->{get_org_setting};
+    my $e = $self->editor;
+    my $cgi = $self->cgi;
+
+    $self->_load_user_with_prefs() if($e->checkauth);
+
+    $ctx->{page} = 'patron_summary';
+    $ctx->{au_id} = $cgi->param('au_id');
+    my @classnames = ();
+
+    # open-ils.actor.user.fleshed.retrieve.authoritative
+    my $au_resp = $U->simplereq(
+        'open-ils.actor',
+        'open-ils.actor.user.fleshed.retrieve.authoritative',
+        $e->authtoken,
+        $ctx->{au_id},
+        [
+            'card',
+            'profile',
+            'mailing_address',
+            'billing_address',
+            'open_billable_transactions_summary',
+            'standing_penalties',
+            'notes',
+            'usr_activity',
+            'home_ou',
+            'ident_type',
+            'ident_type2'
+        ]
+    );
+
+    if (ref $au_resp eq 'HASH' && defined $au_resp->{textcode}) {
+        $ctx->{error} = $au_resp;
+        return Apache2::Const::OK;
+    }
+
+    $au_resp->standing_penalties(
+        grep {
+            isTrue($_->isdeleted) || $_->stop_date
+        } @{ $au_resp->standing_penalties }
+    );
+    $ctx->{user} = $au_resp;
+
+    $ctx->{addr} = $au_resp->mailing_address && $au_resp->mailing_address->valid
+        ? $au_resp->mailing_address
+        : $au_resp->billing_address && $au_resp->billing_address->valid
+            ? $au_resp->billing_address
+            : undef;
+
+    my $classhash = {};
+    my $block_list;
+    foreach my $p ( @{ $au_resp->standing_penalties } ) {
+        $classhash->{ $p->standing_penalty->name } = 1;
+        if ($p->standing_penalty->id >= 100) {
+            $classhash->{'PATRON_HAS_CUSTOM_PENALTY'} = 1;
+        }
+        if (isTrue($p->standing_penalty->staff_alert)) {
+            $classhash->{'PATRON_HAS_STAFF_ALERT'} = 1;
+        }
+        $block_list = $p->standing_penalty->block_list;
+        if ($block_list) {
+            $classhash->{'PATRON_HAS_BLOCK'} = 1;
+            if ($block_list =~ 'CIRC') {
+                $classhash->{'PATRON_HAS_CIRC_BLOCK'} = 1;
+            }
+            if ($block_list =~ 'RENEW') {
+                $classhash->{'PATRON_HAS_RENEW_BLOCK'} = 1;
+            }
+            if ($block_list =~ 'HOLD') {
+                $classhash->{'PATRON_HAS_HOLD_BLOCK'} = 1;
+            }
+            if ($block_list =~ 'CAPTURE') {
+                $classhash->{'PATRON_HAS_CAPTURE_BLOCK'} = 1;
+            }
+            if ($block_list =~ 'FULFILL') {
+                $classhash->{'PATRON_HAS_FULFILL_BLOCK'} = 1;
+            }
+        }
+    }
+    foreach my $c ( keys %{ $classhash } ) {
+        push @classnames, $c;
+    }
+    if (scalar @{ $au_resp->standing_penalties } == 0) {
+        push @classnames, 'NO_PENALTIES';
+    }
+    if (scalar @{ $au_resp->standing_penalties } == 1) {
+        push @classnames, 'ONE_PENALTY';
+    }
+    if (scalar @{ $au_resp->standing_penalties } > 1) {
+        push @classnames, 'MULTIPLE_PENALTIES';
+    }
+    if ($au_resp->alert_message) {
+        push @classnames, 'PATRON_HAS_ALERT';
+    }
+    if (isTrue($au_resp->barred)) {
+        $ctx->{barred} = 1;
+        push @classnames, 'PATRON_BARRED';
+    }
+    if (isTrue($au_resp->juvenile)) {
+        push @classnames, 'PATRON_JUVENILE';
+    }
+    if (!isTrue($au_resp->active)) {
+        push @classnames, 'PATRON_INACTIVE';
+    }
+    if (scalar( @{ $au_resp->notes }) > 0) {
+        push @classnames, 'PATRON_HAS_NOTES';
+    }
+    push @classnames, 'PATRON_NET_ACCESS_' . $au_resp->net_access_level;
+    if (
+        ($au_resp->mailing_address
+        && !isTrue($au_resp->mailing_address->valid))
+    || ($au_resp->billing_address
+        && !isTrue($au_resp->billing_address->valid))
+    ) {
+        push @classnames, 'PATRON_HAS_INVALID_ADDRESS';
+    }
+
+    # TODO: PATRON_EXPIRED
+    # TODO: PATRON_AGE_IS_
+    # TODO: PATRON_AGE_LT_
+    # TODO: PATRON_AGE_GE_
+
+    my $mous_resp = $U->simplereq(
+        'open-ils.actor',
+        'open-ils.actor.user.fines.summary.authoritative',
+        $e->authtoken,
+        $ctx->{au_id}
+    );
+    $ctx->{money_open_user_summary} = $mous_resp;
+
+    if ($mous_resp && $mous_resp->balance_owed > 0) {
+        push @classnames, 'PATRON_HAS_BILLS';
+    }
+
+    my $checked_out_count_resp = $U->simplereq(
+        'open-ils.actor',
+        'open-ils.actor.user.checked_out.count.authoritative',
+        $e->authtoken,
+        $ctx->{au_id}
+    );
+    $ctx->{checked_out_count} = $checked_out_count_resp;
+    if ($checked_out_count_resp
+    && ($checked_out_count_resp->{overdue}
+    + $checked_out_count_resp->{long_overdue}
+    > 0)) {
+        push @classnames, 'PATRON_HAS_OVERDUES';
+    }
+
+    my $holds_count_resp = $U->simplereq(
+        'open-ils.actor',
+        'open-ils.actor.user.hold_requests.count.authoritative',
+        $e->authtoken,
+        $ctx->{au_id}
+    );
+    $ctx->{holds_count} = $holds_count_resp;
+
+    $ctx->{css_classnames} = join ' ', @classnames;
+    $ctx->{orig_params} = $cgi->Vars;
+
+    return Apache2::Const::OK;
+}
+
+
diff --git a/Open-ILS/src/templates/base_nodojo.tt2 b/Open-ILS/src/templates/base_nodojo.tt2
new file mode 100644 (file)
index 0000000..dc2197d
--- /dev/null
@@ -0,0 +1,13 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns='http://www.w3.org/1999/xhtml' lang='[% ctx.locale %]' xml:lang='[% ctx.locale %]'>
+    <head>
+        <title>[% ctx.page_title %]</title>
+        <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
+        <style type="text/css">
+            @import "[% extracss %]";
+        </style>
+    </head>
+    <body class="[% class %]">
+        [% content %]
+    </body>
+</html>
diff --git a/Open-ILS/src/templates/opac/PatronSearchSummary.tt2 b/Open-ILS/src/templates/opac/PatronSearchSummary.tt2
new file mode 100644 (file)
index 0000000..0ca1d64
--- /dev/null
@@ -0,0 +1,123 @@
+[%  PROCESS "opac/parts/header.tt2";
+    WRAPPER "base_nodojo.tt2"
+        extracss="/eg/opac/css/PatronSummary.css";
+    ctx.page_title = l("Patron Summary") %]
+    <div id="content-wrapper">
+        <div id="main-content" class="[% ctx.css_classnames %]">
+            <div class="common-full-pad" style="float:none"></div>
+            [% IF NOT ctx.error %]
+            <div class="table patronSummaryDiv">
+                <div class="row"><div class="cell">
+                    <div class="textBackground">
+                        <span class="patronNameLarge">
+                            [% l(
+                                HUMAN_NAME_FORMAT,
+                                ctx.user.prefix, ctx.user.first_given_name,
+                                ctx.user.second_given_name, ctx.user.family_name,
+                                ctx.user.suffix
+                            ) | html %]
+                        </span><br/>
+                        [% IF ctx.user.mailing_address %]
+                        <span>
+                            [% ctx.user.mailing_address.street1 | html %]<br/>
+                            [% ctx.user.mailing_address.street2 | html %]<br/>
+                            [% ctx.user.mailing_address.city | html %],
+                            [% ctx.user.mailing_address.state | html %]
+                            [% ctx.user.mailing_address.post_code | html %]
+                        </span><br/>
+                        [% END %]
+                    </div>
+                </div><div class="cell">
+                    <div class="textBackground">
+                        <span>
+                            [% ctx.user.email OR ' ' | html %]
+                        </span></br>
+                        [% IF ctx.user.billing_address %]
+                        <span>
+                            [% ctx.user.billing_address.street1 | html %]<br/>
+                            [% ctx.user.billing_address.street2 | html %]<br/>
+                            [% ctx.user.billing_address.city | html %],
+                            [% ctx.user.billing_address.state | html %]
+                            [% ctx.user.billing_address.post_code | html %]
+                        </span><br/>
+                        [% END %]
+                    </div>
+                </div><div class="cell">
+                    <div class="textBackground">
+                        <span>
+                            [% l('D: [_1] ', ctx.user.day_phone) | html %]<br/>
+                            [% l('E: [_1] ', ctx.user.evening_phone) | html %]<br/>
+                            [% l('O: [_1] ', ctx.user.other_phone) | html %]<br/>
+                        </span>
+                        [% IF ctx.user.ident_value %]
+                        <span>
+                            [% l(
+                                '[_1]: [_2]',
+                                ctx.user.ident_type.name,
+                                ctx.user.ident_value
+                            ) | html %]
+                        </span><br/>
+                        [% END %]
+                        [% IF ctx.user.ident_value2 %]
+                        <span>
+                            [% l(
+                                '[_1]: [_2]',
+                                ctx.user.ident_type2.name,
+                                ctx.user.ident_value2
+                            ) | html %]
+                        </span><br/>
+                        [% END %]
+                    </div>
+                </div><div class="cell">
+                    <div class="textBackground">
+                        <span>[% ctx.user.profile.name | html %]</span><br/>
+                        <span>[% ctx.user.home_ou.shortname | html %]</span><br/>
+                        <span>
+                            [% l(
+                                'Items Overdue: [_1] Total: [_2]',
+                                ctx.checked_out_count.overdue + ctx.checked_out_count.long_overdue,
+                                ctx.checked_out_count.out
+                            ) | html %]
+                        <span><br/>
+                        <span>
+                            [% l(
+                                'Holds Ready: [_1] Total: [_2]',
+                                ctx.holds_count.ready,
+                                ctx.holds_count.total
+                            ) | html %]
+                        </span><br/>
+                        <span>
+                        [% IF ctx.money_open_user_summary %]
+                            [% l(
+                                'Bills: [_1]',
+                                ctx.money_open_user_summary.balance_owed
+                            ) | html %]
+                        [% ELSE %]
+                            [% l(
+                                'Bills: [_1]',
+                                '0.00'
+                            ) | html %]
+                        [% END %]
+                        </span><br/>
+                    </div>
+                </div></div>
+            </div>
+            [% ELSE %]
+            <div>
+                <span style="font-weight: bold; font-size: xx-large">
+                    Error loading user with database id = [% ctx.au_id | html %]
+                </span><br/>
+                <span style="font-weight: bold;">
+                    Description: [% ctx.error.desc | html %]
+                </span><br/>
+                <span>Server Time: [% ctx.error.servertime | html %]</span><br/>
+                <span>Text Code: [% ctx.error.textcode | html %]</span><br/>
+                <span>ILS Event: [% ctx.error.ilsevent | html %]</span><br/>
+                <span>PID: [% ctx.error.pid | html %]</span><br/>
+                <span>Stack Trace: [% ctx.error.stacktrace | html %]</span><br/>
+            </div>
+            [% END %]
+            <div class="common-full-pad" style="float:none"></div>
+        </div>
+    </div>
+[% END %]
diff --git a/Open-ILS/src/templates/opac/PatronSummary.tt2 b/Open-ILS/src/templates/opac/PatronSummary.tt2
new file mode 100644 (file)
index 0000000..ccae83f
--- /dev/null
@@ -0,0 +1,147 @@
+[%  PROCESS "opac/parts/header.tt2";
+    WRAPPER "base_nodojo.tt2"
+        extracss="/eg/opac/css/PatronSummary.css";
+    ctx.page_title = l("Patron Summary") %]
+    <div id="content-wrapper">
+        <div id="main-content" class="[% ctx.css_classnames %]">
+            <div class="common-full-pad" style="float:none"></div>
+            [% IF NOT ctx.error %]
+            <div class="table patronSummaryDiv">
+                <div class="row"><div class="cell">
+                    <div class="textBackground">
+                        <span class="patronNameLarge">
+                            [% l(
+                                HUMAN_NAME_FORMAT,
+                                ctx.user.prefix, ctx.user.first_given_name,
+                                ctx.user.second_given_name, ctx.user.family_name,
+                                ctx.user.suffix
+                            ) | html %]
+                        </span><br/>
+                        [% IF ctx.addr %]
+                        <span>
+                            [% ctx.addr.street1 | html %]<br/>
+                            [% ctx.addr.street2 | html %]<br/>
+                            [% ctx.addr.city | html %],
+                            [% ctx.addr.state | html %]
+                            [% ctx.addr.post_code | html %]
+                        </span><br/>
+                        [% END %]
+                    </div>
+                </div><div class="cell">
+                    <div class="textBackground alerts">
+                        [% IF ctx.barred %]
+                        <span>
+                            [% l('Patron is BARRED') | html %]
+                        </span><br/>
+                        [% END %]
+                        [% expire_date = ctx.parse_datetime(ctx.user.expire_date); %]
+                        [% IF (date.format(expire_date, '%s') < date.now) %]
+                        <span>
+                            [% l('Account has EXPIRED') | html %]
+                        </span><br/>
+                        [% END %]
+                        [% IF ctx.holds_count.ready > 0 %]
+                        <span>
+                            [% IF ctx.holds_count.ready == 1 %]
+                                [% l('1 hold Ready for Pickup') | html %]
+                            [% ELSE %]
+                                [% l('[_1] holds Ready for Pickup', ctx.holds_count.ready) | html %]
+                            [% END %]
+                        </span><br/>
+                        [% END %]
+                        [% IF ctx.user.alert_message %]
+                        <span>
+                            [% ctx.user.alert_message | html %]
+                        </span><br/>
+                        [% END %]
+                        [% IF ctx.user.notes.size > 0 %]
+                        <span>
+                        [% IF ctx.user.notes.size == 1 %]
+                            [% l('1 note') | html %]
+                        [% ELSIF ctx.user.notes.size > 1 %]
+                            [% l('[_1] notes', ctx.user.notes.size) | html %]
+                        [% END %]
+                        </span><br/>
+                        [% END %]
+                        [% FOREACH p IN ctx.user.standing_penalties %]
+                        <span>
+                            [% p.standing_penalty.label | html %]
+                            [% IF p.note %]
+                                : [% p.note | html %]
+                            [% END %]
+                        </span><br/>
+                        [% END %]
+                    </div>
+                </div><div class="cell">
+                    <div class="textBackground">
+                        <span>
+                            [% l('D: [_1] ', ctx.user.day_phone) | html %]<br/>
+                            [% l('E: [_1] ', ctx.user.evening_phone) | html %]<br/>
+                            [% l('O: [_1] ', ctx.user.other_phone) | html %]<br/>
+                        </span>
+                        <span>
+                            [% l(
+                                'Card: [_1]',
+                                ctx.user.card.barcode
+                            ) | html %]
+                        </span><br/>
+                        <span>
+                            [% l(
+                                'OPAC: [_1]',
+                                ctx.user.usrname
+                            ) | html %]
+                        </span><br/>
+                    </div>
+                </div><div class="cell">
+                    <div class="textBackground">
+                        <span>[% ctx.user.profile.name | html %]</span><br/>
+                        <span>[% ctx.user.home_ou.shortname | html %]</span><br/>
+                        <span>
+                            [% l(
+                                'Items Overdue: [_1] Total: [_2]',
+                                ctx.checked_out_count.overdue + ctx.checked_out_count.long_overdue,
+                                ctx.checked_out_count.out
+                            ) | html %]
+                        <span><br/>
+                        <span>
+                            [% l(
+                                'Holds Ready: [_1] Total: [_2]',
+                                ctx.holds_count.ready,
+                                ctx.holds_count.total
+                            ) | html %]
+                        </span><br/>
+                        <span>
+                        [% IF ctx.money_open_user_summary %]
+                            [% l(
+                                'Bills: [_1]',
+                                ctx.money_open_user_summary.balance_owed
+                            ) | html %]
+                        [% ELSE %]
+                            [% l(
+                                'Bills: [_1]',
+                                '0.00'
+                            ) | html %]
+                        [% END %]
+                        </span><br/>
+                    </div>
+                </div></div>
+            </div>
+            [% ELSE %]
+            <div>
+                <span style="font-weight: bold; font-size: xx-large">
+                    Error loading user with database id = [% ctx.au_id | html %]
+                </span><br/>
+                <span style="font-weight: bold;">
+                    Description: [% ctx.error.desc | html %]
+                </span><br/>
+                <span>Server Time: [% ctx.error.servertime | html %]</span><br/>
+                <span>Text Code: [% ctx.error.textcode | html %]</span><br/>
+                <span>ILS Event: [% ctx.error.ilsevent | html %]</span><br/>
+                <span>PID: [% ctx.error.pid | html %]</span><br/>
+                <span>Stack Trace: [% ctx.error.stacktrace | html %]</span><br/>
+            </div>
+            [% END %]
+            <div class="common-full-pad" style="float:none"></div>
+        </div>
+    </div>
+[% END %]
diff --git a/Open-ILS/src/templates/opac/css/PatronSummary.css.tt2 b/Open-ILS/src/templates/opac/css/PatronSummary.css.tt2
new file mode 100644 (file)
index 0000000..0ccccdd
--- /dev/null
@@ -0,0 +1,50 @@
+body {
+    font-family: Arial, Helvetica, sans-serif;
+}
+.textBackground {
+}
+.table {
+    display: table;
+    width: 90%;
+}
+.row { display: table-row; }
+.cell {
+    display: table-cell;
+    padding-left: 10px;
+    padding-right: 10px;
+    width: 25%;
+}
+.fLeft {
+    float: left;
+    padding-left: 10px;
+    padding-right: 10px;
+}
+.fRight {
+    float: right;
+    padding-left: 10px;
+    padding-right: 10px;
+}
+.fNone {
+    float: none;
+    padding-left: 10px;
+    padding-right: 10px;
+}
+.alerts {
+    font-weight: bold;
+    overflow: auto;
+}
+.patronNameLarge { font-weight: bold; }
+.patronSummaryDiv { border: solid thick transparent; padding: 10px; }
+.NO_PENALTIES .patronSummaryDiv { border-color: lime; }
+.ONE_PENALTY .patronSummaryDiv { border-color: #66FFFF; }
+.MULTIPLE_PENALTIES .patronSummaryDiv { border-color: #FF6633; }
+.PATRON_HAS_STAFF_ALERT .patronSummaryDiv { border-color: blue; }
+.PATRON_HAS_BILLS .patronSummaryDiv { border-color: #FFC266; }
+.PATRON_HAS_OVERDUES .patronSummaryDiv { border-color: #FFC266; }
+.PATRON_EXCEEDS_CHECKOUT_COUNT .patronSummaryDiv { border-color: #C99DFF; }
+.PATRON_EXCEEDS_OVERDUE_COUNT .patronSummaryDiv { border-color: #C99DFF; }
+.PATRON_EXCEEDS_FINES .patronSummaryDiv { border-color: #C99DFF; }
+.PATRON_HAS_ALERT .patronSummaryDiv { border-color: yellow; }
+.PATRON_INACTIVE .patronSummaryDiv { border-color: #333333; }
+.PATRON_EXPIRED .patronSummaryDiv { border-color: #666666; }
+.PATRON_BARRED .patronSummaryDiv { border-color: #CC3300; }
index fc17229..74c8793 100644 (file)
@@ -646,6 +646,27 @@ OpenILS.data.prototype = {
         this.chain.push(
             function() {
                 var f = gen_fm_retrieval_func(
+                    'cbc',
+                    [
+                        api.FM_CBC_PCRUD_SEARCH.app,
+                        api.FM_CBC_PCRUD_SEARCH.method,
+                        [ obj.session.key, {"active":"t"}, {"order_by":{"cbc":"id"}} ],
+                        false
+                    ]
+                );
+                try {
+                    f();
+                } catch(E) {
+                    var error = 'Error: ' + js2JSON(E);
+                    obj.error.sdump('D_ERROR',error);
+                    throw(E);
+                }
+            }
+        );
+
+        this.chain.push(
+            function() {
+                var f = gen_fm_retrieval_func(
                     'csp',
                     [
                         api.FM_CSP_PCRUD_SEARCH.app,
index d3eb6e2..1ff9b25 100644 (file)
@@ -230,6 +230,7 @@ var api = {
     'FM_BRE_DELETE' : { 'app' : 'open-ils.cat', 'method' : 'open-ils.cat.biblio.record_entry.delete', 'secure' : false },
     'FM_BRE_UNDELETE' : { 'app' : 'open-ils.cat', 'method' : 'open-ils.cat.biblio.record_entry.undelete', 'secure' : false },
     'FM_BRN_FROM_MARCXML' : { 'app' : 'open-ils.search', 'method' : 'open-ils.search.z3950.marcxml_to_brn', 'secure' : false },
+    'FM_CBC_PCRUD_SEARCH' : { 'app' : 'open-ils.pcrud', 'method' : 'open-ils.pcrud.search.cbc.atomic', 'secure' : false },
     'FM_CBS_RETRIEVE_VIA_PCRUD' : { 'app' : 'open-ils.pcrud', 'method' : 'open-ils.pcrud.retrieve.cbs' },
     'FM_CBT_RETRIEVE' : { 'app' : 'open-ils.circ', 'method' : 'open-ils.circ.billing_type.ranged.retrieve.all', 'secure' : false },
     'FM_CCS_RETRIEVE' : { 'app' : 'open-ils.search', 'method' : 'open-ils.search.config.copy_status.retrieve.all', 'secure' : false },
@@ -522,7 +523,10 @@ var urls = {
     'ALT_HOLDS_PRINT' : 'oils://remote/opac/extras/circ/alt_holds_print.html',
     'SERIAL_PRINT_ROUTING_LIST_USERS' : 'oils://remote/eg/serial/print_routing_list_users',
     'XUL_SERIAL_BATCH_RECEIVE': 'oils://remote/xul/server/serial/batch_receive.xul',
-    'EG_TRIGGER_EVENTS' : 'oils://remote/eg/actor/user/event_log'
+    'EG_TRIGGER_EVENTS' : 'oils://remote/eg/actor/user/event_log',
+    'EG_PATRON_SUMMARY' : 'oils://remote/eg/opac/PatronSummary',
+    'EG_PATRON_SEARCH_SUMMARY' : 'oils://remote/eg/opac/PatronSearchSummary',
+    'XUL_SEARCH_PREFS' : 'chrome://open_ils_staff_client/content/main/search_prefs.xul'
 }
 
 if(use_tpac) {
index 55a3682..055eaf5 100644 (file)
@@ -2316,6 +2316,10 @@ commands:
             var id = tab.getAttribute('id');
             return 'id = ' + id + ' semaphore = ' + obj.tab_semaphores[id];
         }
+        content_params.get_idx = function() {
+            var idx = obj.controller.view.tabs.selectedIndex;
+            return idx;
+        }
         content_params.new_tab = function(a,b,c) { return obj.new_tab(a,b,c); };
         content_params.set_tab = function(a,b,c) { return obj.set_tab(a,b,c); };
         content_params.open_external = function(a) { return obj.open_external(a); };
index 9b37385..ce05ddd 100644 (file)
@@ -1308,6 +1308,16 @@ util.list.prototype = {
         this.node.view.selection.selectAll();
     },
 
+    'retrieve_selection_retrieval_data' : function(params) {
+        var obj = this;
+        return util.functional.map_list(
+            obj.retrieve_selection(params),
+            function(el,idx) {
+                return JSON2js( el.getAttribute('retrieve_id') );
+            }
+        );
+    },
+
     'retrieve_selection' : function(params) {
         var obj = this;
         switch(this.node.nodeName) {
index d628861..c5cf940 100644 (file)
@@ -562,16 +562,18 @@ circ.checkin.prototype = {
             var async_checkbox = document.getElementById('async_checkin');
             if (async_checkbox) { async = async_checkbox.getAttribute('checked') == 'true'; }
             var barcode = textbox.value;
-            // Auto-complete the barcode, items only
-            var barcode_object = xulG.get_barcode(window, 'asset', barcode);
             if (async) {
                 textbox.value = ''; textbox.focus();
             }
-            // user_false means the user selected "None of the above", abort before other prompts/errors
-            if(barcode_object == "user_false") return;
-            // Got a barcode without an error? Use it. Otherwise fall through.
-            if(barcode_object && typeof barcode_object.ilsevent == 'undefined')
-                barcode = barcode_object.barcode;
+            if (obj.data.list.cbc.length > 0) { // skip barcode completion lookups if none configured
+                // Auto-complete the barcode, items only
+                var barcode_object = xulG.get_barcode(window, 'asset', barcode);
+                // user_false means the user selected "None of the above", abort before other prompts/errors
+                if(barcode_object == "user_false") return;
+                // Got a barcode without an error? Use it. Otherwise fall through.
+                if(barcode_object && typeof barcode_object.ilsevent == 'undefined')
+                    barcode = barcode_object.barcode;
+            }
             if ( obj.test_barcode(barcode) ) { /* good */ } else { /* bad */ return; }
             var placeholder_item = new acp();
             placeholder_item.barcode( barcode );
index 08455c3..c68e434 100644 (file)
@@ -602,26 +602,32 @@ circ.checkout.prototype = {
         if (! (params.barcode||params.noncat)) { return; }
 
         if (params.barcode) {
-            // Default is "just items"
-            var barcode_context = 'asset';
-            // Add actor (can be any string that includes 'actor') if looking up patrons at checkout
-            if(String( obj.data.hash.aous['circ.staff_client.actor_on_checkout'] ) == 'true')
-                barcode_context += '-actor';
-            // Auto-complete the barcode
-            var in_barcode = xulG.get_barcode(window, barcode_context, params.barcode);
-            // user_false is "None of the above selected", don't error out/fall through as they already said no
-            if(in_barcode == "user_false") return;
-            // We have a barcode and there was no error?
-            if(in_barcode && typeof in_barcode.ilsevent == 'undefined') {
-                // Check if it was an actor barcode (will never happen unless actor was added above)
-                if(in_barcode.type == 'actor') {
-                    // Go to new patron (do not pass go, do not collect $200, do not prompt user)
-                    var horizontal_interface = String( obj.data.hash.aous['ui.circ.patron_summary.horizontal'] ) == 'true';
-                    var loc = xulG.url_prefix( horizontal_interface ? 'XUL_PATRON_HORIZ_DISPLAY' : 'XUL_PATRON_DISPLAY' );
-                    xulG.set_tab( loc, {}, { 'barcode' : in_barcode.barcode } );
-                    return;
+            var actor_on_checkout = String(
+                obj.data.hash.aous['circ.staff_client.actor_on_checkout']
+            ) == 'true';
+            // skip barcode completion lookups if we can
+            if (actor_on_checkout || obj.data.list.cbc.length > 0) {
+                // Default is "just items"
+                var barcode_context = 'asset';
+                // Add actor (can be any string that includes 'actor') if looking up patrons at checkout
+                if(actor_on_checkout)
+                    barcode_context += '-actor';
+                // Auto-complete the barcode
+                var in_barcode = xulG.get_barcode(window, barcode_context, params.barcode);
+                // user_false is "None of the above selected", don't error out/fall through as they already said no
+                if(in_barcode == "user_false") return;
+                // We have a barcode and there was no error?
+                if(in_barcode && typeof in_barcode.ilsevent == 'undefined') {
+                    // Check if it was an actor barcode (will never happen unless actor was added above)
+                    if(in_barcode.type == 'actor') {
+                        // Go to new patron (do not pass go, do not collect $200, do not prompt user)
+                        var horizontal_interface = String( obj.data.hash.aous['ui.circ.patron_summary.horizontal'] ) == 'true';
+                        var loc = xulG.url_prefix( horizontal_interface ? 'XUL_PATRON_HORIZ_DISPLAY' : 'XUL_PATRON_DISPLAY' );
+                        xulG.set_tab( loc, {}, { 'barcode' : in_barcode.barcode } );
+                        return;
+                    }
+                    params.barcode = in_barcode.barcode;
                 }
-                params.barcode = in_barcode.barcode;
             }
 
             if ( obj.test_barcode(params.barcode) ) { /* good */ } else { /* bad */ return; }
index f18146b..7f86c14 100644 (file)
@@ -95,6 +95,8 @@
             //cache_me('/xul/server/util/browser.xul','http');
             //cache_me('/xul/server/util/rbrowser.xul','http');
 
+            cache_me('/xul/server//patron/search.js','http');
+            cache_me('/xul/server//patron/patron.js','http');
             //cache_me('/xul/server//patron/display.js','http');  
             //cache_me('/xul/server//patron/holds.js','http');  
             //cache_me('/xul/server//patron/items.js','http'); 
             //cache_me('/xul/server//patron/summary.js','http'); 
             //cache_me('/xul/server//patron/util.js','http'); 
 
-            //cache_me('/xul/server/patron/display.xul','http');  
+            cache_me('/xul/server/patron/display.xul','http');
+            cache_me('/xul/server/patron/display_horiz.xul','http');
             //cache_me('/xul/server/patron/display_overlay.xul','http');  
             //cache_me('/xul/server/patron/holds.xul','http');  
             //cache_me('/xul/server/patron/holds_overlay.xul','http');  
             //cache_me('/xul/server/patron/search_result_overlay.xul','http');  
             //cache_me('/xul/server/patron/summary.xul','http'); 
             //cache_me('/xul/server/patron/summary_overlay.xul','http'); 
-            //cache_me('/xul/server/patron/barcode_entry.xul','http');
+            cache_me('/xul/server/patron/barcode_entry.xul','http');
 
             //cache_me('/xul/server/admin/adminlib.js','http');
             //cache_me('/xul/server/admin/admin.css','http');
deleted file mode 100644 (file)
index bd8f0776c462435906693ae269e0293eb9f4138a..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1,221 +0,0 @@
-<?xml version="1.0"?>
-<!-- Application: Evergreen Staff Client -->
-<!-- Screen: Retrieve Patron By Barcode -->
-
-<!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
-<!-- STYLESHEETS -->
-<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
-<?xml-stylesheet href="/xul/server/skin/global.css" type="text/css"?>
-
-<!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
-<!-- LOCALIZATION -->
-<!DOCTYPE window PUBLIC "" ""[
-    <!--#include virtual="/opac/locale/${locale}/lang.dtd"-->
-]>
-
-<!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
-<!-- OVERLAYS -->
-<?xul-overlay href="/xul/server/OpenILS/util_overlay.xul"?>
-
-<window id="patron_barcode_entry_win" 
-    onload="try { my_init(); font_helper(); persist_helper(); } catch(E) { alert(E); }"
-    xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-
-    <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
-    <!-- BEHAVIOR -->
-        <script type="text/javascript">var myPackageDir = 'open_ils_staff_client'; var IAMXUL = true; var g = {};</script>
-        <scripts id="openils_util_scripts"/>
-
-    <script type="text/javascript" src="/xul/server/main/JSAN.js"/>
-    <script>
-    <![CDATA[
-        function $(id) { return document.getElementById(id); }
-        
-        function my_init() {
-            try {
-            if (typeof JSAN == 'undefined') { throw( $("commonStrings").getString('common.jsan.missing') ); }
-                JSAN.errorLevel = "die"; // none, warn, or die
-                JSAN.addRepository('/xul/server/');
-                JSAN.use('util.error'); g.error = new util.error();
-                g.error.sdump('D_TRACE','my_init() for patron/barcode_entry.xul');
-
-                JSAN.use('OpenILS.data'); g.data = new OpenILS.data(); g.data.init({'via':'stash'});
-
-                var tb = document.getElementById('barcode_tb');
-                tb.addEventListener(
-                    'keypress',
-                    function(ev) {
-                        if (ev.keyCode == 13 || ev.keyCode == 77) {
-                            setTimeout(
-                                function() {
-                                    submit();
-                                }, 0
-                            );
-                        }
-                    },
-                    false
-                );
-                tb.focus();
-    
-                if (typeof window.xulG == 'object' && typeof window.xulG.set_tab_name == 'function') {
-                    if (xul_param('perm_editor')) {
-                        try { window.xulG.set_tab_name($("patronStrings").getString('staff.patron.barcode_entry.user_permission_editor')); } catch(E) { alert(E); }
-                    } else {
-                        try { window.xulG.set_tab_name($("patronStrings").getString('staff.patron.barcode_entry.check_out')); } catch(E) { alert(E); }
-                    }
-                }
-
-                if (xul_param('error')) { 
-                    var error = xul_param('error');
-                    alert(error);
-                }
-
-            } catch(E) {
-                var err_msg = $("commonStrings").getFormattedString('common.exception', ['patron/barcode_entry.xul', E]);
-                try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); }
-                alert(err_msg);
-            }
-        }
-
-        function submit() {
-            var tb;
-            try {
-                JSAN.use('util.sound'); var sound = new util.sound();
-                tb = document.getElementById('barcode_tb');
-                var barcode = tb.value;
-
-                barcode = String( barcode ).replace( /\s+/g, '' );
-
-                if (!barcode) { sound.bad(); add_msg($("patronStrings").getString('staff.patron.barcode_entry.no_barcode')); tb.select(); tb.focus(); return; }
-
-                JSAN.use('util.network'); var net = new util.network();
-
-                tb.disabled = true;
-                document.getElementById('progress').setAttribute('hidden','false');
-                // Auto-complete the barcode, users only. Handily, looks up all we need to know in the process.
-                var barcode_object = xulG.get_barcode(window, 'actor', barcode);
-                document.getElementById('progress').setAttribute('hidden','true');
-                tb.disabled = false; tb.select(); tb.focus(); ;
-                // user_false means the user said "None of the above", so abort without further prompts/actions
-                if(barcode_object == "user_false") return;
-                if(barcode_object == false) {
-                    // Boolean false means the barcode was not found, and the user wasn't prompted.
-                    sound.bad();
-                    add_msg($("patronStrings").getFormattedString('staff.patron.barcode_entry.barcode_not_found', [barcode]));
-                    return;
-                }
-                else if(typeof barcode_object.ilsevent != 'undefined') {
-                    // Getting an ilsevent error otherwise means something, likely permissions issues, went wrong
-                    sound.bad();
-                    add_msg($("patronStrings").getFormattedString('staff.patron.barcode_entry.barcode_retrieval_problem', [barcode, js2JSON(barcode_object)]));
-                    return;
-                }
-
-                if (g.data.user_org_unit_opt_in_enabled) {
-                    var r = net.simple_request('USER_ORG_UNIT_OPT_IN_CHECK',[ ses(), barcode_object.id ]);
-                    if (typeof r.ilsevent != 'undefined') {
-                        throw(r);
-                    } else {
-
-                        if (r == 0) {
-
-                            JSAN.use('patron.util');
-                            var parts;
-                            // Handily, if the user was prompted, we should already have the user's name information returned from autocomplete
-                            // Use it if there, as it saves us a network call.
-                            if(barcode_object.request_data) parts = barcode_object.request_data;
-                            // Otherwise, make the network call
-                            else parts = patron.util.retrieve_name_via_id( ses(), barcode_object.id );
-    
-                            if (0 != g.error.yns_alert(
-                                    $("patronStrings").getFormattedString('staff.patron.barcode_entry.consent_from_patron',
-                                        [parts[0], parts[1] + (parts[2] ? ' ' + parts[2] : ''), g.data.hash.aou[ parts[3] ].name(), g.data.hash.aou[ parts[3] ].shortname()]),
-                                    $("patronStrings").getString('staff.patron.barcode_entry.patron_consent_title'),
-                                    $("patronStrings").getString('staff.patron.barcode_entry.patron_consent_accept'),
-                                    $("patronStrings").getString('staff.patron.barcode_entry.patron_consent_deny'), null,
-                                    $("patronStrings").getString('staff.patron.barcode_entry.patron_consent_confirm')
-                                )
-                            ) {
-                                tb.select(); tb.focus();
-                                return;
-                            } else {
-                                var c = net.simple_request('USER_ORG_UNIT_OPT_IN_CREATE',[ ses(), barcode_object.id ]);
-                                if (typeof c.ilsevent != 'undefined') throw(r);
-                            }
-                        }
-    
-                        sound.good();
-                        spawn(barcode_object.id, barcode_object.barcode);
-                    }
-                } else {
-                    sound.good();
-                    spawn(barcode_object.id, barcode_object.barcode);
-                }
-            } catch(E) {
-                tb.select(); tb.focus();
-                g.error.standard_unexpected_error_alert('barcode_entry.xul',E);
-            }
-        }
-
-        function add_msg(text) {
-            var x = document.getElementById('status');
-            var d = document.createElement('description');
-            x.appendChild(d);
-            d.appendChild( document.createTextNode( text ) );
-            d.setAttribute('style','color: red');
-        }
-
-        function spawn(id, barcode) {
-            if (xul_param('perm_editor')) { spawn_perm_editor(id); } else { spawn_checkout(barcode); }
-        }
-
-        function spawn_checkout(barcode) {
-            try {
-                var horizontal_interface = String( g.data.hash.aous['ui.circ.patron_summary.horizontal'] ) == 'true';
-                var loc = xulG.url_prefix( horizontal_interface ? 'XUL_PATRON_HORIZ_DISPLAY' : 'XUL_PATRON_DISPLAY' );
-                if (typeof window.xulG == 'object' && typeof window.xulG.set_tab == 'function') {
-                    window.xulG.set_tab( loc, {}, { 'barcode' : barcode } );
-                } else {
-                    location.href = loc + '?barcode=' + window.escape(barcode);
-                }
-            } catch(E) {
-                g.error.standard_unexpected_error_alert($("patronStrings").getString('staff.patron.barcode_entry.patron_display_error'),E);
-            }
-        }
-
-        function spawn_perm_editor(id) {
-            try {
-                var loc = urls.XUL_USER_PERM_EDITOR + '?ses=' + window.escape(ses()) + '&usr=' + id;
-                if (typeof window.xulG == 'object' && typeof window.xulG.set_tab == 'function') {
-                    window.xulG.set_tab( loc, {}, {} );
-                } else {
-                    location.href = loc;
-                }
-            } catch(E) {
-                g.error.standard_unexpected_error_alert($("patronStrings").getString('staff.patron.barcode_entry.user_perm_display_error'),E);
-            }
-        }
-
-
-        function default_focus() { try { setTimeout( function() { document.getElementById('barcode_tb').focus(); }, 0); } catch(E) {} }
-    ]]>
-    </script>
-    
-    <messagecatalog id="patronStrings" src="/xul/server/locale/<!--#echo var='locale'-->/patron.properties" />
-
-    <vbox flex="1" class="my_overflow">
-        <groupbox orient="vertical" flex="1">
-            <caption label="&staff.pat.barcode_entry.retrieve_patron.label;" />
-            <hbox>
-                <label value="&staff.pat.barcode_entry.barcode.label;" accesskey="&staff.pat.barcode_entry.barcode.accesskey;" control="barcode_tb"/>
-                <textbox id="barcode_tb"  context="clipboard"/>
-                <button label="&staff.pat.barcode_entry.submit_btn.label;" accesskey="&staff.pat.barcode_entry.submit_btn.accesskey;" oncommand="submit();"/>
-            </hbox>
-            <label value="&staff.pat.barcode_entry.retrieving.label;" style="color: green" id="progress" hidden="true"/>
-            <vbox id="status">
-            </vbox>
-        </groupbox>
-    </vbox>
-
-</window>
-
new file mode 120000 (symlink)
index 0000000000000000000000000000000000000000..993bbd93dcd54ff855e4c9c173580f223da2d724
--- /dev/null
@@ -0,0 +1 @@
+display.xul
\ No newline at end of file
index 6c0b7de..4e06764 100644 (file)
@@ -139,6 +139,7 @@ function event_listeners() {
         $('bill_patron_btn').addEventListener(
             'command',
             function() {
+                $('bill_patron_btn').disabled = true;
                 JSAN.use('util.window'); var win = new util.window();
                 var my_xulG = win.open(
                     urls.XUL_PATRON_BILL_WIZARD,
@@ -147,6 +148,7 @@ function event_listeners() {
                     { 'patron_id' : g.patron_id }
                 );
                 if (my_xulG.xact_id) { g.funcs.push( gen_list_append_func( my_xulG.xact_id ) ); /* FIXME: do something to update summary sidebar */ }
+                $('bill_patron_btn').disabled = false;
             },
             false
         );
diff --git a/Open-ILS/xul/staff_client/server/patron/display.js b/Open-ILS/xul/staff_client/server/patron/display.js
deleted file mode 100644 (file)
index 7e2a547..0000000
+++ /dev/null
@@ -1,1047 +0,0 @@
-dump('entering patron/display.js\n');
-dojo.require("openils.User");
-dojo.require("openils.XUL");
-
-function $(id) { return document.getElementById(id); }
-
-if (typeof patron == 'undefined') patron = {};
-patron.display = function (params) {
-
-    JSAN.use('util.error'); this.error = new util.error();
-    JSAN.use('util.window'); this.window = new util.window();
-    JSAN.use('util.network'); this.network = new util.network();
-    JSAN.use('util.widgets'); 
-    this.w = window;
-}
-
-patron.display.prototype = {
-
-    'retrieve_ids' : [],
-    'stop_checkouts' : false,
-    'check_stop_checkouts' : function() { return this.stop_checkouts; },
-
-    'init' : function( params ) {
-
-        var obj = this;
-
-        obj.barcode = params['barcode'];
-        obj.id = params['id'];
-
-        JSAN.use('OpenILS.data'); this.OpenILS = {}; 
-        obj.OpenILS.data = new OpenILS.data(); obj.OpenILS.data.init({'via':'stash'});
-        
-        //var horizontal_interface = String( obj.OpenILS.data.hash.aous['ui.circ.patron_summary.horizontal'] ) == 'true';
-        //document.getElementById('ui.circ.patron_summary.horizontal').setAttribute('orient', horizontal_interface ? 'vertical' : 'horizontal');
-        //document.getElementById('pdms1').setAttribute('orient', horizontal_interface ? 'vertical' : 'horizontal');
-        
-        JSAN.use('util.deck'); 
-        obj.right_deck = new util.deck('patron_right_deck');
-        obj.left_deck = new util.deck('patron_left_deck');
-
-        JSAN.use('util.controller'); obj.controller = new util.controller();
-        obj.controller.init(
-            {
-                control_map : {
-                    'cmd_broken' : [
-                        ['command'],
-                        function() { alert($("commonStrings").getString('common.unimplemented')); }
-                    ],
-                    'cmd_patron_retrieve' : [
-                        ['command'],
-                        function(ev) {
-                            if (typeof window.xulG == 'object' && typeof window.xulG.new_tab == 'function') {
-                                for (var i = 0; i < obj.retrieve_ids.length; i++) {    
-                                    try {
-                                        window.xulG.new_patron_tab(
-                                            {}, { 'id' : obj.retrieve_ids[i] }
-                                        );
-                                    } catch(E) {
-                                        alert(E);
-                                    }
-                                }
-                            }
-                        }
-                    ],
-                    'cmd_patron_merge' : [
-                        ['command'],
-                        function(ev) {
-                            JSAN.use('patron.util');
-                            if (patron.util.merge( obj.retrieve_ids )) {
-                                obj.controller.view.cmd_patron_retrieve.setAttribute('disabled','true');
-                                obj.controller.view.cmd_patron_merge.setAttribute('disabled','true');
-                                var sobj = obj.search_result.g.search_result;
-                                if ( sobj.query ) { sobj.search( sobj.query ); }
-                            }
-                        }
-                    ],
-                    'cmd_patron_toggle_summary' : [
-                        ['command'],
-                        function(ev) {
-                            document.getElementById('splitter_grippy').doCommand();
-                        }
-                    ],
-                    'cmd_patron_delete' : [
-                        ['command'],
-                        function(ev) {
-                            try {
-                                if (get_bool( obj.patron.super_user() )) {
-                                    alert($("patronStrings").getString('staff.patron.display.cmd_patron_delete.deny_deletion_of_super_user'));
-                                    return;
-                                }
-                                if (obj.patron.id() == obj.OpenILS.data.list.au[0].id()) {
-                                    alert($("patronStrings").getString('staff.patron.display.cmd_patron_delete.deny_deletion_of_self'));
-                                    return;
-                                }
-                                var rv = obj.error.yns_alert_original(
-                                    $("patronStrings").getString('staff.patron.display.cmd_patron_delete.dialog.message'),
-                                    $("patronStrings").getString('staff.patron.display.cmd_patron_delete.dialog.title'),
-                                    $("patronStrings").getString('staff.patron.display.cmd_patron_delete.dialog.okay'),
-                                    $("patronStrings").getString('staff.patron.display.cmd_patron_delete.dialog.cancel'),
-                                    null,
-                                    $("patronStrings").getString('staff.patron.display.cmd_patron_delete.dialog.confirmation')
-                                );
-                                //alert('rv = ' + rv + ' (' + typeof rv + ')');
-                                if (rv == 0) {
-                                    var params = [ ses(), obj.patron.id() ];
-                                    var staff_check = obj.network.simple_request('PERM_RETRIEVE_WORK_OU',[ ses(), 'STAFF_LOGIN', obj.patron.id() ]);
-                                    if (staff_check.length > 0) {
-                                        var dest_barcode = window.prompt(
-                                            $("patronStrings").getString('staff.patron.display.cmd_patron_delete.dest_user.prompt'),
-                                            $("patronStrings").getString('staff.patron.display.cmd_patron_delete.dest_user.default_value'),
-                                            $("patronStrings").getString('staff.patron.display.cmd_patron_delete.dest_user.title')
-                                        );
-                                        if (!dest_barcode) return;
-                                        JSAN.use('patron.util');
-                                        var dest_usr = patron.util.retrieve_fleshed_au_via_barcode( ses(), dest_barcode );
-                                        if (typeof dest_usr.ilsevent != 'undefined') {
-                                            alert( $("patronStrings").getString('staff.patron.display.cmd_patron_delete.dest_user.failure') );
-                                            return;
-                                        }
-                                        if (dest_usr.id() == obj.patron.id()) {
-                                            alert( $("patronStrings").getString('staff.patron.display.cmd_patron_delete.dest_user.self_reference_failure') );
-                                            return;
-                                        }
-                                        params.push( dest_usr.id() );
-                                    }
-                                    var robj = obj.network.simple_request(
-                                        'FM_AU_DELETE',
-                                        params,
-                                        null,
-                                        {
-                                            'title' : document.getElementById('patronStrings').getString('staff.patron.display.cmd_patron_delete.override_prompt'),
-                                            'overridable_events' : [
-                                                2004 /* ACTOR_USER_DELETE_OPEN_XACTS */
-                                            ]
-                                        }
-                                    );
-                                    if (typeof robj.ilsevent != 'undefined') {
-                                        switch(Number(robj.ilsevent)) {
-                                            /* already informed via override prompt */
-                                            case 2004 /* ACTOR_USER_DELETE_OPEN_XACTS */ :
-                                                return;
-                                            break;
-                                        }
-                                    }
-                                    obj.refresh_all();
-                                }
-                            } catch(E) {
-                                obj.error.standard_unexpected_error_alert('Error in server/patron/display.js -> cmd_patron_delete: ',E);
-                            }
-                        }
-                    ],
-                    'cmd_search_form' : [
-                        ['command'],
-                        function(ev) {
-                            obj.controller.view.cmd_search_form.setAttribute('disabled','true');
-                            obj.left_deck.node.selectedIndex = 0;
-                            obj.controller.view.patron_name.setAttribute('value', $("patronStrings").getString('staff.patron.display.cmd_search_form.no_patron'));
-                            obj.controller.view.patron_name.setAttribute('tooltiptext', '');
-                            obj.controller.view.patron_name.setAttribute('onclick', '');
-                            removeCSSClass(document.documentElement,'PATRON_HAS_BILLS');
-                            removeCSSClass(document.documentElement,'PATRON_HAS_OVERDUES');
-                            removeCSSClass(document.documentElement,'PATRON_HAS_NOTES');
-                            removeCSSClass(document.documentElement,'PATRON_EXCEEDS_CHECKOUT_COUNT');
-                            removeCSSClass(document.documentElement,'PATRON_EXCEEDS_OVERDUE_COUNT');
-                            removeCSSClass(document.documentElement,'PATRON_EXCEEDS_FINES');
-                            removeCSSClass(document.documentElement,'NO_PENALTIES');
-                            removeCSSClass(document.documentElement,'ONE_PENALTY');
-                            removeCSSClass(document.documentElement,'MULTIPLE_PENALTIES');
-                            removeCSSClass(document.documentElement,'PATRON_HAS_ALERT');
-                            removeCSSClass(document.documentElement,'PATRON_BARRED');
-                            removeCSSClass(document.documentElement,'PATRON_INACTIVE');
-                            removeCSSClass(document.documentElement,'PATRON_EXPIRED');
-                            removeCSSClass(document.documentElement,'PATRON_HAS_INVALID_DOB');
-                            removeCSSClass(document.documentElement,'PATRON_JUVENILE');
-                            removeCSSClass(document.documentElement,'PATRON_HAS_INVALID_ADDRESS');
-                            removeCSSClass(document.documentElement,'PATRON_AGE_GE_65');
-                            removeCSSClass(document.documentElement,'PATRON_AGE_LT_65');
-                            removeCSSClass(document.documentElement,'PATRON_AGE_GE_24');
-                            removeCSSClass(document.documentElement,'PATRON_AGE_LT_24');
-                            removeCSSClass(document.documentElement,'PATRON_AGE_GE_21');
-                            removeCSSClass(document.documentElement,'PATRON_AGE_LT_21');
-                            removeCSSClass(document.documentElement,'PATRON_AGE_GE_18');
-                            removeCSSClass(document.documentElement,'PATRON_AGE_LT_18');
-                            removeCSSClass(document.documentElement,'PATRON_AGE_GE_13');
-                            removeCSSClass(document.documentElement,'PATRON_AGE_LT_13');
-                            removeCSSClass(document.documentElement,'PATRON_NET_ACCESS_1');
-                            removeCSSClass(document.documentElement,'PATRON_NET_ACCESS_2');
-                            removeCSSClass(document.documentElement,'PATRON_NET_ACCESS_3');
-                        }
-                    ],
-                    'cmd_patron_refresh' : [
-                        ['command'],
-                        function(ev) {
-                            try { document.getElementById("PatronNavBarScrollbox").ensureElementIsVisible( document.getElementById("PatronNavBar_refresh" ) ); } catch(E) {};
-                            obj.refresh_all();
-                        }
-                    ],
-                    'cmd_patron_checkout' : [
-                        ['command'],
-                        function(ev) {
-                            obj.reset_nav_styling('cmd_patron_checkout');
-                            obj.spawn_checkout_interface();
-                        }
-                    ],
-                    'cmd_patron_items' : [
-                        ['command'],
-                        function(ev) {
-                            try { document.getElementById("PatronNavBarScrollbox").ensureElementIsVisible( document.getElementById("PatronNavBar_items" ) ); } catch(E) {};
-                            obj.reset_nav_styling('cmd_patron_items');
-                            var frame = obj.right_deck.set_iframe(
-                                urls.XUL_PATRON_ITEMS,
-                                //+ '?patron_id=' + window.escape( obj.patron.id() ),
-                                {},
-                                {
-                                    'patron_id' : obj.patron.id(),
-                                    'on_list_change' : function(b) {
-                                        obj.summary_window.g.summary.controller.render('patron_checkouts');
-                                        obj.summary_window.g.summary.controller.render('patron_standing_penalties');
-                                        obj.summary_window.g.summary.controller.render('patron_bill');
-                                        obj.bill_window.g.bills.refresh(true);
-                                    },
-                                    'url_prefix' : function(url,secure) { return xulG.url_prefix(url,secure); },
-                                    'get_new_session' : function(a) { return xulG.get_new_session(a); },
-                                    'new_tab' : function(a,b,c) { return xulG.new_tab(a,b,c); },
-                                    'new_patron_tab' : function(a,b) { return xulG.new_patron_tab(a,b); }
-                                }
-                            );
-                            obj.items_window = get_contentWindow(frame);
-                        }
-                    ],
-                    'cmd_patron_edit' : [
-                        ['command'],
-                        function(ev) {
-                                try { document.getElementById("PatronNavBarScrollbox").ensureElementIsVisible( document.getElementById("PatronNavBar_edit" ) ); } catch(E) {};
-                                obj.reset_nav_styling('cmd_patron_edit');
-
-                                function spawn_search(s) {
-                                    obj.error.sdump('D_TRACE', 'Editor would like to search for: ' + js2JSON(s)); 
-                                    obj.OpenILS.data.stash_retrieve();
-                                    xulG.new_patron_tab( {}, { 'doit' : 1, 'query' : js2JSON(s) } );
-                                }
-
-                                function spawn_editor(p) {
-                                    var url = urls.XUL_PATRON_EDIT;
-                                    //var param_count = 0;
-                                    //for (var i in p) {
-                                    //    if (param_count++ == 0) url += '?'; else url += '&';
-                                    //    url += i + '=' + window.escape(p[i]);
-                                    //}
-                                    var loc = xulG.url_prefix('XUL_REMOTE_BROWSER'); // + '?url=' + window.escape( url );
-                                    xulG.new_tab(
-                                        loc, 
-                                        {}, 
-                                        { 
-                                            'url' : url,
-                                            'show_print_button' : true , 
-                                            'tab_name' : $("patronStrings").getString('staff.patron.display.spawn_editor.editing_related_patron'),
-                                            'passthru_content_params' : {
-                                                'spawn_search' : spawn_search,
-                                                'spawn_editor' : spawn_editor,
-                                                'url_prefix' : function(url,secure) { return xulG.url_prefix(url,secure); },
-                                                'get_new_session' : function(a) { return xulG.get_new_session(a); },
-                                                'new_tab' : function(a,b,c) { return xulG.new_tab(a,b,c); },
-                                                'new_patron_tab' : function(a,b) { return xulG.new_patron_tab(a,b); },
-                                                'params' : p,
-                                                'on_save' : function(p_obj) {
-                                                    JSAN.use('patron.util');
-                                                    patron.util.work_log_patron_edit(p_obj);
-                                                }
-                                            },
-                                            'lock_tab' : function() { return xulG.lock_tab(); },
-                                            'unlock_tab' : function() { return xulG.unlock_tab(); }
-                                        }
-                                    );
-                                }
-
-                            obj.right_deck.set_iframe(
-                                urls.XUL_REMOTE_BROWSER + '?patron_edit=1',
-                                //+ '?url=' + window.escape( 
-                                //    urls.XUL_PATRON_EDIT
-                                //    + '?ses=' + window.escape( ses() )
-                                //    + '&usr=' + window.escape( obj.patron.id() )
-                                //),
-                                {}, {
-                                    'url' : urls.XUL_PATRON_EDIT,
-                                    'show_print_button' : true,
-                                    'passthru_content_params' : {
-                                        'params' : {
-                                            'ses' : ses(),
-                                            'usr' : obj.patron.id()
-                                        },
-                                        'on_save' : function(p) {
-                                            try {
-                                                JSAN.use('patron.util'); 
-                                                patron.util.work_log_patron_edit(p);
-                                                if (obj.barcode) obj.barcode = p.card().barcode();
-                                                //obj.summary_window.g.summary.retrieve();
-                                                obj.refresh_all();
-                                            } catch(E) {
-                                                alert(E);
-                                            }
-                                        },
-                                        'spawn_search' : spawn_search,
-                                        'spawn_editor' : spawn_editor,
-                                        'url_prefix' : function(url,secure) { return xulG.url_prefix(url,secure); },
-                                        'get_new_session' : function(a) { return xulG.get_new_session(a); },
-                                        'new_tab' : function(a,b,c) { return xulG.new_tab(a,b,c); },
-                                        'new_patron_tab' : function(a,b) { return xulG.new_patron_tab(a,b); }
-                                    },
-                                    'lock_tab' : function() { return xulG.lock_tab(); },
-                                    'unlock_tab' : function() { return xulG.unlock_tab(); }
-                                }
-                            );
-                        }
-                    ],
-                    'cmd_patron_other' : [
-                        ['command'],
-                        function(ev) {
-                            try { document.getElementById("PatronNavBarScrollbox").ensureElementIsVisible( document.getElementById("PatronNavBar_other" ) ); } catch(E) {};
-                            obj.reset_nav_styling('cmd_patron_other');
-                            try { document.getElementById('PatronNavBar_other').firstChild.showPopup(); } catch(E) {};
-                        }
-                    ],
-                    'cmd_patron_info_notes' : [
-                        ['command'],
-                        function(ev) {
-                            obj.right_deck.set_iframe(
-                                urls.XUL_PATRON_INFO_NOTES,
-                                {},
-                                {
-                                    'patron_id' : obj.patron.id(),
-                                    'url_prefix' : function(url,secure) { return xulG.url_prefix(url,secure); },
-                                    'get_new_session' : function(a) { return xulG.get_new_session(a); },
-                                    'new_tab' : function(a,b,c) { return xulG.new_tab(a,b,c); },
-                                    'new_patron_tab' : function(a,b) { return xulG.new_patron_tab(a,b); }
-                                }
-                            );
-                        }
-                    ],
-                    'cmd_patron_info_triggered_events' : [
-                        ['command'],
-                        function(ev) {
-                            obj.right_deck.set_iframe(
-                                xulG.url_prefix(urls.XUL_REMOTE_BROWSER),
-                                {},
-                                {
-                                    'url': urls.EG_TRIGGER_EVENTS + "?patron_id=" + obj.patron.id(),
-                                    'show_print_button': false,
-                                    'show_nav_buttons': false
-                                }
-                            );
-                        }
-                    ],
-                    'cmd_patron_info_stats' : [
-                        ['command'],
-                        function(ev) {
-                            obj.right_deck.set_iframe(
-                                urls.XUL_PATRON_INFO_STAT_CATS,
-                                {},
-                                {
-                                    'patron_id' : obj.patron.id(),
-                                    'url_prefix' : function(url,secure) { return xulG.url_prefix(url,secure); },
-                                    'get_new_session' : function(a) { return xulG.get_new_session(a); },
-                                    'new_tab' : function(a,b,c) { return xulG.new_tab(a,b,c); },
-                                    'new_patron_tab' : function(a,b) { return xulG.new_patron_tab(a,b); }
-                                }
-                            );
-                        }
-                    ],
-                    'cmd_patron_info_surveys' : [
-                        ['command'],
-                        function(ev) {
-                            obj.right_deck.set_iframe(
-                                urls.XUL_PATRON_INFO_SURVEYS,
-                                {},
-                                {
-                                    'patron_id' : obj.patron.id(),
-                                    'url_prefix' : function(url,secure) { return xulG.url_prefix(url,secure); },
-                                    'get_new_session' : function(a) { return xulG.get_new_session(a); },
-                                    'new_tab' : function(a,b,c) { return xulG.new_tab(a,b,c); },
-                                    'new_patron_tab' : function(a,b) { return xulG.new_patron_tab(a,b); }
-                                }
-                            );
-                        }
-                    ],
-                    'cmd_patron_info_acq_requests' : [
-                        ['command'],
-                        function(ev) {
-                            obj.right_deck.set_iframe(
-                                urls.EG_ACQ_USER_REQUESTS + '?usr=' + obj.patron.id(),
-                                {},
-                                {
-                                    'get_barcode' : function(a,b,c) { return xulG.get_barcode(a,b,c); },
-                                    'get_barcode_and_settings' : function(a,b,c) { return xulG.get_barcode_and_settings(a,b,c); }
-                                }
-                            );
-                        }
-                    ],
-
-                    'cmd_patron_info_groups' : [
-                        ['command'],
-                        function(ev) {
-                            obj.spawn_group_interface();
-                        }
-                    ],
-                    'cmd_patron_alert' : [
-                        ['command'],
-                        function(ev) {
-                            if (obj.msg_url) {
-                                obj.right_deck.set_iframe('data:text/html,'+obj.msg_url,{},{});
-                            } else {
-                                obj.right_deck.set_iframe('data:text/html,<h1>' + $("patronStrings").getString('staff.patron.display.no_alerts_or_messages') + '</h1>',{},{});
-                            }
-                        }
-                    ],
-                    'cmd_patron_reservation' : [
-                        ['command'],
-                        function(ev) {
-                            openils.XUL.newTabEasy(
-                                "BOOKING_RESERVATION",
-                                $("offlineStrings").getString(
-                                    "menu.cmd_booking_reservation.tab"
-                                ), {
-                                    "bresv_interface_opts": {
-                                        "patron_barcode":
-                                            obj.patron.card().barcode()
-                                    }
-                                },
-                                true
-                            );
-                        }
-                    ],
-                    'cmd_patron_reservation_pickup' : [
-                        ['command'],
-                        function(ev) {
-                            openils.XUL.newTabEasy(
-                                "BOOKING_PICKUP",
-                                $("offlineStrings").getString(
-                                    "menu.cmd_booking_reservation_pickup.tab"
-                                ), {
-                                    "bresv_interface_opts": {
-                                        "patron_barcode":
-                                            obj.patron.card().barcode()
-                                    }
-                                },
-                                true
-                            );
-                        }
-                    ],
-                    'cmd_patron_reservation_return' : [
-                        ['command'],
-                        function(ev) {
-                            openils.XUL.newTabEasy(
-                                "BOOKING_RETURN",
-                                $("offlineStrings").getString(
-                                    "menu.cmd_booking_reservation_return.tab"
-                                ), {
-                                    "bresv_interface_opts": {
-                                        "patron_barcode":
-                                            obj.patron.card().barcode()
-                                    }
-                                },
-                                true
-                            );
-                        }
-                    ],
-                    'cmd_patron_exit' : [
-                        ['command'],
-                        function(ev) {
-                            xulG.set_tab(urls.XUL_PATRON_BARCODE_ENTRY,{},{});
-                        }
-                    ],
-                    'cmd_patron_holds' : [
-                        ['command'],
-                        function(ev) {
-                            try {
-                                try { document.getElementById("PatronNavBarScrollbox").ensureElementIsVisible( document.getElementById("PatronNavBar_holds" ) ); } catch(E) {};
-                                obj.reset_nav_styling('cmd_patron_holds');
-                                obj.right_deck.set_iframe(
-                                    urls.XUL_PATRON_HOLDS,    
-                                    //+ '?patron_id=' + window.escape( obj.patron.id() ),
-                                    {},
-                                    {
-                                        'display_window' : window,
-                                        'patron_id' : obj.patron.id(),
-                                        'patron_barcode' : obj.patron.card().barcode(),
-                                        'on_list_change' : function(h) {
-                                            try {
-                                                obj.summary_window.g.summary.controller.render('patron_holds');
-                                            } catch(E) {
-                                                alert(E);
-                                            }
-                                        },
-                                        'url_prefix' : function(url,secure) { return xulG.url_prefix(url,secure); },
-                                        'get_new_session' : function(a) { return xulG.get_new_session(a); },
-                                        'new_tab' : function(a,b,c) { return xulG.new_tab(a,b,c); },
-                                        'new_patron_tab' : function(a,b) { return xulG.new_patron_tab(a,b); },
-                                        'get_barcode' : function(a,b,c) { return xulG.get_barcode(a,b,c); },
-                                        'get_barcode_and_settings' : function(a,b,c) { return xulG.get_barcode_and_settings(a,b,c); }
-                                    }
-                                );
-                            } catch(E) {
-                                alert(E);
-                            }
-                        }
-                    ],
-                    'cmd_patron_bills' : [
-                        ['command'],
-                        function(ev) {
-                            try { document.getElementById("PatronNavBarScrollbox").ensureElementIsVisible( document.getElementById("PatronNavBar_bills" ) ); } catch(E) {};
-                            obj.reset_nav_styling('cmd_patron_bills');
-                            var f = obj.right_deck.set_iframe(
-                                urls.XUL_PATRON_BILLS,
-                                //+ '?patron_id=' + window.escape( obj.patron.id() ),
-                                {},
-                                {
-                                    'display_window' : window,
-                                    'patron_id' : obj.patron.id(),
-                                    'url_prefix' : function(url,secure) { return xulG.url_prefix(url,secure); },
-                                    'get_new_session' : function(a) { return xulG.get_new_session(a); },
-                                    'new_tab' : function(a,b,c) { return xulG.new_tab(a,b,c); },
-                                    'on_money_change' : function(b) {
-                                        obj.summary_window.refresh();
-                                    }
-                                }
-                            );
-                            obj.bill_window = get_contentWindow(f);
-                        }
-                    ],
-                    'patron_name' : [
-                        ['render'],
-                        function(e) {
-                            return function() { 
-                                JSAN.use('patron.util'); 
-                                e.setAttribute('value',
-                                    patron.util.format_name( obj.patron )
-                                );
-                                patron.util.set_penalty_css(obj.patron);
-                                var tooltiptext = $("patronStrings").getFormattedString(
-                                    'staff.patron.display.db_data',
-                                    [
-                                        obj.patron.id(),
-                                        obj.patron.create_date(),
-                                        obj.patron.last_update_time()
-                                            ? obj.patron.last_update_time()
-                                            : ''
-                                    ]
-                                );
-                                e.setAttribute('tooltiptext',tooltiptext);
-                                e.setAttribute('onclick','try { copy_to_clipboard(event); } catch(E) { alert(E); }');
-                            };
-                        }
-                    ],
-                    'PatronNavBar' : [
-                        ['render'],
-                        function(e) {
-                            return function() {}
-                        }
-                    ],
-                    'cmd_verify_credentials' : [
-                        ['command'],
-                        function() {
-                            var vframe = obj.right_deck.reset_iframe(
-                                urls.XUL_VERIFY_CREDENTIALS,
-                                {},
-                                {
-                                    'barcode' : obj.patron.card().barcode(),
-                                    'usrname' : obj.patron.usrname()
-                                }
-                            );
-                        } 
-                    ],
-                    'cmd_perm_editor' : [
-                        ['command'],
-                        function() {
-                             var frame = obj.right_deck.reset_iframe( urls.XUL_USER_PERM_EDITOR + '?ses=' + window.escape(ses()) + '&usr=' + obj.patron.id(), {}, {});
-                        }
-                    ],
-                    'cmd_standing_penalties' : [
-                        ['command'],
-                        function() {
-                            function penalty_interface() {
-                                try { document.getElementById("PatronNavBarScrollbox").ensureElementIsVisible( document.getElementById("PatronNavBar_messages" ) ); } catch(E) {};
-                                obj.reset_nav_styling('cmd_standing_penalties');
-                                return obj.right_deck.set_iframe(
-                                    urls.XUL_STANDING_PENALTIES,
-                                    {},
-                                    {
-                                        'patron' : obj.patron,
-                                        'refresh' : function() { 
-                                            obj.refresh_all(); 
-                                        }
-                                    }
-                                );
-                            }
-                            penalty_interface();
-                        } 
-                    ]
-                }
-            }
-        );
-
-        var x = document.getElementById("PatronNavBar_checkout");
-        x.addEventListener( 'focus', function(xx) { return function() { try { document.getElementById("PatronNavBarScrollbox").ensureElementIsVisible(xx); } catch(E) {}; } }(x), false);
-        var x = document.getElementById("PatronNavBar_refresh");
-        x.addEventListener( 'focus', function(xx) { return function() { try { document.getElementById("PatronNavBarScrollbox").ensureElementIsVisible(xx); } catch(E) {}; } }(x), false);
-        var x = document.getElementById("PatronNavBar_items");
-        x.addEventListener( 'focus', function(xx) { return function() { try { document.getElementById("PatronNavBarScrollbox").ensureElementIsVisible(xx); } catch(E) {}; } }(x), false);
-        var x = document.getElementById("PatronNavBar_holds");
-        x.addEventListener( 'focus', function(xx) { return function() { try { document.getElementById("PatronNavBarScrollbox").ensureElementIsVisible(xx); } catch(E) {}; } }(x), false);
-        var x = document.getElementById("PatronNavBar_other");
-        x.addEventListener( 'focus', function(xx) { return function() { try { document.getElementById("PatronNavBarScrollbox").ensureElementIsVisible(xx); } catch(E) {}; } }(x), false);
-        var x = document.getElementById("PatronNavBar_edit");
-        x.addEventListener( 'focus', function(xx) { return function() { try { document.getElementById("PatronNavBarScrollbox").ensureElementIsVisible(xx); } catch(E) {}; } }(x), false);
-        var x = document.getElementById("PatronNavBar_bills");
-        x.addEventListener( 'focus', function(xx) { return function() { try { document.getElementById("PatronNavBarScrollbox").ensureElementIsVisible(xx); } catch(E) {}; } }(x), false);
-        var x = document.getElementById("PatronNavBar_messages");
-        x.addEventListener( 'focus', function(xx) { return function() { try { document.getElementById("PatronNavBarScrollbox").ensureElementIsVisible(xx); } catch(E) {}; } }(x), false);
-
-        if (obj.barcode || obj.id) {
-            if (typeof window.xulG == 'object' && typeof window.xulG.set_tab_name == 'function') {
-                try { window.xulG.set_tab_name($("patronStrings").getString('staff.patron.display.init.retrieving_patron')); } catch(E) { alert(E); }
-            }
-
-            obj.controller.view.PatronNavBar.selectedIndex = 1;
-            JSAN.use('util.widgets'); 
-            util.widgets.enable_accesskeys_in_node_and_children(
-                obj.controller.view.PatronNavBar.lastChild
-            );
-            util.widgets.disable_accesskeys_in_node_and_children(
-                obj.controller.view.PatronNavBar.firstChild
-            );
-            obj.controller.view.cmd_patron_refresh.setAttribute('disabled','true');
-            obj.controller.view.cmd_patron_checkout.setAttribute('disabled','true');
-            obj.controller.view.cmd_patron_items.setAttribute('disabled','true');
-            obj.controller.view.cmd_patron_holds.setAttribute('disabled','true');
-            obj.controller.view.cmd_patron_bills.setAttribute('disabled','true');
-            obj.controller.view.cmd_patron_edit.setAttribute('disabled','true');
-            obj.controller.view.patron_name.setAttribute('value', $("patronStrings").getString('staff.patron.display.init.retrieving'));
-            document.documentElement.setAttribute('class','');
-            var frame = obj.left_deck.set_iframe(
-                urls.XUL_PATRON_SUMMARY,
-                {},
-                {
-                    'display_window' : window,
-                    'barcode' : obj.barcode,
-                    'id' : obj.id,
-                    'refresh' : function() { obj.refresh_all(); },
-                    'on_finished' : obj.gen_patron_summary_finish_func(params),
-                    'stop_sign_page' : obj.gen_patron_stop_sign_page_func(),
-                    'spawn_group_interface' : function() { obj.spawn_group_interface(); },
-                    'new_patron_tab' : function(a,b) { return xulG.new_patron_tab(a,b); },
-                    'new_tab' : function(a,b,c) { return xulG.new_tab(a,b,c); },
-                    'set_tab' : function(a,b,c) { return xulG.set_tab(a,b,c); },
-                    'on_error' : function(E) {
-                        try {
-                            var error;
-                            if (typeof E.ilsevent != 'undefined') {
-                                error = E.textcode;
-                            } else {
-                                error = js2JSON(E).substr(0,100);
-                            }
-                            xulG.set_tab(urls.XUL_PATRON_BARCODE_ENTRY + '?error=' + window.escape(error),{},{});
-                        } catch(F) {
-                            alert(F);
-                        }
-                    }
-                }
-            );
-            obj.summary_window = get_contentWindow(frame);
-
-        } else {
-            obj.render_search_form(params);
-        }
-    },
-
-    'reset_nav_styling' : function(btn,dont_hide_summary) {
-        try {
-            if (!dont_hide_summary) { dont_hide_summary = false; }
-            if (this.skip_hide_summary) {
-                this.skip_hide_summary = false;
-                dont_hide_summary = true;
-            }
-            this.controller.view.cmd_patron_checkout.setAttribute('style','');
-            this.controller.view.cmd_patron_items.setAttribute('style','');
-            this.controller.view.cmd_patron_edit.setAttribute('style','');
-            this.controller.view.cmd_patron_other.setAttribute('style','');
-            this.controller.view.cmd_patron_holds.setAttribute('style','');
-            this.controller.view.cmd_patron_bills.setAttribute('style','');
-            this.controller.view.cmd_standing_penalties.setAttribute('style','');
-            this.controller.view[ btn ].setAttribute('style','background: blue; color: white;');
-            var auto_hide_patron_sidebar = String( this.OpenILS.data.hash.aous['circ.auto_hide_patron_summary'] ) == 'true';
-            var x = document.getElementById('splitter_grippy'); 
-            if (x && auto_hide_patron_sidebar && ! dont_hide_summary) {
-                if (! this.summary_hidden_once_already ) {
-                    var first_deck = x.parentNode.previousSibling;
-                    if (! first_deck.collapsed) x.doCommand();
-                    this.summary_hidden_once_already = true;
-                }
-            }
-        } catch(E) {
-            alert(E);
-        }
-    },
-
-    'render_search_form' : function(params) {
-        var obj = this;
-            if (typeof window.xulG == 'object' && typeof window.xulG.set_tab_name == 'function') {
-                try { window.xulG.set_tab_name($("patronStrings").getString('staff.patron.display.render_search_form.patron_search')); } catch(E) { alert(E); }
-            }
-
-            obj.controller.view.PatronNavBar.selectedIndex = 0;
-            obj.controller.view.cmd_patron_retrieve.setAttribute('disabled','true');
-            obj.controller.view.cmd_patron_merge.setAttribute('disabled','true');
-            obj.controller.view.cmd_search_form.setAttribute('disabled','true');
-
-            var horizontal_interface = String( obj.OpenILS.data.hash.aous['ui.circ.patron_summary.horizontal'] ) == 'true';
-            var loc = horizontal_interface ? urls.XUL_PATRON_HORIZONTAL_SEARCH_FORM : urls.XUL_PATRON_SEARCH_FORM; 
-            var my_xulG = {
-                'clear_left_deck' : function() {
-                    setTimeout( function() {
-                        obj.left_deck.clear_all_except(loc);
-                        obj.render_search_form(params);
-                    }, 0);
-                },
-                'on_submit' : function(query,search_limit,search_sort) {
-                    obj.controller.view.cmd_patron_retrieve.setAttribute('disabled','true');
-                    obj.controller.view.cmd_patron_merge.setAttribute('disabled','true');
-                    var list_frame = obj.right_deck.reset_iframe(
-                        urls.XUL_PATRON_SEARCH_RESULT, // + '?' + query,
-                        {},
-                        {
-                            'query' : query,
-                            'search_limit' : search_limit,
-                            'search_sort' : search_sort,
-                            'on_dblclick' : function(list) {
-                                JSAN.use('util.widgets');
-                                util.widgets.dispatch('command','cmd_patron_retrieve')
-                            },
-                            'on_select' : function(list) {
-                                if (!list) return;
-                                if (list.length < 1) return;
-                                obj.controller.view.cmd_patron_retrieve.setAttribute('disabled','false');
-                                if (list.length > 1) obj.controller.view.cmd_patron_merge.setAttribute('disabled','false');
-                                obj.controller.view.cmd_search_form.setAttribute('disabled','false');
-                                obj.retrieve_ids = list;
-                                obj.controller.view.patron_name.setAttribute('value',$("patronStrings").getString('staff.patron.display.init.retrieving'));
-                                document.documentElement.setAttribute('class','');
-                                setTimeout(
-                                    function() {
-                                        var frame = obj.left_deck.set_iframe(
-                                            urls.XUL_PATRON_SUMMARY + '?id=' + window.escape(list[0]),
-                                            {},
-                                            {
-                                                //'id' : list[0],
-                                                'spawn_group_interface' : function() { obj.spawn_group_interface(); },
-                                                'new_patron_tab' : function(a,b) { return xulG.new_patron_tab(a,b); },
-                                                'new_tab' : function(a,b,c) { return xulG.new_tab(a,b,c); },
-                                                'set_tab' : function(a,b,c) { return xulG.set_tab(a,b,c); },
-                                                'on_finished' : function(patron) {
-                                                    obj.patron = patron;
-                                                    obj.controller.render();
-                                                }
-                                            }
-                                        );
-                                        obj.summary_window = get_contentWindow(frame);
-                                        obj.patron = obj.summary_window.g.summary.patron;
-                                        obj.controller.render('patron_name');
-                                    }, 0
-                                );
-                            }
-                        }
-                    );
-                    obj.search_result = get_contentWindow(list_frame);
-                }
-            };
-
-            if (params['query']) {
-                my_xulG.query = JSON2js(params['query']);
-                if (params.doit) my_xulG.doit = 1;
-            }
-
-            var form_frame = obj.left_deck.set_iframe(
-                loc,
-                {},
-                my_xulG
-            );
-            obj.search_window = get_contentWindow(form_frame);
-            obj._already_defaulted_once = true;
-    },
-
-    '_already_defaulted_once' : false,
-
-    'refresh_deck' : function(url) {
-        var obj = this;
-        for (var i = 0; i < obj.right_deck.node.childNodes.length; i++) {
-            try {
-                var f = obj.right_deck.node.childNodes[i];
-                var w = get_contentWindow(f);
-                if (url) {
-                    if (w.location.href == url) w.refresh(true);
-                } else {
-                    if (typeof w.refresh == 'function') {
-                        w.refresh(true);
-                    }
-                }
-
-            } catch(E) {
-                obj.error.sdump('D_ERROR','refresh_deck: ' + E + '\n');
-            }
-        }
-    },
-    
-    'refresh_all' : function() {
-        var obj = this;
-        obj.controller.view.patron_name.setAttribute('value', $("patronStrings").getString('staff.patron.display.init.retrieving'));
-        document.documentElement.setAttribute('class','');
-        obj.network.simple_request(
-            'RECALCULATE_STANDING_PENALTIES',
-            [ ses(), obj.patron.id() ]
-        );
-        try { obj.summary_window.refresh(); } catch(E) { obj.error.sdump('D_ERROR', E + '\n'); }
-        try { obj.refresh_deck(); } catch(E) { obj.error.sdump('D_ERROR', E + '\n'); }
-    },
-
-    'spawn_checkout_interface' : function() {
-        var obj = this;
-        try {
-            try { document.getElementById("PatronNavBarScrollbox").ensureElementIsVisible( document.getElementById("PatronNavBar_checkout" ) ); } catch(E) {};
-            obj.reset_nav_styling('cmd_patron_checkout',true);
-            var frame = obj.right_deck.set_iframe(
-                urls.XUL_CHECKOUT,
-                {},
-                { 
-                    'set_tab' : function(a,b,c) { return xulG.set_tab(a,b,c); },
-                    'patron_id' : obj.patron.id(),
-                    'patron' : obj.patron,
-                    'check_stop_checkouts' : function() { return obj.check_stop_checkouts(); },
-                    'on_list_change_old' : function(checkout) {
-                        var x = obj.summary_window.g.summary.controller.view.patron_checkouts;
-                        var n = Number(x.getAttribute('value'));
-                        x.setAttribute('value',n+1);
-                    },
-                    'on_list_change' : function(checkout,is_renewal) {
-                        // Downside here: an extra network call, open-ils.actor.user.checked_out.count.authoritative
-                        obj.summary_window.g.summary.controller.render('patron_checkouts');
-                        obj.summary_window.g.summary.controller.render('patron_standing_penalties');
-
-                        /* this stops noncats from getting pushed into Items Out */
-                        if (!checkout.circ.id()) return;
-
-                        if (obj.items_window) {
-                            if (is_renewal) {
-                                var original_circ_id = obj.items_window.g.items.list_circ_map_by_copy[ checkout.circ.target_copy() ];
-                                obj.items_window.g.items.list_circ_map[ original_circ_id ].row.my.circ = checkout.circ;
-                                obj.items_window.g.items.list_circ_map[ checkout.circ.id() ] =
-                                    obj.items_window.g.items.list_circ_map[ original_circ_id ];
-                                obj.items_window.g.items.refresh( checkout.circ.id() );
-                            } else {
-                                var nparams = obj.items_window.g.items.list.append(
-                                    {
-                                        'row' : {
-                                            'my' : {
-                                                'circ_id' : checkout.circ.id()
-                                            }
-                                        },
-                                        'to_bottom' : true
-                                    }
-                                )
-                                obj.items_window.g.items.list_circ_map[ checkout.circ.id() ] = nparams;
-                                obj.items_window.g.items.list_circ_map_by_copy[ checkout.circ.target_copy() ] = checkout.circ.id();
-                            }
-                        }
-                    },
-                    'get_barcode' : xulG.get_barcode,
-                    'get_barcode_and_settings' : xulG.get_barcode_and_settings,
-                    'url_prefix' : xulG.url_prefix
-                }
-            );
-            obj.checkout_window = get_contentWindow(frame);
-        } catch(E) {
-            alert('Error in spawn_checkout_interface(): ' + E);
-        }
-    },
-
-    'gen_patron_summary_finish_func' : function(display_params) {
-        var obj = this;
-
-        return function(patron,params) {
-            try {
-                obj.patron = patron; obj.controller.render();
-
-                obj.controller.view.cmd_patron_refresh.setAttribute('disabled','false');
-                obj.controller.view.cmd_patron_checkout.setAttribute('disabled','false');
-                obj.controller.view.cmd_patron_items.setAttribute('disabled','false');
-                obj.controller.view.cmd_patron_holds.setAttribute('disabled','false');
-                obj.controller.view.cmd_patron_bills.setAttribute('disabled','false');
-                obj.controller.view.cmd_patron_edit.setAttribute('disabled','false');
-
-                if (typeof window.xulG == 'object' && typeof window.xulG.set_tab_name == 'function') {
-                    try { 
-                        window.xulG.set_tab_name(
-                            $("patronStrings").getString('staff.patron.display.tab_name')
-                                + ' ' + patron.family_name() + ', ' + patron.first_given_name() + ' ' 
-                                + (patron.second_given_name() ? patron.second_given_name() : '' ) 
-                        ); 
-                    } catch(E) { 
-                        obj.error.sdump('D_ERROR',E);
-                    }
-                }
-
-                if (!obj._already_defaulted_once) {
-                    obj._already_defaulted_once = true;
-                    if (display_params['show']) {
-                        setTimeout(
-                            function() {
-                                switch(display_params['show']) {
-                                    case 'bills' : util.widgets.dispatch('command','cmd_patron_bills'); break;
-                                }
-                            },
-                            0
-                        );
-                    } else {
-                        obj.spawn_checkout_interface();
-                    }
-                }
-
-                if (obj.stop_checkouts && obj.checkout_window) {
-                    setTimeout( function() {
-                        try {
-                            obj.checkout_window.g.checkout.check_disable();
-                        } catch(E) { }
-                    }, 1000);
-                }
-                            
-            } catch(E) {
-                alert('Error in patron_summary_finish_func(): ' + E);
-            }
-        };
-    },
-
-    'gen_patron_stop_sign_page_func' : function() {
-        var obj = this;
-        // FIXME - replace this generated "stop sign" page with a dedicated XUL file or template
-        return function(patron,params) {
-            try {
-                obj._already_defaulted_once = true;
-                var msg = ''; obj.stop_checkouts = false;
-                if (patron.alert_message())
-                    msg += $("patronStrings").getFormattedString('staff.patron.display.init.network_request.alert_message', [patron.alert_message()]);
-                //alert('obj.barcode = ' + obj.barcode);
-                if (obj.barcode) {
-                    if (patron.cards()) for (var i = 0; i < patron.cards().length; i++) {
-                        //alert('card #'+i+' == ' + js2JSON(patron.cards()[i]));
-                        if ( (patron.cards()[i].barcode()==obj.barcode) && ( ! get_bool(patron.cards()[i].active()) ) ) {
-                            msg += $("patronStrings").getString('staff.patron.display.init.network_request.inactive_card');
-                            obj.stop_checkouts = true;
-                        }
-                    }
-                }
-                if (get_bool(patron.barred())) {
-                    msg += $("patronStrings").getString('staff.patron.display.init.network_request.account_barred');
-                    obj.stop_checkouts = true;
-                }
-                if (!get_bool(patron.active())) {
-                    msg += $("patronStrings").getString('staff.patron.display.init.network_request.account_inactive');
-                    obj.stop_checkouts = true;
-                }
-                if (patron.expire_date()) {
-                    var now = new Date();
-                    now = now.getTime()/1000;
-
-                    var expire_parts = patron.expire_date().substr(0,10).split('-');
-                    expire_parts[1] = expire_parts[1] - 1;
-
-                    var expire = new Date();
-                    expire.setFullYear(expire_parts[0], expire_parts[1], expire_parts[2]);
-                    expire = expire.getTime()/1000
-
-                    if (expire < now) {
-                        msg += $("patronStrings").getString('staff.patron.display.init.network_request.account_expired');
-                    obj.stop_checkouts = true;
-                    }
-                }
-                var penalties = patron.standing_penalties();
-                if (!penalties) { penalties = []; }
-                var dl_flag_opened = false;
-                for (var i = 0; i < penalties.length; i++) {
-                    if (get_bool(penalties[i].standing_penalty().staff_alert())) {
-                        if (!dl_flag_opened) {
-                            msg += '<dl>';
-                            dl_flag_opened = true;
-                        }
-                        msg += '<dt>';
-                        msg += obj.OpenILS.data.hash.aou[ penalties[i].org_unit() ].shortname() + ' : ' + penalties[i].standing_penalty().label() + '<br/>';
-                        msg += '</dt><dd>';
-                        msg += (penalties[i].note())?penalties[i].note():'';
-                        msg += '</dd>';
-                    }
-                }
-                if (dl_flag_opened) { msg += '</dl>'; }
-                var holds = params.holds_summary;
-                if (holds.ready && holds.ready > 0) {
-                    msg += $("patronStrings").getFormattedString('staff.patron.display.init.holds_ready', [holds.ready]);
-                }
-                if (msg) {
-                    if (msg != obj.old_msg) {
-                        //obj.error.yns_alert(msg,'Alert Message','OK',null,null,'Check here to confirm this message.');
-                        document.documentElement.firstChild.focus();
-                        var data_url = window.escape("<img src='" + xulG.url_prefix('/xul/server/skin/media/images/stop_sign.png') + "'/>" + '<h1>'
-                            + $("patronStrings").getString('staff.patron.display.init.network_request.window_title') + '</h1><blockquote><p>' + msg + '</p>\r\n\r\n<pre>'
-                            + $("patronStrings").getString('staff.patron.display.init.network_request.window_message') + '</pre></blockquote>');
-                        obj.right_deck.set_iframe('data:text/html,'+data_url,{},{});
-                        obj.old_msg = msg;
-                        obj.msg_url = data_url;
-                    } else {
-                        obj.error.sdump('D_TRACE',$("patronStrings").getFormattedString('staff.patron.display.init.network_request.dump_error_message', [msg]));
-                    }
-                }
-            } catch(E) {
-                alert('Error in patron_stop_sign_page_func(): ' + E);
-            }
-        };
-    },
-
-    'spawn_group_interface' : function() {
-        var obj = this;
-        try {
-            obj.right_deck.set_iframe(
-                urls.XUL_PATRON_INFO_GROUP,
-                {},
-                {
-                    'patron_id' : obj.patron.id(),
-                    'url_prefix' : function(url,secure) { return xulG.url_prefix(url,secure); },
-                    'get_new_session' : function(a) { return xulG.get_new_session(a); },
-                    'new_tab' : function(a,b,c) { return xulG.new_tab(a,b,c); },
-                    'new_patron_tab' : function(a,b) { return xulG.new_patron_tab(a,b); }
-                }
-            );
-        } catch(E) {
-            alert('Error in display.js, spawn_group_interface(): ' + E);
-        }
-    }
-
-}
-
-dump('exiting patron/display.js\n');
index e0861db..95d5e5b 100644 (file)
 <?xml version="1.0"?>
-<!-- Application: Evergreen Staff Client -->
-<!-- Screen: Patron Display -->
-
-<!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
-<!-- STYLESHEETS -->
 <?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
-<?xml-stylesheet href="/xul/server/skin/global.css" type="text/css"?>
-<?xml-stylesheet href="/xul/server/skin/patron_display.css" type="text/css"?>
-
-<!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
-<!-- LOCALIZATION -->
+<?xml-stylesheet href="oils://remote/xul/server/skin/global.css" type="text/css"?>
 <!DOCTYPE window PUBLIC "" ""[
     <!--#include virtual="/opac/locale/${locale}/lang.dtd"-->
 ]>
+<?xul-overlay href="oils://remote/xul/server/OpenILS/util_overlay.xul"?>
 
-<!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
-<!-- OVERLAYS -->
-<?xul-overlay href="/xul/server/OpenILS/util_overlay.xul"?>
-<?xul-overlay href="/xul/server/patron/display_overlay.xul"?>
-
-<window id="patron_display_win" 
-    onload="try { my_init(); font_helper(); persist_helper(); } catch(E) { alert(E); }"
+<window id="search_win"
+    onload="try { persist_helper(); my_init(); font_helper(); } catch(E) { alert(E); }"
     xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
-    <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
-    <!-- BEHAVIOR -->
     <script type="text/javascript">
         var myPackageDir = 'open_ils_staff_client'; var IAMXUL = true; var g = {};
     </script>
     <scripts id="openils_util_scripts"/>
+    <script type="text/javascript" src="chrome://open_ils_staff_client/content/main/JSAN.js"/>
+    <script type="text/javascript" src="oils://remote/xul/server/patron/search.js"/>
+    <script type="text/javascript" src="oils://remote/xul/server/patron/patron.js"/>
 
-    <script type="text/javascript" src="/xul/server/main/JSAN.js"/>
-    <script type="text/javascript" src="/xul/server/patron/display.js"/>
-    <script>
-    <![CDATA[
-        function $(id) { return document.getElementById(id); }
-    
-        function my_init() {
-            try {
-                if (typeof JSAN == 'undefined') { throw( $("commonStrings").getString('common.jsan.missing') ); }
-                JSAN.errorLevel = "die"; // none, warn, or die
-                JSAN.addRepository('/xul/server/');
-                JSAN.use('util.error'); g.error = new util.error();
-                g.error.sdump('D_TRACE','my_init() for patron_display.xul');
-
-                JSAN.use('patron.display'); g.patron = new patron.display();
-                g.patron.init( { 
-                    'barcode' : xul_param('barcode'),
-                    'id' : xul_param('id'),
-                    'query' : xul_param('query'),
-                    'doit' : xul_param('doit'),
-                    'show' : xul_param('show')
-                } );
-
-            //document.documentElement.style.setProperty('font-size-adjust','1','important');
-
-            } catch(E) {
-                var err_msg = $("commonStrings").getFormattedString('common.exception', ['patron/display.xul', E]);
-                try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); }
-                alert(err_msg);
-            }
-        }
-
-        function default_focus() {
-            setTimeout(
-                function() {
-                    try {
-                        var node = g.patron.right_deck.node.selectedPanel;
-                        if (node && get_contentWindow(node) && typeof get_contentWindow(node).default_focus == 'function') {
-                            get_contentWindow(node).default_focus();
-                        } else {
-                            var node = g.patron.left_deck.node.selectedPanel;
-                            if (node && get_contentWindow(node) && typeof get_contentWindow(node).default_focus == 'function') {
-                                get_contentWindow(node).default_focus();
-                            }
-                        }
-                    } catch(E) {
-                        g.error.sdump('D_ERROR','default_focus(): ' + js2JSON(E));
-                    }
-                }, 0
-            );
-        }
-
-    ]]>
-    </script>
+    <messagecatalog id="patronStrings"
+        src="/xul/server/locale/<!--#echo var='locale'-->/patron.properties"/>
+
+    <commandset id="patron_cmds">
+
+        <command id="cmd_swap_view" />
+        <command id="cmd_submit" />
+        <command id="cmd_merge" />
+        <command id="cmd_retrieve" />
+        <command id="cmd_sel_clip" />
+        <command id="cmd_save_columns" />
+        <command id="cmd_search_print" />
+        <command id="cmd_clear" />
+
+        <command id="cmd_reload" />
+        <command id="cmd_bills" />
+        <command id="cmd_checkout" />
+        <command id="cmd_edit" />
+        <command id="cmd_events" />
+        <command id="cmd_group" />
+        <command id="cmd_holds" />
+        <command id="cmd_items_out" />
+        <command id="cmd_messages" />
+        <command id="cmd_notes" />
+        <command id="cmd_perms" />
+        <command id="cmd_reservation" />
+        <command id="cmd_reservation_pickup" />
+        <command id="cmd_reservation_return" />
+        <command id="cmd_requests" />
+        <command id="cmd_statcats" />
+        <command id="cmd_surveys" />
+        <command id="cmd_test_password" />
+        <command id="cmd_delete" />
 
-    <messagecatalog id="patronStrings" src="/xul/server/locale/<!--#echo var='locale'-->/patron.properties"/>
-
-    <commandset id="patron_display_cmds">
-        <command id="cmd_patron_refresh" />
-        <command id="cmd_patron_checkout" />
-        <command id="cmd_patron_items" />
-        <command id="cmd_patron_holds" />
-        <command id="cmd_patron_bills" />
-        <command id="cmd_patron_edit" />
-        <command id="cmd_patron_info_notes" />
-        <command id="cmd_patron_info_triggered_events" />
-        <command id="cmd_patron_info_stats" />
-        <command id="cmd_patron_info_surveys" />
-        <command id="cmd_patron_info_acq_requests" />
-        <command id="cmd_patron_info_groups" />
-        <command id="cmd_patron_other" />
-        <command id="cmd_patron_alert" />
-        <command id="cmd_patron_reservation" />
-        <command id="cmd_patron_reservation_pickup" />
-        <command id="cmd_patron_reservation_return" />
-        <command id="cmd_patron_exit" />
-        <command id="cmd_patron_retrieve" />
-        <command id="cmd_patron_merge" />
-        <command id="cmd_patron_toggle_summary" />
-        <command id="cmd_patron_delete" />
-        <command id="cmd_search_form" />
-        <command id="cmd_verify_credentials" />
-        <command id="cmd_perm_editor" />
-        <command id="cmd_standing_penalties" />
     </commandset>
 
-    <box id="patron_display_main" class="my_overflow" />
+    <deck id="uber_deck" flex="1">
+    <!-- FIXME: this should really be two different XUL files, but for now,
+        to allow testing with stock staff clients, I'm squishing them together
+    -->
+
+    <label value="Loading..."/>
+
+    <vbox flex="1">
+
+    <deck id="deck" flex="1">
+    <groupbox id="psgf_gb">
+        <caption id="psgf_gbc" label='&staff.patron_search_form.caption;' />
+        <hbox>
+            <hbox>
+                <label control="inactive"
+                    accesskey="&staff.patron.search_form_overlay.inactive.accesskey;"
+                    value="&staff.patron.search_form_overlay.inactive.value;"/>
+                <checkbox id="inactive" group="_" tabindex="40" oils_persist="checked"/>
+            </hbox>
+            <hbox>
+                <label control="search_ou_menu"
+                    value="&staff.patron.search_form_overlay.search_range_menu.value;"/>
+                <hbox id="search_ou" group="_" tabindex="41" oils_persist="value"/>
+            </hbox>
+            <hbox>
+                <label control="search_profile_menu"
+                    value="&staff.patron_search_form.profile.label;"/>
+                <hbox id="profile" group="_" tabindex="42" oils_persist="value"/>
+            </hbox>
+        </hbox>
+        <hbox>
+            <!-- group 0 = user  group 1 = address  group 2 = phone, ident -->
+            <grid id="psg">
+                <columns id="psc">
+                    <column id="psc1"/>
+                    <column id="psc2" flex="1"/>
+                    <column id="psc3"/>
+                    <column id="psc4" flex="1"/>
+                    <column id="psc5"/>
+                    <column id="psc6" flex="1"/>
+                    <column id="psc7"/>
+                    <column id="psc8" flex="1"/>
+                </columns>
+                <rows id="psr">
+                    <row id="psr1">
+                        <label id="psl6c" control="card" style="font-weight: bold"
+                            value="&staff.patron_search_form.card.label;"
+                            accesskey="&staff.patron_search_form.card.accesskey;"/>
+                        <textbox id="card" group="0" context="clipboard" tabindex="10"/>
+                        <label id="psl1" control="family_name"
+                            value="&staff.patron_search_form.family_name.label;"
+                            accesskey="a"
+                            oldaccesskey="&staff.patron_search_form.family_name.accesskey;"/>
+                        <textbox id="family_name" group="0" context="clipboard" tabindex="14"/>
+                        <label id="psl7" control="street1"
+                            value="&staff.patron_search_form.street1.label;"
+                            accesskey="&staff.patron_search_form.street1.accesskey;"/>
+                        <textbox id="street1" group="1" context="clipboard" tabindex="18"/>
+                        <label id="psl5" control="phone"
+                            value="&staff.patron_search_form.phone.label;"
+                            accesskey="&staff.patron_search_form.phone.accesskey;"/>
+                        <textbox id="phone" group="2" context="clipboard" tabindex="22"/>
+                    </row>
+                    <row id="psr2">
+                        <label id="psl6b" control="usrname"
+                            value="&staff.patron_search_form.usrname.label;"
+                            accesskey="&staff.patron_search_form.usrname.accesskey;"/>
+                        <textbox id="usrname" group="0" context="clipboard" tabindex="11"/>
+                        <label id="psl2" control="first_given_name"
+                            value="&staff.patron_search_form.first_given_name.label;"
+                            accesskey="&staff.patron_search_form.first_given_name.accesskey;"/>
+                        <textbox id="first_given_name" group="0" context="clipboard" tabindex="15"/>
+                        <label id="psl8" control="street2"
+                            value="&staff.patron_search_form.street2.label;"
+                            accesskey="&staff.patron_search_form.street2.accesskey;"/>
+                        <textbox id="street2" group="1" context="clipboard" tabindex="19"/>
+                        <label id="psl4" control="email"
+                            value="&staff.patron_search_form.email.label;"
+                            accesskey="&staff.patron_search_form.email.accesskey;"/>
+                        <textbox id="email" group="0" context="clipboard" tabindex="23"/>
+                    </row>
+                    <row id="psr3">
+                        <label id="psl6" control="ident"
+                            value="&staff.patron_search_form.ident.label;"
+                            accesskey="&staff.patron_search_form.ident.accesskey;"/>
+                        <textbox id="ident" group="2" context="clipboard" tabindex="12"/>
+                        <label id="psl3" control="second_given_name"
+                            value="&staff.patron_search_form.second_given_name.label;"
+                            accesskey="&staff.patron_search_form.second_given_name.accesskey;"/>
+                        <textbox id="second_given_name" group="0" context="clipboard" tabindex="16"/>
+                        <label id="psl9" control="city"
+                            value="&staff.patron_search_form.city.label;"
+                            accesskey="&staff.patron_search_form.city.accesskey;"/>
+                        <textbox id="city" group="1" context="clipboard" tabindex="20"/>
+                        <label id="psl10" control="state"
+                            value="&staff.patron_search_form.state.label;"
+                            accesskey="&staff.patron_search_form.state.accesskey;"/>
+                        <textbox id="state" group="1" context="clipboard" tabindex="24"/>
+                    </row>
+                    <row id="psr14">
+                        <spacer/>
+                        <spacer/>
+                        <label id="psl14" control="alias"
+                            value="&staff.patron_search_form.alias.label;"
+                            accesskey="&staff.patron_search_form.alias.accesskey;"/>
+                        <textbox id="alias" group="0" context="clipboard" tabindex="17"/>
+                        <label id="psl11" control="post_code"
+                            value="&staff.patron_search_form.post_code.label;"
+                            accesskey="&staff.patron_search_form.post_code.accesskey;"/>
+                        <textbox id="post_code" group="1" context="clipboard" tabindex="21"/>
+                    </row>
+                </rows>
+            </grid>
+            <vbox>
+                <button id="search" flex="1" label="&staff.patron_search_form.search.label;"
+                    accesskey="&staff.patron_search_form.search.accesskey;"
+                    command="cmd_submit" tabindex="30"/>
+                <button id="clear" label="&staff.patron_search_form.clear.label;"
+                    accesskey="&staff.patron_search_form.clear.accesskey;"
+                    command="cmd_clear" tabindex="31"/>
+            </vbox>
+        </hbox>
+    </groupbox>
+    <iframe id="iframe" flex="1"/>
+    </deck>
+    <splitter collapse="before" resizebefore="flex" resizeafter="flex" oils_persist="state hidden" oils_persist_peers="deck search_bottom_pane"><grippy/></splitter>
+    <groupbox id="search_bottom_pane" oils_persist="height" flex="1">
+        <caption label="Patrons"/>
+        <tree id="patron_list" flex="1" enableColumnDrag="true" seltype="multiple"/>
+        <hbox>
+            <hbox id="patron_list_actions"/>
+            <hbox id="retrieve_settings">
+                <button type="menu"
+                    label="Retrieve Settings"
+                    accesskey="t">
+                    <menupopup>
+                        <menuitem type="checkbox" id="auto"
+                            oils_persist="checked"
+                            accesskey="M"
+                            label="Auto-Retrieve Single Match"/>
+                        <menuitem type="checkbox" id="auto_via_barcode"
+                            oils_persist="checked"
+                            accesskey="B"
+                            checked="true"
+                            label="Auto-Retrieve Single Match via Barcode"/>
+                        <menuitem type="checkbox" id="replace_tab"
+                            oils_persist="checked"
+                            accesskey="T"
+                            label="Replace Tab on Retrieve"/>
+                        <menuitem type="checkbox" id="replace_tab_via_barcode"
+                            oils_persist="checked"
+                            accesskey="B"
+                            checked="true"
+                            label="Replace Tab on Retrieve via Barcode"/>
+                        <menuitem type="checkbox" id="retrieve_library_card"
+                            oils_persist="checked"
+                            accesskey="C"
+                            label="Retrieve Library Card with search results"/>
+                        <menuitem type="checkbox" id="retrieve_mailing_address"
+                            oils_persist="checked"
+                            accesskey="M"
+                            label="Retrieve Mailing Address with search results"/>
+                        <menuitem type="checkbox" id="retrieve_billing_address"
+                            oils_persist="checked"
+                            accesskey="B"
+                            label="Retrieve Billing Address with search results"/>
+                    </menupopup>
+                </button>
+            </hbox>
+            <spacer flex="1"/>
+            <button id="swap_btn"
+                label="Toggle View"
+                accesskey="V"
+                command="cmd_swap_view"/>
+            <button id="pnb1b2"
+                label="&staff.patron.display_overlay.merge_patrons.label;"
+                accesskey="&staff.patron.display_overlay.merge_patrons.accesskey;"
+                command="cmd_merge"/>
+            <button id="pnb1b1"
+                label="&staff.patron.display_overlay.retrieve_patron.label;"
+                accesskey="&staff.patron.display_overlay.retrieve_patron.accesskey;"
+                command="cmd_retrieve"/>
+        </hbox>
+    </groupbox>
+
+    </vbox>
+
+    <vbox flex="1">
+        <hbox id="top_pane" flex="1" oils_persist="height">
+            <iframe id="iframe1" flex="1" oils_persist="height"/>
+        </hbox>
+        <splitter collapse="before" resizebefore="flex" resizeafter="flex" oils_persist="state hidden" oils_persist_peers="top_pane bottom_pane"><grippy/></splitter>
+        <hbox id="bottom_pane" flex="1" oils_persist="height">
+            <vbox id="button_box" oils_persist="height width" class="my_overflow">
+                <button id="reload"
+                    label="Reload"
+                    accesskey="R"
+                    command="cmd_reload"/>
+                <label value=" "/>
+                <vbox id="main_button_group">
+                    <button id="bills"
+                        label="Bills"
+                        accesskey="B"
+                        command="cmd_bills"/>
+                    <button id="booking" type="menu"
+                        label="Booking"
+                        accesskey="k">
+                        <menupopup>
+                            <menuitem command="cmd_reservation"
+                                label="&staff.main.menu.booking.reservation.label_alt;"
+                                acceskey="&staff.main.menu.booking.reservation.accesskey;"/>
+                            <menuitem command="cmd_reservation_pickup"
+                                label="&staff.main.menu.booking.reservation_pickup.label;"
+                                acceskey="&staff.main.menu.booking.reservation_pickup.accesskey;"/>
+                            <menuitem command="cmd_reservation_return"
+                                label="&staff.main.menu.booking.reservation_return.label;"
+                                acceskey="&staff.main.menu.booking.reservation_return.accesskey;"/>
+                        </menupopup>
+                    </button>
+                    <button id="checkout"
+                        label="Check Out"
+                        accesskey="C"
+                        command="cmd_checkout"/>
+                    <button id="edit"
+                        label="Edit"
+                        accesskey="E"
+                        command="cmd_edit"/>
+                    <button id="events"
+                        label="Events"
+                        accesskey="v"
+                        command="cmd_events"/>
+                    <button id="group"
+                        label="Group"
+                        accesskey="G"
+                        command="cmd_group"/>
+                    <button id="holds"
+                        label="Holds"
+                        accesskey="H"
+                        command="cmd_holds"/>
+                    <button id="items_out"
+                        label="Items Out"
+                        accesskey="I"
+                        command="cmd_items_out"/>
+                    <button id="messages"
+                        label="Messages"
+                        accesskey="M"
+                        command="cmd_messages"/>
+                    <button id="notes"
+                        label="Notes"
+                        accesskey="N"
+                        command="cmd_notes"/>
+                    <button id="perms"
+                        label="Permissions"
+                        accesskey="P"
+                        command="cmd_perms"/>
+                    <button id="requests"
+                        label="Requests"
+                        accesskey="q"
+                        command="cmd_requests"/>
+                    <button id="statcats"
+                        label="StatCats"
+                        accesskey="S"
+                        command="cmd_statcats"/>
+                    <button id="surveys"
+                        label="Surveys"
+                        accesskey="y"
+                        command="cmd_surveys"/>
+                    <button id="test_password"
+                        label="Test Password"
+                        accesskey="T"
+                        command="cmd_test_password"/>
+                </vbox>
+                <label value=" "/>
+                <button id="delete"
+                    label="Delete"
+                    accesskey=""
+                    command="cmd_delete"/>
+            </vbox>
+            <splitter collapse="before"
+                oils_persist="state hidden"
+                oils_persist_peers="button_box iframe2">
+                <grippy/>
+            </splitter>
+        </hbox>
+    </vbox>
+
+    </deck>
 
 </window>
 
deleted file mode 100644 (file)
index 1c5383410c7188ecf1a6ad2aa3b00841f6eb1f89..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1,121 +0,0 @@
-<?xml version="1.0"?>
-<!-- Application: Evergreen Staff Client -->
-<!-- Screen: Patron Display -->
-
-<!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
-<!-- STYLESHEETS -->
-<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
-<?xml-stylesheet href="/xul/server/skin/global.css" type="text/css"?>
-<?xml-stylesheet href="/xul/server/skin/patron_display.css" type="text/css"?>
-
-<!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
-<!-- LOCALIZATION -->
-<!DOCTYPE window PUBLIC "" ""[
-    <!--#include virtual="/opac/locale/${locale}/lang.dtd"-->
-]>
-
-<!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
-<!-- OVERLAYS -->
-<?xul-overlay href="/xul/server/OpenILS/util_overlay.xul"?>
-<?xul-overlay href="/xul/server/patron/display_horiz_overlay.xul"?>
-
-<window id="patron_display_win" 
-    onload="try { my_init(); font_helper(); persist_helper(); } catch(E) { alert(E); }"
-    xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-
-    <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
-    <!-- BEHAVIOR -->
-    <script type="text/javascript">
-        var myPackageDir = 'open_ils_staff_client'; var IAMXUL = true; var g = {};
-    </script>
-    <scripts id="openils_util_scripts"/>
-
-    <script type="text/javascript" src="/xul/server/main/JSAN.js"/>
-    <script type="text/javascript" src="/xul/server/patron/display.js"/>
-    <script>
-    <![CDATA[
-        function $(id) { return document.getElementById(id); }
-    
-        function my_init() {
-            try {
-                if (typeof JSAN == 'undefined') { throw( $("commonStrings").getString('common.jsan.missing') ); }
-                JSAN.errorLevel = "die"; // none, warn, or die
-                JSAN.addRepository('/xul/server/');
-                JSAN.use('util.error'); g.error = new util.error();
-                g.error.sdump('D_TRACE','my_init() for patron_display.xul');
-
-                JSAN.use('patron.display'); g.patron = new patron.display();
-                g.patron.init( { 
-                    'barcode' : xul_param('barcode'),
-                    'id' : xul_param('id'),
-                    'query' : xul_param('query'),
-                    'doit' : xul_param('doit'),
-                    'show' : xul_param('show')
-                } );
-
-            //document.documentElement.style.setProperty('font-size-adjust','1','important');
-
-            } catch(E) {
-                var err_msg = $("commonStrings").getFormattedString('common.exception', ['patron/display.xul', E]);
-                try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); }
-                alert(err_msg);
-            }
-        }
-
-        function default_focus() {
-            setTimeout(
-                function() {
-                    try {
-                        var node = g.patron.right_deck.node.selectedPanel;
-                        if (node && get_contentWindow(node) && typeof get_contentWindow(node).default_focus == 'function') {
-                            get_contentWindow(node).default_focus();
-                        } else {
-                            var node = g.patron.left_deck.node.selectedPanel;
-                            if (node && get_contentWindow(node) && typeof get_contentWindow(node).default_focus == 'function') {
-                                get_contentWindow(node).default_focus();
-                            }
-                        }
-                    } catch(E) {
-                        g.error.sdump('D_ERROR','default_focus(): ' + js2JSON(E));
-                    }
-                }, 0
-            );
-        }
-
-    ]]>
-    </script>
-
-    <messagecatalog id="patronStrings" src="/xul/server/locale/<!--#echo var='locale'-->/patron.properties"/>
-
-    <commandset id="patron_display_cmds">
-        <command id="cmd_patron_refresh" />
-        <command id="cmd_patron_checkout" />
-        <command id="cmd_patron_items" />
-        <command id="cmd_patron_holds" />
-        <command id="cmd_patron_bills" />
-        <command id="cmd_patron_edit" />
-        <command id="cmd_patron_info_notes" />
-        <command id="cmd_patron_info_triggered_events" />
-        <command id="cmd_patron_info_stats" />
-        <command id="cmd_patron_info_surveys" />
-        <command id="cmd_patron_info_groups" />
-        <command id="cmd_patron_other" />
-        <command id="cmd_patron_alert" />
-        <command id="cmd_patron_reservation" />
-        <command id="cmd_patron_reservation_pickup" />
-        <command id="cmd_patron_reservation_return" />
-        <command id="cmd_patron_exit" />
-        <command id="cmd_patron_retrieve" />
-        <command id="cmd_patron_merge" />
-        <command id="cmd_patron_toggle_summary" />
-        <command id="cmd_patron_delete" />
-        <command id="cmd_search_form" />
-        <command id="cmd_verify_credentials" />
-        <command id="cmd_perm_editor" />
-        <command id="cmd_standing_penalties" />
-    </commandset>
-
-    <box id="patron_display_main" class="my_overflow" />
-
-</window>
-
new file mode 120000 (symlink)
index 0000000000000000000000000000000000000000..993bbd93dcd54ff855e4c9c173580f223da2d724
--- /dev/null
@@ -0,0 +1 @@
+display.xul
\ No newline at end of file
diff --git a/Open-ILS/xul/staff_client/server/patron/display_horiz_overlay.xul b/Open-ILS/xul/staff_client/server/patron/display_horiz_overlay.xul
deleted file mode 100644 (file)
index 085fd5f..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE overlay PUBLIC "" ""[
-    <!--#include virtual="/opac/locale/${locale}/lang.dtd"-->
-]>
-<overlay id="patron_display_overlay" 
-    xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-
-<script>dump('loading patron/display_overlay.xul\n');</script>
-
-<commandset id="patron_display_cmds" />
-
-<box id="patron_display_main" flex="1" orient="vertical">
-<vbox id="pdm2" flex="1">
-    <hbox id="pdm2hb1">
-        <hbox>
-            <label id="patron_name" class="patronNameLarge" value="&staff.patron.display_overlay.none_selected.value;" flex="1"/>
-        </hbox>
-        <deck id="PatronNavBar" flex="1" class="my_overflow" />
-    </hbox>
-    <hbox id="pdm2hb1a">
-        <label class="hideme barred_indicator" value="&staff.patron.display_overlay.barred.value;"/>
-        <label class="hideme expired_indicator" value="&staff.patron.display_overlay.expired.value;"/>
-        <label class="hideme inactive_indicator" value="&staff.patron.display_overlay.inactive.value;"/>
-        <label class="hideme juvenile_indicator" value="&staff.patron.display_overlay.juvenile.value;"/>
-        <label class="hideme alert_indicator" value="&staff.patron.display_overlay.alert.value;"/>
-        <label class="hideme note_indicator" value="&staff.patron.display_overlay.see_notes.value;"/>
-        <label class="hideme max_bills_indicator" value="&staff.patron.display_overlay.max_bills.value;"/>
-        <label class="hideme max_overdues_indicator" value="&staff.patron.display_overlay.max_overdues.value;"/>
-        <label class="hideme bills_indicator" value="&staff.patron.display_overlay.has_bills.value;"/>
-        <label class="hideme overdues_indicator" value="&staff.patron.display_overlay.has_overdues.value;"/>
-        <label class="hideme invalid_dob_indicator" value="&staff.patron.display_overlay.invalid_dob.value;"/>
-        <label class="hideme invalid_address_indicator" value="&staff.patron.display_overlay.invalid_address.value;"/>
-        <label class="hideme invalid_email_indicator" value="&staff.patron.display_overlay.invalid_email.value;"/>
-        <label class="hideme invalid_phone_indicator" value="&staff.patron.display_overlay.invalid_phone.value;"/>
-    </hbox>
-    <vbox id="PatronNotNavBar" flex="1" class="my_bg">
-        <hbox id="left_deck_vbox" flex="1" oils_persist="height"> 
-            <deck id="patron_left_deck" oils_persist="height"/>
-        </hbox>
-        <splitter id="deck_splitter" collapse="before" oils_persist="state hidden" oils_persist_peers="left_deck_vbox right_deck_vbox"><grippy id="splitter_grippy"/></splitter>
-        <hbox id="right_deck_vbox" flex="3" oils_persist="height">
-            <deck id="patron_right_deck" oils_persist="height"/>
-        </hbox>
-    </vbox>
-</vbox>
-</box>
-
-<deck id="patron_right_deck" flex="1">
-</deck>
-
-<deck id="patron_left_deck" flex="1">
-</deck>
-
-<deck id="PatronNavBar">
-    <hbox id="PatronNavBar0" flex="1"/>
-    <hbox id="PatronNavBar1" flex="1"/>
-</deck>
-
-<hbox id="PatronNavBar1" flex="1">
-    <vbox flex="1">
-        <hbox flex="1">
-            <spacer flex="1"/>
-            <arrowscrollbox id="PatronNavBarScrollbox" orient="horizontal" flex="1">
-                <spacer flex="1"/>
-                <grid>
-                    <columns>
-                        <column/>
-                        <column/>
-                        <column/>
-                        <column/>
-                        <column/>
-                        <column/>
-                        <column/>
-                        <column/>
-                    </columns>
-                    <rows>
-                        <row>
-                            <button id="PatronNavBar_refresh" command="cmd_patron_refresh" class="nav"
-                                label="&staff.patron_navbar.refresh;" accesskey="&staff.patron_navbar.refresh.accesskey;"/>
-                            <button id="PatronNavBar_checkout" command="cmd_patron_checkout" class="nav"
-                                label="&staff.patron_navbar.checkout;" accesskey="&staff.patron_navbar.checkout.accesskey;"/>
-                            <button id="PatronNavBar_items" command="cmd_patron_items" class="nav"
-                                label="&staff.patron_navbar.items;" accesskey="&staff.patron_navbar.items.accesskey;"/>
-                            <button id="PatronNavBar_holds" command="cmd_patron_holds" class="nav"
-                                label="&staff.patron_navbar.holds;" accesskey="&staff.patron_navbar.holds.accesskey;"/>
-                            <button id="PatronNavBar_bills" command="cmd_patron_bills" class="nav"
-                                label="&staff.patron_navbar.bills;" accesskey="&staff.patron_navbar.bills.accesskey;"/>
-                            <button id="PatronNavBar_edit" command="cmd_patron_edit" class="nav"
-                                label="&staff.patron_navbar.edit;" accesskey="&staff.patron_navbar.edit.accesskey;"/>
-                            <button id="PatronNavBar_messages" label="&staff.patron_navbar.actions.menu.standing_penalties.label;" accesskey="&staff.patron_navbar.actions.menu.standing_penalties.accesskey;" command="cmd_standing_penalties" class="nav"/>
-                            <button id="PatronNavBar_other" command="cmd_patron_other" class="nav" label="&staff.patron_navbar.other;" accesskey="&staff.patron_navbar.other.accesskey;" type="menu">
-                                <menupopup>
-                                    <menuitem label="&staff.patron_navbar.alert;" accesskey="&staff.patron_navbar.alert.accesskey;" command="cmd_patron_alert"/>
-                                    <menuitem label="&staff.patron.info.notes.label;" accesskey="&staff.patron.info.notes.accesskey;" command="cmd_patron_info_notes"/>
-                                    <menuitem label="&staff.patron.info.triggered_events.label;" accesskey="&staff.patron.info.triggered_events.accesskey;" command="cmd_patron_info_triggered_events"/>
-                                    <menuitem label="&staff.patron.info.stat_cats.label;" accesskey="&staff.patron.info.stat_cats.accesskey;" command="cmd_patron_info_stats"/>
-                                    <menu id="PatronNavBar_other_booking" label="&staff.main.menu.booking.label;" accesskey="&staff.main.menu.booking.accesskey;">
-                                        <menupopup id="PatronNavBar_other_booking_popup">
-                                            <menuitem label="&staff.main.menu.booking.reservation.label_alt;" accesskey="&staff.main.menu.booking.reservation.accesskey;" command="cmd_patron_reservation" />
-                                            <menuitem label="&staff.main.menu.booking.reservation_pickup.label;" accesskey="&staff.main.menu.booking.reservation_pickup.accesskey;" command="cmd_patron_reservation_pickup" />
-                                            <menuitem label="&staff.main.menu.booking.reservation_return.label;" accesskey="&staff.main.menu.booking.reservation_return.accesskey;" command="cmd_patron_reservation_return" />
-                                        </menupopup>
-                                    </menu>
-                                    <menuitem label="&staff.patron.info.surveys.label;" accesskey="&staff.patron.info.surveys.accesskey;" command="cmd_patron_info_surveys"/>
-                                    <menuitem label="&staff.patron.info.acq_requests.label;" accesskey="&staff.patron.info.acq_requests.accesskey;" command="cmd_patron_info_acq_requests"/>
-                                    <menuitem label="&staff.patron.info.group.label;" accesskey="&staff.patron.info.group.accesskey;" command="cmd_patron_info_groups"/>
-                                    <menuitem label="&staff.patron_display.verify_password.label;" accesskey="&staff.patron_display.verify_password.accesskey;" command="cmd_verify_credentials"/>
-                                    <menuitem label="&staff.main.menu.admin.user_edit.label;" accesskey="&staff.main.menu.admin.user_edit.accesskey;" command="cmd_perm_editor"/>
-                                    <menuitem label="&staff.patron_display.toggle_summary.label;" accesskey="&staff.patron_display.toggle_summary.accesskey;" command="cmd_patron_toggle_summary"/>
-                                    <menuitem label="&staff.patron_display.delete_patron.label;" accesskey="&staff.patron_display.delete_patron.accesskey;" command="cmd_patron_delete"/>
-                                    <menuitem label="&staff.patron.display_overlay.exit.label;" accesskey="&staff.patron.display_overlay.exit.accesskey;" command="cmd_patron_exit"/>
-                                </menupopup>
-                            </button>
-                        </row>
-                        <row>
-                            <label id="under_refresh"/>
-                            <label id="under_checkout"/>
-                            <label id="under_items"/>
-                            <label id="under_holds"/>
-                            <label id="under_bills"/>
-                            <label id="under_edit"/>
-                            <label id="under_info"/>
-                            <label id="under_edit"/>
-                        </row>
-                    </rows>
-                </grid>
-            </arrowscrollbox>
-        </hbox>
-    </vbox>
-</hbox>
-
-<hbox id="PatronNavBar0" flex="1">
-    <vbox flex="1">
-        <hbox flex="1">
-            <spacer flex="1"/>
-            <button id="pnb1b2" label="&staff.patron.display_overlay.merge_patrons.label;" accesskey="&staff.patron.display_overlay.merge_patrons.accesskey;" command="cmd_patron_merge"/>
-            <button id="pnb1b0" label="&staff.patron.display_overlay.search_form.label;" accesskey="&staff.patron.display_overlay.search_form.accesskey;" command="cmd_search_form"/>
-            <button id="pnb1b1" label="&staff.patron.display_overlay.retrieve_patron.label;" accesskey="&staff.patron.display_overlay.retrieve_patron.accesskey;" command="cmd_patron_retrieve"/>
-        </hbox>
-        <label value=" "/>
-    </vbox>
-</hbox>
-
-</overlay>
diff --git a/Open-ILS/xul/staff_client/server/patron/display_overlay.xul b/Open-ILS/xul/staff_client/server/patron/display_overlay.xul
deleted file mode 100644 (file)
index 876e137..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE overlay PUBLIC "" ""[
-    <!--#include virtual="/opac/locale/${locale}/lang.dtd"-->
-]>
-<overlay id="patron_display_overlay" 
-    xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-
-<script>dump('loading patron/display_overlay.xul\n');</script>
-
-<commandset id="patron_display_cmds" />
-
-<box id="patron_display_main" flex="1" orient="vertical">
-<vbox id="pdm2" flex="1">
-    <hbox id="pdm2hb1">
-        <hbox>
-            <label id="patron_name" class="patronNameLarge" value="&staff.patron.display_overlay.none_selected.value;" flex="1"/>
-        </hbox>
-        <deck id="PatronNavBar" flex="1" class="my_overflow" />
-    </hbox>
-    <hbox id="pdm2hb1a">
-        <label class="hideme barred_indicator" value="&staff.patron.display_overlay.barred.value;"/>
-        <label class="hideme expired_indicator" value="&staff.patron.display_overlay.expired.value;"/>
-        <label class="hideme inactive_indicator" value="&staff.patron.display_overlay.inactive.value;"/>
-        <label class="hideme juvenile_indicator" value="&staff.patron.display_overlay.juvenile.value;"/>
-        <label class="hideme alert_indicator" value="&staff.patron.display_overlay.alert.value;"/>
-        <label class="hideme note_indicator" value="&staff.patron.display_overlay.see_notes.value;"/>
-        <label class="hideme max_bills_indicator" value="&staff.patron.display_overlay.max_bills.value;"/>
-        <label class="hideme max_overdues_indicator" value="&staff.patron.display_overlay.max_overdues.value;"/>
-        <label class="hideme bills_indicator" value="&staff.patron.display_overlay.has_bills.value;"/>
-        <label class="hideme overdues_indicator" value="&staff.patron.display_overlay.has_overdues.value;"/>
-        <label class="hideme invalid_dob_indicator" value="&staff.patron.display_overlay.invalid_dob.value;"/>
-        <label class="hideme invalid_address_indicator" value="&staff.patron.display_overlay.invalid_address.value;"/>
-        <label class="hideme invalid_email_indicator" value="&staff.patron.display_overlay.invalid_email.value;"/>
-        <label class="hideme invalid_phone_indicator" value="&staff.patron.display_overlay.invalid_phone.value;"/>
-    </hbox>
-    <hbox id="PatronNotNavBar" flex="1" class="my_bg">
-        <vbox id="left_deck_vbox" flex="1" oils_persist="width"> 
-            <deck id="patron_left_deck" oils_persist="width"/>
-        </vbox>
-        <splitter id="deck_splitter" collapse="before" oils_persist="state hidden" oils_persist_peers="left_deck_vbox right_deck_vbox"><grippy id="splitter_grippy"/></splitter>
-        <vbox id="right_deck_vbox" flex="3" oils_persist="width">
-            <deck id="patron_right_deck" oils_persist="width"/>
-        </vbox>
-    </hbox>
-</vbox>
-</box>
-
-<deck id="patron_right_deck" flex="1">
-</deck>
-
-<deck id="patron_left_deck" flex="1">
-</deck>
-
-<deck id="PatronNavBar">
-    <hbox id="PatronNavBar0" flex="1"/>
-    <hbox id="PatronNavBar1" flex="1"/>
-</deck>
-
-<hbox id="PatronNavBar1" flex="1">
-    <vbox flex="1">
-        <hbox flex="1">
-            <spacer flex="1"/>
-            <arrowscrollbox id="PatronNavBarScrollbox" orient="horizontal" flex="1">
-                <spacer flex="1"/>
-                <grid>
-                    <columns>
-                        <column/>
-                        <column/>
-                        <column/>
-                        <column/>
-                        <column/>
-                        <column/>
-                        <column/>
-                        <column/>
-                    </columns>
-                    <rows>
-                        <row>
-                            <button id="PatronNavBar_refresh" command="cmd_patron_refresh" class="nav"
-                                label="&staff.patron_navbar.refresh;" accesskey="&staff.patron_navbar.refresh.accesskey;"/>
-                            <button id="PatronNavBar_checkout" command="cmd_patron_checkout" class="nav"
-                                label="&staff.patron_navbar.checkout;" accesskey="&staff.patron_navbar.checkout.accesskey;"/>
-                            <button id="PatronNavBar_items" command="cmd_patron_items" class="nav"
-                                label="&staff.patron_navbar.items;" accesskey="&staff.patron_navbar.items.accesskey;"/>
-                            <button id="PatronNavBar_holds" command="cmd_patron_holds" class="nav"
-                                label="&staff.patron_navbar.holds;" accesskey="&staff.patron_navbar.holds.accesskey;"/>
-                            <button id="PatronNavBar_bills" command="cmd_patron_bills" class="nav"
-                                label="&staff.patron_navbar.bills;" accesskey="&staff.patron_navbar.bills.accesskey;"/>
-                            <button id="PatronNavBar_edit" command="cmd_patron_edit" class="nav"
-                                label="&staff.patron_navbar.edit;" accesskey="&staff.patron_navbar.edit.accesskey;"/>
-                            <button id="PatronNavBar_messages" label="&staff.patron_navbar.actions.menu.standing_penalties.label;" accesskey="&staff.patron_navbar.actions.menu.standing_penalties.accesskey;" command="cmd_standing_penalties" class="nav"/>
-                            <button id="PatronNavBar_other" command="cmd_patron_other" class="nav" label="&staff.patron_navbar.other;" accesskey="&staff.patron_navbar.other.accesskey;" type="menu">
-                                <menupopup>
-                                    <menuitem label="&staff.patron_navbar.alert;" accesskey="&staff.patron_navbar.alert.accesskey;" command="cmd_patron_alert"/>
-                                    <menuitem label="&staff.patron.info.notes.label;" accesskey="&staff.patron.info.notes.accesskey;" command="cmd_patron_info_notes"/>
-                                    <menuitem label="&staff.patron.info.triggered_events.label;" accesskey="&staff.patron.info.triggered_events.accesskey;" command="cmd_patron_info_triggered_events"/>
-                                    <menuitem label="&staff.patron.info.stat_cats.label;" accesskey="&staff.patron.info.stat_cats.accesskey;" command="cmd_patron_info_stats"/>
-                                    <menu id="PatronNavBar_other_booking" label="&staff.main.menu.booking.label;" accesskey="&staff.main.menu.booking.accesskey;">
-                                        <menupopup id="PatronNavBar_other_booking_popup">
-                                            <menuitem label="&staff.main.menu.booking.reservation.label_alt;" accesskey="&staff.main.menu.booking.reservation.accesskey;" command="cmd_patron_reservation" />
-                                            <menuitem label="&staff.main.menu.booking.reservation_pickup.label;" accesskey="&staff.main.menu.booking.reservation_pickup.accesskey;" command="cmd_patron_reservation_pickup" />
-                                            <menuitem label="&staff.main.menu.booking.reservation_return.label;" accesskey="&staff.main.menu.booking.reservation_return.accesskey;" command="cmd_patron_reservation_return" />
-                                        </menupopup>
-                                    </menu>
-                                    <menuitem label="&staff.patron.info.surveys.label;" accesskey="&staff.patron.info.surveys.accesskey;" command="cmd_patron_info_surveys"/>
-                                    <menuitem label="&staff.patron.info.acq_requests.label;" accesskey="&staff.patron.info.acq_requests.accesskey;" command="cmd_patron_info_acq_requests"/>
-                                    <menuitem label="&staff.patron.info.group.label;" accesskey="&staff.patron.info.group.accesskey;" command="cmd_patron_info_groups"/>
-                                    <menuitem label="&staff.patron_display.verify_password.label;" accesskey="&staff.patron_display.verify_password.accesskey;" command="cmd_verify_credentials"/>
-                                    <menuitem label="&staff.main.menu.admin.user_edit.label;" accesskey="&staff.main.menu.admin.user_edit.accesskey;" command="cmd_perm_editor"/>
-                                    <menuitem label="&staff.patron_display.toggle_summary.label;" accesskey="&staff.patron_display.toggle_summary.accesskey;" command="cmd_patron_toggle_summary"/>
-                                    <menuitem label="&staff.patron_display.delete_patron.label;" accesskey="&staff.patron_display.delete_patron.accesskey;" command="cmd_patron_delete"/>
-                                    <menuitem label="&staff.patron.display_overlay.exit.label;" accesskey="&staff.patron.display_overlay.exit.accesskey;" command="cmd_patron_exit"/>
-                                </menupopup>
-                            </button>
-                        </row>
-                        <row>
-                            <label id="under_refresh"/>
-                            <label id="under_checkout"/>
-                            <label id="under_items"/>
-                            <label id="under_holds"/>
-                            <label id="under_bills"/>
-                            <label id="under_edit"/>
-                            <label id="under_info"/>
-                            <label id="under_edit"/>
-                        </row>
-                    </rows>
-                </grid>
-            </arrowscrollbox>
-        </hbox>
-    </vbox>
-</hbox>
-
-<hbox id="PatronNavBar0" flex="1">
-    <vbox flex="1">
-        <hbox flex="1">
-            <spacer flex="1"/>
-            <button id="pnb1b2" label="&staff.patron.display_overlay.merge_patrons.label;" accesskey="&staff.patron.display_overlay.merge_patrons.accesskey;" command="cmd_patron_merge"/>
-            <button id="pnb1b0" label="&staff.patron.display_overlay.search_form.label;" accesskey="&staff.patron.display_overlay.search_form.accesskey;" command="cmd_search_form"/>
-            <button id="pnb1b1" label="&staff.patron.display_overlay.retrieve_patron.label;" accesskey="&staff.patron.display_overlay.retrieve_patron.accesskey;" command="cmd_patron_retrieve"/>
-        </hbox>
-        <label value=" "/>
-    </vbox>
-</hbox>
-
-</overlay>
index 9b15aef..4d23726 100644 (file)
@@ -1519,7 +1519,17 @@ patron.holds.prototype = {
                                     'url_prefix' : xulG.url_prefix,
                                     'url' : xulG.url_prefix('browser')
                                 };
-                                xulG.display_window.g.patron.right_deck.set_iframe( urls.XUL_REMOTE_BROWSER + '?patron_hold=1', {}, content_params);
+                                if (typeof xulG.display_window != 'undefined') {
+                                    xulG.display_window.g.patron.right_deck.set_iframe( urls.XUL_REMOTE_BROWSER + '?patron_hold=1', {}, content_params);
+                                } else {
+                                    xulG.new_tab(
+                                        urls.XUL_REMOTE_BROWSER + '?patron_hold=1',
+                                        {
+                                            'tab_name' : 'Place Hold Patron #'+xulG.patron_id
+                                        },
+                                        content_params
+                                    );
+                                }
                             } catch(E) {
                                 obj.error.sdump('D_ERROR','cmd_search_opac: ' + E);
                             }
diff --git a/Open-ILS/xul/staff_client/server/patron/patron.js b/Open-ILS/xul/staff_client/server/patron/patron.js
new file mode 100644 (file)
index 0000000..c273cc8
--- /dev/null
@@ -0,0 +1,687 @@
+var patron_id;
+var main_interface;
+
+function patron_init() {
+    try {
+        if (typeof JSAN == 'undefined') {
+            throw( "The JSAN library object is missing.");
+        }
+        JSAN.errorLevel = "die"; // none, warn, or die
+        JSAN.addRepository('oils://remote/xul/server/');
+        JSAN.use('util.error'); g.error = new util.error();
+        g.error.sdump('D_TRACE','my_init() for patron.xul');
+
+        JSAN.use('OpenILS.data');
+        g.data = new OpenILS.data();
+        g.data.stash_retrieve();
+
+        patron_id = xul_param('id');
+        if (!patron_id && xul_param('barcode')) {
+            // FIXME - not ideal; these come from the Offline XACT Mgr
+            var p_obj = patron.util.retrieve_fleshed_au_via_barcode(
+                ses(),
+                xul_param('barcode')
+            );
+            if (typeof p_obj.ilsevent != 'undefined') { throw(p_obj); }
+            patron_id = p_obj.id();
+        }
+
+        main_interface = xul_param('interface')
+            || xul_param('show') || 'checkout';
+
+        g.data.last_patron = patron_id;
+        g.data.stash('last_patron');
+
+        JSAN.use('util.file');
+        JSAN.use('util.widgets');
+        JSAN.use('util.functional');
+
+        try {
+            xulG.set_tab_name(get_tab_name(main_interface));
+        } catch(E) {}
+
+        patron_ui_setup();
+        patron_ui_populate();
+        patron_default_focus();
+
+    } catch(E) {
+        alert('Error in patron.xul, my_init(): ' + E);
+    }
+}
+
+function spawn_search(s) {
+    try {
+        xulG.new_patron_tab(
+            { 'tab_name' : 'Patron Search' },
+            {
+                'run_query' : 1,
+                'query' : s
+            }
+        );
+    } catch(E) {
+        dump('Error in patron.xul, spawn_search('+s+'): ' + E + '\n');
+    }
+}
+
+function spawn_editor(p) {
+    var url = urls.XUL_PATRON_EDIT;
+    var loc = xulG.url_prefix('XUL_REMOTE_BROWSER');
+    xulG.new_tab(
+        loc,
+        {},
+        {
+            'url' : url,
+            'show_print_button' : true ,
+            'tab_name' : $("patronStrings").getString(
+                'staff.patron.display.spawn_editor.editing_related_patron'
+            ),
+            'passthru_content_params' : {
+                'spawn_search' : spawn_search,
+                'spawn_editor' : spawn_editor,
+                'url_prefix' : xulG.url_prefix,
+                'get_new_session' : xulG.get_new_session,
+                'new_tab' : xulG.new_tab,
+                'new_patron_tab' : xulG.new_patron_tab,
+                'params' : p,
+                'on_save' : function(p_obj) {
+                    JSAN.use('patron.util');
+                    patron.util.work_log_patron_edit(p_obj);
+                    patron_tab('edit','merely_reset');
+                }
+            },
+            'lock_tab' : xulG.lock_tab,
+            'unlock_tab' : xulG.unlock_tab
+        }
+    );
+}
+
+function get_tab_name(p_interface) {
+    try {
+        var tab_name = p_interface + ' Patron#' + patron_id;
+        switch(p_interface) {
+            case 'checkout':
+                tab_name = 'Check Out Patron#' + patron_id;
+            break;
+            case 'items_out':
+                tab_name = 'Items Out Patron#' + patron_id;
+            break;
+            case 'holds':
+                tab_name = 'Holds Patron#' + patron_id;
+            break;
+            case 'messages':
+                tab_name = 'Messages Patron#' + patron_id;
+            break;
+            case 'notes':
+                tab_name = 'Notes Patron#' + patron_id;
+            break;
+            case 'group':
+                tab_name = 'Group Patron#' + patron_id;
+            break;
+            case 'bills':
+                tab_name = 'Bills Patron#' + patron_id;
+            break;
+            case 'edit':
+                tab_name = 'Edit Patron#' + patron_id;
+            break;
+            case 'perms':
+                tab_name = 'Permissions Patron#' + patron_id;
+            break;
+            case 'events':
+                tab_name = 'Events Patron#' + patron_id;
+            break;
+            case 'requests':
+                tab_name = 'Requests Patron#' + patron_id;
+            break;
+            case 'statcats':
+                tab_name = 'StatCats Patron#' + patron_id;
+            break;
+            case 'surveys':
+                tab_name = 'Surveys Patron#' + patron_id;
+            break;
+            case 'test_password':
+                tab_name = 'Verify Credentials Patron#' + patron_id;
+            break;
+        }
+        return tab_name;
+    } catch(E) {
+        dump('Error in patron.xul, get_tab_name('+p_interface+'): ' + E + '\n');
+    }
+}
+
+function patron_tab(p_interface,replace_tab) {
+    try {
+        if (replace_tab == 'merely_reset') {
+            $(main_interface).disabled = false;
+            main_interface = p_interface;
+            try {
+                xulG.set_tab_name(get_tab_name(main_interface));
+            } catch(E) {}
+            patron_ui_populate();
+        } else {
+            xulG[
+                replace_tab
+                ? 'set_tab'
+                : 'new_tab'
+            ](
+                urls.XUL_PATRON_DISPLAY,{
+                    'tab_name' : get_tab_name(p_interface)
+                },{
+                    'id':patron_id,
+                    'interface' : p_interface
+                }
+            );
+        }
+    } catch(E) {
+        dump('Error in patron.xul, patron_tab('+p_interface+'): ' + E + '\n');
+    }
+}
+
+function reset_summary() {
+    try {
+        $('iframe1').setAttribute(
+            'src',
+            'about:blank'
+        );
+        setTimeout(
+            function() {
+                $('iframe1').setAttribute(
+                    'src',
+                    urls.EG_PATRON_SUMMARY + '?au_id=' + patron_id
+                );
+            }, 0
+        );
+    } catch(E) {
+        dump('Error in patron.xul, reset_summary(): ' + E + '\n');
+    }
+}
+
+function sort_button_box(box, recurse) {
+    try {
+        var curgroup = new Array();
+        var curstart = 1;
+        var curordinal = 0;
+        for (var itemid = 0; itemid < box.children.length; itemid++) {
+            var item = box.children[itemid];
+            curordinal++;
+            if (item.getAttribute('forceFirst')) {
+                item.setAttribute('ordinal', curstart);
+                curstart++;
+                continue;
+            }
+            if (item.nodeName == 'description'
+                || item.nodeName == 'label'
+                || item.nodeName == 'spacer'
+            ) {
+                sort_button_box_items(curgroup, curstart);
+                item.setAttribute('ordinal', curordinal);
+                curstart = curordinal + 1;
+                curgroup = new Array();
+                continue;
+            }
+            if ((item.nodeName == 'hbox'
+                    || item.nodeName == 'vbox'
+                ) && recurse
+            ) {
+                sort_menu_box(item, recurse);
+            }
+            curgroup.push(item);
+        }
+        sort_button_box_items(curgroup, curstart);
+    } catch(E) {
+        dump('Error in patron.xul, sort_button_box(): ' + E + '\n');
+    }
+}
+
+function sort_button_box_items(itemgroup, start) {
+    try {
+        var curpos = start;
+        var sorted = itemgroup.sort(function(a,b) {
+            var labelA = a.getAttribute('label').toUpperCase();
+            var labelB = b.getAttribute('label').toUpperCase();
+            return labelA.localeCompare(labelB);
+        });
+        for(var item = 0; item < sorted.length; item++) {
+            sorted[item].setAttribute('ordinal', curpos++);
+        }
+    } catch(E) {
+        dump('Error in patron.xul, sort_button_box_items(): ' + E + '\n');
+    }
+}
+
+function handle_reservation(ev) {
+    try {
+        JSAN.use('patron.util');
+        dojo.require("openils.User");
+        dojo.require("openils.XUL");
+        openils.XUL.newTabEasy(
+            "BOOKING_RESERVATION",
+            $("offlineStrings").getString(
+                "menu.cmd_booking_reservation.tab"
+            ), {
+                "bresv_interface_opts": {
+                    "patron_barcode":
+                        xul_param('barcode')
+                        || patron.util.retrieve_fleshed_au_via_id(
+                                ses(),
+                                patron_id
+                            ).card().barcode()
+                }
+            },
+            true
+        );
+    } catch(E) {
+        dump('Error in patron.xul, handle_reservation(): ' + E + '\n');
+    }
+}
+
+function handle_reservation_pickup(ev) {
+    try {
+        JSAN.use('patron.util');
+        dojo.require("openils.User");
+        dojo.require("openils.XUL");
+        openils.XUL.newTabEasy(
+            "BOOKING_PICKUP",
+            $("offlineStrings").getString(
+                "menu.cmd_booking_reservation_pickup.tab"
+            ), {
+                "bresv_interface_opts": {
+                    "patron_barcode":
+                        xul_param('barcode')
+                        || patron.util.retrieve_fleshed_au_via_id(
+                                ses(),
+                                patron_id
+                            ).card().barcode()
+                }
+            },
+            true
+        );
+    } catch(E) {
+        dump('Error in patron.xul, handle_reservation_pickup(): ' + E + '\n');
+    }
+}
+
+function handle_reservation_return(ev) {
+    try {
+        JSAN.use('patron.util');
+        dojo.require("openils.User");
+        dojo.require("openils.XUL");
+        openils.XUL.newTabEasy(
+            "BOOKING_RETURN",
+            $("offlineStrings").getString(
+                "menu.cmd_booking_reservation_return.tab"
+            ), {
+                "bresv_interface_opts": {
+                    "patron_barcode":
+                        xul_param('barcode')
+                        || patron.util.retrieve_fleshed_au_via_id(
+                                ses(),
+                                patron_id
+                            ).card().barcode()
+                }
+            },
+            true
+        );
+    } catch(E) {
+        dump('Error in patron.xul, handle_reservation_pickup(): ' + E + '\n');
+    }
+}
+
+function handle_delete(ev) {
+    try {
+        $('delete').disabled;
+        JSAN.use('patron.util');
+        var p_obj = patron.util.retrieve_fleshed_au_via_id(
+            ses(),
+            patron_id
+        );
+        JSAN.use('util.network');
+        var net = new util.network();
+        if (get_bool( p_obj.super_user() )) {
+            alert($("patronStrings").getString(
+                'staff.patron.display.cmd_patron_delete.deny_deletion_of_super_user'));
+            return;
+        }
+        if (patron_id == g.data.list.au[0].id()) {
+            alert($("patronStrings").getString(
+                'staff.patron.display.cmd_patron_delete.deny_deletion_of_self'));
+            return;
+        }
+        var rv = g.error.yns_alert_original(
+            $("patronStrings").getString(
+                'staff.patron.display.cmd_patron_delete.dialog.message'),
+            $("patronStrings").getString(
+                'staff.patron.display.cmd_patron_delete.dialog.title'),
+            $("patronStrings").getString(
+                'staff.patron.display.cmd_patron_delete.dialog.okay'),
+            $("patronStrings").getString(
+                'staff.patron.display.cmd_patron_delete.dialog.cancel'),
+            null,
+            $("patronStrings").getString(
+                'staff.patron.display.cmd_patron_delete.dialog.confirmation')
+        );
+        if (rv == 0) {
+            var params = [ ses(), patron_id ];
+            var staff_check = net.simple_request(
+                'PERM_RETRIEVE_WORK_OU',[
+                    ses(),
+                    'STAFF_LOGIN',
+                    patron_id
+                ]
+            );
+            if (staff_check.length > 0) {
+                var dest_barcode = window.prompt(
+                    $("patronStrings").getString(
+                        'staff.patron.display.cmd_patron_delete.dest_user.prompt'),
+                    $("patronStrings").getString(
+                        'staff.patron.display.cmd_patron_delete.dest_user.default_value'),
+                    $("patronStrings").getString(
+                        'staff.patron.display.cmd_patron_delete.dest_user.title')
+                );
+                if (!dest_barcode) return;
+                var dest_usr = patron.util.retrieve_fleshed_au_via_barcode(
+                    ses(), dest_barcode );
+                if (typeof dest_usr.ilsevent != 'undefined') {
+                    alert($("patronStrings").getString(
+                        'staff.patron.display.cmd_patron_delete.dest_user.failure'));
+                    return;
+                }
+                if (dest_usr.id() == patron_id) {
+                    alert($("patronStrings").getString(
+                        'staff.patron.display.cmd_patron_delete.dest_user.self_reference_failure'));
+                    return;
+                }
+                params.push( dest_usr.id() );
+            }
+            var robj = net.simple_request(
+                'FM_AU_DELETE',
+                params,
+                null,
+                {
+                    'title' : $("patronStrings").getString(
+                        'staff.patron.display.cmd_patron_delete.override_prompt'),
+                    'overridable_events' : [
+                        2004 /* ACTOR_USER_DELETE_OPEN_XACTS */
+                    ]
+                }
+            );
+            if (typeof robj.ilsevent != 'undefined') {
+                switch(Number(robj.ilsevent)) {
+                    /* already informed via override prompt */
+                    case 2004 /* ACTOR_USER_DELETE_OPEN_XACTS */ :
+                        return;
+                    break;
+                }
+            }
+            util.widgets.dispatch('command','cmd_reload');
+        }
+        $('delete').disabled = false;
+    } catch(E) {
+        dump('Error in patron.xul, handle_delete(): ' + E + '\n');
+    }
+}
+
+function patron_ui_setup() {
+    try {
+        dump('entering patron.xul, ui_setup()\n');
+
+        sort_button_box( $('main_button_group'), false );
+
+        $('cmd_reload').addEventListener(
+            'command',
+            function(ev){ patron_tab(main_interface,'merely_reset'); },
+            false
+        );
+
+        $('cmd_reservation').addEventListener(
+            'command',
+            handle_reservation,
+            false
+        );
+
+        $('cmd_reservation_pickup').addEventListener(
+            'command',
+            handle_reservation_pickup,
+            false
+        );
+
+        $('cmd_reservation_return').addEventListener(
+            'command',
+            handle_reservation_return,
+            false
+        );
+
+        $('cmd_delete').addEventListener(
+            'command',
+            handle_delete,
+            false
+        );
+
+        [
+            "bills",
+            "checkout",
+            "edit",
+            "events",
+            "group",
+            "holds",
+            "items_out",
+            "messages",
+            "notes",
+            "perms",
+            "requests",
+            "statcats",
+            "surveys",
+            "test_password"
+        ].forEach(
+            function(cmd) {
+                $('cmd_'+cmd).addEventListener(
+                    'command',
+                    function(c_interface) {
+                        return function(ev) {
+                            patron_tab(c_interface,'merely_reset');
+                        }
+                    }(cmd),
+                    false
+                );
+            }
+        );
+
+    } catch(E) {
+        alert('Error in patron.xul, ui_setup(): ' + E + '\n');
+    }
+}
+
+function patron_ui_populate() {
+    try {
+        $('iframe1').setAttribute(
+            'src',
+            'data:,Loading...'
+        );
+        setTimeout(
+            function() {
+                $('iframe1').setAttribute(
+                    'src',
+                    urls.EG_PATRON_SUMMARY + '?au_id=' + patron_id
+                );
+            }, 0
+        );
+
+        $(main_interface).disabled = true;
+
+        var barcode_for_some_interfaces = xul_param('barcode');
+        var patron_object_for_some_interfaces;
+
+        var bottom_pane = $('bottom_pane');
+        if ($('iframe2')) { bottom_pane.removeChild($('iframe2')); }
+        var iframe = document.createElement('iframe');
+        iframe.setAttribute('id','iframe2');
+        iframe.setAttribute('flex','1');
+        var src = 'data:text/plain,Missing interface';
+        switch(main_interface) {
+            case 'checkout':
+                src = urls.XUL_CHECKOUT;
+            break;
+            case 'items_out':
+                src = urls.XUL_PATRON_ITEMS;
+            break;
+            case 'holds':
+                src = urls.XUL_PATRON_HOLDS;
+                // FIXME - not ideal; but OPAC Place Hold needs this
+                if (!barcode_for_some_interfaces) {
+                    JSAN.use('patron.util');
+                    var p_obj = patron.util.retrieve_fleshed_au_via_id(
+                        ses(),
+                        patron_id
+                    );
+                    barcode_for_some_interfaces = p_obj.card().barcode();
+                }
+            break;
+            case 'messages':
+                src = urls.XUL_STANDING_PENALTIES;
+                JSAN.use('patron.util');
+                patron_object_for_some_interfaces = patron.util.retrieve_fleshed_au_via_id(
+                    ses(),
+                    patron_id
+                );
+            break;
+            case 'group':
+                src = urls.XUL_PATRON_INFO_GROUP;
+            break;
+            case 'bills':
+                src = urls.XUL_PATRON_BILLS;
+            break;
+            case 'edit':
+                src = urls.XUL_REMOTE_BROWSER; /* XUL_PATRON_EDIT */
+            break;
+            case 'events':
+                src = urls.XUL_REMOTE_BROWSER; /* EG_TRIGGER_EVENTS */
+            break;
+            case 'statcats':
+                src = urls.XUL_PATRON_INFO_STAT_CATS;
+            break;
+            case 'notes':
+                src = urls.XUL_PATRON_INFO_NOTES;
+            break;
+            case 'requests':
+                src = urls.EG_ACQ_USER_REQUESTS + '?usr=' + patron_id;
+            break;
+            case 'surveys':
+                src = urls.XUL_PATRON_INFO_SURVEYS;
+            break;
+            case 'test_password':
+                src = urls.XUL_VERIFY_CREDENTIALS;
+                var p_obj = patron.util.retrieve_fleshed_au_via_id(
+                    ses(),
+                    patron_id
+                );
+                patron_object_for_some_interfaces = p_obj;
+                barcode_for_some_interfaces = p_obj.card().barcode();
+            break;
+            case 'perms':
+                src = urls.XUL_USER_PERM_EDITOR
+                    + '?ses=' + window.escape(ses())
+                    + '&usr=' + patron_id;
+            break;
+        }
+        iframe.setAttribute('src',src);
+        bottom_pane.appendChild(iframe);
+        var cw = get_contentWindow(iframe);
+        cw.IAMXUL = true;
+        cw.xulG = {
+            'set_tab' : function(a,b,c) { return xulG.set_tab(a,b,c); },
+            'patron_id' : patron_id,
+            'get_barcode' : xulG.get_barcode,
+            'get_barcode_and_settings' : xulG.get_barcode_and_settings,
+            'get_new_session' : xulG.get_new_session,
+            'new_tab' : xulG.new_tab,
+            'new_patron_tab' : xulG.new_patron_tab,
+            'url_prefix' : xulG.url_prefix,
+            'on_list_change' : function(x) {},
+            'lock_tab' : xulG.lock_tab,
+            'unlock_tab' : xulG.unlock_tab
+        }
+        switch(main_interface) {
+            case 'checkout':
+                cw.xulG.check_stop_checkouts = function() { return false; };
+            break;
+            case 'items_out':
+            break;
+            case 'holds':
+                cw.xulG.patron_barcode = barcode_for_some_interfaces;
+            break;
+            case 'messages':
+                cw.xulG.patron = patron_object_for_some_interfaces;
+                cw.xulG.reset_summary = reset_summary;
+            break;
+            case 'group':
+            break;
+            case 'bills':
+                cw.xulG.on_money_change = function(b) {
+                    reset_summary();
+                }
+            break;
+            case 'edit':
+                cw.xulG.url = urls.XUL_PATRON_EDIT;
+                cw.xulG.show_print_button = urls.XUL_PATRON_EDIT;
+                cw.xulG.passthru_content_params = {
+                    'params' : {
+                        'ses' : ses(),
+                        'usr' : patron_id
+                    },
+                    'on_save' : function(p) {
+                        JSAN.use('patron.util');
+                        patron.util.work_log_patron_edit(p);
+                        patron_tab('edit','merely_reset');
+                    },
+                    'spawn_search' : spawn_search,
+                    'spawn_editor' : spawn_editor,
+                    'url_prefix' : xulG.url_prefix,
+                    'get_new_session' : xulG.get_new_session,
+                    'new_tab' : xulG.new_tab,
+                    'new_patron_tab' : xulG.new_patron_tab
+                }
+            break;
+            case 'events':
+                cw.xulG.url = urls.EG_TRIGGER_EVENTS + '?patron_id=' + patron_id;
+                cw.xulG.show_print_button = false;
+                cw.xulG.show_nav_buttons = false;
+            break;
+            case 'statcats':
+            break;
+            case 'notes':
+            break;
+            case 'requests':
+            break;
+            case 'surveys':
+            break;
+            case 'test_password':
+                cw.xulG.barcode = barcode_for_some_interfaces;
+                cw.xulG.usrname = patron_object_for_some_interfaces.usrname();
+            break;
+            case 'perms':
+            break;
+        }
+
+    } catch(E) {
+        alert('Error in patron.xul, ui_setup_populate(): ' + E + '\n');
+    }
+}
+
+function patron_default_focus() {
+    setTimeout(
+        function() {
+            try {
+                dump('entering patron.xul, default_focus()\n');
+                if ($('iframe2')) {
+                    $('iframe2').focus();
+                    var cw = get_contentWindow($('iframe2'));
+                    if (cw && typeof cw.default_focus == 'function') {
+                        cw.default_focus();
+                    }
+                }
+            } catch(E) {
+                dump('Error in patron.xul, default_focus(): ' + E + '\n');
+            }
+        }, 0
+    );
+}
+
diff --git a/Open-ILS/xul/staff_client/server/patron/search.js b/Open-ILS/xul/staff_client/server/patron/search.js
new file mode 100644 (file)
index 0000000..716b4b4
--- /dev/null
@@ -0,0 +1,455 @@
+/** FIXME: kludge to allow for testing with stock clients **/
+
+function my_init() {
+    try {
+        if (xul_param('id')||xul_param('barcode')) {
+            $('uber_deck').selectedIndex = 2;
+            patron_init();
+        } else {
+            $('uber_deck').selectedIndex = 1;
+            search_init();
+        }
+    } catch(E) {
+        alert('Error in my_init(): ' + E);
+    }
+}
+
+function default_focus() {
+    if (xul_param('id')||xul_param('barcode')) {
+        patron_default_focus();
+    } else {
+        search_default_focus();
+    }
+}
+
+/******/
+
+function search_init() {
+    try {
+        if (typeof JSAN == 'undefined') {
+            throw( "The JSAN library object is missing.");
+        }
+        JSAN.errorLevel = "die"; // none, warn, or die
+        JSAN.addRepository('oils://remote/xul/server/');
+        JSAN.use('util.error'); g.error = new util.error();
+        g.error.sdump('D_TRACE','my_init() for patron/search.xul');
+
+        JSAN.use('OpenILS.data');
+        g.data = new OpenILS.data();
+        g.data.stash_retrieve();
+
+        JSAN.use('util.file');
+        JSAN.use('util.widgets');
+        JSAN.use('util.functional');
+        JSAN.use('patron.search_result');
+
+        try {
+            window.xulG.set_tab_name(
+                xul_param('perm_editor')
+                ? 'Patron Search (for Perm Editor)'
+                : 'Patron Search (for Check Out)'
+            );
+        } catch(E) {}
+
+        search_ui_setup();
+        g.search = new patron.search_result();
+        g.search.init({});
+        $('patron_list_actions').appendChild(
+            g.search.list.render_list_actions()
+        );
+        g.search.list.set_list_actions();
+        search_default_focus();
+
+    } catch(E) {
+        alert('Error in patron/search.xul: ' + E);
+    }
+}
+
+function handle_enter(ev) {
+    try {
+        if (ev.target.tagName != 'textbox') {
+            return;
+        }
+        if (ev.keyCode == 13 /* enter */
+        || ev.keyCode == 77 /* enter on a mac */) {
+            submit();
+        }
+    } catch(E) {
+        dump('Error in patron/search.xul, handle_enter(): ' + E + '\n');
+    }
+}
+
+function update_search_summary_view() {
+    try {
+        var patrons = g.search.list.retrieve_selection_retrieval_data();
+        if (patrons.length > 0) {
+            $('iframe').setAttribute('src','data:,Loading...');
+            setTimeout(
+                function() {
+                    $('iframe').setAttribute(
+                        'src',
+                        urls.EG_PATRON_SEARCH_SUMMARY+'?au_id='+patrons[0]
+                    );
+                }, 0
+            );
+        }
+    } catch(E) {
+        dump('Error in patron/search.xul, update_search_summary_view(): ' + E + '\n');
+    }
+}
+
+function swap_view(ev) {
+    try {
+        var idx = $('deck').selectedIndex;
+        if (idx == 0) {
+            $('deck').selectedIndex = 1;
+            $('patron_list').focus();
+            update_search_summary_view();
+        } else {
+            $('deck').selectedIndex = 0;
+            search_default_focus();
+        }
+    } catch(E) {
+        dump('Error in patron/search.xul, swap_view(): ' + E + '\n');
+    }
+}
+
+function handle_merge(ev) {
+    try {
+        JSAN.use('patron.util');
+        if (
+            patron.util.merge(
+                g.search.list.retrieve_selection_retrieval_data()
+            )
+        ) {
+            util.widgets.dispatch('command','cmd_submit');
+        }
+    } catch(E) {
+        dump('Error in patron/search.xul, handle_merge: ' + E + '\n');
+    }
+}
+
+function search_ui_setup() {
+    try {
+        dump('entering patron/search.xul, ui_setup()\n');
+
+        $('cmd_swap_view').setAttribute('disabled','true');
+        $('cmd_retrieve').setAttribute('disabled','true');
+        $('cmd_merge').setAttribute('disabled','true');
+
+        $('cmd_swap_view').addEventListener(
+            'command',
+            swap_view,
+            false
+        );
+
+        $('cmd_clear').addEventListener(
+            'command',
+            clear_form,
+            false
+        );
+
+        $('cmd_submit').addEventListener(
+            'command',
+            submit,
+            false
+        );
+
+        $('cmd_retrieve').addEventListener(
+            'command',
+            function(ev) { retrieve_patrons(); },
+            false
+        );
+
+        $('cmd_merge').addEventListener(
+            'command',
+            handle_merge,
+            false
+        );
+
+        var nl = document.getElementsByTagName('textbox');
+        for (var i = 0; i < nl.length; i++) {
+            nl[i].addEventListener(
+                'keypress',
+                handle_enter,
+                false
+            );
+        }
+
+        util.widgets.remove_children('search_ou');
+        if (! $('search_ou').hasAttribute('value')) {
+            $('search_ou').setAttribute('value',g.data.tree.aou.id());
+        }
+
+        var search_ou_ml = util.widgets.make_menulist(
+            util.functional.map_list( g.data.list.my_aou,
+                function(el,idx) {
+                    return [ el.name(), el.id() ]
+                }
+            ).sort(
+                function(a,b) {
+                    if (a[1] < b[1]) return -1;
+                    if (a[1] > b[1]) return 1;
+                    return 0;
+                }
+            ),
+            $('search_ou').getAttribute('value')
+        );
+        search_ou_ml.addEventListener(
+            'command',
+            function(ev) {
+                search_ou_ml.parentNode.setAttribute(
+                    'value',
+                    ev.target.value
+                );
+                oils_persist(search_ou_ml.parentNode);
+            },
+            false
+        );
+        search_ou_ml.setAttribute('id','search_ou_ml');
+        $('search_ou').appendChild(search_ou_ml);
+
+        util.widgets.remove_children('profile');
+        var profile_ml = util.widgets.make_menulist(
+            [
+                ['','']
+            ].concat(
+                util.functional.map_list(
+                    g.data.list.pgt,
+                    function(el,idx) {
+                        return [ el.name(), el.id() ]
+                    }
+                ).sort(
+                    function(a,b) {
+                        if (a[0] < b[0]) return -1;
+                        if (a[0] > b[0]) return 1;
+                        return 0;
+                    }
+                )
+            ),
+            $('profile').getAttribute('value')
+        );
+        profile_ml.addEventListener(
+                'command',
+                function(ev) {
+                    profile_ml.parentNode.setAttribute(
+                        'value',
+                        ev.target.value
+                    );
+                    oils_persist(profile_ml.parentNode);
+                },
+                false
+        );
+        profile_ml.setAttribute('id','profile_ml');
+        $('profile').appendChild(profile_ml);
+
+    } catch(E) {
+        dump('Error in patron/search.xul, ui_setup(): ' + E + '\n');
+    }
+}
+
+function search_default_focus() {
+    setTimeout(
+        function() {
+            try {
+                dump('entering patron/search.xul, default_focus()\n');
+                var field = xul_param('focus')||'card';
+                // HACK for while we're symlinking barcode_entry.xul
+                // to allow testing with stock clients
+                if (! location.href.match(/barcode_entry/)) {
+                    field = 'family_name';
+                }
+                $(field).select();
+                $(field).focus();
+            } catch(E) {
+                dump('Error in patron/search.xul, default_focus(): ' + E + '\n');
+            }
+        }, 0
+    );
+}
+
+function clear_form() {
+    try {
+        var render_list = document.getElementsByAttribute('group','*');
+        for (var i = 0; i < render_list.length; i++) {
+            var node = render_list[i];
+            var id = node.id;
+            if (id == 'inactive') {
+                // no-op, sticky
+            } else if (id == 'profile'
+            || id == 'search_ou') {
+                // no-op, sticky
+            } else {
+                render_list[i].value = '';
+            }
+        }
+        search_default_focus();
+    } catch(E) {
+        dump('Error in patron/search.xul, clear_form(): ' + E + '\n');
+    }
+}
+
+var _submitting = false;
+function submit(ev) {
+    if (_submitting) {
+        dump('submit() in patron/search.xul while already submitting\n');
+        return;
+    }
+    _submitting = true;
+    try {
+        var query = {};
+        var render_list = document.getElementsByAttribute('group','*');
+        for (var i = 0; i < render_list.length; i++) {
+            var node = render_list[i];
+            var id = node.id;
+            var value;
+            if (id == 'inactive') {
+                value = node.getAttribute('checked');
+            } else if (id == 'profile'
+            || id == 'search_ou') {
+                value  = node.getAttribute('value');
+            } else {
+                value = node.value.replace(/^\s+/,'').replace(/[\\\s]+$/,'');
+                switch(id) {
+                    case 'family_name' :
+                    case 'first_given_name' :
+                    case 'second_given_name' :
+                        value = value.replace(/^[\d\s]+/g,'').replace(/[\d\s]+$/g,'')
+                    break;
+                }
+            }
+            if (value != '') {
+                query[id] = value;
+            }
+        }
+        search(query,undefined,undefined);
+    } catch(E) {
+        dump('Error in patron/search.xul, submit(): ' + E + '\n');
+    }
+}
+
+function handle_search_select(ev){
+    var select_count = g.search.list.retrieve_selection_retrieval_data().length;
+    $('cmd_swap_view').setAttribute('disabled','true');
+    $('cmd_retrieve').setAttribute('disabled','true');
+    $('cmd_merge').setAttribute('disabled','true');
+    if (select_count > 0) {
+        $('cmd_swap_view').setAttribute('disabled','false');
+        $('cmd_retrieve').setAttribute('disabled','false');
+    }
+    if (select_count > 1) {
+        $('cmd_merge').setAttribute('disabled','false');
+    }
+    if (_submitting) { return; }
+    if ($('deck').selectedIndex == 1) {
+        update_search_summary_view();
+    } else {
+        swap_view();
+    }
+}
+
+function want_auto_retrieve() {
+    if ($('auto').getAttribute('checked') == 'true') {
+        return true;
+    }
+    if ($('auto_via_barcode').getAttribute('checked') == 'true'
+        && $('card').value != ''
+    ) {
+        return true;
+    }
+    return false;
+}
+
+function want_tab_replace() {
+    if ($('replace_tab').getAttribute('checked') == 'true') {
+        return true;
+    }
+    if ($('replace_tab_via_barcode').getAttribute('checked') == 'true'
+        && $('card').value != ''
+    ) {
+        return true;
+    }
+    return false;
+}
+
+function search(query,limit,sort) {
+    try {
+        g.search.search_limit = limit;
+        g.search.search_sort = sort;
+        g.search.on_select =  handle_search_select;
+        g.search.on_dblclick = function(ev) { retrieve_patrons() };
+        g.search.on_finished = function(results) { _submitting = false; }
+        var patron_parts = [];
+        if ($('retrieve_library_card').getAttribute('checked') == 'true') {
+            patron_parts.push('card');
+        }
+        if ($('retrieve_mailing_address').getAttribute('checked') == 'true') {
+            patron_parts.push('mailing_address');
+        }
+        if ($('retrieve_billing_address').getAttribute('checked') == 'true') {
+            patron_parts.push('billing_address');
+        }
+        g.search.patron_parts = patron_parts;
+        g.search.skip_render_of_single_result = want_tab_replace();
+        if (want_auto_retrieve()) {
+            g.search.single_result_callback =
+                function(id) { retrieve_patrons([id]); }
+        } else {
+            g.search.single_result_callback = null;
+        }
+        g.search.list.clear();
+        $('patron_list').focus();
+        g.search.search(query);
+    } catch(E) {
+        dump('Error in patron/search.xul, search(): ' + E + '\n');
+    }
+}
+
+function retrieve_patrons(patrons) {
+    if (!patrons) {
+        patrons = g.search.list.retrieve_selection_retrieval_data();
+    }
+    var current_tab_index = typeof xulG.get_idx == 'function'
+        ? xulG.get_idx()
+        : -1; // Just want to test this code without requiring a
+              // local staff client upgrade. get_idx is needed if
+              // we want to replace a tab that does not have focus
+    for (
+        var i = want_tab_replace()
+        ? 1 // open new tabs before replacing current tab
+        : 0;
+        i < patrons.length;
+        i++
+    ) {
+        xulG.new_tab(
+            urls.XUL_PATRON_DISPLAY,{
+                'nofocus' : current_tab_index == -1
+                && want_tab_replace()
+            },{
+                'id':patrons[i],
+                'interface' : xul_param('perm_editor')
+                ? 'perms'
+                : 'checkout'
+            }
+        );
+    }
+    if (want_tab_replace()) {
+        var tab_params = {};
+        if (current_tab_index != -1) {
+            tab_params.index = current_tab_index;
+        }
+        xulG.set_tab(
+            urls.XUL_PATRON_DISPLAY,
+            tab_params,{
+                'id':patrons[0],
+                'interface' : xul_param('perm_editor')
+                ? 'perms'
+                : 'checkout'
+            }
+        );
+    } else {
+        if (current_tab_index == -1) {
+            search_default_focus();
+        }
+    }
+}
index e9e5f4a..e356d6f 100644 (file)
@@ -21,7 +21,8 @@ patron.search_result.prototype = {
         obj.query = params['query'];
         obj.search_limit = params['search_limit'];
         obj.search_sort = params['search_sort'];
-
+        obj.patron_parts = params['patron_parts']
+            || ["card","billing_address","mailing_address"];
         JSAN.use('OpenILS.data'); this.OpenILS = {}; 
         obj.OpenILS.data = new OpenILS.data(); obj.OpenILS.data.init({'via':'stash'});
         var obscure_dob = String( obj.OpenILS.data.hash.aous['circ.obscure_dob'] ) == 'true';
@@ -81,7 +82,7 @@ patron.search_result.prototype = {
                     var au_obj = patron.util.retrieve_fleshed_au_via_id(
                         ses(),
                         id,
-                        ["card","billing_address","mailing_address"],
+                        obj.patron_parts,
                         function(req) {
                             try {
                                 var row = params.row;
@@ -189,7 +190,7 @@ patron.search_result.prototype = {
         var search_hash = {};
         obj.search_term_count = 0;
         var inactive = false;
-        var search_depth = 0;
+        var search_ou = 0;
         for (var i in query) {
             switch( i ) {
                 case 'card':
@@ -227,8 +228,9 @@ patron.search_result.prototype = {
                     if (query[i] == 'checked' || query[i] == 'true') inactive = true;
                 break;
 
-                case 'search_depth':
-                    search_depth = function(a){return a;}(query[i]);
+                case 'search_depth' /* bad name, but keeping for the moment */:
+                case 'search_ou' /* truthful name */:
+                    search_ou = function(a){return a;}(query[i]);
                 break;
             }
         }
@@ -254,10 +256,13 @@ patron.search_result.prototype = {
             } else {
                 params.push(0);
             }
-            params.push(search_depth);
+            params.push(search_ou);
             if (obj.search_term_count > 0) {
                 //alert('search params = ' + obj.error.pretty_print( js2JSON( params ) ) );
                 results = this.network.simple_request( 'FM_AU_IDS_RETRIEVE_VIA_HASH', params );
+                if (typeof obj.on_select == 'function') {
+                    obj.on_finished(results);
+                }
                 if ( results == null ) results = [];
                 if (typeof results.ilsevent != 'undefined') throw(results);
                 if (results.length == 0) {
@@ -273,21 +278,33 @@ patron.search_result.prototype = {
                 return;
             }
 
-            obj.list.clear();
-            //this.list.append( { 'retrieve_id' : results[i], 'row' : {} } );
-            var funcs = [];
+            if (results.length == 1 && obj.skip_render_of_single_result) {
+                // no-op
+            } else {
+                obj.list.clear();
+                var funcs = [];
 
                 function gen_func(r) {
                     return function() {
-                        obj.list.append( { 'retrieve_id' : r, 'row' : {}, 'to_bottom' : true, 'no_auto_select' : true } );
+                        obj.list.append({
+                            'retrieve_id' : r,
+                            'row' : {},
+                            'to_bottom' : true,
+                            'no_auto_select' : true
+                        });
                     }
                 }
 
-            for (var i = 0; i < results.length; i++) {
-                funcs.push( gen_func(results[i]) );
+                for (var i = 0; i < results.length; i++) {
+                    funcs.push( gen_func(results[i]) );
+                }
+                JSAN.use('util.exec'); var exec = new util.exec(4);
+                exec.chain( funcs );
+            }
+
+            if (results.length == 1 && typeof obj.single_result_callback == 'function') {
+                obj.single_result_callback(results[0]);
             }
-            JSAN.use('util.exec'); var exec = new util.exec(4);
-            exec.chain( funcs );
 
         } catch(E) {
             this.error.standard_unexpected_error_alert('patron.search_result.search',E);
index d36edf4..f5c6d61 100644 (file)
@@ -197,6 +197,9 @@ function generate_request_handler_for_penalty_apply(penalty,id) {
                 xulG.refresh();
             }
             */
+            if (xulG && typeof xulG.reset_summary == 'function') {
+                xulG.reset_summary();
+            }
             document.getElementById('progress').hidden = true;
 
         } catch(E) {
@@ -224,6 +227,9 @@ function handle_remove_penalty(ev) {
                     xulG.refresh();
                 }
                 */
+                if (xulG && typeof xulG.reset_summary == 'function') {
+                    xulG.reset_summary();
+                }
                 document.getElementById('progress').hidden = true;
 
                 //patron.util.set_penalty_css(xulG.patron);
@@ -326,6 +332,9 @@ function handle_edit_penalty(ev) {
                 xulG.refresh();
             }
             */
+            if (xulG && typeof xulG.reset_summary == 'function') {
+                xulG.reset_summary();
+            }
         }
 
     } catch(E) {
@@ -386,6 +395,9 @@ function handle_archive_penalty(ev) {
                 xulG.refresh();
             }
             */
+            if (xulG && typeof xulG.reset_summary == 'function') {
+                xulG.reset_summary();
+            }
         }
 
     } catch(E) {