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

(-)a/Koha/Item.pm (+50 lines)
Lines 1443-1448 sub columns_to_str { Link Here
1443
    return $values;
1443
    return $values;
1444
}
1444
}
1445
1445
1446
sub _status {
1447
    my ($self) = @_;
1448
1449
    my @statuses;
1450
    if ( my $checkout = $self->checkout ) {
1451
        unless ( $checkout->onsite_checkout ) {
1452
            push @statuses, "checked_out";
1453
        } else {
1454
            push @statuses, "local_use";
1455
        }
1456
    } elsif ( my $transfer = $self->transfer ) {
1457
        if ( $transfer->datesent ) {
1458
            push @statuses, "in_transit";
1459
        } else {
1460
            push @statuses, "transit_pending";
1461
        }
1462
    }
1463
    if ( $self->itemlost ) {
1464
        push @statuses, 'lost';
1465
    }
1466
    if ( $self->withdrawn ) {
1467
        push @statuses, 'withdrawn';
1468
    }
1469
    if ( $self->damaged ) {
1470
        push @statuses, 'damaged';
1471
    }
1472
    if ( $self->notforloan || $self->item_type->notforloan  ) {
1473
        # TODO on a big Koha::Items loop we are going to join with item_type too often, use a cache
1474
        push @statuses, 'not_for_loan';
1475
    }
1476
    if ( $self->first_hold ) {
1477
        push @statuses, 'on_hold';
1478
    }
1479
    if ( C4::Context->preference('UseRecalls') && $self->recall ) {
1480
        push @statuses, 'recalled';
1481
    }
1482
1483
    unless (@statuses ){
1484
        push @statuses, 'available';
1485
    }
1486
1487
    if ( $self->restricted ) {
1488
        push @statuses, 'restricted';
1489
    }
1490
1491
    # TODO in_bundle?
1492
1493
    return join ',', @statuses;
1494
}
1495
1446
=head3 additional_attributes
1496
=head3 additional_attributes
1447
1497
1448
    my $attributes = $item->additional_attributes;
1498
    my $attributes = $item->additional_attributes;
(-)a/api/v1/swagger/definitions/item.yaml (+5 lines)
Lines 322-325 properties: Link Here
322
      - object
322
      - object
323
      - "null"
323
      - "null"
324
    description: A return claims object if one exists that's unresolved
324
    description: A return claims object if one exists that's unresolved
325
  _status:
326
    type:
327
      - string
328
      - "null"
329
    description: The status of the item
325
additionalProperties: false
330
additionalProperties: false
(-)a/api/v1/swagger/paths/biblios.yaml (+1 lines)
Lines 455-460 Link Here
455
          type: string
455
          type: string
456
          enum:
456
          enum:
457
            - +strings
457
            - +strings
458
            - _status
458
            - home_library
459
            - home_library
459
            - holding_library
460
            - holding_library
460
            - biblio.title
461
            - biblio.title
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/html_helpers/tables/items/catalogue_detail.inc (-73 / +75 lines)
Lines 227-233 Link Here
227
    [%# In case or SeparateHoldings we may need to display the number of biblios in each tab %]
227
    [%# In case or SeparateHoldings we may need to display the number of biblios in each tab %]
228
    [%# Do we need separate/new endpoints or do we hack the somewhere client-side? %]
228
    [%# Do we need separate/new endpoints or do we hack the somewhere client-side? %]
229
    let item_table_url = "/api/v1/biblios/[% biblio.biblionumber | uri %]/items?";
229
    let item_table_url = "/api/v1/biblios/[% biblio.biblionumber | uri %]/items?";
230
    let embed = ["+strings,home_library,holding_library,checkout,checkout.patron,transfer,transfer+strings,first_hold,first_hold+strings,first_hold.patron,first_hold.desk"];
230
    let embed = ["+strings,_status,home_library,holding_library,checkout,checkout.patron,transfer,transfer+strings,first_hold,first_hold+strings,first_hold.patron,first_hold.desk"];
231
    [% IF Koha.Preference('LocalCoverImages') %]
231
    [% IF Koha.Preference('LocalCoverImages') %]
232
        embed.push('cover_image_ids');
232
        embed.push('cover_image_ids');
233
    [% END %]
233
    [% END %]
Lines 463-566 Link Here
463
                }
463
                }
464
            },
464
            },
