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

(-)a/C4/Accounts.pm (-1 / +6 lines)
Lines 70-76 FIXME : if no replacement price, borrower just doesn't get charged? Link Here
70
sub chargelostitem {
70
sub chargelostitem {
71
    my $dbh = C4::Context->dbh();
71
    my $dbh = C4::Context->dbh();
72
    my ($borrowernumber, $itemnumber, $amount, $description) = @_;
72
    my ($borrowernumber, $itemnumber, $amount, $description) = @_;
73
    my $itype = Koha::ItemTypes->find({ itemtype => Koha::Items->find($itemnumber)->effective_itemtype() });
73
    my $item  = Koha::Items->find($itemnumber);
74
    my $itype = Koha::ItemTypes->find({ itemtype => $item->effective_itemtype() });
74
    my $replacementprice = $amount;
75
    my $replacementprice = $amount;
75
    my $defaultreplacecost = $itype->defaultreplacecost;
76
    my $defaultreplacecost = $itype->defaultreplacecost;
76
    my $processfee = $itype->processfee;
77
    my $processfee = $itype->processfee;
Lines 80-85 sub chargelostitem { Link Here
80
        $replacementprice = $defaultreplacecost;
81
        $replacementprice = $defaultreplacecost;
81
    }
82
    }
82
    my $checkout = Koha::Checkouts->find({ itemnumber => $itemnumber });
83
    my $checkout = Koha::Checkouts->find({ itemnumber => $itemnumber });
84
    if ( !$checkout && $item->in_bundle ) {
85
        my $host = $item->bundle_host;
86
        $checkout = $host->checkout;
87
    }
83
    my $issue_id = $checkout ? $checkout->issue_id : undef;
88
    my $issue_id = $checkout ? $checkout->issue_id : undef;
84
89
85
    my $account = Koha::Account->new({ patron_id => $borrowernumber });
90
    my $account = Koha::Account->new({ patron_id => $borrowernumber });
(-)a/Koha/Item.pm (-1 / +15 lines)
Lines 397-402 sub checkout { Link Here
397
    return Koha::Checkout->_new_from_dbic( $checkout_rs );
397
    return Koha::Checkout->_new_from_dbic( $checkout_rs );
398
}
398
}
399
399
400
=head3 return_claims
401
402
  my $return_claims = $item->return_claims;
