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

(-)a/Koha/Illrequest.pm (-3 / +219 lines)
Lines 36-41 use Koha::AuthorisedValue; Link Here
36
use Koha::Illrequest::Logger;
36
use Koha::Illrequest::Logger;
37
use Koha::Patron;
37
use Koha::Patron;
38
use Koha::AuthorisedValues;
38
use Koha::AuthorisedValues;
39
use Koha::Biblios;
40
use Koha::Items;
41
use Koha::ItemTypes;
42
use Koha::Libraries;
43
use C4::Items qw( AddItem );
44
use C4::Circulation qw( CanBookBeIssued AddIssue  );
39
45
40
use base qw(Koha::Object);
46
use base qw(Koha::Object);
41
47
Lines 426-432 sub _core_status_graph { Link Here
426
            name           => 'Requested',
432
            name           => 'Requested',
427
            ui_method_name => 'Confirm request',
433
            ui_method_name => 'Confirm request',
428
            method         => 'confirm',
434
            method         => 'confirm',
429
            next_actions   => [ 'REQREV', 'COMP' ],
435
            next_actions   => [ 'REQREV', 'COMP', 'CHK' ],
430
            ui_method_icon => 'fa-check',
436
            ui_method_icon => 'fa-check',
431
        },
437
        },
432
        GENREQ => {
438
        GENREQ => {
Lines 435-441 sub _core_status_graph { Link Here
435
            name           => 'Requested from partners',
441
            name           => 'Requested from partners',
436
            ui_method_name => 'Place request with partners',
442
            ui_method_name => 'Place request with partners',
437
            method         => 'generic_confirm',
443
            method         => 'generic_confirm',
438
            next_actions   => [ 'COMP' ],
444
            next_actions   => [ 'COMP', 'CHK' ],
439
            ui_method_icon => 'fa-send-o',
445
            ui_method_icon => 'fa-send-o',
440
        },
446
        },
441
        REQREV => {
447
        REQREV => {
Lines 471-477 sub _core_status_graph { Link Here
471
            name           => 'Completed',
477
            name           => 'Completed',
472
            ui_method_name => 'Mark completed',
478
            ui_method_name => 'Mark completed',
473
            method         => 'mark_completed',
479
            method         => 'mark_completed',
474
            next_actions   => [ ],
480
            next_actions   => [ 'CHK' ],
475
            ui_method_icon => 'fa-check',
481
            ui_method_icon => 'fa-check',
476
        },
482
        },
477
        KILL => {
483
        KILL => {
Lines 483-488 sub _core_status_graph { Link Here
483
            next_actions   => [ ],
489
            next_actions   => [ ],
484
            ui_method_icon => 'fa-trash',
490
            ui_method_icon => 'fa-trash',
485
        },
491
        },
492
        CHK => {
493
            prev_actions   => [ 'REQ', 'GENREQ', 'COMP' ],
494
            id             => 'CHK',
495
            name           => 'Checked out',
496
            ui_method_name => 'Check out',
497
            method         => 'check_out',
498
            next_actions   => [ ],
499
            ui_method_icon => 'fa-upload',
500
        }
486
    };
501
    };
487
}
502
}
488
503
Lines 1024-1029 sub requires_moderation { Link Here
1024
    return $require_moderation->{$self->status};
1039
    return $require_moderation->{$self->status};
1025
}
1040
}
1026
1041
1042
=head3 check_out
1043
1044
    my $stage_summary = $request->check_out;
