View | Details | Raw Unified | Return to bug 23112
Collapse All | Expand All

(-)a/Koha/Illrequest.pm (-3 / +219 lines)
Lines 35-40 use Koha::AuthorisedValue; Link Here
35
use Koha::Illrequest::Logger;
35
use Koha::Illrequest::Logger;
36
use Koha::Patron;
36
use Koha::Patron;
37
use Koha::AuthorisedValues;
37
use Koha::AuthorisedValues;
38
use Koha::Biblios;
39
use Koha::Items;
40
use Koha::ItemTypes;
41
use Koha::Libraries;
42
use C4::Items qw( AddItem );
43
use C4::Circulation qw( CanBookBeIssued AddIssue  );
38
44
39
use base qw(Koha::Object);
45
use base qw(Koha::Object);
40
46
Lines 425-431 sub _core_status_graph { Link Here
425
            name           => 'Requested',
431
            name           => 'Requested',
426
            ui_method_name => 'Confirm request',
432
            ui_method_name => 'Confirm request',
427
            method         => 'confirm',
433
            method         => 'confirm',
428
            next_actions   => [ 'REQREV', 'COMP' ],
434
            next_actions   => [ 'REQREV', 'COMP', 'CHK' ],
429
            ui_method_icon => 'fa-check',
435
            ui_method_icon => 'fa-check',
430
        },
436
        },
431
        GENREQ => {
437
        GENREQ => {
Lines 434-440 sub _core_status_graph { Link Here
434
            name           => 'Requested from partners',
440
            name           => 'Requested from partners',
435
            ui_method_name => 'Place request with partners',
441
            ui_method_name => 'Place request with partners',
436
            method         => 'generic_confirm',
442
            method         => 'generic_confirm',
437
            next_actions   => [ 'COMP' ],
443
            next_actions   => [ 'COMP', 'CHK' ],
438
            ui_method_icon => 'fa-send-o',
444
            ui_method_icon => 'fa-send-o',
439
        },
445
        },
440
        REQREV => {
446
        REQREV => {
Lines 470-476 sub _core_status_graph { Link Here
470
            name           => 'Completed',
476
            name           => 'Completed',
471
            ui_method_name => 'Mark completed',
477
            ui_method_name => 'Mark completed',
472
            method         => 'mark_completed',
478
            method         => 'mark_completed',
473
            next_actions   => [ ],
479
            next_actions   => [ 'CHK' ],
474
            ui_method_icon => 'fa-check',
480
            ui_method_icon => 'fa-check',
475
        },
481
        },
476
        KILL => {
482
        KILL => {
Lines 482-487 sub _core_status_graph { Link Here
482
            next_actions   => [ ],
488
            next_actions   => [ ],
483
            ui_method_icon => 'fa-trash',
489
            ui_method_icon => 'fa-trash',
484
        },
490
        },
491
        CHK => {
492
            prev_actions   => [ 'REQ', 'GENREQ', 'COMP' ],
493
            id             => 'CHK',
494
            name           => 'Checked out',
495
            ui_method_name => 'Check out',
496
            method         => 'check_out',
497
            next_actions   => [ ],
498
            ui_method_icon => 'fa-upload',
499
        }
485
    };
500
    };
486
}
501
}
487
502
Lines 1023-1028 sub requires_moderation { Link Here
1023
    return $require_moderation->{$self->status};
1038
    return $require_moderation->{$self->status};
1024
}
1039
}
1025
1040
1041
=head3 check_out
1042
1043
    my $stage_summary = $request->check_out;
