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

(-)a/C4/Reserves.pm (-3 / +10 lines)
Lines 804-816 sub GetReserveStatus { Link Here
804
804
805
    my $dbh = C4::Context->dbh;
805
    my $dbh = C4::Context->dbh;
806
806
807
    my ($sth, $found, $priority);
807
    my ($sth, $found, $priority, $pending);
808
    if ( $itemnumber ) {
808
    if ( $itemnumber ) {
809
        $sth = $dbh->prepare("SELECT found, priority FROM reserves WHERE itemnumber = ? order by priority LIMIT 1");
809
        $sth = $dbh->prepare(q{
810
                SELECT found, priority, IF( tmp_holdsqueue.itemnumber IS NULL, 0, 1) AS pending
811
                FROM reserves
812
                LEFT JOIN tmp_holdsqueue USING (itemnumber)
813
                WHERE itemnumber = ? order by priority LIMIT 1
814
        });
810
        $sth->execute($itemnumber);
815
        $sth->execute($itemnumber);
811
        ($found, $priority) = $sth->fetchrow_array;
816
        ($found, $priority, $pending) = $sth->fetchrow_array;
812
    }
817
    }
813
818
819
    return 'Pending' if $pending;
820
814
    if(defined $found) {
821
    if(defined $found) {
815
        return 'Waiting'  if $found eq 'W' and $priority == 0;
822
        return 'Waiting'  if $found eq 'W' and $priority == 0;
816
        return 'Processing'  if $found eq 'P';
823
        return 'Processing'  if $found eq 'P';
(-)a/C4/Search.pm (-9 / +20 lines)
Lines 1641-1655 sub searchResults { Link Here
1641
    #Build branchnames hash
1641
    #Build branchnames hash
1642
    my %branches = map { $_->branchcode => $_->branchname } Koha::Libraries->search({}, { order_by => 'branchname' })->as_list;
1642
    my %branches = map { $_->branchcode => $_->branchname } Koha::Libraries->search({}, { order_by => 'branchname' })->as_list;
1643
1643
1644
# FIXME - We build an authorised values hash here, using the default framework
1644
    my $description = $is_opac ? 'opac_description' : 'lib';
1645
# though it is possible to have different authvals for different fws.
1646
1647
    my $shelflocations =
1645
    my $shelflocations =
1648
      { map { $_->{authorised_value} => $_->{lib} } Koha::AuthorisedValues->get_descriptions_by_koha_field( { frameworkcode => '', kohafield => 'items.location' } ) };
1646
      { map { $_->{authorised_value} => $_->{$description} } Koha::AuthorisedValues->get_descriptions_by_koha_field( { frameworkcode => '', kohafield => 'items.location' } ) };
1647
    my $ccodes = { map { $_->{authorised_value} => $_->{$description} } Koha::AuthorisedValues->get_descriptions_by_koha_field( { frameworkcode => "", kohafield => 'items.ccode' } ) };
1649
1648
1650
    # get notforloan authorised value list (see $shelflocations  FIXME)
1649
    # get notforloan authorised value list (see $shelflocations  FIXME)
1651
    my $av = Koha::MarcSubfieldStructures->search({ frameworkcode => '', kohafield => 'items.notforloan', authorised_value => [ -and => {'!=' => undef }, {'!=' => ''}] });
1650
    my $av = Koha::MarcSubfieldStructures->search({ frameworkcode => '', kohafield => 'items.notforloan', authorised_value => [ -and => {'!=' => undef }, {'!=' => ''}] });
1652
    my $notforloan_authorised_value = $av->count ? $av->next->authorised_value : undef;
1651
    my $notforloan_authorised_value = $av->count ? $av->next->authorised_value : undef;
1652
    my $notforloan_descriptions = { map { $_->{authorised_value} => $_->{$description} } Koha::AuthorisedValues->get_descriptions_by_koha_field( { kohafield => 'items.notforloan' } ) };
1653
1653
1654
1654
    #Get itemtype hash
1655
    #Get itemtype hash
1655
    my $itemtypes = Koha::ItemTypes->search_with_localization;
1656
    my $itemtypes = Koha::ItemTypes->search_with_localization;
Lines 1793-1798 sub searchResults { Link Here
1793
        my @hiddenitems; # hidden itemnumbers based on OpacHiddenItems syspref
1794
        my @hiddenitems; # hidden itemnumbers based on OpacHiddenItems syspref
1794
1795
1795
        # loop through every item
1796
        # loop through every item
1797
        my @items = ();
1796
        foreach my $field (@fields) {
1798
        foreach my $field (@fields) {
1797
            my $item;
1799
            my $item;
1798
1800
Lines 1830-1835 sub searchResults { Link Here
1830
            elsif ($item->{$otherbranch}) {	# Last resort
1832
            elsif ($item->{$otherbranch}) {	# Last resort
1831
                $item->{'branchname'} = $branches{$item->{$otherbranch}};
1833
                $item->{'branchname'} = $branches{$item->{$otherbranch}};
1832
            }
1834
            }
1835
            $item->{homebranch} = $branches{ $item->{homebranch} } if defined $item->{homebranch};
1836
            $item->{holdingbranch} = $branches{ $item->{holdingbranch} } if defined $item->{holdingbranch};
1833
1837
1834
            my $prefix =
1838
            my $prefix =
1835
                ( $item->{$hbranch} ? $item->{$hbranch} . '--' : q{} )
1839
                ( $item->{$hbranch} ? $item->{$hbranch} . '--' : q{} )
Lines 1837-1842 sub searchResults { Link Here
1837
              . ( $item->{itype}    ? $item->{itype}    : q{} )
1841
              . ( $item->{itype}    ? $item->{itype}    : q{} )
1838
              . ( $item->{itemcallnumber} ? $item->{itemcallnumber} : q{} );
1842
              . ( $item->{itemcallnumber} ? $item->{itemcallnumber} : q{} );
1839
# For each grouping of items (onloan, available, unavailable), we build a key to store relevant info about that item
1843
# For each grouping of items (onloan, available, unavailable), we build a key to store relevant info about that item
1844
            my $itemtype = C4::Context->preference("item-level_itypes")? $item->{itype}: $oldbiblio->{itemtype};
1845
            $item->{itemtype} = $itemtype;
1846
            $item->{location} = $item->{location} && exists $shelflocations->{$item->{location}} ? $shelflocations->{$item->{location}} : $item->{location} ;
1847
            $item->{notforloan_description} = exists $notforloan_descriptions->{ $item->{notforloan} } ? $notforloan_descriptions->{ $item->{notforloan} } : "Not for loan";
1848
            $item->{ccode_description} = defined $item->{ccode} && exists $ccodes->{ $item->{ccode} } ? $ccodes->{ $item->{ccode} } :  $item->{ccode};
1849
            $item->{notforloan_itemtype} = defined $itemtype && exists $itemtypes{ $itemtype } ? $itemtypes{ $itemtype }->{notforloan} : undef;
1840
            if ( $item->{onloan}
1850
            if ( $item->{onloan}
1841
                and $logged_in_user
1851
                and $logged_in_user
1842
                and !( $patron_category_hide_lost_items and $item->{itemlost} ) )
1852
                and !( $patron_category_hide_lost_items and $item->{itemlost} ) )
Lines 1846-1852 sub searchResults { Link Here
1846
                $onloan_items->{$key}->{due_date} = $item->{onloan};
1856
                $onloan_items->{$key}->{due_date} = $item->{onloan};
1847
                $onloan_items->{$key}->{count}++ if $item->{$hbranch};
1857
                $onloan_items->{$key}->{count}++ if $item->{$hbranch};
1848
                $onloan_items->{$key}->{branchname}     = $item->{branchname};
1858
                $onloan_items->{$key}->{branchname}     = $item->{branchname};
1849
                $onloan_items->{$key}->{location}       = $shelflocations->{ $item->{location} } if $item->{location};
1859
                $onloan_items->{$key}->{location}       = $item->{location} if $item->{location};
1850
                $onloan_items->{$key}->{itemcallnumber} = $item->{itemcallnumber};
1860
                $onloan_items->{$key}->{itemcallnumber} = $item->{itemcallnumber};
1851
                $onloan_items->{$key}->{description}    = $item->{description};
1861
                $onloan_items->{$key}->{description}    = $item->{description};
1852
                $onloan_items->{$key}->{imageurl} =
1862
                $onloan_items->{$key}->{imageurl} =
Lines 1862-1868 sub searchResults { Link Here
1862
         # items not on loan, but still unavailable ( lost, withdrawn, damaged )
1872
         # items not on loan, but still unavailable ( lost, withdrawn, damaged )
1863
            else {
1873
            else {
1864
1874
1865
                my $itemtype = C4::Context->preference("item-level_itypes")? $item->{itype}: $oldbiblio->{itemtype};
1866
                $item->{notforloan} = 1 if !$item->{notforloan} &&
1875
                $item->{notforloan} = 1 if !$item->{notforloan} &&
1867
                    $itemtype && $itemtypes{ $itemtype }->{notforloan};
1876
                    $itemtype && $itemtypes{ $itemtype }->{notforloan};
1868
1877
Lines 1939-1945 sub searchResults { Link Here
1939
                    $other_items->{$key}->{onhold} = ($reservestatus) ? 1 : 0;
1948
                    $other_items->{$key}->{onhold} = ($reservestatus) ? 1 : 0;
1940
                    $other_items->{$key}->{notforloan} = GetAuthorisedValueDesc('','',$item->{notforloan},'','',$notforloan_authorised_value) if $notforloan_authorised_value and $item->{notforloan};
1949
                    $other_items->{$key}->{notforloan} = GetAuthorisedValueDesc('','',$item->{notforloan},'','',$notforloan_authorised_value) if $notforloan_authorised_value and $item->{notforloan};
1941
                    $other_items->{$key}->{count}++ if $item->{$hbranch};
1950
                    $other_items->{$key}->{count}++ if $item->{$hbranch};
1942
                    $other_items->{$key}->{location} = $shelflocations->{ $item->{location} } if $item->{location};
1951
                    $other_items->{$key}->{location} = $item->{location} if $item->{location};
1943
                    $other_items->{$key}->{description} = $item->{description};
1952
                    $other_items->{$key}->{description} = $item->{description};
1944
                    $other_items->{$key}->{imageurl} = getitemtypeimagelocation( $search_context->{'interface'}, $itemtypes{ $item->{itype}//q{} }->{imageurl} );
1953
                    $other_items->{$key}->{imageurl} = getitemtypeimagelocation( $search_context->{'interface'}, $itemtypes{ $item->{itype}//q{} }->{imageurl} );
1945
                }
1954
                }
Lines 1950-1959 sub searchResults { Link Here
1950
                    foreach (qw(branchname itemcallnumber description)) {
1959
                    foreach (qw(branchname itemcallnumber description)) {
1951
                        $available_items->{$prefix}->{$_} = $item->{$_};
1960
                        $available_items->{$prefix}->{$_} = $item->{$_};
1952
                    }
1961
                    }
1953
                    $available_items->{$prefix}->{location} = $shelflocations->{ $item->{location} } if $item->{location};
1962
                    $available_items->{$prefix}->{location} = $item->{location} if $item->{location};
1954
                    $available_items->{$prefix}->{imageurl} = getitemtypeimagelocation( $search_context->{'interface'}, $itemtypes{ $item->{itype}//q{} }->{imageurl} );
1963
                    $available_items->{$prefix}->{imageurl} = getitemtypeimagelocation( $search_context->{'interface'}, $itemtypes{ $item->{itype}//q{} }->{imageurl} );
1955
                }
1964
                }
1956
            }
1965
            }
1966
            push @items, $item;
1957
        }    # notforloan, item level and biblioitem level
1967
        }    # notforloan, item level and biblioitem level
1958
1968
1959
        # if all items are hidden, do not show the record
1969
        # if all items are hidden, do not show the record
Lines 1996-2002 sub searchResults { Link Here
1996
                    ),
2006
                    ),
1997
                    fix_amps       => 1,
2007
                    fix_amps       => 1,
1998
                    hidden_items   => \@hiddenitems,
2008
                    hidden_items   => \@hiddenitems,
1999
                    xslt_variables => $xslt_variables
2009
                    xslt_variables => $xslt_variables,
2010
                    items          => \@items
2000
                }
2011
                }
2001
            );
2012
            );
2002
        }
2013
        }
(-)a/C4/XSLT.pm (-54 / +29 lines)
Lines 250-256 sub XSLTParse4Display { Link Here
250
    my $fixamps      = $params->{fix_amps};
250
    my $fixamps      = $params->{fix_amps};
251
    my $hidden_items = $params->{hidden_items} || [];
251
    my $hidden_items = $params->{hidden_items} || [];
252
    my $variables    = $params->{xslt_variables};
252
    my $variables    = $params->{xslt_variables};
253
    my $items_rs     = $params->{items_rs};
253
    my $items        = $params->{items};
254
254
255
    die "Mandatory \$params->{xsl_syspref} was not provided, called with biblionumber $params->{biblionumber}"
255
    die "Mandatory \$params->{xsl_syspref} was not provided, called with biblionumber $params->{biblionumber}"
256
        if not defined $params->{xsl_syspref};
256
        if not defined $params->{xsl_syspref};
Lines 263-269 sub XSLTParse4Display { Link Here
263
    if ( $xslsyspref eq "OPACXSLTDetailsDisplay" || $xslsyspref eq "XSLTDetailsDisplay" || $xslsyspref eq "XSLTResultsDisplay" ) {
263
    if ( $xslsyspref eq "OPACXSLTDetailsDisplay" || $xslsyspref eq "XSLTDetailsDisplay" || $xslsyspref eq "XSLTResultsDisplay" ) {
264
        $itemsxml = ""; #We don't use XSLT for items display on these pages
264
        $itemsxml = ""; #We don't use XSLT for items display on these pages
265
    } else {
265
    } else {
266
        $itemsxml = buildKohaItemsNamespace($biblionumber, $hidden_items, $items_rs);
266
        $itemsxml = buildKohaItemsNamespace($items);
267
    }
267
    }
268
    my $xmlrecord = $record->as_xml(C4::Context->preference('marcflavour'));
268
    my $xmlrecord = $record->as_xml(C4::Context->preference('marcflavour'));
269
269
Lines 310-407 sub XSLTParse4Display { Link Here
310
310
311
=head2 buildKohaItemsNamespace
311
=head2 buildKohaItemsNamespace
312
312
313
    my $items_xml = buildKohaItemsNamespace( $biblionumber, [ $hidden_items, $items ] );
313
    my $items_xml = buildKohaItemsNamespace( $items );
314
314
315
Returns XML for items. It accepts two optional parameters:
315
Returns XML for items. It requires one parameter:
316
- I<$hidden_items>: An arrayref of itemnumber values, for items that should be hidden
316
- I<$items>: An arrayref of item hashes, for the items to be returned, hidden items should be filtered before calling this routine
317
- I<$items>: A Koha::Items resultset, for the items to be returned
318
319
If both parameters are passed, I<$items> is used as the basis resultset, and I<$hidden_items>
320
are filtered out of it.
321
317
322
Is only used in this module currently.
318
Is only used in this module currently.
323
319
324
=cut
320
=cut
325
321
326
sub buildKohaItemsNamespace {
322
sub buildKohaItemsNamespace {
327
    my ($biblionumber, $hidden_items, $items_rs) = @_;
323
    my ($items) = @_;
328
329
    $hidden_items ||= [];
330
331
    my $query = {};
332
    $query = { 'me.itemnumber' => { not_in => $hidden_items } }
333
      if $hidden_items;
334
335
    unless ( $items_rs && ref($items_rs) eq 'Koha::Items' ) {
336
        $query->{'me.biblionumber'} = $biblionumber;
337
        $items_rs = Koha::Items->new;
338
    }
339
324
340
    my $items = $items_rs->search( $query, { prefetch => [ 'branchtransfers', 'reserves' ] } );
341
342
    my $shelflocations =
343
      { map { $_->{authorised_value} => $_->{opac_description} } Koha::AuthorisedValues->get_descriptions_by_koha_field( { frameworkcode => "", kohafield => 'items.location' } ) };
344
    my $ccodes =
345
      { map { $_->{authorised_value} => $_->{opac_description} } Koha::AuthorisedValues->get_descriptions_by_koha_field( { frameworkcode => "", kohafield => 'items.ccode' } ) };
346
347
    my %branches = map { $_->branchcode => $_->branchname } Koha::Libraries->search({}, { order_by => 'branchname' })->as_list;
348
349
    my $itemtypes = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search->unblessed } };
350
    my $xml = '';
325
    my $xml = '';
351
    my %descs = map { $_->{authorised_value} => $_ } Koha::AuthorisedValues->get_descriptions_by_koha_field( { kohafield => 'items.notforloan' } );
352
    my $ref_status = C4::Context->preference('Reference_NFL_Statuses') || '1|2';
326
    my $ref_status = C4::Context->preference('Reference_NFL_Statuses') || '1|2';
353
327
354
    while ( my $item = $items->next ) {
328
    for my $item ( @$items ) {
355
        my $status;
329
        my $status;
356
        my $substatus = '';
330
        my $substatus = '';
357
        my $recalls_count;
331
        my $recalls_count;
358
332
359
        if ( C4::Context->preference('UseRecalls') ) {
333
        if ( C4::Context->preference('UseRecalls') ) {
360
            $recalls_count = Koha::Recalls->search({ item_id => $item->itemnumber, status => 'waiting' })->count;
334
            $recalls_count = Koha::Recalls->search({ item_id => $item->{itemnumber}, status => 'waiting' })->count;
361
        }
335
        }
362
336
337
        my $reservestatus = C4::Reserves::GetReserveStatus( $item->{itemnumber} );
338
        my $transfer = C4::Circulation::GetTransfers($item->{itemnumber});
339
363
        if ($recalls_count) {
340
        if ($recalls_count) {
364
            # recalls take priority over holds
341
            # recalls take priority over holds
365
            $status = 'other';
342
            $status = 'other';
366
            $substatus = 'Recall waiting';
343
            $substatus = 'Recall waiting';
367
        }
344
        }
368
        elsif ( $item->has_pending_hold ) {
345
        elsif ($reservestatus eq 'Pending' ) {
369
            $status = 'other';
346
            $status = 'other';
370
            $substatus = 'Pending hold';
347
            $substatus = 'Pending hold';
371
        }
348
        }
372
        elsif ( $item->holds->waiting->count ) {
349
        elsif ( $reservestatus eq 'Waiting' ) {
373
            $status = 'other';
350
            $status = 'other';
374
            $substatus = 'Hold waiting';
351
            $substatus = 'Waiting';
375
        }
352
        }
376
        elsif ($item->get_transfer) {
353
        elsif ($transfer) {
377
            $status = 'other';
354
            $status = 'other';
378
            $substatus = 'In transit';
355
            $substatus = 'In transit';
379
        }
356
        }
380
        elsif ($item->damaged) {
357
        elsif ($item->{damaged}) {
381
            $status = 'other';
358
            $status = 'other';
382
            $substatus = "Damaged";
359
            $substatus = "Damaged";
383
        }
360
        }
384
        elsif ($item->itemlost) {
361
        elsif ($item->{itemlost}) {
385
            $status = 'other';
362
            $status = 'other';
386
            $substatus = "Lost";
363
            $substatus = "Lost";
387
        }
364
        }
388
        elsif ( $item->withdrawn) {
365
        elsif ( $item->{withdrawn}) {
389
            $status = 'other';
366
            $status = 'other';
390
            $substatus = "Withdrawn";
367
            $substatus = "Withdrawn";
391
        }
368
        }
392
        elsif ($item->onloan) {
369
        elsif ($item->{onloan}) {
393
            $status = 'other';
370
            $status = 'other';
394
            $substatus = "Checked out";
371
            $substatus = "Checked out";
395
        }
372
        }
396
        elsif ( $item->notforloan ) {
373
        elsif ( $item->{notforloan} ) {
397
            $status = $item->notforloan =~ /^($ref_status)$/
374
            $status = $item->{notforloan} =~ /^($ref_status)$/
398
                ? "reference"
375
                ? "reference"
399
                : "reallynotforloan";
376
                : "reallynotforloan";
400
            $substatus = exists $descs{$item->notforloan} ? $descs{$item->notforloan}->{opac_description} : "Not for loan";
377
            $substatus = $item->{notforloan_description};
401
        }
378
        }
402
        elsif ( exists $itemtypes->{ $item->effective_itemtype }
379
        elsif ( defined $item->{notforloan_itemtype} && $item->{notforloan_itemtype} == 1 )
403
            && $itemtypes->{ $item->effective_itemtype }->{notforloan}
404
            && $itemtypes->{ $item->effective_itemtype }->{notforloan} == 1 )
405
        {
380
        {
406
            $status = "1" =~ /^($ref_status)$/
381
            $status = "1" =~ /^($ref_status)$/
407
                ? "reference"
382
                ? "reference"
Lines 411-423 sub buildKohaItemsNamespace { Link Here
411
        else {
386
        else {
412
            $status = "available";
387
            $status = "available";
413
        }
388
        }
414
        my $homebranch     = C4::Koha::xml_escape($branches{$item->homebranch});
389
        my $homebranch     = xml_escape( $item->{homebranch} );
415
        my $holdingbranch  = C4::Koha::xml_escape($branches{$item->holdingbranch});
390
        my $holdingbranch  = xml_escape( $item->{holdingbranch} );
416
        my $resultbranch   = C4::Context->preference('OPACResultsLibrary') eq 'homebranch' ? $homebranch : $holdingbranch;
391
        my $resultbranch   = C4::Context->preference('OPACResultsLibrary') eq 'homebranch' ? $homebranch : $holdingbranch;
417
        my $location       = C4::Koha::xml_escape($item->location && exists $shelflocations->{$item->location} ? $shelflocations->{$item->location} : $item->location);
392
        my $location       = xml_escape( $item->{location} );
418
        my $ccode          = C4::Koha::xml_escape($item->ccode    && exists $ccodes->{$item->ccode}            ? $ccodes->{$item->ccode}            : $item->ccode);
393
        my $ccode          = xml_escape( $item->{ccode} );
419
        my $itemcallnumber = C4::Koha::xml_escape($item->itemcallnumber);
394
        my $itemcallnumber = xml_escape($item->{itemcallnumber});
420
        my $stocknumber    = C4::Koha::xml_escape($item->stocknumber);
395
        my $stocknumber    = xml_escape($item->{stocknumber});
421
        $xml .=
396
        $xml .=
422
            "<item>"
397
            "<item>"
423
          . "<homebranch>$homebranch</homebranch>"
398
          . "<homebranch>$homebranch</homebranch>"
(-)a/opac/opac-shelves.pl (+18 lines)
Lines 349-354 if ( $op eq 'view' ) { Link Here
349
                $art_req_itypes = Koha::CirculationRules->guess_article_requestable_itemtypes({ $patron ? ( categorycode => $patron->categorycode ) : () });
349
                $art_req_itypes = Koha::CirculationRules->guess_article_requestable_itemtypes({ $patron ? ( categorycode => $patron->categorycode ) : () });
350
            }
350
            }
351
351
352
            # Build lookup tables now to avoid fetching later
353
            my %branches = map { $_->branchcode => $_->branchname } Koha::Libraries->search({}, { order_by => 'branchname' });
354
            my $shelflocations = { map { $_->{authorised_value} => $_->{opac_description} } Koha::AuthorisedValues->get_descriptions_by_koha_field( { frameworkcode => '', kohafield => 'items.location' } ) };
355
            my $notforloan_descriptions = { map { $_->{authorised_value} => $_->{opac_description} } Koha::AuthorisedValues->get_descriptions_by_koha_field( { kohafield => 'items.notforloan' } ) };
356
            my $ccodes = { map { $_->{authorised_value} => $_->{opac_description} } Koha::AuthorisedValues->get_descriptions_by_koha_field( { frameworkcode => "", kohafield => 'items.ccode' } ) };
357
            my $itemtypes = Koha::ItemTypes->search_with_localization;
358
            my %itemtypes = map { $_->{itemtype} => $_ } @{ $itemtypes->unblessed };
359
352
            my @items_info;
360
            my @items_info;
353
            while ( my $content = $contents->next ) {
361
            while ( my $content = $contents->next ) {
354
                my $biblionumber = $content->biblionumber;
362
                my $biblionumber = $content->biblionumber;
Lines 394-404 if ( $op eq 'view' ) { Link Here
394
402
395
                my $items = $biblio->items->filter_by_visible_in_opac({ patron => $patron });
403
                my $items = $biblio->items->filter_by_visible_in_opac({ patron => $patron });
396
                my $allow_onshelf_holds;
404
                my $allow_onshelf_holds;
405
                my @items;
397
                while ( my $item = $items->next ) {
406
                while ( my $item = $items->next ) {
398
407
399
                    # This method must take a Koha::Items rs
408
                    # This method must take a Koha::Items rs
400
                    $allow_onshelf_holds ||= Koha::CirculationRules->get_onshelfholds_policy(
409
                    $allow_onshelf_holds ||= Koha::CirculationRules->get_onshelfholds_policy(
401
                        { item => $item, patron => $patron } );
410
                        { item => $item, patron => $patron } );
411
                    my $item_hash = $item->unblessed;
412
                    $item_hash->{itemtype} = $item->effective_itemtype;
413
                    $item_hash->{homebranch} = $branches{ $item->homebranch };
414
                    $item_hash->{holdingbranch} = $branches{ $item->holdingbranch };
415
                    $item_hash->{notforloan_description} = $item->notforloan && exists $notforloan_descriptions->{ $item->notforloan } ? $notforloan_descriptions->{ $item->notforloan } : "Not for loan";
416
                    $item_hash->{location} = $item->{location} && exists $shelflocations->{$item->location} ? $shelflocations->{$item->location} : $item->location ;
417
                    $item_hash->{ccode_description} = $item->{ccode} && exists $ccodes->{$item->ccode} ? $ccodes->{$item->ccode} : $item->ccode ;
418
                    $item_hash->{notforloan_itemtype} = $itemtypes{ $itemtype }->{notforloan};
419
                    push @items, $item_hash;
402
420
403
                }
421
                }
404
422
(-)a/t/db_dependent/XSLT.t (-136 / +42 lines)
Lines 18-24 Link Here
18
use Modern::Perl;
18
use Modern::Perl;
19
19
20
use MARC::Record;
20
use MARC::Record;
21
use Test::More tests => 4;
21
use Test::More tests => 3;
22
use Test::Warn;
22
use Test::Warn;
23
use t::lib::TestBuilder;
23
use t::lib::TestBuilder;
24
use t::lib::Mocks;
24
use t::lib::Mocks;
Lines 48-237 subtest 'transformMARCXML4XSLT tests' => sub { Link Here
48
};
48
};
49
49
50
subtest 'buildKohaItemsNamespace status tests' => sub {
50
subtest 'buildKohaItemsNamespace status tests' => sub {
51
    plan tests => 17;
51
    plan tests => 14;
52
52
53
    t::lib::Mocks::mock_preference('Reference_NFL_Statuses', '1|2');
53
    t::lib::Mocks::mock_preference('Reference_NFL_Statuses', '1|2');
54
    t::lib::Mocks::mock_preference( 'OPACResultsLibrary', 'holdingbranch' );
54
    t::lib::Mocks::mock_preference( 'OPACResultsLibrary', 'holdingbranch' );
55
    t::lib::Mocks::mock_preference( 'OPACResultsMaxItems', '2' );
55
    t::lib::Mocks::mock_preference( 'OPACResultsMaxItems', '2' );
56
56
57
    my $itype = $builder->build_object({ class => 'Koha::ItemTypes' });
57
    my $holdingbranch = $builder->build_object({ class => 'Koha::Libraries' });
58
    my $itemtype = $builder->build_object({ class => 'Koha::ItemTypes' });
58
    my $item  = $builder->build_sample_item({ holdingbranch => $holdingbranch->branchcode  })->unblessed;
59
    my $holdinglibrary = $builder->build_object({ class => 'Koha::Libraries' });
60
    my $item = $builder->build_sample_item({ itype => $itype->itemtype });
61
    $item->holdingbranch( $holdinglibrary->branchcode )->store;
62
    $item->biblioitem->itemtype($itemtype->itemtype)->store;
63
59
64
    my $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber,[]);
60
    my $xml = C4::XSLT::buildKohaItemsNamespace([$item]);
65
    like($xml,qr{<status>available</status>},"Item is available when no other status applied");
61
    like($xml,qr{<status>available</status>},"Item is available when no other status applied");
66
62
67
    # notforloan
63
    # notforloan
68
    {
64
    {
69
        t::lib::Mocks::mock_preference('item-level_itypes', 0);
65
70
        $item->notforloan(0)->store;
66
        $item->{notforloan} = 1;
71
        Koha::ItemTypes->find($item->itype)->notforloan(0)->store;
67
        $xml = C4::XSLT::buildKohaItemsNamespace([$item]);
72
        Koha::ItemTypes->find($item->biblioitem->itemtype)->notforloan(1)->store;
68
        like($xml,qr{<status>reference</status>},"reference if itemtype notforloan value in Reference_NFL_Statuses");
73
        $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber,[]);
69
74
        like($xml,qr{<status>reference</status>},"reference if positive itype notforloan value");
70
        $item->{notforloan} = -1;
75
71
        $item->{notforloan_description} = 'nopenope';
76
        t::lib::Mocks::mock_preference('item-level_itypes', 1);
72
        $xml = C4::XSLT::buildKohaItemsNamespace( [$item]);
77
        Koha::ItemTypes->find($item->itype)->notforloan(1)->store;
73
        like($xml,qr{<status>reallynotforloan</status>},"reallynotforloan if notforloan value not in Reference_NFL_Statuses");
78
        Koha::ItemTypes->find($item->biblioitem->itemtype)->notforloan(0)->store;
74
        like($xml,qr{<substatus>nopenope</substatus>},"substatus set if notforloan value not in Reference_NFL_Statuses");
79
        $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber,[]);
80
        like($xml,qr{<status>reference</status>},"reference if positive itemtype notforloan value");
81
        Koha::ItemTypes->find($item->itype)->notforloan(0)->store;
82
83
        my $substatus = Koha::AuthorisedValues->search({ category => 'NOT_LOAN', authorised_value => -1 })->next->lib;
84
        $item->notforloan(-1)->store;
85
        $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber,[]);
86
        like($xml,qr{<status>reallynotforloan</status>},"reallynotforloan if negative notforloan value");
87
        like($xml,qr{<substatus>$substatus</substatus>},"substatus set if negative notforloan value");
88
89
        $item->notforloan(1)->store;
90
        $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber,[]);
91
        like($xml,qr{<status>reference</status>},"reference if positive notforloan value");
92
75
93
        # But now make status notforloan==1 count under Not available
76
        # But now make status notforloan==1 count under Not available
77
        $item->{notforloan} = 1;
94
        t::lib::Mocks::mock_preference('Reference_NFL_Statuses', '2');
78
        t::lib::Mocks::mock_preference('Reference_NFL_Statuses', '2');
95
        $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber,[]);
79
        $xml = C4::XSLT::buildKohaItemsNamespace( [$item]);
96
        like($xml,qr{<status>reallynotforloan</status>},"reallynotforloan when we change Reference_NFL_Statuses");
80
        like($xml,qr{<status>reallynotforloan</status>},"reallynotforloan when we change Reference_NFL_Statuses");
97
        t::lib::Mocks::mock_preference('Reference_NFL_Statuses', '1|2');
81
        t::lib::Mocks::mock_preference('Reference_NFL_Statuses', '1|2');
98
    }
82
    }
99
83
100
    $item->onloan('2001-01-01')->store;
84
    $item->{onloan} = '2001-01-01';
101
    $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber,[]);
85
    $xml = C4::XSLT::buildKohaItemsNamespace( [$item]);
102
    like( $xml, qr/<status>other<\/status>/, "Checked out is part of other statuses" );
103
    like($xml,qr{<substatus>Checked out</substatus>},"Checked out status takes precedence over Not for loan");
86
    like($xml,qr{<substatus>Checked out</substatus>},"Checked out status takes precedence over Not for loan");
104
87
105
    $item->withdrawn(1)->store;
88
    $item->{withdrawn} = 1;
106
    $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber,[]);
89
    $xml = C4::XSLT::buildKohaItemsNamespace( [$item]);
107
    like($xml,qr{<substatus>Withdrawn</substatus>},"Withdrawn status takes precedence over Checked out");
90
    like($xml,qr{<substatus>Withdrawn</substatus>},"Withdrawn status takes precedence over Checked out");
108
91
109
    $item->itemlost(1)->store;
92
    $item->{itemlost} = 1;
110
    $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber,[]);
93
    $xml = C4::XSLT::buildKohaItemsNamespace( [$item]);
111
    like($xml,qr{<substatus>Lost</substatus>},"Lost status takes precedence over Withdrawn");
94
    like($xml,qr{<substatus>Lost</substatus>},"Lost status takes precedence over Withdrawn");
112
95
113
    $item->damaged(1)->store;
96
    $item->{damaged} = 1;
114
    $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber,[]);
97
    $xml = C4::XSLT::buildKohaItemsNamespace( [$item]);
115
    like($xml,qr{<substatus>Damaged</substatus>},"Damaged status takes precedence over Lost");
98
    like($xml,qr{<substatus>Damaged</substatus>},"Damaged status takes precedence over Lost");
116
99
117
    $builder->build({ source => "Branchtransfer", value => {
100
    $builder->build({ source => "Branchtransfer", value => {
118
        itemnumber  => $item->itemnumber,
101
        itemnumber  => $item->{itemnumber},
119
        datearrived => undef,
102
        datearrived => undef,
120
        datecancelled => undef,
103
        datecancelled => undef,
121
        }
104
        }
122
    });
105
    });
123
    $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber,[]);
106
    $xml = C4::XSLT::buildKohaItemsNamespace( [$item]);
124
    like($xml,qr{<substatus>In transit</substatus>},"In-transit status takes precedence over Damaged");
107
    like($xml,qr{<substatus>In transit</substatus>},"In-transit status takes precedence over Damaged");
125
108
126
    my $hold = $builder->build_object({ class => 'Koha::Holds', value => {
109
    my $hold = $builder->build_object({ class => 'Koha::Holds', value => {
127
        biblionumber => $item->biblionumber,
110
        biblionumber => $item->{biblionumber},
128
        itemnumber   => $item->itemnumber,
111
        itemnumber   => $item->{itemnumber},
129
        found        => 'W',
112
        found        => 'W',
130
        priority     => 0,
113
        priority     => 0,
131
        }
114
        }
132
    });
115
    });
133
    $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber,[]);
116
    $xml = C4::XSLT::buildKohaItemsNamespace( [$item]);
134
    like($xml,qr{<substatus>Hold waiting</substatus>},"Waiting status takes precedence over In transit (holds)");
117
    like($xml,qr{<substatus>Waiting</substatus>},"Waiting status takes precedence over In transit");
135
    $hold->cancel;
136
118
137
    $builder->build({ source => "TmpHoldsqueue", value => {
119
    $builder->build({ source => "TmpHoldsqueue", value => {
138
        itemnumber => $item->itemnumber
120
        itemnumber => $item->{itemnumber}
139
        }
121
        }
140
    });
122
    });
141
    $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber,[]);
123
124
    $xml = C4::XSLT::buildKohaItemsNamespace( [$item]);
142
    like($xml,qr{<substatus>Pending hold</substatus>},"Pending status takes precedence over all");
125
    like($xml,qr{<substatus>Pending hold</substatus>},"Pending status takes precedence over all");
143
    my $library_name = $holdinglibrary->branchname;
126
144
    like($xml,qr{<resultbranch>${library_name}</resultbranch>}, "Found resultbranch / holding branch" );
127
    my $resultbranch = $holdingbranch->branchcode;
128
    like($xml,qr{<resultbranch>${resultbranch}</resultbranch>}, "Found resultbranch / holding branch" );
145
129
146
    t::lib::Mocks::mock_preference('UseRecalls', 1);
130
    t::lib::Mocks::mock_preference('UseRecalls', 1);
147
    my $recall = $builder->build_object({ class => 'Koha::Recalls', value => {
131
    my $recall = $builder->build_object({ class => 'Koha::Recalls', value => {
148
        biblio_id         => $item->biblionumber,
132
        biblio_id         => $item->{biblionumber},
149
        item_id           => $item->itemnumber,
133
        item_id           => $item->{itemnumber},
150
        pickup_library_id => $item->holdingbranch,
134
        pickup_library_id => $item->{holdingbranch},
151
    }});
135
    }});
152
    $recall->set_waiting;
136
    $recall->set_waiting;
153
    $xml = C4::XSLT::buildKohaItemsNamespace( $item->biblionumber,[]);
137
    $xml = C4::XSLT::buildKohaItemsNamespace( [$item] );
154
    like($xml,qr{<substatus>Recall waiting</substatus>},"Waiting status takes precedence over In transit (recalls)");
138
    like($xml,qr{<substatus>Recall waiting</substatus>},"Waiting status takes precedence over In transit (recalls)");
155
    t::lib::Mocks::mock_preference('UseRecalls', 0);
139
    t::lib::Mocks::mock_preference('UseRecalls', 0);
156
140
141
157
};
142
};
158
143
159
$schema->storage->txn_rollback;
144
$schema->storage->txn_rollback;
160
161
subtest 'buildKohaItemsNamespace() including/omitting items tests' => sub {
162
163
    plan tests => 23;
164
165
    $schema->storage->txn_begin;
166
167
    my $biblio = $builder->build_sample_biblio;
168
    my $biblio2 = $builder->build_sample_biblio;
169
170
    # Have two known libraries for testing purposes
171
    my $library_1 = $builder->build_object({ class => 'Koha::Libraries' });
172
    my $library_2 = $builder->build_object({ class => 'Koha::Libraries' });
173
    my $library_3 = $builder->build_object({ class => 'Koha::Libraries' });
174
175
    my $item_1 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber, library => $library_1->id });
176
    my $item_2 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber, library => $library_2->id });
177
    my $item_3 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber, library => $library_3->id });