465
            {
465
            {
466
                data: "me.lost_status",
466
                data: "me._status",
467
                className: "status",
467
                className: "status",
468
                searchable: false, // FIXME We are losing the ability to search on the status
468
                searchable: false, // FIXME We are losing the ability to search on the status
469
                orderable: false,
469
                orderable: false,
470
                render: function (data, type, row, meta) {
470
                render: function (data, type, row, meta) {
471
                    let nodes = "";
471
                    let nodes = "";
472
                    if ( row.checkout ) {
472
                    row._status.split(",").forEach( status => {
473
                        [%# Hacky for patron_to_html in case we simply want to display the patron's library name %]
473
                        if ( status == 'checked_out' || status == 'local_use') {
474
                        row.checkout.patron.library = { name: libraries_names.get(row.checkout.patron.library_id) };
474
                            nodes += '<span>';
475
475
476
                        nodes += '<span>';
476
                            [%# Hacky for patron_to_html in case we simply want to display the patron's library name %]
477
                        if ( row.checkout.onsite_checkout ) {
477
                            row.checkout.patron.library = { name: libraries_names.get(row.checkout.patron.library_id) };
478
                            let patron_to_html = $patron_to_html(row.checkout.patron, { url: true, display_cardnumber: true, hide_patron_name });
478
                            let patron_to_html = $patron_to_html(row.checkout.patron, { url: true, display_cardnumber: true, hide_patron_name });
479
                            nodes += _("Currently in local use by %s").format(patron_to_html);
479
480
                        } else {
480
                            if ( status == 'local_use' ) {
481
                            nodes += '<span class="datedue">';
481
                                nodes += _("Currently in local use by %s").format(patron_to_html);
482
                            let patron_to_html = $patron_to_html(row.checkout.patron, { url: true, display_cardnumber: true, hide_patron_name });
482
                            } else {
483
                            nodes += _("Checked out to %s").format(patron_to_html);
483
                                nodes += '<span class="datedue">';
484
                                nodes += _("Checked out to %s").format(patron_to_html);
485
                            }
486
                            nodes += ': ';
487
                            nodes += _("due %s").format($date(row.checkout.due_date, { as_due_date: true }));
488
                            nodes += "</span>"
489
484
                        }
490
                        }
485
                        nodes += ': ';
491
                        if ( status == 'in_transit' ) {
486
                        nodes += _("due %s").format($date(row.checkout.due_date, { as_due_date: true }));
487
                        nodes += "</span>"
488
                    } else if ( row.transfer ) {
489
                        if ( row.transfer.datesent ) {
490
                            nodes += '<span class="intransit">%s</span>'.format(_("In transit from %s to %s since %s").format(escape_str(row.transfer._strings.from_library.str), escape_str(row.transfer._strings.to_library.str), $date(row.transfer.datesent)));
492
                            nodes += '<span class="intransit">%s</span>'.format(_("In transit from %s to %s since %s").format(escape_str(row.transfer._strings.from_library.str), escape_str(row.transfer._strings.to_library.str), $date(row.transfer.datesent)));
491
                        } else {
493
                        }
494
495
                        if ( status == 'transit_pending' ) {
492
                            nodes += '<span class="transitrequested">%s</span>'.format(_("Transit pending from %s to %s since %s").format(escape_str(row.transfer._strings.from_library.str), escape_str(row.transfer._strings.to_library.str), $date(row.transfer.daterequested)));
496
                            nodes += '<span class="transitrequested">%s</span>'.format(_("Transit pending from %s to %s since %s").format(escape_str(row.transfer._strings.from_library.str), escape_str(row.transfer._strings.to_library.str), $date(row.transfer.daterequested)));
493
                        }
497
                        }
494
                    }
495
498
496
                    if ( row.lost_status ) {
499
                        if ( status == 'lost' ) {
497
                        let lost_lib = av_lost.get(row.lost_status.toString()) || _("Unavailable (lost or missing");
500
                            let lost_lib = av_lost.get(row.lost_status.toString()) || _("Unavailable (lost or missing");
498
                        nodes += '<span class="lost">%s</span>'.format(escape_str(lost_lib));
501
                            nodes += '<span class="lost">%s</span>'.format(escape_str(lost_lib));
499
                        [% IF Koha.Preference('ClaimReturnedLostValue') %]
502
500
                            const hasReturnClaims = row.return_claims.filter(rc => !rc.resolution).length > 0 ? true : false
503
                            const hasReturnClaims = row.return_claims && row.return_claims.filter(rc => !rc.resolution).length > 0 ? true : false
501
                            if(hasReturnClaims) {
504
                            if(hasReturnClaims) {
502
                                nodes += '<span class="claimed_returned">' + _("(Claimed returned)") + '</span>';
505
                                nodes += '<span class="claimed_returned">' + _("(Claimed returned)") + '</span>';
503
                            }
506
                            }
504
                        [% END %]
507
                        }
505
                    }
506
508
507
                    if ( row.withdrawn ) {
509
                        if ( status == 'withdrawn' ) {
508
                        let withdrawn_lib = av_withdrawn.get(row.withdrawn.toString()) || _("Withdrawn");
510
                            let withdrawn_lib = av_withdrawn.get(row.withdrawn.toString()) || _("Withdrawn");
509
                        nodes += '<span class="wdn">%s</span>'.format(escape_str(withdrawn_lib));
511
                            nodes += '<span class="wdn">%s</span>'.format(escape_str(withdrawn_lib));
510
                    }
512
                        }
511
513
512
                    if ( row.damaged_status ) {
514
                        if ( status == 'damaged' ) {
513
                        let damaged_lib = av_damaged.get(row.damaged_status.toString()) || _("Damaged");
515
                            let damaged_lib = av_damaged.get(row.damaged_status.toString()) || _("Damaged");
514
                        nodes += '<span class="dmg">%s</span>'.format(escape_str(damaged_lib));
516
                            nodes += '<span class="dmg">%s</span>'.format(escape_str(damaged_lib));
515
                    }
517
                        }
516
518
517
                    if ( row.not_for_loan_status || item_types_notforloan.get(row.item_type_id) ) {
519
                        if ( status == 'not_for_loan' ) {
518
                        let not_for_loan_lib = av_not_for_loan.get(row.not_for_loan_status.toString());
520
                            let not_for_loan_lib = av_not_for_loan.get(row.not_for_loan_status.toString());
519
                        nodes += '<span class="notforloan">%s'.format(_("Not for loan")) + ( not_for_loan_lib ? '<span class="reason"> (%s)</span>'.format(escape_str(not_for_loan_lib)) : '' ) + '</span>';
521
                            nodes += '<span class="notforloan">%s'.format(_("Not for loan")) + ( not_for_loan_lib ? '<span class="reason"> (%s)</span>'.format(escape_str(not_for_loan_lib)) : '' ) + '</span>';
520
                    }
522
                        }
521
523
522
                    if ( row.first_hold ) {
524
                        if ( status == 'on_hold') {
523
                        if ( row.first_hold.waiting_date ) {
525
                            if ( row.first_hold.waiting_date ) {
524
                            if ( row.first_hold.desk ) {
526
                                if ( row.first_hold.desk ) {
525
                                nodes += '<span class="waitingat">%s</span>'.format(_("Waiting at %s, %s since %s.".format(row.first_hold._strings.pickup_library_id.str, row.first_hold.desk.desk_name, $date(row.first_hold.waiting_date))));
527
                                    nodes += '<span class="waitingat">%s</span>'.format(_("Waiting at %s, %s since %s.".format(row.first_hold._strings.pickup_library_id.str, row.first_hold.desk.desk_name, $date(row.first_hold.waiting_date))));
528
                                } else {
529
                                    nodes += '<span class="waitingat">%s</span>'.format(_("Waiting at %s since %s.".format(row.first_hold._strings.pickup_library_id.str, $date(row.first_hold.waiting_date))));
530
                                }
531
                                [% IF Koha.Preference('canreservefromotherbranches') %]
532
                                    if ( row.first_hold.waiting_date || row.first_hold.priority == 1 ) {
533
                                        [%# Hacky for patron_to_html in case we simply want to display the patron's library name %]
534
                                        row.first_hold.patron.library = { name: libraries_names.get(row.first_hold.patron.library_id) };
535
536
                                        let patron_to_html = $patron_to_html(row.first_hold.patron, { url: true, display_cardnumber: true, hide_patron_name });
537
                                        nodes += ' <span class="heldfor">%s</span>'.format(_("Hold for: %s").format(patron_to_html));
538
                                    }
539
                                [% END %]
526
                            } else {
540
                            } else {
527
                                nodes += '<span class="waitingat">%s</span>'.format(_("Waiting at %s since %s.".format(row.first_hold._strings.pickup_library_id.str, $date(row.first_hold.waiting_date))));
541
                                nodes += ' <span class="holdonitem">%s</span>'.format(_("There is an item level hold on this item (priority = %s).").format(row.first_hold.priority));
528
                            }
542
                            }
529
                            [% IF Koha.Preference('canreservefromotherbranches') %]
530
                                if ( row.first_hold.waiting_date || row.first_hold.priority == 1 ) {
531
                                    [%# Hacky for patron_to_html in case we simply want to display the patron's library name %]
532
                                    row.first_hold.patron.library = { name: libraries_names.get(row.first_hold.patron.library_id) };
533
534
                                    let patron_to_html = $patron_to_html(row.first_hold.patron, { url: true, display_cardnumber: true, hide_patron_name });
535
                                    nodes += ' <span class="heldfor">%s</span>'.format(_("Hold for: %s").format(patron_to_html));
536
                                }
537
                            [% END %]
538
                        } else {
539
                            nodes += ' <span class="holdonitem">%s</span>'.format(_("There is an item level hold on this item (priority = %s).").format(row.first_hold.priority));
540
                        }
543
                        }
541
                    }
542
544
543
                    [% IF Koha.Preference('UseRecalls') %]
545
                        [% IF Koha.Preference('UseRecalls') %]
544
                        if ( row.recall ) {
546
                            if ( status == 'recalled' ) {
545
                            if ( row.recall.waiting_date ) {
547
                                if ( row.recall.waiting_date ) {
546
                                nodes += '<span>%s</span>'.format(_("Waiting at %s since %s").format(escape_str(row.recall.pickup_library_id.str), $date(row.recall.waiting_date)));
548
                                    nodes += '<span>%s</span>'.format(_("Waiting at %s since %s").format(escape_str(row.recall.pickup_library_id.str), $date(row.recall.waiting_date)));
547
                            } else {
549
                                } else {
548
                                [%# Hacky for patron_to_html in case we simply want to display the patron's library name %]
550
                                    [%# Hacky for patron_to_html in case we simply want to display the patron's library name %]
549
                                row.recall.patron.library = { name: libraries_names.get(row.recall.patron.library_id) };
551
                                    row.recall.patron.library = { name: libraries_names.get(row.recall.patron.library_id) };
550
552
551
                                let patron_to_html = $patron_to_html(row.recall.patron, {url: true, display_cardnumber: true, hide_patron_name });
553
                                    let patron_to_html = $patron_to_html(row.recall.patron, {url: true, display_cardnumber: true, hide_patron_name });
552
                                nodes += '<span>%s</span>'.format(_("recalled by %s on %s").format(patron_to_html, $date(row.recall.created_date)))
554
                                    nodes += '<span>%s</span>'.format(_("recalled by %s on %s").format(patron_to_html, $date(row.recall.created_date)))
555
                                }
553
                            }
556
                            }
554
                        }
557
                        [% END %]
555
                    [% END %]
556
558
557
                    if ( ! ( row.not_for_loan_status || item_types_notforloan.get(row.item_type_id) || row.checked_out_date || row.lost_status || row.withdrawn || row.damaged_status || row.transfer || row.first_hold || row.recall ) ) {
559
                        if ( status == 'available' ) {
558
                        nodes += ' <span>%s</span>'.format(_("Available"))
560
                            nodes += ' <span>%s</span>'.format(_("Available"))
559
                    }
561
                        }
560
562
561
                    if ( row.restricted_status ) {
563
                        if ( status == 'restricted') {
562
                        nodes += '<span class="restricted">(%s)</span>'.format(escape_str(av_restricted.get(row.restricted_status.toString())));
564
                            nodes += '<span class="restricted">(%s)</span>'.format(escape_str(av_restricted.get(row.restricted_status.toString())));
563
                    }
565
                        }
566
                    });
564
567
565
                    [% IF bundlesEnabled %]
568
                    [% IF bundlesEnabled %]
566
                        if ( row.in_bundle ) {
569
                        if ( row.in_bundle ) {
567
- 

Return to bug 37334