1044
1045
Handle the check_out method. The first stage involves gathering the required
1046
data from the user via a form, the second stage creates an item and tries to
1047
issue it to the patron. If successful, it notifies the patron, then it
1048
returns a summary of how things went
1049
1050
=cut
1051
1052
sub check_out {
1053
    my ( $self, $params ) = @_;
1054
1055
    # Objects required by the template
1056
    my $itemtypes = Koha::ItemTypes->search(
1057
        {},
1058
        { order_by => ['description'] }
1059
    );
1060
    my $libraries = Koha::Libraries->search(
1061
        {},
1062
        { order_by => ['branchcode'] }
1063
    );
1064
    my $biblio = Koha::Biblios->find({
1065
        biblionumber => $self->biblio_id
1066
    });
1067
    # Find all statistical patrons
1068
    my $statistical_patrons = Koha::Patrons->search(
1069
        { 'category_type' => 'x' },
1070
        { join => { 'categorycode' => 'borrowers' } }
1071
    );
1072
1073
    if (!$params->{stage} || $params->{stage} eq 'init') {
1074
        # Present a form to gather the required data
1075
        #
1076
        # We may be viewing this page having previously tried to issue
1077
        # the item (in which case, we may already have created an item)
1078
        # so we pass the biblio for this request
1079
        return {
1080
            method  => 'check_out',
1081
            stage   => 'form',
1082
            value   => {
1083
                itemtypes   => $itemtypes,
1084
                libraries   => $libraries,
1085
                statistical => $statistical_patrons,
1086
                biblio      => $biblio
1087
            }
1088
        };
1089
    } elsif ($params->{stage} eq 'form') {
1090
        # Validate what we've got and return with an error if we fail
1091
        my $errors = {};
1092
        if (!$params->{item_type} || length $params->{item_type} == 0) {
1093
            $errors->{item_type} = 1;
1094
        }
1095
        if ($params->{inhouse} && length $params->{inhouse} > 0) {
1096
            my $patron_count = Koha::Patrons->search({
1097
                cardnumber => $params->{inhouse}
1098
            })->count();
1099
            if ($patron_count != 1) {
1100
                $errors->{inhouse} = 1;
1101
            }
1102
        }
1103
1104
        # Check we don't have more than one item for this bib,
1105
        # if we do, something very odd is going on
1106
        # Having 1 is OK, it means we're likely trying to issue
1107
        # following a previously failed attempt, the item exists
1108
        # so we'll use it
1109
        my @items = $biblio->items->as_list;
1110
        my $item_count = scalar @items;
1111
        if ($item_count > 1) {
1112
            $errors->{itemcount} = 1;
1113
        }
1114
1115
        # Failed validation, go back to the form
1116
        if (%{$errors}) {
1117
            return {
1118
                method  => 'check_out',
1119
                stage   => 'form',
1120
                value   => {
1121
                    params      => $params,
1122
                    statistical => $statistical_patrons,
1123
                    itemtypes   => $itemtypes,
1124
                    libraries   => $libraries,
1125
                    biblio      => $biblio,
1126
                    errors      => $errors
1127
                }
1128
            };
1129
        }
1130
1131
        # Passed validation
1132
        #
1133
        # Create an item if one doesn't already exist,
1134
        # if one does, use that
1135
        my $itemnumber;
1136
        if ($item_count == 0) {
1137
            my $item_hash = {
1138
                homebranch    => $params->{branchcode},
1139
                holdingbranch => $params->{branchcode},
1140
                location      => $params->{branchcode},
1141
                itype         => $params->{item_type},
1142
                barcode       => 'ILL-' . $self->illrequest_id
1143
            };
1144
            my (undef, undef, $item_no) =
1145
                AddItem($item_hash, $self->biblio_id);
1146
            $itemnumber = $item_no;
1147
        } else {
1148
            $itemnumber = $items[0]->itemnumber;
1149
        }
1150
        # Check we have an item before going forward
1151
        if (!$itemnumber) {
1152
            return {
1153
                method  => 'check_out',
1154
                stage   => 'form',
1155
                value   => {
1156
                    params      => $params,
1157
                    itemtypes   => $itemtypes,
1158
                    libraries   => $libraries,
1159
                    statistical => $statistical_patrons,
1160
                    errors      => { item_creation => 1 }
1161
                }
1162
            };
1163
        }
1164
1165
        # Do the check out
1166
        #
1167
        # Gather what we need
1168
        my $target_item = Koha::Items->find( $itemnumber );
1169
        # Determine who we're issuing to
1170
        my $patron = $params->{inhouse} && length $params->{inhouse} > 0 ?
1171
            Koha::Patrons->find({ cardnumber => $params->{inhouse} }) :
1172
            $self->patron;
1173
1174
        my @issue_args = (
1175
            $patron,
1176
            scalar $target_item->barcode
1177
        );
1178
        if ($params->{duedate} && length $params->{duedate} > 0) {
1179
            push @issue_args, $params->{duedate};
1180
        }
1181
        # Check if we can check out
1182
        my ( $error, $confirm, $alerts, $messages ) =
1183
            C4::Circulation::CanBookBeIssued(@issue_args);
1184
1185
        # If we got anything back saying we can't check out,
1186
        # return it to the template
1187
        my $problems = {};
1188
        if ( $error && %{$error} ) { $problems->{error} = $error };
1189
        if ( $confirm && %{$confirm} ) { $problems->{confirm} = $confirm };
1190
        if ( $alerts && %{$alerts} ) { $problems->{alerts} = $alerts };
1191
        if ( $messages && %{$messages} ) { $problems->{messages} = $messages };
1192
1193
        if (%{$problems}) {
1194
            return {
1195
                method  => 'check_out',
1196
                stage   => 'form',
1197
                value   => {
1198
                    params           => $params,
1199
                    itemtypes        => $itemtypes,
1200
                    libraries        => $libraries,
1201
                    statistical      => $statistical_patrons,
1202
                    patron           => $patron,
1203
                    biblio           => $biblio,
1204
                    check_out_errors => $problems
1205
                }
1206
            };
1207
        }
1208
1209
        # We can allegedly check out, so make it so
1210
        # For some reason, AddIssue requires an unblessed Patron
1211
        $issue_args[0] = $patron->unblessed;
1212
        my $issue = C4::Circulation::AddIssue(@issue_args);
1213
1214
        if ($issue && %{$issue}) {
1215
            # Update the request status
1216
            $self->status('CHK')->store;
1217
            return {
1218
                method  => 'check_out',
1219
                stage   => 'done_check_out',
1220
                value   => {
1221
                    params    => $params,
1222
                    patron    => $patron,
1223
                    check_out => $issue
1224
                }
1225
            };
1226
        } else {
1227
            return {
1228
                method  => 'check_out',
1229
                stage   => 'form',
1230
                value   => {
1231
                    params    => $params,
1232
                    itemtypes => $itemtypes,
1233
                    libraries => $libraries,
1234
                    errors    => { item_check_out => 1 }
1235
                }
1236
            };
1237
        }
1238
    }
1239
1240
}
1241
1026
=head3 generic_confirm
1242
=head3 generic_confirm
1027
1243
1028
    my $stage_summary = $illRequest->generic_confirm;