403
404
Return any return_claims associated with this item
405
406
=cut
407
408
sub return_claims {
409
    my ( $self, $params, $attrs ) = @_;
410
    my $claims_rs = $self->_result->return_claims->search($params, $attrs);
411
    return Koha::Checkouts::ReturnClaims->_new_from_dbic( $claims_rs );
412
}
413
400
=head3 holds
414
=head3 holds
401
415
402
my $holds = $item->holds();
416
my $holds = $item->holds();
Lines 1070-1076 Internal function, not exported, called only by Koha::Item->store. Link Here
1070
sub _set_found_trigger {
1084
sub _set_found_trigger {
1071
    my ( $self, $pre_mod_item ) = @_;
1085
    my ( $self, $pre_mod_item ) = @_;
1072
1086
1073
    ## If item was lost, it has now been found, reverse any list item charges if necessary.
1087
    # Reverse any lost item charges if necessary.
1074
    my $no_refund_after_days =
1088
    my $no_refund_after_days =
1075
      C4::Context->preference('NoRefundOnLostReturnedItemsAge');
1089
      C4::Context->preference('NoRefundOnLostReturnedItemsAge');
1076
    if ($no_refund_after_days) {
1090
    if ($no_refund_after_days) {
(-)a/circ/returns.pl (-37 / +72 lines)
Lines 353-395 if ($barcode) { Link Here
353
            }
353
            }
354
        }
354
        }
355
355
356
        # Mark missing bundle items as lost and report unexpected items
357
        if ( $item->is_bundle ) {
358
            my $BundleLostValue = C4::Context->preference('BundleLostValue');
359
            my $barcodes = $query->param('verify-items-bundle-contents-barcodes');
360
            my @barcodes = map { s/^\s+|\s+$//gr } ( split /\n/, $barcodes );
361
            my $expected_items = { map { $_->barcode => $_ } $item->bundle_items->as_list };
362
            my $verify_items = Koha::Items->search( { barcode => { 'in' => \@barcodes } } );
363
            my @unexpected_items;
364
            my @missing_items;
365
            my @bundle_items;
366
            while ( my $verify_item = $verify_items->next ) {
367
                # Fix and lost statuses
368
                $verify_item->itemlost(0);
369
370
                # Expected item, remove from lookup table
371
                if ( delete $expected_items->{$verify_item->barcode} ) {
372
                    push @bundle_items, $verify_item;
373
                }
374
                # Unexpected item, warn and remove from bundle
375
                else {
376
                    $verify_item->remove_from_bundle;
377
                    push @unexpected_items, $verify_item;
378
                }
379
                # Store results
380
                $verify_item->store();
381
            }
382
            for my $missing_item ( keys %{$expected_items} ) {
383
                my $bundle_item = $expected_items->{$missing_item};
384
                $bundle_item->itemlost($BundleLostValue)->store();
385
                push @missing_items, $bundle_item;
386
            }
387
            $template->param(
388
                unexpected_items => \@unexpected_items,
389
                missing_items    => \@missing_items,
390
                bundle_items     => \@bundle_items
391
            );
392
        }
393
    } elsif ( C4::Context->preference('ShowAllCheckins') and !$messages->{'BadBarcode'} and !$needs_confirm and !$bundle_confirm ) {
356
    } elsif ( C4::Context->preference('ShowAllCheckins') and !$messages->{'BadBarcode'} and !$needs_confirm and !$bundle_confirm ) {
394
        $input{duedate}   = 0;
357
        $input{duedate}   = 0;
395
        $returneditems{0} = $barcode;
358
        $returneditems{0} = $barcode;
Lines 407-412 if ($barcode) { Link Here
407
            items_bundle_return_confirmation => 1,
370
            items_bundle_return_confirmation => 1,
408
        );
371
        );
409
    }
372
    }
373
374
    # Mark missing bundle items as lost and report unexpected items
375
    if ( $item->is_bundle && $query->param('confirm_items_bundle_return') ) {
376
        my $BundleLostValue = C4::Context->preference('BundleLostValue');
377
        my $barcodes = $query->param('verify-items-bundle-contents-barcodes');
378
        my @barcodes = map { s/^\s+|\s+$//gr } ( split /\n/, $barcodes );
379
        my $expected_items = { map { $_->barcode => $_ } $item->bundle_items->as_list };
380
        my $verify_items = Koha::Items->search( { barcode => { 'in' => \@barcodes } } );
381
        my @unexpected_items;
382
        my @missing_items;
383
        my @bundle_items;
384
        while ( my $verify_item = $verify_items->next ) {
385
            # Fix and lost statuses
386
            $verify_item->itemlost(0);
387
388
            # Update last_seen
389
            $verify_item->datelastseen( dt_from_string()->ymd() );
390
391
            # Update last_borrowed if actual checkin
392
            $verify_item->datelastborrowed( dt_from_string()->ymd() ) if $issue;
393
394
            # Expected item, remove from lookup table
395
            if ( delete $expected_items->{$verify_item->barcode} ) {
396
                push @bundle_items, $verify_item;
397
            }
398
            # Unexpected item, warn and remove from bundle
399
            else {
400
                $verify_item->remove_from_bundle;
401
                push @unexpected_items, $verify_item;
402
            }
403
404
            # Store results
405
            $verify_item->store();
406
        }
407
        for my $missing_item ( keys %{$expected_items} ) {
408
            my $bundle_item = $expected_items->{$missing_item};
409
            $bundle_item->itemlost($BundleLostValue)->store();
410
            # Add return_claim record if this is an actual checkin
411
            if ($issue) {
412
                $bundle_item->_result->create_related(
413
                    'return_claims',
414
                    {
415
                        issue_id       => $issue->issue_id,
416
                        itemnumber     => $bundle_item->itemnumber,
417
                        borrowernumber => $issue->borrowernumber,
418
                        created_by     => C4::Context->userenv()->{number},
419
                        created_on     => dt_from_string
420
                    }
421
                );
422
            }
423
            push @missing_items, $bundle_item;
424
            # NOTE: We cannot use C4::LostItem here because the item itself doesn't have a checkout
425
            # and thus would not get charged.. it's checked out as part of the bundle.
426
            if ( C4::Context->preference('WhenLostChargeReplacementFee') && $issue ) {
427
                C4::Accounts::chargelostitem(
428
                    $issue->borrowernumber,
429
                    $bundle_item->itemnumber,
430
                    $bundle_item->replacementprice,
431
                    sprintf( "%s %s %s",
432
                        $bundle_item->biblio->title  || q{},
433
                        $bundle_item->barcode        || q{},
434
                        $bundle_item->itemcallnumber || q{},
435
                    ),
436
                );
437
            }
438
        }
439
        $template->param(
440
            unexpected_items => \@unexpected_items,
441
            missing_items    => \@missing_items,
442
            bundle_items     => \@bundle_items
443
        );
444
    }
410
}
445
}
411
$template->param( inputloop => \@inputloop );
446
$template->param( inputloop => \@inputloop );
412
447
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt (-3 / +4 lines)
Lines 1378-1383 Note that permanent location is a code, and location may be an authval. Link Here
1378
        browser.show();