178
179
    my $items_rs = $biblio->items->search({ "me.itemnumber" => { '!=' => $item_3->itemnumber } });
180
181
    ## Test passing items_rs only
182
    my $xml = C4::XSLT::buildKohaItemsNamespace( $biblio->biblionumber, undef, $items_rs );
183
184
    my $library_1_name = $library_1->branchname;
185
    my $library_2_name = $library_2->branchname;
186
    my $library_3_name = $library_3->branchname;
187
188
    like(   $xml, qr{<homebranch>$library_1_name</homebranch>}, '$item_1 present in the XML' );
189
    like(   $xml, qr{<homebranch>$library_2_name</homebranch>}, '$item_2 present in the XML' );
190
    unlike( $xml, qr{<homebranch>$library_3_name</homebranch>}, '$item_3 not present in the XML' );
191
192
    t::lib::Mocks::mock_preference('OpacHiddenItems', 'biblionumber: ['.$biblio2->biblionumber.']');
193
    my $hid_rs = $biblio->items->search({ "me.itemnumber" => { '!=' => $item_3->itemnumber } })->filter_by_visible_in_opac();
194
    $xml = C4::XSLT::buildKohaItemsNamespace( $biblio->biblionumber, undef, $hid_rs );
195
    like(   $xml, qr{<homebranch>$library_1_name</homebranch>}, '$item_1 present in the XML' );