1045
1046
Handle the check_out method. The first stage involves gathering the required
1047
data from the user via a form, the second stage creates an item and tries to
1048
issue it to the patron. If successful, it notifies the patron, then it
1049
returns a summary of how things went
1050
1051
=cut
1052
1053
sub check_out {
1054
    my ( $self, $params ) = @_;
1055
1056
    # Objects required by the template
1057
    my $itemtypes = Koha::ItemTypes->search(
1058
        {},
1059
        { order_by => ['description'] }
1060
    );
1061
    my $libraries = Koha::Libraries->search(
1062
        {},
1063
        { order_by => ['branchcode'] }
1064
    );
1065
    my $biblio = Koha::Biblios->find({
1066
        biblionumber => $self->biblio_id
1067
    });
1068
    # Find all statistical patrons
1069
    my $statistical_patrons = Koha::Patrons->search(
1070
        { 'category_type' => 'x' },
1071
        { join => { 'categorycode' => 'borrowers' } }
1072
    );
1073
1074
    if (!$params->{stage} || $params->{stage} eq 'init') {
1075
        # Present a form to gather the required data
1076
        #
1077
        # We may be viewing this page having previously tried to issue
1078
        # the item (in which case, we may already have created an item)
1079
        # so we pass the biblio for this request
1080
        return {
1081
            method  => 'check_out',
1082
            stage   => 'form',
1083
            value   => {
1084
                itemtypes   => $itemtypes,
1085
                libraries   => $libraries,
1086
                statistical => $statistical_patrons,
1087
                biblio      => $biblio
1088
            }
1089
        };
1090
    } elsif ($params->{stage} eq 'form') {
1091
        # Validate what we've got and return with an error if we fail
1092
        my $errors = {};
1093
        if (!$params->{item_type} || length $params->{item_type} == 0) {
1094
            $errors->{item_type} = 1;
1095
        }
1096
        if ($params->{inhouse} && length $params->{inhouse} > 0) {
1097
            my $patron_count = Koha::Patrons->search({
1098
                cardnumber => $params->{inhouse}
1099
            })->count();
1100
            if ($patron_count != 1) {
1101
                $errors->{inhouse} = 1;
1102
            }
1103
        }
1104
1105
        # Check we don't have more than one item for this bib,
1106
        # if we do, something very odd is going on
1107
        # Having 1 is OK, it means we're likely trying to issue
1108
        # following a previously failed attempt, the item exists
1109
        # so we'll use it
1110
        my @items = $biblio->items->as_list;
1111
        my $item_count = scalar @items;
1112
        if ($item_count > 1) {
1113
            $errors->{itemcount} = 1;
1114
        }
1115
1116
        # Failed validation, go back to the form
1117
        if (%{$errors}) {
1118
            return {
1119
                method  => 'check_out',
1120
                stage   => 'form',
1121
                value   => {
1122
                    params      => $params,
1123
                    statistical => $statistical_patrons,
1124
                    itemtypes   => $itemtypes,
1125
                    libraries   => $libraries,
1126
                    biblio      => $biblio,
1127
                    errors      => $errors
1128
                }
1129
            };
1130
        }
1131
1132
        # Passed validation
1133
        #
1134
        # Create an item if one doesn't already exist,
1135
        # if one does, use that
1136
        my $itemnumber;    
1137
        if ($item_count == 0) {
1138
            my $item_hash = {
1139
                homebranch    => $params->{branchcode},
1140
                holdingbranch => $params->{branchcode},
1141
                location      => $params->{branchcode},
1142
                itype         => $params->{item_type},
1143
                barcode       => 'ILL-' . $self->illrequest_id
1144
            };
1145
            my (undef, undef, $item_no) =
1146
                AddItem($item_hash, $self->biblio_id);
1147
            $itemnumber = $item_no;
1148
        } else {
1149
            $itemnumber = $items[0]->itemnumber;
1150
        }
1151
        # Check we have an item before going forward
1152
        if (!$itemnumber) {
1153
            return {
1154
                method  => 'check_out',
1155
                stage   => 'form',
1156
                value   => {
1157
                    params      => $params,
1158
                    itemtypes   => $itemtypes,
1159
                    libraries   => $libraries,
1160
                    statistical => $statistical_patrons,
1161
                    errors      => { item_creation => 1 }
1162
                }
1163
            };
1164
        }
1165
1166
        # Do the check out
1167
        #
1168
        # Gather what we need
1169
        my $target_item = Koha::Items->find( $itemnumber );
1170
        # Determine who we're issuing to
1171
        my $patron = $params->{inhouse} && length $params->{inhouse} > 0 ?
1172
            Koha::Patrons->find({ cardnumber => $params->{inhouse} }) :
1173
            $self->patron;
1174
1175
        my @issue_args = (
1176
            $patron,
1177
            scalar $target_item->barcode
1178
        );
1179
        if ($params->{duedate} && length $params->{duedate} > 0) {
1180
            push @issue_args, $params->{duedate};
1181
        }
1182
        # Check if we can check out
1183
        my ( $error, $confirm, $alerts, $messages ) =
1184
            C4::Circulation::CanBookBeIssued(@issue_args);
1185
1186
        # If we got anything back saying we can't check out,
1187
        # return it to the template
1188
        my $problems = {};
1189
        if ( $error && %{$error} ) { $problems->{error} = $error };
1190
        if ( $confirm && %{$confirm} ) { $problems->{confirm} = $confirm };
1191
        if ( $alerts && %{$alerts} ) { $problems->{alerts} = $alerts };
1192
        if ( $messages && %{$messages} ) { $problems->{messages} = $messages };
1193
1194
        if (%{$problems}) {
1195
            return {
1196
                method  => 'check_out',
1197
                stage   => 'form',
1198
                value   => {
1199
                    params           => $params,
1200
                    itemtypes        => $itemtypes,
1201
                    libraries        => $libraries,
1202
                    statistical      => $statistical_patrons,
1203
                    patron           => $patron,
1204
                    biblio           => $biblio,
1205
                    check_out_errors => $problems
1206
                }
1207
            };
1208
        }
1209
1210
        # We can allegedly check out, so make it so
1211
        # For some reason, AddIssue requires an unblessed Patron
1212
        $issue_args[0] = $patron->unblessed;
1213
        my $issue = C4::Circulation::AddIssue(@issue_args);
1214
1215
        if ($issue && %{$issue}) {
1216
            # Update the request status
1217
            $self->status('CHK')->store;
1218
            return {
1219
                method  => 'check_out',
1220
                stage   => 'done_check_out',
1221
                value   => {
1222
                    params    => $params,
1223
                    patron    => $patron,
1224
                    check_out => $issue
1225
                }
1226
            };
1227
        } else {
1228
            return {
1229
                method  => 'check_out',
1230
                stage   => 'form',
1231
                value   => {
1232
                    params    => $params,
1233
                    itemtypes => $itemtypes,
1234
                    libraries => $libraries,
1235
                    errors    => { item_check_out => 1 }
1236
                }
1237
            };
1238
        }
1239
    }
1240
1241
}
1242
1027
=head3 generic_confirm
1243
=head3 generic_confirm
1028
1244
1029
    my $stage_summary = $illRequest->generic_confirm;
1245
    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 3961-3966 input.renew { Link Here
3961
    width: 100% !important;
3961
    width: 100% !important;
3962
}
3962
}
3963
3963
3964
#ill-issue-title {
3965
    margin: 20px 0 30px 0;
3966
}
3967
3964
#stockrotation {
3968
#stockrotation {
3965
    h3 {
3969
    h3 {
3966
        margin: 30px 0 10px 0;
3970
        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