Lines 50-56
use vars qw(@ISA @EXPORT);
Link Here
|
50 |
|
50 |
|
51 |
BEGIN { |
51 |
BEGIN { |
52 |
|
52 |
|
53 |
require Exporter; |
53 |
require Exporter; |
54 |
@ISA = qw( Exporter ); |
54 |
@ISA = qw( Exporter ); |
55 |
|
55 |
|
56 |
# function exports |
56 |
# function exports |
Lines 60-92
BEGIN {
Link Here
|
60 |
AddItem |
60 |
AddItem |
61 |
AddItemBatchFromMarc |
61 |
AddItemBatchFromMarc |
62 |
ModItemFromMarc |
62 |
ModItemFromMarc |
63 |
Item2Marc |
63 |
Item2Marc |
64 |
ModItem |
64 |
ModItem |
65 |
ModDateLastSeen |
65 |
ModDateLastSeen |
66 |
ModItemTransfer |
66 |
ModItemTransfer |
67 |
DelItem |
67 |
DelItem |
68 |
|
68 |
|
69 |
CheckItemPreSave |
69 |
CheckItemPreSave |
70 |
|
70 |
|
71 |
GetItemsForInventory |
71 |
GetItemsForInventory |
72 |
GetItemsByBiblioitemnumber |
72 |
GetItemsByBiblioitemnumber |
73 |
GetItemsInfo |
73 |
GetItemsInfo |
74 |
GetItemsLocationInfo |
74 |
GetItemsLocationInfo |
75 |
GetHostItemsInfo |
75 |
GetHostItemsInfo |
76 |
GetItemnumbersForBiblio |
76 |
GetItemnumbersForBiblio |
77 |
get_hostitemnumbers_of |
77 |
get_hostitemnumbers_of |
78 |
GetItemnumberFromBarcode |
78 |
GetItemnumberFromBarcode |
79 |
GetBarcodeFromItemnumber |
79 |
GetBarcodeFromItemnumber |
80 |
GetHiddenItemnumbers |
80 |
GetHiddenItemnumbers |
81 |
ItemSafeToDelete |
81 |
ItemSafeToDelete |
82 |
DelItemCheck |
82 |
DelItemCheck |
83 |
MoveItemFromBiblio |
83 |
MoveItemFromBiblio |
84 |
GetLatestAcquisitions |
84 |
GetLatestAcquisitions |
85 |
|
85 |
|
86 |
CartToShelf |
86 |
CartToShelf |
87 |
ShelfToCart |
87 |
ShelfToCart |
88 |
|
88 |
|
89 |
GetAnalyticsCount |
89 |
GetAnalyticsCount |
90 |
|
90 |
|
91 |
SearchItemsByField |
91 |
SearchItemsByField |
92 |
SearchItems |
92 |
SearchItems |
Lines 102-108
C4::Items - item management functions
Link Here
|
102 |
|
102 |
|
103 |
=head1 DESCRIPTION |
103 |
=head1 DESCRIPTION |
104 |
|
104 |
|
105 |
This module contains an API for manipulating item |
105 |
This module contains an API for manipulating item |
106 |
records in Koha, and is used by cataloguing, circulation, |
106 |
records in Koha, and is used by cataloguing, circulation, |
107 |
acquisitions, and serials management. |
107 |
acquisitions, and serials management. |
108 |
|
108 |
|
Lines 116-122
modification transaction must keep the items table
Link Here
|
116 |
and the MARC XML in sync at all times. |
116 |
and the MARC XML in sync at all times. |
117 |
|
117 |
|
118 |
Consequently, all code that creates, modifies, or deletes |
118 |
Consequently, all code that creates, modifies, or deletes |
119 |
item records B<must> use an appropriate function from |
119 |
item records B<must> use an appropriate function from |
120 |
C<C4::Items>. If no existing function is suitable, it is |
120 |
C<C4::Items>. If no existing function is suitable, it is |
121 |
better to add one to C<C4::Items> than to use add |
121 |
better to add one to C<C4::Items> than to use add |
122 |
one-off SQL statements to add or modify items. |
122 |
one-off SQL statements to add or modify items. |
Lines 222-228
sub ShelfToCart {
Link Here
|
222 |
|
222 |
|
223 |
=head2 AddItemFromMarc |
223 |
=head2 AddItemFromMarc |
224 |
|
224 |
|
225 |
my ($biblionumber, $biblioitemnumber, $itemnumber) |
225 |
my ($biblionumber, $biblioitemnumber, $itemnumber) |
226 |
= AddItemFromMarc($source_item_marc, $biblionumber); |
226 |
= AddItemFromMarc($source_item_marc, $biblionumber); |
227 |
|
227 |
|
228 |
Given a MARC::Record object containing an embedded item |
228 |
Given a MARC::Record object containing an embedded item |
Lines 237-245
sub AddItemFromMarc {
Link Here
|
237 |
# parse item hash from MARC |
237 |
# parse item hash from MARC |
238 |
my $frameworkcode = C4::Biblio::GetFrameworkCode( $biblionumber ); |
238 |
my $frameworkcode = C4::Biblio::GetFrameworkCode( $biblionumber ); |
239 |
my ($itemtag,$itemsubfield)=C4::Biblio::GetMarcFromKohaField("items.itemnumber",$frameworkcode); |
239 |
my ($itemtag,$itemsubfield)=C4::Biblio::GetMarcFromKohaField("items.itemnumber",$frameworkcode); |
240 |
|
240 |
|
241 |
my $localitemmarc=MARC::Record->new; |
241 |
my $localitemmarc=MARC::Record->new; |
242 |
$localitemmarc->append_fields($source_item_marc->field($itemtag)); |
242 |
$localitemmarc->append_fields($source_item_marc->field($itemtag)); |
243 |
my $item = &TransformMarcToKoha( $localitemmarc, $frameworkcode ,'items'); |
243 |
my $item = &TransformMarcToKoha( $localitemmarc, $frameworkcode ,'items'); |
244 |
my $unlinked_item_subfields = _get_unlinked_item_subfields($localitemmarc, $frameworkcode); |
244 |
my $unlinked_item_subfields = _get_unlinked_item_subfields($localitemmarc, $frameworkcode); |
245 |
return AddItem($item, $biblionumber, $dbh, $frameworkcode, $unlinked_item_subfields); |
245 |
return AddItem($item, $biblionumber, $dbh, $frameworkcode, $unlinked_item_subfields); |
Lines 247-253
sub AddItemFromMarc {
Link Here
|
247 |
|
247 |
|
248 |
=head2 AddItem |
248 |
=head2 AddItem |
249 |
|
249 |
|
250 |
my ($biblionumber, $biblioitemnumber, $itemnumber) |
250 |
my ($biblionumber, $biblioitemnumber, $itemnumber) |
251 |
= AddItem($item, $biblionumber[, $dbh, $frameworkcode, $unlinked_item_subfields]); |
251 |
= AddItem($item, $biblionumber[, $dbh, $frameworkcode, $unlinked_item_subfields]); |
252 |
|
252 |
|
253 |
Given a hash containing item column names as keys, |
253 |
Given a hash containing item column names as keys, |
Lines 261-267
The final optional parameter, C<$unlinked_item_subfields>, contains
Link Here
|
261 |
an arrayref containing subfields present in the original MARC |
261 |
an arrayref containing subfields present in the original MARC |
262 |
representation of the item (e.g., from the item editor) that are |
262 |
representation of the item (e.g., from the item editor) that are |
263 |
not mapped to C<items> columns directly but should instead |
263 |
not mapped to C<items> columns directly but should instead |
264 |
be stored in C<items.more_subfields_xml> and included in |
264 |
be stored in C<items.more_subfields_xml> and included in |
265 |
the biblio items tag for display and indexing. |
265 |
the biblio items tag for display and indexing. |
266 |
|
266 |
|
267 |
=cut |
267 |
=cut |
Lines 309-315
sub AddItem {
Link Here
|
309 |
|
309 |
|
310 |
=head2 AddItemBatchFromMarc |
310 |
=head2 AddItemBatchFromMarc |
311 |
|
311 |
|
312 |
($itemnumber_ref, $error_ref) = AddItemBatchFromMarc($record, |
312 |
($itemnumber_ref, $error_ref) = AddItemBatchFromMarc($record, |
313 |
$biblionumber, $biblioitemnumber, $frameworkcode); |
313 |
$biblionumber, $biblioitemnumber, $frameworkcode); |
314 |
|
314 |
|
315 |
Efficiently create item records from a MARC biblio record with |
315 |
Efficiently create item records from a MARC biblio record with |
Lines 374-380
sub AddItemBatchFromMarc {
Link Here
|
374 |
# and there is no TransformMarcFieldToKoha |
374 |
# and there is no TransformMarcFieldToKoha |
375 |
my $temp_item_marc = MARC::Record->new(); |
375 |
my $temp_item_marc = MARC::Record->new(); |
376 |
$temp_item_marc->append_fields($item_field); |
376 |
$temp_item_marc->append_fields($item_field); |
377 |
|
377 |
|
378 |
# add biblionumber and biblioitemnumber |
378 |
# add biblionumber and biblioitemnumber |
379 |
my $item = TransformMarcToKoha( $temp_item_marc, $frameworkcode, 'items' ); |
379 |
my $item = TransformMarcToKoha( $temp_item_marc, $frameworkcode, 'items' ); |
380 |
my $unlinked_item_subfields = _get_unlinked_item_subfields($temp_item_marc, $frameworkcode); |
380 |
my $unlinked_item_subfields = _get_unlinked_item_subfields($temp_item_marc, $frameworkcode); |
Lines 397-403
sub AddItemBatchFromMarc {
Link Here
|
397 |
push @itemnumbers, $itemnumber; # FIXME not checking error |
397 |
push @itemnumbers, $itemnumber; # FIXME not checking error |
398 |
$item->{'itemnumber'} = $itemnumber; |
398 |
$item->{'itemnumber'} = $itemnumber; |
399 |
|
399 |
|
400 |
logaction("CATALOGUING", "ADD", $itemnumber, "item") if C4::Context->preference("CataloguingLog"); |
400 |
logaction("CATALOGUING", "ADD", $itemnumber, "item") if C4::Context->preference("CataloguingLog"); |
401 |
|
401 |
|
402 |
my $new_item_marc = _marc_from_item_hash($item, $frameworkcode, $unlinked_item_subfields); |
402 |
my $new_item_marc = _marc_from_item_hash($item, $frameworkcode, $unlinked_item_subfields); |
403 |
$item_field->replace_with($new_item_marc->field($itemtag)); |
403 |
$item_field->replace_with($new_item_marc->field($itemtag)); |
Lines 420-426
sub AddItemBatchFromMarc {
Link Here
|
420 |
|
420 |
|
421 |
This function updates an item record based on a supplied |
421 |
This function updates an item record based on a supplied |
422 |
C<MARC::Record> object containing an embedded item field. |
422 |
C<MARC::Record> object containing an embedded item field. |
423 |
This API is meant for the use of C<additem.pl>; for |
423 |
This API is meant for the use of C<additem.pl>; for |
424 |
other purposes, C<ModItem> should be used. |
424 |
other purposes, C<ModItem> should be used. |
425 |
|
425 |
|
426 |
This function uses the hash %default_values_for_mod_from_marc, |
426 |
This function uses the hash %default_values_for_mod_from_marc, |
Lines 539-549
C<$unlinked_item_subfields> contains an arrayref containing
Link Here
|
539 |
subfields present in the original MARC |
539 |
subfields present in the original MARC |
540 |
representation of the item (e.g., from the item editor) that are |
540 |
representation of the item (e.g., from the item editor) that are |
541 |
not mapped to C<items> columns directly but should instead |
541 |
not mapped to C<items> columns directly but should instead |
542 |
be stored in C<items.more_subfields_xml> and included in |
542 |
be stored in C<items.more_subfields_xml> and included in |
543 |
the biblio items tag for display and indexing. |
543 |
the biblio items tag for display and indexing. |
544 |
|
544 |
|
545 |
If one of the changed columns is used to calculate |
545 |
If one of the changed columns is used to calculate |
546 |
the derived value of a column such as C<items.cn_sort>, |
546 |
the derived value of a column such as C<items.cn_sort>, |
547 |
this routine will perform the necessary calculation |
547 |
this routine will perform the necessary calculation |
548 |
and set the value. |
548 |
and set the value. |
549 |
|
549 |
|
Lines 771-777
sub CheckItemPreSave {
Link Here
|
771 |
|
771 |
|
772 |
=head1 EXPORTED SPECIAL ACCESSOR FUNCTIONS |
772 |
=head1 EXPORTED SPECIAL ACCESSOR FUNCTIONS |
773 |
|
773 |
|
774 |
The following functions provide various ways of |
774 |
The following functions provide various ways of |
775 |
getting an item record, a set of item records, or |
775 |
getting an item record, a set of item records, or |
776 |
lists of authorized values for certain item fields. |
776 |
lists of authorized values for certain item fields. |
777 |
|
777 |
|
Lines 948-956
sub GetItemsByBiblioitemnumber {
Link Here
|
948 |
my $sth = $dbh->prepare("SELECT * FROM items WHERE items.biblioitemnumber = ? AND items.deleted_at IS NULL") || die $dbh->errstr; |
948 |
my $sth = $dbh->prepare("SELECT * FROM items WHERE items.biblioitemnumber = ? AND items.deleted_at IS NULL") || die $dbh->errstr; |
949 |
# Get all items attached to a biblioitem |
949 |
# Get all items attached to a biblioitem |
950 |
my $i = 0; |
950 |
my $i = 0; |
951 |
my @results; |
951 |
my @results; |
952 |
$sth->execute($bibitem) || die $sth->errstr; |
952 |
$sth->execute($bibitem) || die $sth->errstr; |
953 |
while ( my $data = $sth->fetchrow_hashref ) { |
953 |
while ( my $data = $sth->fetchrow_hashref ) { |
954 |
# Foreach item, get circulation information |
954 |
# Foreach item, get circulation information |
955 |
my $sth2 = $dbh->prepare( "SELECT * FROM issues,borrowers |
955 |
my $sth2 = $dbh->prepare( "SELECT * FROM issues,borrowers |
956 |
WHERE itemnumber = ? |
956 |
WHERE itemnumber = ? |
Lines 965-973
sub GetItemsByBiblioitemnumber {
Link Here
|
965 |
} |
965 |
} |
966 |
else { |
966 |
else { |
967 |
# set date_due to blank, so in the template we check itemlost, and withdrawn |
967 |
# set date_due to blank, so in the template we check itemlost, and withdrawn |
968 |
$data->{'date_due'} = ''; |
968 |
$data->{'date_due'} = ''; |
969 |
} # else |
969 |
} # else |
970 |
# Find the last 3 people who borrowed this item. |
970 |
# Find the last 3 people who borrowed this item. |
971 |
my $query2 = "SELECT * FROM old_issues, borrowers WHERE itemnumber = ? |
971 |
my $query2 = "SELECT * FROM old_issues, borrowers WHERE itemnumber = ? |
972 |
AND old_issues.borrowernumber = borrowers.borrowernumber |
972 |
AND old_issues.borrowernumber = borrowers.borrowernumber |
973 |
ORDER BY returndate desc,timestamp desc LIMIT 3"; |
973 |
ORDER BY returndate desc,timestamp desc LIMIT 3"; |
Lines 981-988
sub GetItemsByBiblioitemnumber {
Link Here
|
981 |
$i2++; |
981 |
$i2++; |
982 |
} |
982 |
} |
983 |
push(@results,$data); |
983 |
push(@results,$data); |
984 |
} |
984 |
} |
985 |
return (\@results); |
985 |
return (\@results); |
986 |
} |
986 |
} |
987 |
|
987 |
|
988 |
=head2 GetItemsInfo |
988 |
=head2 GetItemsInfo |
Lines 1066-1086
sub GetItemsInfo {
Link Here
|
1066 |
home.opac_info as home_branch_opac_info |
1066 |
home.opac_info as home_branch_opac_info |
1067 |
"; |
1067 |
"; |
1068 |
$query .= " |
1068 |
$query .= " |
1069 |
FROM items |
1069 |
FROM items |
1070 |
LEFT JOIN branches AS holding ON items.holdingbranch = holding.branchcode |
1070 |
LEFT JOIN branches AS holding ON items.holdingbranch = holding.branchcode |
1071 |
LEFT JOIN branches AS home ON items.homebranch=home.branchcode |
1071 |
LEFT JOIN branches AS home ON items.homebranch=home.branchcode |
1072 |
LEFT JOIN biblio ON biblio.biblionumber = items.biblionumber AND biblio.deleted_at IS NULL |
1072 |
LEFT JOIN biblio ON biblio.biblionumber = items.biblionumber AND biblio.deleted_at IS NULL |
1073 |
LEFT JOIN biblioitems ON biblioitems.biblioitemnumber = items.biblioitemnumber |
1073 |
LEFT JOIN biblioitems ON biblioitems.biblioitemnumber = items.biblioitemnumber |
1074 |
LEFT JOIN issues USING (itemnumber) |
1074 |
LEFT JOIN issues USING (itemnumber) |
1075 |
LEFT JOIN borrowers USING (borrowernumber) |
1075 |
LEFT JOIN borrowers USING (borrowernumber) |
1076 |
LEFT JOIN serialitems USING (itemnumber) |
1076 |
LEFT JOIN serialitems USING (itemnumber) |
1077 |
LEFT JOIN serial USING (serialid) |
1077 |
LEFT JOIN serial USING (serialid) |
1078 |
LEFT JOIN itemtypes ON itemtypes.itemtype = " |
1078 |
LEFT JOIN itemtypes ON itemtypes.itemtype = " |
1079 |
. (C4::Context->preference('item-level_itypes') ? 'items.itype' : 'biblioitems.itemtype'); |
1079 |
. (C4::Context->preference('item-level_itypes') ? 'items.itype' : 'biblioitems.itemtype'); |
1080 |
$query .= q| |
1080 |
$query .= q| |
1081 |
LEFT JOIN localization ON itemtypes.itemtype = localization.code |
1081 |
LEFT JOIN localization ON itemtypes.itemtype = localization.code |
1082 |
AND localization.entity = 'itemtypes' |
1082 |
AND localization.entity = 'itemtypes' |
1083 |
AND localization.lang = ? |
1083 |
AND localization.lang = ? |
1084 |
|; |
1084 |
|; |
1085 |
|
1085 |
|
1086 |
$query .= " WHERE items.biblionumber = ? AND items.deleted_at IS NULL ORDER BY home.branchname, items.enumchron, LPAD( items.copynumber, 8, '0' ), items.dateaccessioned DESC" ; |
1086 |
$query .= " WHERE items.biblionumber = ? AND items.deleted_at IS NULL ORDER BY home.branchname, items.enumchron, LPAD( items.copynumber, 8, '0' ), items.dateaccessioned DESC" ; |
Lines 1166-1172
The intranet description for the Shelving Location as set in authorised_values '
Link Here
|
1166 |
|
1166 |
|
1167 |
=item C<$data-E<gt>{location_opac}> |
1167 |
=item C<$data-E<gt>{location_opac}> |
1168 |
|
1168 |
|
1169 |
The OPAC description for the Shelving Location as set in authorised_values 'LOC'. Falls back to intranet description if no OPAC |
1169 |
The OPAC description for the Shelving Location as set in authorised_values 'LOC'. Falls back to intranet description if no OPAC |
1170 |
description is set. |
1170 |
description is set. |
1171 |
|
1171 |
|
1172 |
=item C<$data-E<gt>{itemcallnumber}> |
1172 |
=item C<$data-E<gt>{itemcallnumber}> |
Lines 1178-1198
Item's itemcallnumber
Link Here
|
1178 |
Item's call number normalized for sorting |
1178 |
Item's call number normalized for sorting |
1179 |
|
1179 |
|
1180 |
=back |
1180 |
=back |
1181 |
|
1181 |
|
1182 |
=cut |
1182 |
=cut |
1183 |
|
1183 |
|
1184 |
sub GetItemsLocationInfo { |
1184 |
sub GetItemsLocationInfo { |
1185 |
my $biblionumber = shift; |
1185 |
my $biblionumber = shift; |
1186 |
my @results; |
1186 |
my @results; |
1187 |
|
1187 |
|
1188 |
my $dbh = C4::Context->dbh; |
1188 |
my $dbh = C4::Context->dbh; |
1189 |
my $query = "SELECT a.branchname as homebranch, b.branchname as holdingbranch, |
1189 |
my $query = "SELECT a.branchname as homebranch, b.branchname as holdingbranch, |
1190 |
location, itemcallnumber, cn_sort |
1190 |
location, itemcallnumber, cn_sort |
1191 |
FROM items, branches as a, branches as b |
1191 |
FROM items, branches as a, branches as b |
1192 |
WHERE homebranch = a.branchcode AND holdingbranch = b.branchcode |
1192 |
WHERE homebranch = a.branchcode AND holdingbranch = b.branchcode |
1193 |
AND biblionumber = ? AND deleted_at IS NULL |
1193 |
AND biblionumber = ? AND deleted_at IS NULL |
1194 |
ORDER BY cn_sort ASC"; |
1194 |
ORDER BY cn_sort ASC"; |
1195 |
my $sth = $dbh->prepare($query); |
1195 |
my $sth = $dbh->prepare($query); |
1196 |
$sth->execute($biblionumber); |
1196 |
$sth->execute($biblionumber); |
1197 |
|
1197 |
|
1198 |
while ( my $data = $sth->fetchrow_hashref ) { |
1198 |
while ( my $data = $sth->fetchrow_hashref ) { |
Lines 1200-1300
sub GetItemsLocationInfo {
Link Here
|
1200 |
$av = $av->count ? $av->next : undef; |
1200 |
$av = $av->count ? $av->next : undef; |
1201 |
$data->{location_intranet} = $av ? $av->lib : ''; |
1201 |
$data->{location_intranet} = $av ? $av->lib : ''; |
1202 |
$data->{location_opac} = $av ? $av->opac_description : ''; |
1202 |
$data->{location_opac} = $av ? $av->opac_description : ''; |
1203 |
push @results, $data; |
1203 |
push @results, $data; |
1204 |
} |
1204 |
} |
1205 |
return @results; |
1205 |
return @results; |
1206 |
} |
1206 |
} |
1207 |
|
1207 |
|
1208 |
=head2 GetHostItemsInfo |
1208 |
=head2 GetHostItemsInfo |
1209 |
|
1209 |
|
1210 |
$hostiteminfo = GetHostItemsInfo($hostfield); |
1210 |
$hostiteminfo = GetHostItemsInfo($hostfield); |
1211 |
Returns the iteminfo for items linked to records via a host field |
1211 |
Returns the iteminfo for items linked to records via a host field |
1212 |
|
1212 |
|
1213 |
=cut |
1213 |
=cut |
1214 |
|
1214 |
|
1215 |
sub GetHostItemsInfo { |
1215 |
sub GetHostItemsInfo { |
1216 |
my ($record) = @_; |
1216 |
my ($record) = @_; |
1217 |
my @returnitemsInfo; |
1217 |
my @returnitemsInfo; |
1218 |
|
1218 |
|
1219 |
if (C4::Context->preference('marcflavour') eq 'MARC21' || |
1219 |
if (C4::Context->preference('marcflavour') eq 'MARC21' || |
1220 |
C4::Context->preference('marcflavour') eq 'NORMARC'){ |
1220 |
C4::Context->preference('marcflavour') eq 'NORMARC'){ |
1221 |
foreach my $hostfield ( $record->field('773') ) { |
1221 |
foreach my $hostfield ( $record->field('773') ) { |
1222 |
my $hostbiblionumber = $hostfield->subfield("0"); |
1222 |
my $hostbiblionumber = $hostfield->subfield("0"); |
1223 |
my $linkeditemnumber = $hostfield->subfield("9"); |
1223 |
my $linkeditemnumber = $hostfield->subfield("9"); |
1224 |
my @hostitemInfos = GetItemsInfo($hostbiblionumber); |
1224 |
my @hostitemInfos = GetItemsInfo($hostbiblionumber); |
1225 |
foreach my $hostitemInfo (@hostitemInfos){ |
1225 |
foreach my $hostitemInfo (@hostitemInfos){ |
1226 |
if ($hostitemInfo->{itemnumber} eq $linkeditemnumber){ |
1226 |
if ($hostitemInfo->{itemnumber} eq $linkeditemnumber){ |
1227 |
push (@returnitemsInfo,$hostitemInfo); |
1227 |
push (@returnitemsInfo,$hostitemInfo); |
1228 |
last; |
1228 |
last; |
1229 |
} |
1229 |
} |
1230 |
} |
1230 |
} |
1231 |
} |
1231 |
} |
1232 |
} elsif ( C4::Context->preference('marcflavour') eq 'UNIMARC'){ |
1232 |
} elsif ( C4::Context->preference('marcflavour') eq 'UNIMARC'){ |
1233 |
foreach my $hostfield ( $record->field('461') ) { |
1233 |
foreach my $hostfield ( $record->field('461') ) { |
1234 |
my $hostbiblionumber = $hostfield->subfield("0"); |
1234 |
my $hostbiblionumber = $hostfield->subfield("0"); |
1235 |
my $linkeditemnumber = $hostfield->subfield("9"); |
1235 |
my $linkeditemnumber = $hostfield->subfield("9"); |
1236 |
my @hostitemInfos = GetItemsInfo($hostbiblionumber); |
1236 |
my @hostitemInfos = GetItemsInfo($hostbiblionumber); |
1237 |
foreach my $hostitemInfo (@hostitemInfos){ |
1237 |
foreach my $hostitemInfo (@hostitemInfos){ |
1238 |
if ($hostitemInfo->{itemnumber} eq $linkeditemnumber){ |
1238 |
if ($hostitemInfo->{itemnumber} eq $linkeditemnumber){ |
1239 |
push (@returnitemsInfo,$hostitemInfo); |
1239 |
push (@returnitemsInfo,$hostitemInfo); |
1240 |
last; |
1240 |
last; |
1241 |
} |
1241 |
} |
1242 |
} |
1242 |
} |
1243 |
} |
1243 |
} |
1244 |
} |
1244 |
} |
1245 |
return @returnitemsInfo; |
1245 |
return @returnitemsInfo; |
1246 |
} |
1246 |
} |
1247 |
|
1247 |
|
1248 |
|
1248 |
|
1249 |
=head2 GetLastAcquisitions |
1249 |
=head2 GetLastAcquisitions |
1250 |
|
1250 |
|
1251 |
my $lastacq = GetLastAcquisitions({'branches' => ('branch1','branch2'), |
1251 |
my $lastacq = GetLastAcquisitions({'branches' => ('branch1','branch2'), |
1252 |
'itemtypes' => ('BK','BD')}, 10); |
1252 |
'itemtypes' => ('BK','BD')}, 10); |
1253 |
|
1253 |
|
1254 |
=cut |
1254 |
=cut |
1255 |
|
1255 |
|
1256 |
sub GetLastAcquisitions { |
1256 |
sub GetLastAcquisitions { |
1257 |
my ($data,$max) = @_; |
1257 |
my ($data,$max) = @_; |
1258 |
|
1258 |
|
1259 |
my $itemtype = C4::Context->preference('item-level_itypes') ? 'itype' : 'itemtype'; |
1259 |
my $itemtype = C4::Context->preference('item-level_itypes') ? 'itype' : 'itemtype'; |
1260 |
|
1260 |
|
1261 |
my $number_of_branches = @{$data->{branches}}; |
1261 |
my $number_of_branches = @{$data->{branches}}; |
1262 |
my $number_of_itemtypes = @{$data->{itemtypes}}; |
1262 |
my $number_of_itemtypes = @{$data->{itemtypes}}; |
1263 |
|
1263 |
|
1264 |
|
1264 |
my @where = ('WHERE (items.deleted_at IS NULL AND biblio.deleted_at IS NULL AND biblioitems.deleted_at IS NULL)'); |
1265 |
my @where = ('WHERE (items.deleted_at IS NULL AND biblio.deleted_at IS NULL AND biblioitems.deleted_at IS NULL) '); |
1265 |
$number_of_branches and push @where |
1266 |
$number_of_branches and push @where |
1266 |
, 'AND holdingbranch IN (' |
1267 |
, 'AND holdingbranch IN (' |
1267 |
, join(',', ('?') x $number_of_branches ) |
1268 |
, join(',', ('?') x $number_of_branches ) |
1268 |
, ')' |
1269 |
, ')' |
1269 |
; |
1270 |
; |
1270 |
|
1271 |
|
1271 |
$number_of_itemtypes and push @where |
1272 |
$number_of_itemtypes and push @where |
1272 |
, "AND $itemtype IN (" |
1273 |
, "AND $itemtype IN (" |
1273 |
, join(',', ('?') x $number_of_itemtypes ) |
1274 |
, join(',', ('?') x $number_of_itemtypes ) |
1274 |
, ')' |
1275 |
, ')' |
1275 |
; |
1276 |
; |
1276 |
|
1277 |
|
1277 |
my $query = "SELECT biblio.biblionumber as biblionumber, title, dateaccessioned |
1278 |
my $query = "SELECT biblio.biblionumber as biblionumber, title, dateaccessioned |
1278 |
FROM items RIGHT JOIN biblio ON (items.biblionumber=biblio.biblionumber) |
1279 |
FROM items RIGHT JOIN biblio ON (items.biblionumber=biblio.biblionumber) |
1279 |
RIGHT JOIN biblioitems ON (items.biblioitemnumber=biblioitems.biblioitemnumber) |
1280 |
RIGHT JOIN biblioitems ON (items.biblioitemnumber=biblioitems.biblioitemnumber) |
1280 |
@where |
1281 |
@where |
1281 |
GROUP BY biblio.biblionumber |
1282 |
GROUP BY biblio.biblionumber |
1282 |
ORDER BY dateaccessioned DESC LIMIT $max"; |
1283 |
ORDER BY dateaccessioned DESC LIMIT $max"; |
1283 |
|
1284 |
|
1284 |
my $dbh = C4::Context->dbh; |
1285 |
my $dbh = C4::Context->dbh; |
1285 |
my $sth = $dbh->prepare($query); |
1286 |
my $sth = $dbh->prepare($query); |
1286 |
|
1287 |
|
|
|
1288 |
$sth->execute((@{$data->{branches}}, @{$data->{itemtypes}})); |
1287 |
$sth->execute((@{$data->{branches}}, @{$data->{itemtypes}})); |
1289 |
|
1288 |
|
1290 |
my @results; |
1289 |
my @results; |
1291 |
while( my $row = $sth->fetchrow_hashref){ |
1290 |
while( my $row = $sth->fetchrow_hashref){ |
1292 |
push @results, {date => $row->{dateaccessioned} |
1291 |
push @results, {date => $row->{dateaccessioned} |
1293 |
, biblionumber => $row->{biblionumber} |
1292 |
, biblionumber => $row->{biblionumber} |
1294 |
, title => $row->{title}}; |
1293 |
, title => $row->{title}}; |
1295 |
} |
1294 |
} |
1296 |
|
1295 |
|
1297 |
return @results; |
1296 |
return @results; |
1298 |
} |
1297 |
} |
1299 |
|
1298 |
|
1300 |
=head2 GetItemnumbersForBiblio |
1299 |
=head2 GetItemnumbersForBiblio |
Lines 1497-1512
sub GetMarcItem {
Link Here
|
1497 |
# Tack on 'items.' prefix to column names so that C4::Biblio::TransformKohaToMarc will work. |
1496 |
# Tack on 'items.' prefix to column names so that C4::Biblio::TransformKohaToMarc will work. |
1498 |
# Also, don't emit a subfield if the underlying field is blank. |
1497 |
# Also, don't emit a subfield if the underlying field is blank. |
1499 |
|
1498 |
|
1500 |
|
1499 |
|
1501 |
return Item2Marc($itemrecord,$biblionumber); |
1500 |
return Item2Marc($itemrecord,$biblionumber); |
1502 |
|
1501 |
|
1503 |
} |
1502 |
} |
1504 |
sub Item2Marc { |
1503 |
sub Item2Marc { |
1505 |
my ($itemrecord,$biblionumber)=@_; |
1504 |
my ($itemrecord,$biblionumber)=@_; |
1506 |
my $mungeditem = { |
1505 |
my $mungeditem = { |
1507 |
map { |
1506 |
map { |
1508 |
defined($itemrecord->{$_}) && $itemrecord->{$_} ne '' ? ("items.$_" => $itemrecord->{$_}) : () |
1507 |
defined($itemrecord->{$_}) && $itemrecord->{$_} ne '' ? ("items.$_" => $itemrecord->{$_}) : () |
1509 |
} keys %{ $itemrecord } |
1508 |
} keys %{ $itemrecord } |
1510 |
}; |
1509 |
}; |
1511 |
my $framework = C4::Biblio::GetFrameworkCode( $biblionumber ); |
1510 |
my $framework = C4::Biblio::GetFrameworkCode( $biblionumber ); |
1512 |
my $itemmarc = C4::Biblio::TransformKohaToMarc( |
1511 |
my $itemmarc = C4::Biblio::TransformKohaToMarc( |
Lines 1518-1528
sub Item2Marc {
Link Here
|
1518 |
|
1517 |
|
1519 |
my $unlinked_item_subfields = _parse_unlinked_item_subfields_from_xml($mungeditem->{'items.more_subfields_xml'}); |
1518 |
my $unlinked_item_subfields = _parse_unlinked_item_subfields_from_xml($mungeditem->{'items.more_subfields_xml'}); |
1520 |
if (defined $unlinked_item_subfields and $#$unlinked_item_subfields > -1) { |
1519 |
if (defined $unlinked_item_subfields and $#$unlinked_item_subfields > -1) { |
1521 |
foreach my $field ($itemmarc->field($itemtag)){ |
1520 |
foreach my $field ($itemmarc->field($itemtag)){ |
1522 |
$field->add_subfields(@$unlinked_item_subfields); |
1521 |
$field->add_subfields(@$unlinked_item_subfields); |
1523 |
} |
1522 |
} |
1524 |
} |
1523 |
} |
1525 |
return $itemmarc; |
1524 |
return $itemmarc; |
1526 |
} |
1525 |
} |
1527 |
|
1526 |
|
1528 |
=head1 PRIVATE FUNCTIONS AND VARIABLES |
1527 |
=head1 PRIVATE FUNCTIONS AND VARIABLES |
Lines 1558-1564
my %derived_columns = (
Link Here
|
1558 |
} |
1557 |
} |
1559 |
); |
1558 |
); |
1560 |
|
1559 |
|
1561 |
=head2 _set_derived_columns_for_add |
1560 |
=head2 _set_derived_columns_for_add |
1562 |
|
1561 |
|
1563 |
_set_derived_column_for_add($item); |
1562 |
_set_derived_column_for_add($item); |
1564 |
|
1563 |
|
Lines 1582-1588
sub _set_derived_columns_for_add {
Link Here
|
1582 |
} |
1581 |
} |
1583 |
} |
1582 |
} |
1584 |
|
1583 |
|
1585 |
=head2 _set_derived_columns_for_mod |
1584 |
=head2 _set_derived_columns_for_mod |
1586 |
|
1585 |
|
1587 |
_set_derived_column_for_mod($item); |
1586 |
_set_derived_column_for_mod($item); |
1588 |
|
1587 |
|
Lines 1685-1696
row specified by C<$itemnumber>.
Link Here
|
1685 |
sub _get_single_item_column { |
1684 |
sub _get_single_item_column { |
1686 |
my $column = shift; |
1685 |
my $column = shift; |
1687 |
my $itemnumber = shift; |
1686 |
my $itemnumber = shift; |
1688 |
|
1687 |
|
1689 |
my $dbh = C4::Context->dbh; |
1688 |
my $dbh = C4::Context->dbh; |
1690 |
my $sth = $dbh->prepare("SELECT $column FROM items WHERE itemnumber = ?"); |
1689 |
my $sth = $dbh->prepare("SELECT $column FROM items WHERE itemnumber = ?"); |
1691 |
$sth->execute($itemnumber); |
1690 |
$sth->execute($itemnumber); |
1692 |
my ($value) = $sth->fetchrow(); |
1691 |
my ($value) = $sth->fetchrow(); |
1693 |
return $value; |
1692 |
return $value; |
1694 |
} |
1693 |
} |
1695 |
|
1694 |
|
1696 |
=head2 _calc_items_cn_sort |
1695 |
=head2 _calc_items_cn_sort |
Lines 1708-1714
sub _calc_items_cn_sort {
Link Here
|
1708 |
$item->{'items.cn_sort'} = GetClassSort($source_values->{'items.cn_source'}, $source_values->{'itemcallnumber'}, ""); |
1707 |
$item->{'items.cn_sort'} = GetClassSort($source_values->{'items.cn_source'}, $source_values->{'itemcallnumber'}, ""); |
1709 |
} |
1708 |
} |
1710 |
|
1709 |
|
1711 |
=head2 _set_defaults_for_add |
1710 |
=head2 _set_defaults_for_add |
1712 |
|
1711 |
|
1713 |
_set_defaults_for_add($item_hash); |
1712 |
_set_defaults_for_add($item_hash); |
1714 |
|
1713 |
|
Lines 1719-1725
columns:
Link Here
|
1719 |
|
1718 |
|
1720 |
=over 2 |
1719 |
=over 2 |
1721 |
|
1720 |
|
1722 |
=item * |
1721 |
=item * |
1723 |
|
1722 |
|
1724 |
C<items.dateaccessioned> |
1723 |
C<items.dateaccessioned> |
1725 |
|
1724 |
|
Lines 1759-1765
Perform the actual insert into the C<items> table.
Link Here
|
1759 |
|
1758 |
|
1760 |
sub _koha_new_item { |
1759 |
sub _koha_new_item { |
1761 |
my ( $item, $barcode ) = @_; |
1760 |
my ( $item, $barcode ) = @_; |
1762 |
my $dbh=C4::Context->dbh; |
1761 |
my $dbh=C4::Context->dbh; |
1763 |
my $error; |
1762 |
my $error; |
1764 |
$item->{permanent_location} //= $item->{location}; |
1763 |
$item->{permanent_location} //= $item->{location}; |
1765 |
_mod_item_dates( $item ); |
1764 |
_mod_item_dates( $item ); |
Lines 1890-1903
sub MoveItemFromBiblio {
Link Here
|
1890 |
if ($return == 1) { |
1889 |
if ($return == 1) { |
1891 |
ModZebra( $tobiblio, "specialUpdate", "biblioserver" ); |
1890 |
ModZebra( $tobiblio, "specialUpdate", "biblioserver" ); |
1892 |
ModZebra( $frombiblio, "specialUpdate", "biblioserver" ); |
1891 |
ModZebra( $frombiblio, "specialUpdate", "biblioserver" ); |
1893 |
# Checking if the item we want to move is in an order |
1892 |
# Checking if the item we want to move is in an order |
1894 |
require C4::Acquisition; |
1893 |
require C4::Acquisition; |
1895 |
my $order = C4::Acquisition::GetOrderFromItemnumber($itemnumber); |
1894 |
my $order = C4::Acquisition::GetOrderFromItemnumber($itemnumber); |
1896 |
if ($order) { |
1895 |
if ($order) { |
1897 |
# Replacing the biblionumber within the order if necessary |
1896 |
# Replacing the biblionumber within the order if necessary |
1898 |
$order->{'biblionumber'} = $tobiblio; |
1897 |
$order->{'biblionumber'} = $tobiblio; |
1899 |
C4::Acquisition::ModOrder($order); |
1898 |
C4::Acquisition::ModOrder($order); |
1900 |
} |
1899 |
} |
1901 |
|
1900 |
|
1902 |
# Update reserves, hold_fill_targets, tmp_holdsqueue and linktracker tables |
1901 |
# Update reserves, hold_fill_targets, tmp_holdsqueue and linktracker tables |
1903 |
for my $table_name ( qw( reserves hold_fill_targets tmp_holdsqueue linktracker ) ) { |
1902 |
for my $table_name ( qw( reserves hold_fill_targets tmp_holdsqueue linktracker ) ) { |
Lines 1908-1914
sub MoveItemFromBiblio {
Link Here
|
1908 |
|, undef, $tobiblio, $itemnumber ); |
1907 |
|, undef, $tobiblio, $itemnumber ); |
1909 |
} |
1908 |
} |
1910 |
return $tobiblio; |
1909 |
return $tobiblio; |
1911 |
} |
1910 |
} |
1912 |
return; |
1911 |
return; |
1913 |
} |
1912 |
} |
1914 |
|
1913 |
|
Lines 2021-2027
routine accepts a hashref specifying the columns to update.
Link Here
|
2021 |
|
2020 |
|
2022 |
sub _koha_modify_item { |
2021 |
sub _koha_modify_item { |
2023 |
my ( $item ) = @_; |
2022 |
my ( $item ) = @_; |
2024 |
my $dbh=C4::Context->dbh; |
2023 |
my $dbh=C4::Context->dbh; |
2025 |
my $error; |
2024 |
my $error; |
2026 |
|
2025 |
|
2027 |
my $query = "UPDATE items SET "; |
2026 |
my $query = "UPDATE items SET "; |
Lines 2112-2123
sub _marc_from_item_hash {
Link Here
|
2112 |
if (@_) { |
2111 |
if (@_) { |
2113 |
$unlinked_item_subfields = shift; |
2112 |
$unlinked_item_subfields = shift; |
2114 |
} |
2113 |
} |
2115 |
|
2114 |
|
2116 |
# Tack on 'items.' prefix to column names so lookup from MARC frameworks will work |
2115 |
# Tack on 'items.' prefix to column names so lookup from MARC frameworks will work |
2117 |
# Also, don't emit a subfield if the underlying field is blank. |
2116 |
# Also, don't emit a subfield if the underlying field is blank. |
2118 |
my $mungeditem = { map { (defined($item->{$_}) and $item->{$_} ne '') ? |
2117 |
my $mungeditem = { map { (defined($item->{$_}) and $item->{$_} ne '') ? |
2119 |
(/^items\./ ? ($_ => $item->{$_}) : ("items.$_" => $item->{$_})) |
2118 |
(/^items\./ ? ($_ => $item->{$_}) : ("items.$_" => $item->{$_})) |
2120 |
: () } keys %{ $item } }; |
2119 |
: () } keys %{ $item } }; |
2121 |
|
2120 |
|
2122 |
my $item_marc = MARC::Record->new(); |
2121 |
my $item_marc = MARC::Record->new(); |
2123 |
foreach my $item_field ( keys %{$mungeditem} ) { |
2122 |
foreach my $item_field ( keys %{$mungeditem} ) { |
Lines 2161-2167
sub _repack_item_errors {
Link Here
|
2161 |
$repacked_error->{'error_code'} = $error_code; |
2160 |
$repacked_error->{'error_code'} = $error_code; |
2162 |
$repacked_error->{'error_information'} = $error_ref->{$error_code}; |
2161 |
$repacked_error->{'error_information'} = $error_ref->{$error_code}; |
2163 |
push @repacked_errors, $repacked_error; |
2162 |
push @repacked_errors, $repacked_error; |
2164 |
} |
2163 |
} |
2165 |
|
2164 |
|
2166 |
return @repacked_errors; |
2165 |
return @repacked_errors; |
2167 |
} |
2166 |
} |
Lines 2184-2190
sub _get_unlinked_item_subfields {
Link Here
|
2184 |
my @fields = $original_item_marc->fields(); |
2183 |
my @fields = $original_item_marc->fields(); |
2185 |
if ($#fields > -1) { |
2184 |
if ($#fields > -1) { |
2186 |
my $field = $fields[0]; |
2185 |
my $field = $fields[0]; |
2187 |
my $tag = $field->tag(); |
2186 |
my $tag = $field->tag(); |
2188 |
foreach my $subfield ($field->subfields()) { |
2187 |
foreach my $subfield ($field->subfields()) { |
2189 |
if (defined $subfield->[1] and |
2188 |
if (defined $subfield->[1] and |
2190 |
$subfield->[1] ne '' and |
2189 |
$subfield->[1] ne '' and |
Lines 2211-2217
sub _get_unlinked_subfields_xml {
Link Here
|
2211 |
# use of tag 999 is arbitrary, and doesn't need to match the item tag |
2210 |
# use of tag 999 is arbitrary, and doesn't need to match the item tag |
2212 |
# used in the framework |
2211 |
# used in the framework |
2213 |
$marc->append_fields(MARC::Field->new('999', ' ', ' ', @$unlinked_item_subfields)); |
2212 |
$marc->append_fields(MARC::Field->new('999', ' ', ' ', @$unlinked_item_subfields)); |
2214 |
$marc->encoding("UTF-8"); |
2213 |
$marc->encoding("UTF-8"); |
2215 |
$xml = $marc->as_xml("USMARC"); |
2214 |
$xml = $marc->as_xml("USMARC"); |
2216 |
} |
2215 |
} |
2217 |
|
2216 |
|
Lines 2243-2249
sub _parse_unlinked_item_subfields_from_xml {
Link Here
|
2243 |
|
2242 |
|
2244 |
$count= &GetAnalyticsCount($itemnumber) |
2243 |
$count= &GetAnalyticsCount($itemnumber) |
2245 |
|
2244 |
|
2246 |
counts Usage of itemnumber in Analytical bibliorecords. |
2245 |
counts Usage of itemnumber in Analytical bibliorecords. |
2247 |
|
2246 |
|
2248 |
=cut |
2247 |
=cut |
2249 |
|
2248 |
|
Lines 2447-2456
sub SearchItems {
Link Here
|
2447 |
my $query = q{ |
2446 |
my $query = q{ |
2448 |
SELECT SQL_CALC_FOUND_ROWS items.* |
2447 |
SELECT SQL_CALC_FOUND_ROWS items.* |
2449 |
FROM items |
2448 |
FROM items |
2450 |
LEFT JOIN biblio ON biblio.biblionumber = items.biblionumber |
2449 |
LEFT JOIN biblio ON biblio.biblionumber = items.biblionumber |
2451 |
LEFT JOIN biblioitems ON biblioitems.biblioitemnumber = items.biblioitemnumber |
2450 |
LEFT JOIN biblioitems ON biblioitems.biblioitemnumber = items.biblioitemnumber |
2452 |
LEFT JOIN biblio_metadata ON biblio_metadata.biblionumber = biblio.biblionumber |
2451 |
LEFT JOIN biblio_metadata ON biblio_metadata.biblionumber = biblio.biblionumber |
2453 |
WHERE items.deleted_at IS NULL |
2452 |
WHERE items.deleted_at IS NULL |
2454 |
}; |
2453 |
}; |
2455 |
if (defined $where_str and $where_str ne '') { |
2454 |
if (defined $where_str and $where_str ne '') { |
2456 |
$query .= qq{ AND $where_str }; |
2455 |
$query .= qq{ AND $where_str }; |
2457 |
- |
|
|