1378
        browser.show();
1379
1379
1380
        var bundle_columns = [% TablesSettings.GetColumns('catalogue', 'detail','bundle_tables','json') | $raw %];
1380
        var bundle_columns = [% TablesSettings.GetColumns('catalogue', 'detail','bundle_tables','json') | $raw %];
1381
        var bundle_lost_value = [% Koha.Preference('BundleLostValue') %];
1381
        $(document).ready(function() {
1382
        $(document).ready(function() {
1382
1383
1383
            function createChild ( row, itemnumber ) {
1384
            function createChild ( row, itemnumber ) {
Lines 1464-1473 Note that permanent location is a code, and location may be an authval. Link Here
1464
                            "searchable": false,
1465
                            "searchable": false,
1465
                            "orderable": true,
1466
                            "orderable": true,
1466
                            "render": function(data, type, row, meta) {
1467
                            "render": function(data, type, row, meta) {
1467
                                if ( row.lost_status ) {
1468
                                if ( row.lost_status == bundle_lost_value ) {
1468
                                    return "Lost: " + row.lost_status;
1469
                                    return "Last seen: " + row.last_seen_date;
1469
                                }
1470
                                }
1470
                                return "";
1471
                                return "Present";
1471
                            }
1472
                            }
1472
                        },
1473
                        },
1473
                        {
1474
                        {
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/returns.tt (-1 / +19 lines)
Lines 429-439 Link Here
429
                                                        <th>[% t('Author') | html %]</th>
429
                                                        <th>[% t('Author') | html %]</th>
430
                                                        <th>[% t('Item type') | html %]</th>
430
                                                        <th>[% t('Item type') | html %]</th>
431
                                                        <th>[% t('Barcode') | html %]</th>
431
                                                        <th>[% t('Barcode') | html %]</th>
432
                                                        [% IF !item.onloan %]
432
                                                        <th>[% t('Status') | html %]</th>
433
                                                        <th>[% t('Status') | html %]</th>
434
                                                        [% END %]
433
                                                    </tr>
435
                                                    </tr>
434
                                                </thead>
436
                                                </thead>
435
                                                <tbody>
437
                                                <tbody>
436
                                                    [% FOREACH bundle_item IN item.bundle_items %]
438
                                                    [% FOREACH bundle_item IN item.bundle_items %]
439
                                                    [% IF !item.onloan %]
437
                                                    <tr data-barcode="[% bundle_item.barcode | html %]">
440
                                                    <tr data-barcode="[% bundle_item.barcode | html %]">
438
                                                        <td>[% INCLUDE 'biblio-title.inc' biblio=bundle_item.biblio link = 1 %]</td>
441
                                                        <td>[% INCLUDE 'biblio-title.inc' biblio=bundle_item.biblio link = 1 %]</td>
439
                                                        <td>[% bundle_item.biblio.author | html %]</td>
442
                                                        <td>[% bundle_item.biblio.author | html %]</td>
Lines 441-446 Link Here
441
                                                        <td>[% bundle_item.barcode | html %]</td>
444
                                                        <td>[% bundle_item.barcode | html %]</td>
442
                                                        <td>[% INCLUDE 'item-status.inc' item=bundle_item %]</td>
445
                                                        <td>[% INCLUDE 'item-status.inc' item=bundle_item %]</td>
443
                                                    </tr>
446
                                                    </tr>
447
                                                    [% ELSIF !bundle_item.itemlost %]
448
                                                    <tr data-barcode="[% bundle_item.barcode | html %]">
449
                                                        <td>[% INCLUDE 'biblio-title.inc' biblio=bundle_item.biblio link = 1 %]</td>
450
                                                        <td>[% bundle_item.biblio.author | html %]</td>
451
                                                        <td>[% ItemTypes.GetDescription(bundle_item.itype) | html %]</td>
452
                                                        <td>[% bundle_item.barcode | html %]</td>
453
                                                    </tr>
454
                                                    [% END %]
444
                                                    [% END %]
455
                                                    [% END %]
445
                                                </tbody>
456
                                                </tbody>
446
                                            </table>
457
                                            </table>
Lines 448-454 Link Here
448
                                            <div class="form-group">
459
                                            <div class="form-group">
449
                                                <label for="verify-items-bundle-contents-barcodes">Barcodes</label>
460
                                                <label for="verify-items-bundle-contents-barcodes">Barcodes</label>
450
                                                <textarea autocomplete="off" id="verify-items-bundle-contents-barcodes" name="verify-items-bundle-contents-barcodes" class="form-control"></textarea>
461
                                                <textarea autocomplete="off" id="verify-items-bundle-contents-barcodes" name="verify-items-bundle-contents-barcodes" class="form-control"></textarea>
462
                                                [% IF item.onloan %]
451
                                                <div class="help-block">[% t('Scan all barcodes of items found in the items bundle. If any items are missing, they will be marked as lost') | html %]</div>
463
                                                <div class="help-block">[% t('Scan all barcodes of items found in the items bundle. If any items are missing, they will be marked as lost') | html %]</div>
464
                                                [% ELSE %]
465
                                                <div class="help-block">[% t('Optionally scan all barcodes of items found in the items bundle to perform an inventory check. If any items are missing, they will be marked as lost') | html %]</div>
466
                                                [% END %]
452
                                            </div>
467
                                            </div>
453
468
454
                                        </div>
469
                                        </div>
Lines 460-466 Link Here
460
                                            <input type="hidden" name="dd-[% inputloo.counter | html %]" value="[% inputloo.duedate | html %]" />
475
                                            <input type="hidden" name="dd-[% inputloo.counter | html %]" value="[% inputloo.duedate | html %]" />
461
                                            <input type="hidden" name="bn-[% inputloo.counter | html %]" value="[% inputloo.borrowernumber | html %]" />
476
                                            <input type="hidden" name="bn-[% inputloo.counter | html %]" value="[% inputloo.borrowernumber | html %]" />
462
                                            [% END %]
477
                                            [% END %]
478
                                            [% IF item.onloan %]
463
                                            <button type="submit" class="btn btn-default"><i class="fa fa-check"></i> [% t('Confirm checkin and mark missing items as lost') | html %]</button>
479
                                            <button type="submit" class="btn btn-default"><i class="fa fa-check"></i> [% t('Confirm checkin and mark missing items as lost') | html %]</button>
480
                                            [% ELSE %]
481
                                            <button type="submit" class="btn btn-default"><i class="fa fa-check"></i> [% t('Confirm inventory check and mark items as lost') | html %]</button>
482
                                            [% END %]
464
                                            <button type="button" data-dismiss="modal" class="btn btn-default"><i class="fa fa-close"></i> [% t('Cancel') | html %]</button>
483
                                            <button type="button" data-dismiss="modal" class="btn btn-default"><i class="fa fa-close"></i> [% t('Cancel') | html %]</button>
465
                                        </div>
484
                                        </div>
466
                                    </form>
485
                                    </form>
467
- 

Return to bug 28854