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 404-409 sub checkout { Link Here
404
    return Koha::Checkout->_new_from_dbic( $checkout_rs );
404
    return Koha::Checkout->_new_from_dbic( $checkout_rs );
405
}
405
}
406
406
407
=head3 return_claims
408
409
  my $return_claims = $item->return_claims;
410
411
Return any return_claims associated with this item
412
413
=cut
414
415
sub return_claims {
416
    my ( $self, $params, $attrs ) = @_;
417
    my $claims_rs = $self->_result->return_claims->search($params, $attrs);
418
    return Koha::Checkouts::ReturnClaims->_new_from_dbic( $claims_rs );
419
}
420
407
=head3 holds
421
=head3 holds
408
422
409
my $holds = $item->holds();
423
my $holds = $item->holds();
Lines 1077-1083 Internal function, not exported, called only by Koha::Item->store. Link Here
1077
sub _set_found_trigger {
1091
sub _set_found_trigger {
1078
    my ( $self, $pre_mod_item ) = @_;
1092
    my ( $self, $pre_mod_item ) = @_;
1079
1093
1080
    ## If item was lost, it has now been found, reverse any list item charges if necessary.
1094
    # Reverse any lost item charges if necessary.
1081
    my $no_refund_after_days =
1095
    my $no_refund_after_days =
1082
      C4::Context->preference('NoRefundOnLostReturnedItemsAge');
1096
      C4::Context->preference('NoRefundOnLostReturnedItemsAge');
1083
    if ($no_refund_after_days) {
1097
    if ($no_refund_after_days) {
(-)a/circ/returns.pl (-37 / +72 lines)
Lines 393-435 if ($barcode) { Link Here
393
            }
393
            }
394
        }
394
        }
395
395
396
        # Mark missing bundle items as lost and report unexpected items
397
        if ( $item->is_bundle ) {
398
            my $BundleLostValue = C4::Context->preference('BundleLostValue');
399
            my $barcodes = $query->param('verify-items-bundle-contents-barcodes');
400
            my @barcodes = map { s/^\s+|\s+$//gr } ( split /\n/, $barcodes );
401
            my $expected_items = { map { $_->barcode => $_ } $item->bundle_items->as_list };
402
            my $verify_items = Koha::Items->search( { barcode => { 'in' => \@barcodes } } );
403
            my @unexpected_items;
404
            my @missing_items;
405
            my @bundle_items;
406
            while ( my $verify_item = $verify_items->next ) {
407
                # Fix and lost statuses
408
                $verify_item->itemlost(0);
409
410
                # Expected item, remove from lookup table
411
                if ( delete $expected_items->{$verify_item->barcode} ) {
412
                    push @bundle_items, $verify_item;
413
                }
414
                # Unexpected item, warn and remove from bundle
415
                else {
416
                    $verify_item->remove_from_bundle;
417
                    push @unexpected_items, $verify_item;
418
                }
419
                # Store results
420
                $verify_item->store();
421
            }
422
            for my $missing_item ( keys %{$expected_items} ) {
423
                my $bundle_item = $expected_items->{$missing_item};
424
                $bundle_item->itemlost($BundleLostValue)->store();
425
                push @missing_items, $bundle_item;
426
            }
427
            $template->param(
428
                unexpected_items => \@unexpected_items,
429
                missing_items    => \@missing_items,
430
                bundle_items     => \@bundle_items
431
            );
432
        }
433
    } elsif ( C4::Context->preference('ShowAllCheckins') and !$messages->{'BadBarcode'} and !$needs_confirm and !$bundle_confirm ) {
396
    } elsif ( C4::Context->preference('ShowAllCheckins') and !$messages->{'BadBarcode'} and !$needs_confirm and !$bundle_confirm ) {
434
        $input{duedate}   = 0;
397
        $input{duedate}   = 0;
435
        $returneditems{0} = $barcode;
398
        $returneditems{0} = $barcode;
Lines 447-452 if ($barcode) { Link Here
447
            items_bundle_return_confirmation => 1,
410
            items_bundle_return_confirmation => 1,
448
        );
411
        );
449
    }
412
    }
413
414
    # Mark missing bundle items as lost and report unexpected items
