&GetBiblioItemByBiblioNumber
&GetBiblioFromItemNumber
- &GetItemInfosOf
- &GetItemStatus
- &GetItemLocation
- &GetLostItems
- &GetItemsForInventory
- &GetItemsCount
-
&GetMarcNotes
&GetMarcSubjects
&GetMarcBiblio
GetMarcUrls
&GetUsedMarcStructure
- &GetItemsInfo
- &GetItemsByBiblioitemnumber
&GetItemnumberFromBarcode
- &get_itemnumbers_of
&GetXmlBiblio
&GetAuthorisedValueDesc
return ($data);
} # sub GetBiblioData
-
-=head2 GetItemsInfo
-
-=over 4
-
- @results = &GetItemsInfo($biblionumber, $type);
-
-Returns information about books with the given biblionumber.
-
-C<$type> may be either C<intra> or anything else. If it is not set to
-C<intra>, then the search will exclude lost, very overdue, and
-withdrawn items.
-
-C<&GetItemsInfo> returns a list of references-to-hash. Each element
-contains a number of keys. Most of them are table items from the
-C<biblio>, C<biblioitems>, C<items>, and C<itemtypes> tables in the
-Koha database. Other keys include:
-
-=over 4
-
-=item C<$data-E<gt>{branchname}>
-
-The name (not the code) of the branch to which the book belongs.
-
-=item C<$data-E<gt>{datelastseen}>
-
-This is simply C<items.datelastseen>, except that while the date is
-stored in YYYY-MM-DD format in the database, here it is converted to
-DD/MM/YYYY format. A NULL date is returned as C<//>.
-
-=item C<$data-E<gt>{datedue}>
-
-=item C<$data-E<gt>{class}>
-
-This is the concatenation of C<biblioitems.classification>, the book's
-Dewey code, and C<biblioitems.subclass>.
-
-=item C<$data-E<gt>{ocount}>
-
-I think this is the number of copies of the book available.
-
-=item C<$data-E<gt>{order}>
-
-If this is set, it is set to C<One Order>.
-
-=back
-
-=back
-
-=cut
-
-sub GetItemsInfo {
- my ( $biblionumber, $type ) = @_;
- my $dbh = C4::Context->dbh;
- my $query = "SELECT *,items.notforloan as itemnotforloan
- FROM items
- LEFT JOIN biblio ON biblio.biblionumber = items.biblionumber
- LEFT JOIN biblioitems ON biblioitems.biblioitemnumber = items.biblioitemnumber";
- $query .= (C4::Context->preference('item-level_itypes')) ?
- " LEFT JOIN itemtypes on items.itype = itemtypes.itemtype "
- : " LEFT JOIN itemtypes on biblioitems.itemtype = itemtypes.itemtype ";
- $query .= "WHERE items.biblionumber = ? ORDER BY items.dateaccessioned desc" ;
- my $sth = $dbh->prepare($query);
- $sth->execute($biblionumber);
- my $i = 0;
- my @results;
- my ( $date_due, $count_reserves );
-
- my $isth = $dbh->prepare(
- "SELECT issues.*,borrowers.cardnumber,borrowers.surname,borrowers.firstname,borrowers.branchcode as bcode
- FROM issues LEFT JOIN borrowers ON issues.borrowernumber=borrowers.borrowernumber
- WHERE itemnumber = ?
- AND returndate IS NULL"
- );
- while ( my $data = $sth->fetchrow_hashref ) {
- my $datedue = '';
- $isth->execute( $data->{'itemnumber'} );
- if ( my $idata = $isth->fetchrow_hashref ) {
- $data->{borrowernumber} = $idata->{borrowernumber};
- $data->{cardnumber} = $idata->{cardnumber};
- $data->{surname} = $idata->{surname};
- $data->{firstname} = $idata->{firstname};
- $datedue = $idata->{'date_due'};
- if (C4::Context->preference("IndependantBranches")){
- my $userenv = C4::Context->userenv;
- if ( ($userenv) && ( $userenv->{flags} != 1 ) ) {
- $data->{'NOTSAMEBRANCH'} = 1 if ($idata->{'bcode'} ne $userenv->{branch});
- }
- }
- }
- if ( $datedue eq '' ) {
- my ( $restype, $reserves ) =
- C4::Reserves::CheckReserves( $data->{'itemnumber'} );
- if ($restype) {
- $count_reserves = $restype;
- }
- }
- $isth->finish;
-
- #get branch information.....
- my $bsth = $dbh->prepare(
- "SELECT * FROM branches WHERE branchcode = ?
- "
- );
- $bsth->execute( $data->{'holdingbranch'} );
- if ( my $bdata = $bsth->fetchrow_hashref ) {
- $data->{'branchname'} = $bdata->{'branchname'};
- }
- $data->{'datedue'} = $datedue;
- $data->{'count_reserves'} = $count_reserves;
-
- # get notforloan complete status if applicable
- my $sthnflstatus = $dbh->prepare(
- 'SELECT authorised_value
- FROM marc_subfield_structure
- WHERE kohafield="items.notforloan"
- '
- );
-
- $sthnflstatus->execute;
- my ($authorised_valuecode) = $sthnflstatus->fetchrow;
- if ($authorised_valuecode) {
- $sthnflstatus = $dbh->prepare(
- "SELECT lib FROM authorised_values
- WHERE category=?
- AND authorised_value=?"
- );
- $sthnflstatus->execute( $authorised_valuecode,
- $data->{itemnotforloan} );
- my ($lib) = $sthnflstatus->fetchrow;
- $data->{notforloan} = $lib;
- }
-
- # my stack procedures
- my $stackstatus = $dbh->prepare(
- 'SELECT authorised_value
- FROM marc_subfield_structure
- WHERE kohafield="items.stack"
- '
- );
- $stackstatus->execute;
-
- ($authorised_valuecode) = $stackstatus->fetchrow;
- if ($authorised_valuecode) {
- $stackstatus = $dbh->prepare(
- "SELECT lib
- FROM authorised_values
- WHERE category=?
- AND authorised_value=?
- "
- );
- $stackstatus->execute( $authorised_valuecode, $data->{stack} );
- my ($lib) = $stackstatus->fetchrow;
- $data->{stack} = $lib;
- }
- # Find the last 3 people who borrowed this item.
- my $sth2 = $dbh->prepare("SELECT * FROM issues,borrowers
- WHERE itemnumber = ?
- AND issues.borrowernumber = borrowers.borrowernumber
- AND returndate IS NOT NULL LIMIT 3");
- $sth2->execute($data->{'itemnumber'});
- my $ii = 0;
- while (my $data2 = $sth2->fetchrow_hashref()) {
- $data->{"timestamp$ii"} = $data2->{'timestamp'} if $data2->{'timestamp'};
- $data->{"card$ii"} = $data2->{'cardnumber'} if $data2->{'cardnumber'};
- $data->{"borrower$ii"} = $data2->{'borrowernumber'} if $data2->{'borrowernumber'};
- $ii++;
- }
-
- $results[$i] = $data;
- $i++;
- }
- $sth->finish;
-
- return (@results);
-}
-
-=head2 getitemstatus
-
-=over 4
-
-$itemstatushash = &getitemstatus($fwkcode);
-returns information about status.
-Can be MARC dependant.
-fwkcode is optional.
-But basically could be can be loan or not
-Create a status selector with the following code
-
-=head3 in PERL SCRIPT
-
-my $itemstatushash = getitemstatus;
-my @itemstatusloop;
-foreach my $thisstatus (keys %$itemstatushash) {
- my %row =(value => $thisstatus,
- statusname => $itemstatushash->{$thisstatus}->{'statusname'},
- );
- push @itemstatusloop, \%row;
-}
-$template->param(statusloop=>\@itemstatusloop);
-
-
-=head3 in TEMPLATE
-
- <select name="statusloop">
- <option value="">Default</option>
- <!-- TMPL_LOOP name="statusloop" -->
- <option value="<!-- TMPL_VAR name="value" -->" <!-- TMPL_IF name="selected" -->selected<!-- /TMPL_IF -->><!-- TMPL_VAR name="statusname" --></option>
- <!-- /TMPL_LOOP -->
- </select>
-
-=cut
-
-sub GetItemStatus {
-
- # returns a reference to a hash of references to status...
- my ($fwk) = @_;
- my %itemstatus;
- my $dbh = C4::Context->dbh;
- my $sth;
- $fwk = '' unless ($fwk);
- my ( $tag, $subfield ) =
- GetMarcFromKohaField( "items.notforloan", $fwk );
- if ( $tag and $subfield ) {
- my $sth =
- $dbh->prepare(
- "SELECT authorised_value
- FROM marc_subfield_structure
- WHERE tagfield=?
- AND tagsubfield=?
- AND frameworkcode=?
- "
- );
- $sth->execute( $tag, $subfield, $fwk );
- if ( my ($authorisedvaluecat) = $sth->fetchrow ) {
- my $authvalsth =
- $dbh->prepare(
- "SELECT authorised_value,lib
- FROM authorised_values
- WHERE category=?
- ORDER BY lib
- "
- );
- $authvalsth->execute($authorisedvaluecat);
- while ( my ( $authorisedvalue, $lib ) = $authvalsth->fetchrow ) {
- $itemstatus{$authorisedvalue} = $lib;
- }
- $authvalsth->finish;
- return \%itemstatus;
- exit 1;
- }
- else {
-
- #No authvalue list
- # build default
- }
- $sth->finish;
- }
-
- #No authvalue list
- #build default
- $itemstatus{"1"} = "Not For Loan";
- return \%itemstatus;
-}
-
-=head2 getitemlocation
-
-=over 4
-
-$itemlochash = &getitemlocation($fwk);
-returns informations about location.
-where fwk stands for an optional framework code.
-Create a location selector with the following code
-
-=head3 in PERL SCRIPT
-
-my $itemlochash = getitemlocation;
-my @itemlocloop;
-foreach my $thisloc (keys %$itemlochash) {
- my $selected = 1 if $thisbranch eq $branch;
- my %row =(locval => $thisloc,
- selected => $selected,
- locname => $itemlochash->{$thisloc},
- );
- push @itemlocloop, \%row;
-}
-$template->param(itemlocationloop => \@itemlocloop);
-
-=head3 in TEMPLATE
-
-<select name="location">
- <option value="">Default</option>
-<!-- TMPL_LOOP name="itemlocationloop" -->
- <option value="<!-- TMPL_VAR name="locval" -->" <!-- TMPL_IF name="selected" -->selected<!-- /TMPL_IF -->><!-- TMPL_VAR name="locname" --></option>
-<!-- /TMPL_LOOP -->
-</select>
-
-=back
-
-=cut
-
-sub GetItemLocation {
-
- # returns a reference to a hash of references to location...
- my ($fwk) = @_;
- my %itemlocation;
- my $dbh = C4::Context->dbh;
- my $sth;
- $fwk = '' unless ($fwk);
- my ( $tag, $subfield ) =
- GetMarcFromKohaField( "items.location", $fwk );
- if ( $tag and $subfield ) {
- my $sth =
- $dbh->prepare(
- "SELECT authorised_value
- FROM marc_subfield_structure
- WHERE tagfield=?
- AND tagsubfield=?
- AND frameworkcode=?"
- );
- $sth->execute( $tag, $subfield, $fwk );
- if ( my ($authorisedvaluecat) = $sth->fetchrow ) {
- my $authvalsth =
- $dbh->prepare(
- "SELECT authorised_value,lib
- FROM authorised_values
- WHERE category=?
- ORDER BY lib"
- );
- $authvalsth->execute($authorisedvaluecat);
- while ( my ( $authorisedvalue, $lib ) = $authvalsth->fetchrow ) {
- $itemlocation{$authorisedvalue} = $lib;
- }
- $authvalsth->finish;
- return \%itemlocation;
- exit 1;
- }
- else {
-
- #No authvalue list
- # build default
- }
- $sth->finish;
- }
-
- #No authvalue list
- #build default
- $itemlocation{"1"} = "Not For Loan";
- return \%itemlocation;
-}
-
-=head2 GetLostItems
-
-$items = GetLostItems($where,$orderby);
-
-This function get the items lost into C<$items>.
-
-=over 2
-
-=item input:
-C<$where> is a hashref. it containts a field of the items table as key
-and the value to match as value.
-C<$orderby> is a field of the items table.
-
-=item return:
-C<$items> is a reference to an array full of hasref which keys are items' table column.
-
-=item usage in the perl script:
-
-my %where;
-$where{barcode} = 0001548;
-my $items = GetLostItems( \%where, "homebranch" );
-$template->param(itemsloop => $items);
-
-=back
-
-=cut
-
-sub GetLostItems {
- # Getting input args.
- my $where = shift;
- my $orderby = shift;
- my $dbh = C4::Context->dbh;
-
- my $query = "
- SELECT *
- FROM items
- WHERE itemlost IS NOT NULL
- AND itemlost <> 0
- ";
- foreach my $key (keys %$where) {
- $query .= " AND " . $key . " LIKE '%" . $where->{$key} . "%'";
- }
- $query .= " ORDER BY ".$orderby if defined $orderby;
-
- my $sth = $dbh->prepare($query);
- $sth->execute;
- my @items;
- while ( my $row = $sth->fetchrow_hashref ){
- push @items, $row;
- }
- return \@items;
-}
-
-=head2 GetItemsForInventory
-
-$itemlist = GetItemsForInventory($minlocation,$maxlocation,$datelastseen,$offset,$size)
-
-Retrieve a list of title/authors/barcode/callnumber, for biblio inventory.
-
-The sub returns a list of hashes, containing itemnumber, author, title, barcode & item callnumber.
-It is ordered by callnumber,title.
-
-The minlocation & maxlocation parameters are used to specify a range of item callnumbers
-the datelastseen can be used to specify that you want to see items not seen since a past date only.
-offset & size can be used to retrieve only a part of the whole listing (defaut behaviour)
-
-=cut
-
-sub GetItemsForInventory {
- my ( $minlocation, $maxlocation,$location, $datelastseen, $branch, $offset, $size ) = @_;
- my $dbh = C4::Context->dbh;
- my $sth;
- if ($datelastseen) {
- $datelastseen=format_date_in_iso($datelastseen);
- my $query =
- "SELECT itemnumber,barcode,itemcallnumber,title,author,biblio.biblionumber,datelastseen
- FROM items
- LEFT JOIN biblio ON items.biblionumber=biblio.biblionumber
- WHERE itemcallnumber>= ?
- AND itemcallnumber <=?
- AND (datelastseen< ? OR datelastseen IS NULL)";
- $query.= " AND items.location=".$dbh->quote($location) if $location;
- $query.= " AND items.homebranch=".$dbh->quote($branch) if $branch;
- $query .= " ORDER BY itemcallnumber,title";
- $sth = $dbh->prepare($query);
- $sth->execute( $minlocation, $maxlocation, $datelastseen );
- }
- else {
- my $query ="
- SELECT itemnumber,barcode,itemcallnumber,biblio.biblionumber,title,author,datelastseen
- FROM items
- LEFT JOIN biblio ON items.biblionumber=biblio.biblionumber
- WHERE itemcallnumber>= ?
- AND itemcallnumber <=?";
- $query.= " AND items.location=".$dbh->quote($location) if $location;
- $query.= " AND items.homebranch=".$dbh->quote($branch) if $branch;
- $query .= " ORDER BY itemcallnumber,title";
- $sth = $dbh->prepare($query);
- $sth->execute( $minlocation, $maxlocation );
- }
- my @results;
- while ( my $row = $sth->fetchrow_hashref ) {
- $offset-- if ($offset);
- $row->{datelastseen}=format_date($row->{datelastseen});
- if ( ( !$offset ) && $size ) {
- push @results, $row;
- $size--;
- }
- }
- return \@results;
-}
-
=head2 &GetBiblioItemData
=over 4
return ( $count, @results );
} # sub GetBiblio
-=head2 get_itemnumbers_of
-
-=over 4
-
-my @itemnumbers_of = get_itemnumbers_of(@biblionumbers);
-
-Given a list of biblionumbers, return the list of corresponding itemnumbers
-for each biblionumber.
-
-Return a reference on a hash where keys are biblionumbers and values are
-references on array of itemnumbers.
-
-=back
-
-=cut
-
-sub get_itemnumbers_of {
- my @biblionumbers = @_;
-
- my $dbh = C4::Context->dbh;
-
- my $query = '
- SELECT itemnumber,
- biblionumber
- FROM items
- WHERE biblionumber IN (?' . ( ',?' x scalar @biblionumbers - 1 ) . ')
- ';
- my $sth = $dbh->prepare($query);
- $sth->execute(@biblionumbers);
-
- my %itemnumbers_of;
-
- while ( my ( $itemnumber, $biblionumber ) = $sth->fetchrow_array ) {
- push @{ $itemnumbers_of{$biblionumber} }, $itemnumber;
- }
-
- return \%itemnumbers_of;
-}
-
-=head2 GetItemInfosOf
-
-=over 4
-
-GetItemInfosOf(@itemnumbers);
-
-=back
-
-=cut
-
-sub GetItemInfosOf {
- my @itemnumbers = @_;
-
- my $query = '
- SELECT *
- FROM items
- WHERE itemnumber IN (' . join( ',', @itemnumbers ) . ')
- ';
- return get_infos_of( $query, 'itemnumber' );
-}
-
-=head2 GetItemsByBiblioitemnumber
-
-=over 4
-
-GetItemsByBiblioitemnumber($biblioitemnumber);
-
-Returns an arrayref of hashrefs suitable for use in a TMPL_LOOP
-Called by moredetail.pl
-
-=back
-
-=cut
-
-sub GetItemsByBiblioitemnumber {
- my ( $bibitem ) = @_;
- my $dbh = C4::Context->dbh;
- my $sth = $dbh->prepare("SELECT * FROM items WHERE items.biblioitemnumber = ?") || die $dbh->errstr;
- # Get all items attached to a biblioitem
- my $i = 0;
- my @results;
- $sth->execute($bibitem) || die $sth->errstr;
- while ( my $data = $sth->fetchrow_hashref ) {
- # Foreach item, get circulation information
- my $sth2 = $dbh->prepare( "SELECT * FROM issues,borrowers
- WHERE itemnumber = ?
- AND returndate is NULL
- AND issues.borrowernumber = borrowers.borrowernumber"
- );
- $sth2->execute( $data->{'itemnumber'} );
- if ( my $data2 = $sth2->fetchrow_hashref ) {
- # if item is out, set the due date and who it is out too
- $data->{'date_due'} = $data2->{'date_due'};
- $data->{'cardnumber'} = $data2->{'cardnumber'};
- $data->{'borrowernumber'} = $data2->{'borrowernumber'};
- }
- else {
- # set date_due to blank, so in the template we check itemlost, and wthdrawn
- $data->{'date_due'} = '';
- } # else
- $sth2->finish;
- # Find the last 3 people who borrowed this item.
- my $query2 = "SELECT * FROM issues, borrowers WHERE itemnumber = ?
- AND issues.borrowernumber = borrowers.borrowernumber
- AND returndate is not NULL
- ORDER BY returndate desc,timestamp desc LIMIT 3";
- $sth2 = $dbh->prepare($query2) || die $dbh->errstr;
- $sth2->execute( $data->{'itemnumber'} ) || die $sth2->errstr;
- my $i2 = 0;
- while ( my $data2 = $sth2->fetchrow_hashref ) {
- $data->{"timestamp$i2"} = $data2->{'timestamp'};
- $data->{"card$i2"} = $data2->{'cardnumber'};
- $data->{"borrower$i2"} = $data2->{'borrowernumber'};
- $i2++;
- }
- $sth2->finish;
- push(@results,$data);
- }
- $sth->finish;
- return (\@results);
-}
-
-
=head2 GetBiblioItemInfosOf
=over 4
return $serviceOptions;
}
-=head2 GetItemsCount
-
-$count = &GetItemsCount( $biblionumber);
-this function return count of item with $biblionumber
-=cut
-
-sub GetItemsCount {
- my ( $biblionumber ) = @_;
- my $dbh = C4::Context->dbh;
- my $query = "SELECT count(*)
- FROM items
- WHERE biblionumber=?";
- my $sth = $dbh->prepare($query);
- $sth->execute($biblionumber);
- my $count = $sth->fetchrow;
- $sth->finish;
- return ($count);
-}
-
END { } # module clean-up code here (global destructor)
1;
require Exporter;
use C4::Context;
+use C4::Koha;
use C4::Biblio;
-use C4::Dates;
+use C4::Dates qw/format_date format_date_in_iso/;
use MARC::Record;
use C4::ClassSource;
use C4::Log;
+use C4::Reserves;
use vars qw($VERSION @ISA @EXPORT);
ModItem
ModDateLastSeen
ModItemTransfer
+
+ GetItemStatus
+ GetItemLocation
+ GetLostItems
+ GetItemsForInventory
+ GetItemsCount
+ GetItemInfosOf
+ GetItemsByBiblioitemnumber
+ GetItemsInfo
+ get_itemnumbers_of
);
=head1 NAME
Most of the functions in C<C4::Items> were originally in
the C<C4::Biblio> module.
-=head1 EXPORTED FUNCTIONS
+=head1 CORE EXPORTED FUNCTIONS
The following functions are meant for use by users
of C<C4::Items>
ModItem({ itemlost => 0, datelastseen => $today->output("iso") }, undef, $itemnumber);
}
+=head1 EXPORTED SPECIAL ACCESSOR FUNCTIONS
+
+The following functions provide various ways of
+getting an item record, a set of item records, or
+lists of authorized values for certain item fields.
+
+Some of the functions in this group are candidates
+for refactoring -- for example, some of the code
+in C<GetItemsByBiblioitemnumber> and C<GetItemsInfo>
+has copy-and-paste work.
+
+=cut
+
+=head2 GetItemStatus
+
+=over 4
+
+$itemstatushash = GetItemStatus($fwkcode);
+
+=back
+
+Returns a list of valid values for the
+C<items.notforloan> field.
+
+NOTE: does B<not> return an individual item's
+status.
+
+Can be MARC dependant.
+fwkcode is optional.
+But basically could be can be loan or not
+Create a status selector with the following code
+
+=head3 in PERL SCRIPT
+
+=over 4
+
+my $itemstatushash = getitemstatus;
+my @itemstatusloop;
+foreach my $thisstatus (keys %$itemstatushash) {
+ my %row =(value => $thisstatus,
+ statusname => $itemstatushash->{$thisstatus}->{'statusname'},
+ );
+ push @itemstatusloop, \%row;
+}
+$template->param(statusloop=>\@itemstatusloop);
+
+=back
+
+=head3 in TEMPLATE
+
+=over 4
+
+<select name="statusloop">
+ <option value="">Default</option>
+<!-- TMPL_LOOP name="statusloop" -->
+ <option value="<!-- TMPL_VAR name="value" -->" <!-- TMPL_IF name="selected" -->selected<!-- /TMPL_IF -->><!-- TMPL_VAR name="statusname" --></option>
+<!-- /TMPL_LOOP -->
+</select>
+
+=back
+
+=cut
+
+sub GetItemStatus {
+
+ # returns a reference to a hash of references to status...
+ my ($fwk) = @_;
+ my %itemstatus;
+ my $dbh = C4::Context->dbh;
+ my $sth;
+ $fwk = '' unless ($fwk);
+ my ( $tag, $subfield ) =
+ GetMarcFromKohaField( "items.notforloan", $fwk );
+ if ( $tag and $subfield ) {
+ my $sth =
+ $dbh->prepare(
+ "SELECT authorised_value
+ FROM marc_subfield_structure
+ WHERE tagfield=?
+ AND tagsubfield=?
+ AND frameworkcode=?
+ "
+ );
+ $sth->execute( $tag, $subfield, $fwk );
+ if ( my ($authorisedvaluecat) = $sth->fetchrow ) {
+ my $authvalsth =
+ $dbh->prepare(
+ "SELECT authorised_value,lib
+ FROM authorised_values
+ WHERE category=?
+ ORDER BY lib
+ "
+ );
+ $authvalsth->execute($authorisedvaluecat);
+ while ( my ( $authorisedvalue, $lib ) = $authvalsth->fetchrow ) {
+ $itemstatus{$authorisedvalue} = $lib;
+ }
+ $authvalsth->finish;
+ return \%itemstatus;
+ exit 1;
+ }
+ else {
+
+ #No authvalue list
+ # build default
+ }
+ $sth->finish;
+ }
+
+ #No authvalue list
+ #build default
+ $itemstatus{"1"} = "Not For Loan";
+ return \%itemstatus;
+}
+
+=head2 GetItemLocation
+
+=over 4
+
+$itemlochash = GetItemLocation($fwk);
+
+=back
+
+Returns a list of valid values for the
+C<items.location> field.
+
+NOTE: does B<not> return an individual item's
+location.
+
+where fwk stands for an optional framework code.
+Create a location selector with the following code
+
+=head3 in PERL SCRIPT
+
+=over 4
+
+my $itemlochash = getitemlocation;
+my @itemlocloop;
+foreach my $thisloc (keys %$itemlochash) {
+ my $selected = 1 if $thisbranch eq $branch;
+ my %row =(locval => $thisloc,
+ selected => $selected,
+ locname => $itemlochash->{$thisloc},
+ );
+ push @itemlocloop, \%row;
+}
+$template->param(itemlocationloop => \@itemlocloop);
+
+=back
+
+=head3 in TEMPLATE
+
+=over 4
+
+<select name="location">
+ <option value="">Default</option>
+<!-- TMPL_LOOP name="itemlocationloop" -->
+ <option value="<!-- TMPL_VAR name="locval" -->" <!-- TMPL_IF name="selected" -->selected<!-- /TMPL_IF -->><!-- TMPL_VAR name="locname" --></option>
+<!-- /TMPL_LOOP -->
+</select>
+
+=back
+
+=cut
+
+sub GetItemLocation {
+
+ # returns a reference to a hash of references to location...
+ my ($fwk) = @_;
+ my %itemlocation;
+ my $dbh = C4::Context->dbh;
+ my $sth;
+ $fwk = '' unless ($fwk);
+ my ( $tag, $subfield ) =
+ GetMarcFromKohaField( "items.location", $fwk );
+ if ( $tag and $subfield ) {
+ my $sth =
+ $dbh->prepare(
+ "SELECT authorised_value
+ FROM marc_subfield_structure
+ WHERE tagfield=?
+ AND tagsubfield=?
+ AND frameworkcode=?"
+ );
+ $sth->execute( $tag, $subfield, $fwk );
+ if ( my ($authorisedvaluecat) = $sth->fetchrow ) {
+ my $authvalsth =
+ $dbh->prepare(
+ "SELECT authorised_value,lib
+ FROM authorised_values
+ WHERE category=?
+ ORDER BY lib"
+ );
+ $authvalsth->execute($authorisedvaluecat);
+ while ( my ( $authorisedvalue, $lib ) = $authvalsth->fetchrow ) {
+ $itemlocation{$authorisedvalue} = $lib;
+ }
+ $authvalsth->finish;
+ return \%itemlocation;
+ exit 1;
+ }
+ else {
+
+ #No authvalue list
+ # build default
+ }
+ $sth->finish;
+ }
+
+ #No authvalue list
+ #build default
+ $itemlocation{"1"} = "Not For Loan";
+ return \%itemlocation;
+}
+
+=head2 GetLostItems
+
+=over 4
+
+$items = GetLostItems($where,$orderby);
+
+=back
+
+This function get the items lost into C<$items>.
+
+=over 2
+
+=item input:
+C<$where> is a hashref. it containts a field of the items table as key
+and the value to match as value.
+C<$orderby> is a field of the items table.
+
+=item return:
+C<$items> is a reference to an array full of hasref which keys are items' table column.
+
+=item usage in the perl script:
+
+my %where;
+$where{barcode} = 0001548;
+my $items = GetLostItems( \%where, "homebranch" );
+$template->param(itemsloop => $items);
+
+=back
+
+=cut
+
+sub GetLostItems {
+ # Getting input args.
+ my $where = shift;
+ my $orderby = shift;
+ my $dbh = C4::Context->dbh;
+
+ my $query = "
+ SELECT *
+ FROM items
+ WHERE itemlost IS NOT NULL
+ AND itemlost <> 0
+ ";
+ foreach my $key (keys %$where) {
+ $query .= " AND " . $key . " LIKE '%" . $where->{$key} . "%'";
+ }
+ $query .= " ORDER BY ".$orderby if defined $orderby;
+
+ my $sth = $dbh->prepare($query);
+ $sth->execute;
+ my @items;
+ while ( my $row = $sth->fetchrow_hashref ){
+ push @items, $row;
+ }
+ return \@items;
+}
+
+=head2 GetItemsForInventory
+
+=over 4
+
+$itemlist = GetItemsForInventory($minlocation,$maxlocation,$datelastseen,$offset,$size)
+
+=back
+
+Retrieve a list of title/authors/barcode/callnumber, for biblio inventory.
+
+The sub returns a list of hashes, containing itemnumber, author, title, barcode & item callnumber.
+It is ordered by callnumber,title.
+
+The minlocation & maxlocation parameters are used to specify a range of item callnumbers
+the datelastseen can be used to specify that you want to see items not seen since a past date only.
+offset & size can be used to retrieve only a part of the whole listing (defaut behaviour)
+
+=cut
+
+sub GetItemsForInventory {
+ my ( $minlocation, $maxlocation,$location, $datelastseen, $branch, $offset, $size ) = @_;
+ my $dbh = C4::Context->dbh;
+ my $sth;
+ if ($datelastseen) {
+ $datelastseen=format_date_in_iso($datelastseen);
+ my $query =
+ "SELECT itemnumber,barcode,itemcallnumber,title,author,biblio.biblionumber,datelastseen
+ FROM items
+ LEFT JOIN biblio ON items.biblionumber=biblio.biblionumber
+ WHERE itemcallnumber>= ?
+ AND itemcallnumber <=?
+ AND (datelastseen< ? OR datelastseen IS NULL)";
+ $query.= " AND items.location=".$dbh->quote($location) if $location;
+ $query.= " AND items.homebranch=".$dbh->quote($branch) if $branch;
+ $query .= " ORDER BY itemcallnumber,title";
+ $sth = $dbh->prepare($query);
+ $sth->execute( $minlocation, $maxlocation, $datelastseen );
+ }
+ else {
+ my $query ="
+ SELECT itemnumber,barcode,itemcallnumber,biblio.biblionumber,title,author,datelastseen
+ FROM items
+ LEFT JOIN biblio ON items.biblionumber=biblio.biblionumber
+ WHERE itemcallnumber>= ?
+ AND itemcallnumber <=?";
+ $query.= " AND items.location=".$dbh->quote($location) if $location;
+ $query.= " AND items.homebranch=".$dbh->quote($branch) if $branch;
+ $query .= " ORDER BY itemcallnumber,title";
+ $sth = $dbh->prepare($query);
+ $sth->execute( $minlocation, $maxlocation );
+ }
+ my @results;
+ while ( my $row = $sth->fetchrow_hashref ) {
+ $offset-- if ($offset);
+ $row->{datelastseen}=format_date($row->{datelastseen});
+ if ( ( !$offset ) && $size ) {
+ push @results, $row;
+ $size--;
+ }
+ }
+ return \@results;
+}
+
+=head2 GetItemsCount
+
+=over 4
+$count = &GetItemsCount( $biblionumber);
+
+=back
+
+This function return count of item with $biblionumber
+
+=cut
+
+sub GetItemsCount {
+ my ( $biblionumber ) = @_;
+ my $dbh = C4::Context->dbh;
+ my $query = "SELECT count(*)
+ FROM items
+ WHERE biblionumber=?";
+ my $sth = $dbh->prepare($query);
+ $sth->execute($biblionumber);
+ my $count = $sth->fetchrow;
+ $sth->finish;
+ return ($count);
+}
+
+=head2 GetItemInfosOf
+
+=over 4
+
+GetItemInfosOf(@itemnumbers);
+
+=back
+
+=cut
+
+sub GetItemInfosOf {
+ my @itemnumbers = @_;
+
+ my $query = '
+ SELECT *
+ FROM items
+ WHERE itemnumber IN (' . join( ',', @itemnumbers ) . ')
+ ';
+ return get_infos_of( $query, 'itemnumber' );
+}
+
+=head2 GetItemsByBiblioitemnumber
+
+=over 4
+
+GetItemsByBiblioitemnumber($biblioitemnumber);
+
+=back
+
+Returns an arrayref of hashrefs suitable for use in a TMPL_LOOP
+Called by C<C4::XISBN>
+
+=cut
+
+sub GetItemsByBiblioitemnumber {
+ my ( $bibitem ) = @_;
+ my $dbh = C4::Context->dbh;
+ my $sth = $dbh->prepare("SELECT * FROM items WHERE items.biblioitemnumber = ?") || die $dbh->errstr;
+ # Get all items attached to a biblioitem
+ my $i = 0;
+ my @results;
+ $sth->execute($bibitem) || die $sth->errstr;
+ while ( my $data = $sth->fetchrow_hashref ) {
+ # Foreach item, get circulation information
+ my $sth2 = $dbh->prepare( "SELECT * FROM issues,borrowers
+ WHERE itemnumber = ?
+ AND returndate is NULL
+ AND issues.borrowernumber = borrowers.borrowernumber"
+ );
+ $sth2->execute( $data->{'itemnumber'} );
+ if ( my $data2 = $sth2->fetchrow_hashref ) {
+ # if item is out, set the due date and who it is out too
+ $data->{'date_due'} = $data2->{'date_due'};
+ $data->{'cardnumber'} = $data2->{'cardnumber'};
+ $data->{'borrowernumber'} = $data2->{'borrowernumber'};
+ }
+ else {
+ # set date_due to blank, so in the template we check itemlost, and wthdrawn
+ $data->{'date_due'} = '';
+ } # else
+ $sth2->finish;
+ # Find the last 3 people who borrowed this item.
+ my $query2 = "SELECT * FROM issues, borrowers WHERE itemnumber = ?
+ AND issues.borrowernumber = borrowers.borrowernumber
+ AND returndate is not NULL
+ ORDER BY returndate desc,timestamp desc LIMIT 3";
+ $sth2 = $dbh->prepare($query2) || die $dbh->errstr;
+ $sth2->execute( $data->{'itemnumber'} ) || die $sth2->errstr;
+ my $i2 = 0;
+ while ( my $data2 = $sth2->fetchrow_hashref ) {
+ $data->{"timestamp$i2"} = $data2->{'timestamp'};
+ $data->{"card$i2"} = $data2->{'cardnumber'};
+ $data->{"borrower$i2"} = $data2->{'borrowernumber'};
+ $i2++;
+ }
+ $sth2->finish;
+ push(@results,$data);
+ }
+ $sth->finish;
+ return (\@results);
+}
+
+=head2 GetItemsInfo
+
+=over 4
+
+@results = GetItemsInfo($biblionumber, $type);
+
+=back
+
+Returns information about books with the given biblionumber.
+
+C<$type> may be either C<intra> or anything else. If it is not set to
+C<intra>, then the search will exclude lost, very overdue, and
+withdrawn items.
+
+C<GetItemsInfo> returns a list of references-to-hash. Each element
+contains a number of keys. Most of them are table items from the
+C<biblio>, C<biblioitems>, C<items>, and C<itemtypes> tables in the
+Koha database. Other keys include:
+
+=over 2
+
+=item C<$data-E<gt>{branchname}>
+
+The name (not the code) of the branch to which the book belongs.
+
+=item C<$data-E<gt>{datelastseen}>
+
+This is simply C<items.datelastseen>, except that while the date is
+stored in YYYY-MM-DD format in the database, here it is converted to
+DD/MM/YYYY format. A NULL date is returned as C<//>.
+
+=item C<$data-E<gt>{datedue}>
+
+=item C<$data-E<gt>{class}>
+
+This is the concatenation of C<biblioitems.classification>, the book's
+Dewey code, and C<biblioitems.subclass>.
+
+=item C<$data-E<gt>{ocount}>
+
+I think this is the number of copies of the book available.
+
+=item C<$data-E<gt>{order}>
+
+If this is set, it is set to C<One Order>.
+
+=back
+
+=cut
+
+sub GetItemsInfo {
+ my ( $biblionumber, $type ) = @_;
+ my $dbh = C4::Context->dbh;
+ my $query = "SELECT *,items.notforloan as itemnotforloan
+ FROM items
+ LEFT JOIN biblio ON biblio.biblionumber = items.biblionumber
+ LEFT JOIN biblioitems ON biblioitems.biblioitemnumber = items.biblioitemnumber";
+ $query .= (C4::Context->preference('item-level_itypes')) ?
+ " LEFT JOIN itemtypes on items.itype = itemtypes.itemtype "
+ : " LEFT JOIN itemtypes on biblioitems.itemtype = itemtypes.itemtype ";
+ $query .= "WHERE items.biblionumber = ? ORDER BY items.dateaccessioned desc" ;
+ my $sth = $dbh->prepare($query);
+ $sth->execute($biblionumber);
+ my $i = 0;
+ my @results;
+ my ( $date_due, $count_reserves );
+
+ my $isth = $dbh->prepare(
+ "SELECT issues.*,borrowers.cardnumber,borrowers.surname,borrowers.firstname,borrowers.branchcode as bcode
+ FROM issues LEFT JOIN borrowers ON issues.borrowernumber=borrowers.borrowernumber
+ WHERE itemnumber = ?
+ AND returndate IS NULL"
+ );
+ while ( my $data = $sth->fetchrow_hashref ) {
+ my $datedue = '';
+ $isth->execute( $data->{'itemnumber'} );
+ if ( my $idata = $isth->fetchrow_hashref ) {
+ $data->{borrowernumber} = $idata->{borrowernumber};
+ $data->{cardnumber} = $idata->{cardnumber};
+ $data->{surname} = $idata->{surname};
+ $data->{firstname} = $idata->{firstname};
+ $datedue = $idata->{'date_due'};
+ if (C4::Context->preference("IndependantBranches")){
+ my $userenv = C4::Context->userenv;
+ if ( ($userenv) && ( $userenv->{flags} != 1 ) ) {
+ $data->{'NOTSAMEBRANCH'} = 1 if ($idata->{'bcode'} ne $userenv->{branch});
+ }
+ }
+ }
+ if ( $datedue eq '' ) {
+ my ( $restype, $reserves ) =
+ C4::Reserves::CheckReserves( $data->{'itemnumber'} );
+ if ($restype) {
+ $count_reserves = $restype;
+ }
+ }
+ $isth->finish;
+
+ #get branch information.....
+ my $bsth = $dbh->prepare(
+ "SELECT * FROM branches WHERE branchcode = ?
+ "
+ );
+ $bsth->execute( $data->{'holdingbranch'} );
+ if ( my $bdata = $bsth->fetchrow_hashref ) {
+ $data->{'branchname'} = $bdata->{'branchname'};
+ }
+ $data->{'datedue'} = $datedue;
+ $data->{'count_reserves'} = $count_reserves;
+
+ # get notforloan complete status if applicable
+ my $sthnflstatus = $dbh->prepare(
+ 'SELECT authorised_value
+ FROM marc_subfield_structure
+ WHERE kohafield="items.notforloan"
+ '
+ );
+
+ $sthnflstatus->execute;
+ my ($authorised_valuecode) = $sthnflstatus->fetchrow;
+ if ($authorised_valuecode) {
+ $sthnflstatus = $dbh->prepare(
+ "SELECT lib FROM authorised_values
+ WHERE category=?
+ AND authorised_value=?"
+ );
+ $sthnflstatus->execute( $authorised_valuecode,
+ $data->{itemnotforloan} );
+ my ($lib) = $sthnflstatus->fetchrow;
+ $data->{notforloan} = $lib;
+ }
+
+ # my stack procedures
+ my $stackstatus = $dbh->prepare(
+ 'SELECT authorised_value
+ FROM marc_subfield_structure
+ WHERE kohafield="items.stack"
+ '
+ );
+ $stackstatus->execute;
+
+ ($authorised_valuecode) = $stackstatus->fetchrow;
+ if ($authorised_valuecode) {
+ $stackstatus = $dbh->prepare(
+ "SELECT lib
+ FROM authorised_values
+ WHERE category=?
+ AND authorised_value=?
+ "
+ );
+ $stackstatus->execute( $authorised_valuecode, $data->{stack} );
+ my ($lib) = $stackstatus->fetchrow;
+ $data->{stack} = $lib;
+ }
+ # Find the last 3 people who borrowed this item.
+ my $sth2 = $dbh->prepare("SELECT * FROM issues,borrowers
+ WHERE itemnumber = ?
+ AND issues.borrowernumber = borrowers.borrowernumber
+ AND returndate IS NOT NULL LIMIT 3");
+ $sth2->execute($data->{'itemnumber'});
+ my $ii = 0;
+ while (my $data2 = $sth2->fetchrow_hashref()) {
+ $data->{"timestamp$ii"} = $data2->{'timestamp'} if $data2->{'timestamp'};
+ $data->{"card$ii"} = $data2->{'cardnumber'} if $data2->{'cardnumber'};
+ $data->{"borrower$ii"} = $data2->{'borrowernumber'} if $data2->{'borrowernumber'};
+ $ii++;
+ }
+
+ $results[$i] = $data;
+ $i++;
+ }
+ $sth->finish;
+
+ return (@results);
+}
+
+=head2 get_itemnumbers_of
+
+=over 4
+
+my @itemnumbers_of = get_itemnumbers_of(@biblionumbers);
+
+=back
+
+Given a list of biblionumbers, return the list of corresponding itemnumbers
+for each biblionumber.
+
+Return a reference on a hash where keys are biblionumbers and values are
+references on array of itemnumbers.
+
+=cut
+
+sub get_itemnumbers_of {
+ my @biblionumbers = @_;
+
+ my $dbh = C4::Context->dbh;
+
+ my $query = '
+ SELECT itemnumber,
+ biblionumber
+ FROM items
+ WHERE biblionumber IN (?' . ( ',?' x scalar @biblionumbers - 1 ) . ')
+ ';
+ my $sth = $dbh->prepare($query);
+ $sth->execute(@biblionumbers);
+
+ my %itemnumbers_of;
+
+ while ( my ( $itemnumber, $biblionumber ) = $sth->fetchrow_array ) {
+ push @{ $itemnumbers_of{$biblionumber} }, $itemnumber;
+ }
+
+ return \%itemnumbers_of;
+}
+
=head1 LIMITED USE FUNCTIONS
The following functions, while part of the public API,