196
    like(   $xml, qr{<homebranch>$library_2_name</homebranch>}, '$item_2 present in the XML' );
197
    unlike( $xml, qr{<homebranch>$library_3_name</homebranch>}, '$item_3 not present in the XML' );
198
199
    ## Test passing one item in hidden_items and items_rs
200
    $xml = C4::XSLT::buildKohaItemsNamespace( $biblio->biblionumber, [ $item_1->itemnumber ], $items_rs->reset );
201
202
    unlike( $xml, qr{<homebranch>$library_1_name</homebranch>}, '$item_1 not present in the XML' );
203
    like(   $xml, qr{<homebranch>$library_2_name</homebranch>}, '$item_2 present in the XML' );
204
    unlike( $xml, qr{<homebranch>$library_3_name</homebranch>}, '$item_3 not present in the XML' );
205
206
    ## Test passing both items in hidden_items and items_rs
207
    $xml = C4::XSLT::buildKohaItemsNamespace( $biblio->biblionumber, [ $item_1->itemnumber, $item_2->itemnumber ], $items_rs->reset );
208
209
    unlike( $xml, qr{<homebranch>$library_1_name</homebranch>}, '$item_1 not present in the XML' );
210
    unlike( $xml, qr{<homebranch>$library_2_name</homebranch>}, '$item_2 not present in the XML' );