415
    if ( $item->is_bundle && $query->param('confirm_items_bundle_return') ) {
416
        my $BundleLostValue = C4::Context->preference('BundleLostValue');
417
        my $barcodes = $query->param('verify-items-bundle-contents-barcodes');
418
        my @barcodes = map { s/^\s+|\s+$//gr } ( split /\n/, $barcodes );
419
        my $expected_items = { map { $_->barcode => $_ } $item->bundle_items->as_list };
420
        my $verify_items = Koha::Items->search( { barcode => { 'in' => \@barcodes } } );
421
        my @unexpected_items;
422
        my @missing_items;
423
        my @bundle_items;
424
        while ( my $verify_item = $verify_items->next ) {
425
            # Fix and lost statuses
426
            $verify_item->itemlost(0);
427
428
            # Update last_seen
429
            $verify_item->datelastseen( dt_from_string()->ymd() );
430
431
            # Update last_borrowed if actual checkin
432
            $verify_item->datelastborrowed( dt_from_string()->ymd() ) if $issue;
433
434
            # Expected item, remove from lookup table
435
            if ( delete $expected_items->{$verify_item->barcode} ) {
436
                push @bundle_items, $verify_item;
437
            }
438
            # Unexpected item, warn and remove from bundle
439
            else {
440
                $verify_item->remove_from_bundle;
441
                push @unexpected_items, $verify_item;
442
            }
443
444
            # Store results
445
            $verify_item->store();
446
        }
447
        for my $missing_item ( keys %{$expected_items} ) {
448
            my $bundle_item = $expected_items->{$missing_item};
449
            $bundle_item->itemlost($BundleLostValue)->store();
450
            # Add return_claim record if this is an actual checkin
451
            if ($issue) {
452
                $bundle_item->_result->create_related(
453
                    'return_claims',
454
                    {
455
                        issue_id       => $issue->issue_id,
456
                        itemnumber     => $bundle_item->itemnumber,
457
                        borrowernumber => $issue->borrowernumber,
458
                        created_by     => C4::Context->userenv()->{number},
459
                        created_on     => dt_from_string
460
                    }
461
                );
462
            }
463
            push @missing_items, $bundle_item;
464
            # NOTE: We cannot use C4::LostItem here because the item itself doesn't have a checkout
465
            # and thus would not get charged.. it's checked out as part of the bundle.
466
            if ( C4::Context->preference('WhenLostChargeReplacementFee') && $issue ) {
467
                C4::Accounts::chargelostitem(
468
                    $issue->borrowernumber,
469
                    $bundle_item->itemnumber,
470
                    $bundle_item->replacementprice,
471
                    sprintf( "%s %s %s",
472
                        $bundle_item->biblio->title  || q{},
473
                        $bundle_item->barcode        || q{},
474
                        $bundle_item->itemcallnumber || q{},
475
                    ),
476
                );
477
            }
478
        }
479
        $template->param(
480
            unexpected_items => \@unexpected_items,
481
            missing_items    => \@missing_items,
482
            bundle_items     => \@bundle_items
483
        );
484
    }
450
}
485
}
451
$template->param( inputloop => \@inputloop );
486
$template->param( inputloop => \@inputloop );
452
487
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/html_helpers.inc (+2 lines)
Lines 102-107 Link Here
102
                            [% ELSE %]
102
                            [% ELSE %]
103
                                [% IF subfield.IS_LOST_AV && Koha.Preference("ClaimReturnedLostValue") && aval == Koha.Preference("ClaimReturnedLostValue") %]
103
                                [% IF subfield.IS_LOST_AV && Koha.Preference("ClaimReturnedLostValue") && aval == Koha.Preference("ClaimReturnedLostValue") %]
104
                                    <option disabled="disabled" value="[%- aval | html -%]" title="Return claims must be processed from the patron details page">[%- mv.labels.$aval | html -%]</option>
104
                                    <option disabled="disabled" value="[%- aval | html -%]" title="Return claims must be processed from the patron details page">[%- mv.labels.$aval | html -%]</option>
105
                                [% ELSIF subfield.IS_LOST_AV && Koha.Preference("BundleLostValue") && aval == Koha.Preference("BundleLostValue") %]
106
                                    <option disabled="disabled" value="[%- aval | html -%]" title="Bundle losses are set at checkin automatically">[%- mv.labels.$aval | html -%]</option>
105
                                [%  ELSE %]
107
                                [%  ELSE %]
106
                                    <option value="[%- aval | html -%]">[%- mv.labels.$aval | html -%]</option>
108
                                    <option value="[%- aval | html -%]">[%- mv.labels.$aval | html -%]</option>
107
                                [% END %]
109
                                [% END %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt (-3 / +4 lines)
Lines 1390-1395 Note that permanent location is a code, and location may be an authval. Link Here
1390
1390
1391
        [% IF bundlesEnabled %]
1391
        [% IF bundlesEnabled %]
1392
        var bundle_columns = [% TablesSettings.GetColumns('catalogue', 'detail','bundle_tables','json') | $raw %];
1392
        var bundle_columns = [% TablesSettings.GetColumns('catalogue', 'detail','bundle_tables','json') | $raw %];
1393
        var bundle_lost_value = [% Koha.Preference('BundleLostValue') %];
1393
        [% END %]
1394
        [% END %]
1394
        $(document).ready(function() {
1395
        $(document).ready(function() {
1395
1396
Lines 1478-1487 Note that permanent location is a code, and location may be an authval. Link Here
1478
                            "searchable": false,
1479
                            "searchable": false,
1479
                            "orderable": true,
1480
                            "orderable": true,
1480
                            "render": function(data, type, row, meta) {
1481
                            "render": function(data, type, row, meta) {
1481
                                if ( row.lost_status ) {
1482
                                if ( row.lost_status == bundle_lost_value ) {
1482
                                    return "Lost: " + row.lost_status;
1483
                                    return "Last seen: " + row.last_seen_date;
1483
                                }
1484
                                }
1484
                                return "";
1485
                                return "Present";
1485
                            }
1486
                            }
1486
                        },
1487
                        },
1487
                        {
1488
                        {
(-)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