1244
    my $stage_summary = $illRequest->generic_confirm;
(-)a/ill/ill-requests.pl (+8 lines)
Lines 267-272 if ( $backends_available ) { Link Here
267
267
268
        # handle special commit rules & update type
268
        # handle special commit rules & update type
269
        handle_commit_maybe($backend_result, $request);
269
        handle_commit_maybe($backend_result, $request);
270
    } elsif ( $op eq 'check_out') {
271
        my $request = Koha::Illrequests->find($params->{illrequest_id});
272
        my $backend_result = $request->check_out($params);
273
        $template->param(
274
            params  => $params,
275
            whole   => $backend_result,
276
            request => $request
277
        );
270
    } elsif ( $op eq 'illlist') {
278
    } elsif ( $op eq 'illlist') {
271
279
272
        # If we receive a pre-filter, make it available to the template
280
        # If we receive a pre-filter, make it available to the template
(-)a/koha-tmpl/intranet-tmpl/prog/css/src/staff-global.scss (+4 lines)
Lines 3784-3789 input.renew { Link Here
3784
    }
3784
    }
3785
}
3785
}
3786
3786
3787
#ill-issue-title {
3788
    margin: 20px 0 30px 0;
3789
}
3790
3787
#stockrotation {
3791
#stockrotation {
3788
    h3 {
3792
    h3 {
3789
        margin: 30px 0 10px 0;
3793
        margin: 30px 0 10px 0;
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/ill/ill-requests.tt (-1 / +163 lines)
Lines 111-116 Link Here
111
                    <h1>Cancel a confirmed request</h1>
111
                    <h1>Cancel a confirmed request</h1>
112
                    [% PROCESS $whole.template %]
112
                    [% PROCESS $whole.template %]
113
113
114
                [% ELSIF query_type == 'check_out' and !whole.error %]
115
                    [% IF !whole.stage || whole.stage == 'form' %]
116
                        <h1 id="ill-issue-title">Issue requested item to [% request.patron.firstname %] [% request.patron.surname %]</h1>
117
                        [% IF !request.biblio_id || request.biblio_id.length == 0 %]
118
                        <div class="alert">This item cannot be issued as it has no biblio record associated with it</div>
119
                        [% END %]
120
                        [% IF whole.value.errors.itemcount %]
121
                        <div class="alert">The bibliographic record for this request has multiple items, it should only have one. Please fix this then try again.</div>
122
                        [% END %]
123
                        [% IF whole.value.errors.item_creation %]
124
                        <div class="alert">An unknown error occurred while trying to add an item</div>
125
                        [% END %]
126
                        [% IF whole.value.errors.item_check_out %]
127
                        <div class="alert">An unknown error occurred while trying to check out the item</div>
128
                        [% END %]
129
                        [% IF whole.value.check_out_errors %]
130
                            [% IF whole.value.check_out_errors.error.STATS %]
131
                            <div class="alert">
132
                                Local use recorded
133
                            </div>
134
                            [% ELSE %]
135
                            <div class="alert">
136
                                There was a problem checking this item out, please check for problems with the <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% whole.value.patron.borrowernumber %]">patron's account</a>
137
                            </div>
138
                            [% END %]
139
                        [% END %]
140
                        [% IF request.biblio_id && request.biblio_id.length > 0  && !whole.value.check_out_errors.error.STATS %]
141
                            <form method="POST" action="/cgi-bin/koha/ill/ill-requests.pl">
142
                                <fieldset class="rows">
143
                                    <legend>Check out details</legend>
144
                                    [% items = whole.value.biblio.items.unblessed %]
145
                                    [% IF items.size == 1 %]
146
                                        <p>The bibliographic record for this request already has an item attached to it, you are about to check it out</p>
147
                                    [% ELSE %]
148
                                        <p>A bibliographic record for this request exists, but no item. You are about to create an item and check it out</p>
149
                                    [% END %]
150
                                    <ol>
151
                                        <li class="ill_checkout_inhouse">
152
                                            <label for="inhouse" class="ill_checkout_inhouse_label">Statistical patron:</label>
153
                                            <select id="ill_checkout_inhouse_select" name="inhouse" class="ill_checkout_inhouse_select">
154
                                                <option value=""></option>
155
                                                [% FOREACH stat IN whole.value.statistical %]
156
                                                    [% IF stat.borrowernumber == params.inhouse %]
157
                                                        <option value="[% stat.cardnumber %]" selected>[% stat.firstname %] [% stat.surname %]</option>
158
                                                    [% ELSE %]
159
                                                        <option value="[% stat.cardnumber %]">[% stat.firstname %] [% stat.surname %]</option>
160
                                                    [% END %]
161
                                                [% END %]
162
                                            </select>
163
                                            [% IF whole.value.errors.inhouse %]
164
                                            <span class="required">You must choose a valid patron</span>
165
                                            [% END %]
166
                                            <div class="hint">If you do not wish to check out the item to [% request.patron.firstname | html %] [% request.patron.surname | html %] and would rather issue it to an in-house statistical patron, choose the patron here</div>
167
                                        </li>
168
                                        <li class="ill_checkout_item_type">
169
                                            <label for="item_type" class="ill_checkout_item_type_label required">Item type:</label>
170
                                            [% IF items.size != 1 %]
171
                                                <select id="ill_checkout_item_type_select" name="item_type" required>
172
                                                    [% FOREACH type IN whole.value.itemtypes %]
173
                                                        [% IF type.itemtype == params.item_type %]
174
                                                        <option value="[% type.itemtype | html %]" selected>
175
                                                        [% ELSE %]
176
                                                        <option value="[% type.itemtype | html %]">
177
                                                        [% END %]
178
                                                            [% type.description | html %]
179
                                                        </option>
180
                                                    [% END %]
181
                                                </select>
182
                                            [% ELSE %]
183
                                                [% FOREACH type IN whole.value.itemtypes %]
184
                                                    [% IF type.itemtype == items.0.itype %]
185
                                                        [% type.description | html %]
186
                                                    [% END %]
187
                                                [% END %]
188
                                            [% END %]
189
                                            [% IF whole.value.errors.item_type %]
190
                                            <span class="required">You must choose an item type</span>
191
                                            [% END %]
192
                                        </li>
193
                                        [% IF items.size == 1 %]
194
                                            <li>
195
                                                <label for="barcode" class="ill_checkout_barcode_label">Item barcode:</label>
196
                                                [% items.0.barcode %]
197
                                            </li>
198
                                        [% END %]
199
                                        <li class="ill_checkout_branchcode">
200
                                            <label for="branchcode" class="ill_checkout_branchcode_label required">Library:</label>
201
                                            [% branchcode = items.size == 1 ? items.0.homebranch : params.branchcode ? params.branchcode : request.branchcode %]
202
                                            [% IF items.size != 1 %]
203
                                                <select name="branchcode" id="ill_checkout_branchcode_select" required>
204
                                                    [% PROCESS options_for_libraries libraries => Branches.all( selected => branchcode ) %]
205
                                                </select>
206
                                            [% ELSE %]
207
                                                [% FOREACH branch IN whole.value.libraries.unblessed %]
208
                                                    [% IF branch.branchcode == branchcode %]
209
                                                        [% branch.branchname %]
210
                                                    [% END %]
211
                                                [% END %]
212
                                            [% END %]
213
                                            [% IF whole.value.errors.branchcode %]
214
                                            <span class="required">You must choose a branch</span>
215
                                            [% END %]
216
                                        </li>
217
                                        <li class="ill_checkout_due_date">
218
                                            <label for="duedate" class="ill_checkout_duedate_label">Due date:</label>
219
                                            <input name="duedate" id="ill_checkout_duedate_input" type="text" value="[% params.duedate | html %]"> [% INCLUDE 'date-format.inc' %]
220
                                            <div class="hint">If you do not specify a due date, it will be set according to circulation rules</p>
221
                                        </li>
222
                                    </ol>
223
                                </fieldset>
224
                                <fieldset class="action">
225
                                    <input type="hidden" value="check_out" name="method">
226
                                    <input type="hidden" value="form" name="stage">
227
                                    [% IF items.size == 1 %]
228
                                        <input name="branchcode" type="hidden" value="[% branchcode  %]">
229
                                        <input name="item_type" type="hidden" value="[% items.0.itype %]">
230
                                    [% END %]
231
                                    <input type="hidden" value="[% request.illrequest_id | html %]" name="illrequest_id">
232
                                    <input type="submit" value="Submit">
233
                                    <a class="cancel" href="/cgi-bin/koha/ill/ill-requests.pl?method=illview&amp;illrequest_id=[% request.id | html %]">Cancel</a>
234
                                </fieldset>
235
                            </form>
236
                        [% END %]
237
                        [% IF whole.value.check_out_errors.error.STATS %]
238
                            <a class="cancel" href="/cgi-bin/koha/ill/ill-requests.pl?method=illview&amp;illrequest_id=[% request.id | html %]">Return to request</a>
239
                        [% END %]
240
                    [% ELSIF whole.stage == 'done_check_out' %]
241
                        <h1>Item checked out</h1>
242
                        <fieldset class="rows">
243
                            <legend>Check out details</legend>
244
                            <ol>
245
                                <li>
246
                                    <label>Checked out to:</label>
247
                                    [% whole.value.patron.firstname | html %] [% whole.value.patron.surname | html %]
248
                                </li>
249
                                <li>
250
                                    <label>Due date:</label>
251
                                    [% whole.value.check_out.date_due | $KohaDates with_hours => 1 %]
252
                                </li>
253
                            </ol>
254
                        </fieldset>
255
                        <fieldset class="action">
256
                            <a class="cancel" href="/cgi-bin/koha/ill/ill-requests.pl?method=illview&amp;illrequest_id=[% request.id | html %]">Return to request</a>
257
                        </fieldset>
258
                    [% END %]
259
114
                [% ELSIF query_type == 'generic_confirm' %]
260
                [% ELSIF query_type == 'generic_confirm' %]
115
                    <h1>Place request with partner libraries</h1>
261
                    <h1>Place request with partner libraries</h1>
116
                  [% IF error %]
262
                  [% IF error %]
Lines 534-547 Link Here
534
    [% INCLUDE 'datatables.inc' %]
680
    [% INCLUDE 'datatables.inc' %]
535
    [% INCLUDE 'columns_settings.inc' %]
681
    [% INCLUDE 'columns_settings.inc' %]
536
    [% INCLUDE 'calendar.inc' %]
682
    [% INCLUDE 'calendar.inc' %]
683
    [% Asset.js("lib/jquery/plugins/jquery-ui-timepicker-addon.min.js") | $raw %]
537
    [% Asset.js("lib/jquery/plugins/jquery.checkboxes.min.js") | $raw %]
684
    [% Asset.js("lib/jquery/plugins/jquery.checkboxes.min.js") | $raw %]
538
    <script>
685
    <script>
539
        var prefilters = '[% prefilters | $raw %]';
686
        var prefilters = '[% prefilters | $raw %]';
540
        // Set column settings
687
        // Set column settings
541
        var columns_settings = [% ColumnsSettings.GetColumns( 'illrequests', 'ill-requests', 'ill-requests', 'json' ) %];
688
        var columns_settings = [% ColumnsSettings.GetColumns( 'illrequests', 'ill-requests', 'ill-requests', 'json' ) %];
689
        $("#ill_checkout_duedate_input").datetimepicker({
690
            hour: 23,
691
            minute: 59
692
        }).on("change", function(e, value) {
693
            if ( ! is_valid_date( $(this).val() ) ) {$(this).val("");}
694
        });
695
    </script>
696
    <script>
697
        $('#ill_checkout_inhouse_select').on('change', function() {
698
            if ($(this).val().length > 0) {
699
                $('.ill_checkout_due_date').hide();
700
            } else {
701
                $('.ill_checkout_due_date').show();
702
            }
703
        });
542
    </script>
704
    </script>
543
    [% INCLUDE 'ill-list-table-strings.inc' %]
705
    [% INCLUDE 'ill-list-table-strings.inc' %]
544
    [% Asset.js("js/ill-list-table.js") | $raw %]
706
    [% Asset.js("js/ill-list-table.js") | $raw %]
707
    [% Asset.js("js/ill-check-out.js") | $raw %]
545
[% END %]
708
[% END %]
546
709
547
[% TRY %]
710
[% TRY %]
548
- 

Return to bug 23112