211
    unlike( $xml, qr{<homebranch>$library_3_name</homebranch>}, '$item_3 not present in the XML' );
212
    is( $xml, '<items xmlns="http://www.koha-community.org/items"></items>', 'Empty XML' );
213
214
    ## Test passing both items in hidden_items and no items_rs
215
    $xml = C4::XSLT::buildKohaItemsNamespace( $biblio->biblionumber, [ $item_1->itemnumber, $item_2->itemnumber, $item_3->itemnumber ] );
216
217
    unlike( $xml, qr{<homebranch>$library_1_name</homebranch>}, '$item_1 not present in the XML' );
218
    unlike( $xml, qr{<homebranch>$library_2_name</homebranch>}, '$item_2 not present in the XML' );
219
    unlike( $xml, qr{<homebranch>$library_3_name</homebranch>}, '$item_3 not present in the XML' );
220
    is( $xml, '<items xmlns="http://www.koha-community.org/items"></items>', 'Empty XML' );
221
222
    ## Test passing one item in hidden_items and items_rs
223
    $xml = C4::XSLT::buildKohaItemsNamespace( $biblio->biblionumber, [ $item_1->itemnumber ] );
224
225
    unlike( $xml, qr{<homebranch>$library_1_name</homebranch>}, '$item_1 not present in the XML' );
226
    like(   $xml, qr{<homebranch>$library_2_name</homebranch>}, '$item_2 present in the XML' );
227
    like(   $xml, qr{<homebranch>$library_3_name</homebranch>}, '$item_3 present in the XML' );
228
229
    ## Test not passing any param
230
    $xml = C4::XSLT::buildKohaItemsNamespace( $biblio->biblionumber );
231
232
    like( $xml, qr{<homebranch>$library_1_name</homebranch>}, '$item_1 present in the XML' );
233
    like( $xml, qr{<homebranch>$library_2_name</homebranch>}, '$item_2 present in the XML' );
234
    like( $xml, qr{<homebranch>$library_3_name</homebranch>}, '$item_3 present in the XML' );
235
236
    $schema->storage->txn_rollback;
237
};
238
- 

Return to bug 28702