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 351-393 if ($barcode) { Link Here
351
            }
351
            }
352
        }
352
        }
353
353
354
        # Mark missing bundle items as lost and report unexpected items
355
        if ( $item->is_bundle ) {
356
            my $BundleLostValue = C4::Context->preference('BundleLostValue');
357
            my $barcodes = $query->param('verify-items-bundle-contents-barcodes');
358
            my @barcodes = map { s/^\s+|\s+$//gr } ( split /\n/, $barcodes );
359
            my $expected_items = { map { $_->barcode => $_ } $item->bundle_items->as_list };
360
            my $verify_items = Koha::Items->search( { barcode => { 'in' => \@barcodes } } );
361
            my @unexpected_items;
362
            my @missing_items;
363
            my @bundle_items;
364
            while ( my $verify_item = $verify_items->next ) {
365
                # Fix and lost statuses
366
                $verify_item->itemlost(0);
367
368
                # Expected item, remove from lookup table
369
                if ( delete $expected_items->{$verify_item->barcode} ) {
370
                    push @bundle_items, $verify_item;
371
                }
372
                # Unexpected item, warn and remove from bundle
373
                else {
374
                    $verify_item->remove_from_bundle;
375
                    push @unexpected_items, $verify_item;
376
                }
377
                # Store results
378
                $verify_item->store();
379
            }
380
            for my $missing_item ( keys %{$expected_items} ) {
381
                my $bundle_item = $expected_items->{$missing_item};
382
                $bundle_item->itemlost($BundleLostValue)->store();
383
                push @missing_items, $bundle_item;
384
            }
385
            $template->param(
386
                unexpected_items => \@unexpected_items,
387
                missing_items    => \@missing_items,
388
                bundle_items     => \@bundle_items
389
            );
390
        }
391
    } elsif ( C4::Context->preference('ShowAllCheckins') and !$messages->{'BadBarcode'} and !$needs_confirm and !$bundle_confirm ) {
354
    } elsif ( C4::Context->preference('ShowAllCheckins') and !$messages->{'BadBarcode'} and !$needs_confirm and !$bundle_confirm ) {
392
        $input{duedate}   = 0;
355
        $input{duedate}   = 0;
393
        $returneditems{0} = $barcode;
356
        $returneditems{0} = $barcode;
Lines 405-410 if ($barcode) { Link Here
405
            items_bundle_return_confirmation => 1,
368
            items_bundle_return_confirmation => 1,
406
        );
369
        );
407
    }
370
    }
371
372
    # Mark missing bundle items as lost and report unexpected items
373
    if ( $item->is_bundle && $query->param('confirm_items_bundle_return') ) {
374
        my $BundleLostValue = C4::Context->preference('BundleLostValue');
375
        my $barcodes = $query->param('verify-items-bundle-contents-barcodes');
376
        my @barcodes = map { s/^\s+|\s+$//gr } ( split /\n/, $barcodes );
377
        my $expected_items = { map { $_->barcode => $_ } $item->bundle_items->as_list };
378
        my $verify_items = Koha::Items->search( { barcode => { 'in' => \@barcodes } } );
379
        my @unexpected_items;
380
        my @missing_items;
381
        my @bundle_items;
382
        while ( my $verify_item = $verify_items->next ) {
383
            # Fix and lost statuses
384
            $verify_item->itemlost(0);
385
386
            # Update last_seen
387
            $verify_item->datelastseen( dt_from_string()->ymd() );
388
389
            # Update last_borrowed if actual checkin
390
            $verify_item->datelastborrowed( dt_from_string()->ymd() ) if $issue;
391
392
            # Expected item, remove from lookup table
393
            if ( delete $expected_items->{$verify_item->barcode} ) {
394
                push @bundle_items, $verify_item;
395
            }
396
            # Unexpected item, warn and remove from bundle
397
            else {
398
                $verify_item->remove_from_bundle;
399
                push @unexpected_items, $verify_item;
400
            }
401
402
            # Store results
403
            $verify_item->store();
404
        }
405
        for my $missing_item ( keys %{$expected_items} ) {
406
            my $bundle_item = $expected_items->{$missing_item};
407
            $bundle_item->itemlost($BundleLostValue)->store();
408
            # Add return_claim record if this is an actual checkin
409
            if ($issue) {
410
                $bundle_item->_result->create_related(
411
                    'return_claims',
412
                    {
413
                        issue_id       => $issue->issue_id,
414
                        itemnumber     => $bundle_item->itemnumber,
415
                        borrowernumber => $issue->borrowernumber,
416
                        created_by     => C4::Context->userenv()->{number},
417
                        created_on     => dt_from_string
418
                    }
419
                );
420
            }
421
            push @missing_items, $bundle_item;
422
            # NOTE: We cannot use C4::LostItem here because the item itself doesn't have a checkout
423
            # and thus would not get charged.. it's checked out as part of the bundle.
424
            if ( C4::Context->preference('WhenLostChargeReplacementFee') && $issue ) {
425
                C4::Accounts::chargelostitem(
426
                    $issue->borrowernumber,
427
                    $bundle_item->itemnumber,
428
                    $bundle_item->replacementprice,
429
                    sprintf( "%s %s %s",
430
                        $bundle_item->biblio->title  || q{},
431
                        $bundle_item->barcode        || q{},
432
                        $bundle_item->itemcallnumber || q{},
433
                    ),
434
                );
435
            }
436
        }
437
        $template->param(
438
            unexpected_items => \@unexpected_items,
439
            missing_items    => \@missing_items,
440
            bundle_items     => \@bundle_items
441
        );
442
    }
408
}
443
}
409
$template->param( inputloop => \@inputloop );
444
$template->param( inputloop => \@inputloop );
410
445
(-)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 1375-1380 Note that permanent location is a code, and location may be an authval. Link Here
1375
1375
1376
        [% IF bundlesEnabled %]
1376
        [% IF bundlesEnabled %]
1377
        var bundle_columns = [% TablesSettings.GetColumns('catalogue', 'detail','bundle_tables','json') | $raw %];
1377
        var bundle_columns = [% TablesSettings.GetColumns('catalogue', 'detail','bundle_tables','json') | $raw %];
1378
        var bundle_lost_value = [% Koha.Preference('BundleLostValue') %];
1378
        [% END %]
1379
        [% END %]
1379
        $(document).ready(function() {
1380
        $(document).ready(function() {
1380
1381
Lines 1463-1472 Note that permanent location is a code, and location may be an authval. Link Here
1463
                            "searchable": false,
1464
                            "searchable": false,
1464
                            "orderable": true,
1465
                            "orderable": true,
1465
                            "render": function(data, type, row, meta) {
1466
                            "render": function(data, type, row, meta) {
1466
                                if ( row.lost_status ) {
1467
                                if ( row.lost_status == bundle_lost_value ) {
1467
                                    return "Lost: " + row.lost_status;
1468
                                    return "Last seen: " + row.last_seen_date;
1468
                                }
1469
                                }
1469
                                return "";
1470
                                return "Present";
1470
                            }
1471
                            }
1471
                        },
1472
                        },
1472
                        {
1473
                        {
(-)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