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-1208
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 |
Lines 1244-1296
sub GetHostItemsInfo {
Link Here
|
1244 |
|
1244 |
|
1245 |
=head2 GetLastAcquisitions |
1245 |
=head2 GetLastAcquisitions |
1246 |
|
1246 |
|
1247 |
my $lastacq = GetLastAcquisitions({'branches' => ('branch1','branch2'), |
1247 |
my $lastacq = GetLastAcquisitions({'branches' => ('branch1','branch2'), |
1248 |
'itemtypes' => ('BK','BD')}, 10); |
1248 |
'itemtypes' => ('BK','BD')}, 10); |
1249 |
|
1249 |
|
1250 |
=cut |
1250 |
=cut |
1251 |
|
1251 |
|
1252 |
sub GetLastAcquisitions { |
1252 |
sub GetLastAcquisitions { |
1253 |
my ($data,$max) = @_; |
1253 |
my ($data,$max) = @_; |
1254 |
|
1254 |
|
1255 |
my $itemtype = C4::Context->preference('item-level_itypes') ? 'itype' : 'itemtype'; |
1255 |
my $itemtype = C4::Context->preference('item-level_itypes') ? 'itype' : 'itemtype'; |
1256 |
|
1256 |
|
1257 |
my $number_of_branches = @{$data->{branches}}; |
1257 |
my $number_of_branches = @{$data->{branches}}; |
1258 |
my $number_of_itemtypes = @{$data->{itemtypes}}; |
1258 |
my $number_of_itemtypes = @{$data->{itemtypes}}; |
1259 |
|
1259 |
|
1260 |
|
1260 |
my @where = ('WHERE (items.deleted_at IS NULL AND biblio.deleted_at IS NULL AND biblioitems.deleted_at IS NULL)'); |
1261 |
my @where = ('WHERE (items.deleted_at IS NULL AND biblio.deleted_at IS NULL AND biblioitems.deleted_at IS NULL) '); |
1261 |
$number_of_branches and push @where |
1262 |
$number_of_branches and push @where |
1262 |
, 'AND holdingbranch IN (' |
1263 |
, 'AND holdingbranch IN (' |
1263 |
, join(',', ('?') x $number_of_branches ) |
1264 |
, join(',', ('?') x $number_of_branches ) |
1264 |
, ')' |
1265 |
, ')' |
1265 |
; |
1266 |
; |
1266 |
|
1267 |
|
1267 |
$number_of_itemtypes and push @where |
1268 |
$number_of_itemtypes and push @where |
1268 |
, "AND $itemtype IN (" |
1269 |
, "AND $itemtype IN (" |
1269 |
, join(',', ('?') x $number_of_itemtypes ) |
1270 |
, join(',', ('?') x $number_of_itemtypes ) |
1270 |
, ')' |
1271 |
, ')' |
1271 |
; |
1272 |
; |
1272 |
|
1273 |
|
1273 |
my $query = "SELECT biblio.biblionumber as biblionumber, title, dateaccessioned |
1274 |
my $query = "SELECT biblio.biblionumber as biblionumber, title, dateaccessioned |
1274 |
FROM items RIGHT JOIN biblio ON (items.biblionumber=biblio.biblionumber) |
1275 |
FROM items RIGHT JOIN biblio ON (items.biblionumber=biblio.biblionumber) |
1275 |
RIGHT JOIN biblioitems ON (items.biblioitemnumber=biblioitems.biblioitemnumber) |
1276 |
RIGHT JOIN biblioitems ON (items.biblioitemnumber=biblioitems.biblioitemnumber) |
1276 |
@where |
1277 |
@where |
1277 |
GROUP BY biblio.biblionumber |
1278 |
GROUP BY biblio.biblionumber |
1278 |
ORDER BY dateaccessioned DESC LIMIT $max"; |
1279 |
ORDER BY dateaccessioned DESC LIMIT $max"; |
1279 |
|
1280 |
|
1280 |
my $dbh = C4::Context->dbh; |
1281 |
my $dbh = C4::Context->dbh; |
1281 |
my $sth = $dbh->prepare($query); |
1282 |
my $sth = $dbh->prepare($query); |
1282 |
|
1283 |
|
|
|
1284 |
$sth->execute((@{$data->{branches}}, @{$data->{itemtypes}})); |
1283 |
$sth->execute((@{$data->{branches}}, @{$data->{itemtypes}})); |
1285 |
|
1284 |
|
1286 |
my @results; |
1285 |
my @results; |
1287 |
while( my $row = $sth->fetchrow_hashref){ |
1286 |
while( my $row = $sth->fetchrow_hashref){ |
1288 |
push @results, {date => $row->{dateaccessioned} |
1287 |
push @results, {date => $row->{dateaccessioned} |
1289 |
, biblionumber => $row->{biblionumber} |
1288 |
, biblionumber => $row->{biblionumber} |
1290 |
, title => $row->{title}}; |
1289 |
, title => $row->{title}}; |
1291 |
} |
1290 |
} |
1292 |
|
1291 |
|
1293 |
return @results; |
1292 |
return @results; |
1294 |
} |
1293 |
} |
1295 |
|
1294 |
|
1296 |
=head2 GetItemnumbersForBiblio |
1295 |
=head2 GetItemnumbersForBiblio |
Lines 1493-1508
sub GetMarcItem {
Link Here
|
1493 |
# Tack on 'items.' prefix to column names so that C4::Biblio::TransformKohaToMarc will work. |
1492 |
# Tack on 'items.' prefix to column names so that C4::Biblio::TransformKohaToMarc will work. |
1494 |
# Also, don't emit a subfield if the underlying field is blank. |
1493 |
# Also, don't emit a subfield if the underlying field is blank. |
1495 |
|
1494 |
|
1496 |
|
1495 |
|
1497 |
return Item2Marc($itemrecord,$biblionumber); |
1496 |
return Item2Marc($itemrecord,$biblionumber); |
1498 |
|
1497 |
|
1499 |
} |
1498 |
} |
1500 |
sub Item2Marc { |
1499 |
sub Item2Marc { |
1501 |
my ($itemrecord,$biblionumber)=@_; |
1500 |
my ($itemrecord,$biblionumber)=@_; |
1502 |
my $mungeditem = { |
1501 |
my $mungeditem = { |
1503 |
map { |
1502 |
map { |
1504 |
defined($itemrecord->{$_}) && $itemrecord->{$_} ne '' ? ("items.$_" => $itemrecord->{$_}) : () |
1503 |
defined($itemrecord->{$_}) && $itemrecord->{$_} ne '' ? ("items.$_" => $itemrecord->{$_}) : () |
1505 |
} keys %{ $itemrecord } |
1504 |
} keys %{ $itemrecord } |
1506 |
}; |
1505 |
}; |
1507 |
my $framework = C4::Biblio::GetFrameworkCode( $biblionumber ); |
1506 |
my $framework = C4::Biblio::GetFrameworkCode( $biblionumber ); |
1508 |
my $itemmarc = C4::Biblio::TransformKohaToMarc( |
1507 |
my $itemmarc = C4::Biblio::TransformKohaToMarc( |
Lines 1514-1524
sub Item2Marc {
Link Here
|
1514 |
|
1513 |
|
1515 |
my $unlinked_item_subfields = _parse_unlinked_item_subfields_from_xml($mungeditem->{'items.more_subfields_xml'}); |
1514 |
my $unlinked_item_subfields = _parse_unlinked_item_subfields_from_xml($mungeditem->{'items.more_subfields_xml'}); |
1516 |
if (defined $unlinked_item_subfields and $#$unlinked_item_subfields > -1) { |
1515 |
if (defined $unlinked_item_subfields and $#$unlinked_item_subfields > -1) { |
1517 |
foreach my $field ($itemmarc->field($itemtag)){ |
1516 |
foreach my $field ($itemmarc->field($itemtag)){ |
1518 |
$field->add_subfields(@$unlinked_item_subfields); |
1517 |
$field->add_subfields(@$unlinked_item_subfields); |
1519 |
} |
1518 |
} |
1520 |
} |
1519 |
} |
1521 |
return $itemmarc; |
1520 |
return $itemmarc; |
1522 |
} |
1521 |
} |
1523 |
|
1522 |
|
1524 |
=head1 PRIVATE FUNCTIONS AND VARIABLES |
1523 |
=head1 PRIVATE FUNCTIONS AND VARIABLES |
Lines 1554-1560
my %derived_columns = (
Link Here
|
1554 |
} |
1553 |
} |
1555 |
); |
1554 |
); |
1556 |
|
1555 |
|
1557 |
=head2 _set_derived_columns_for_add |
1556 |
=head2 _set_derived_columns_for_add |
1558 |
|
1557 |
|
1559 |
_set_derived_column_for_add($item); |
1558 |
_set_derived_column_for_add($item); |
1560 |
|
1559 |
|
Lines 1578-1584
sub _set_derived_columns_for_add {
Link Here
|
1578 |
} |
1577 |
} |
1579 |
} |
1578 |
} |
1580 |
|
1579 |
|
1581 |
=head2 _set_derived_columns_for_mod |
1580 |
=head2 _set_derived_columns_for_mod |
1582 |
|
1581 |
|
1583 |
_set_derived_column_for_mod($item); |
1582 |
_set_derived_column_for_mod($item); |
1584 |
|
1583 |
|
Lines 1681-1692
row specified by C<$itemnumber>.
Link Here
|
1681 |
sub _get_single_item_column { |
1680 |
sub _get_single_item_column { |
1682 |
my $column = shift; |
1681 |
my $column = shift; |
1683 |
my $itemnumber = shift; |
1682 |
my $itemnumber = shift; |
1684 |
|
1683 |
|
1685 |
my $dbh = C4::Context->dbh; |
1684 |
my $dbh = C4::Context->dbh; |
1686 |
my $sth = $dbh->prepare("SELECT $column FROM items WHERE itemnumber = ?"); |
1685 |
my $sth = $dbh->prepare("SELECT $column FROM items WHERE itemnumber = ?"); |
1687 |
$sth->execute($itemnumber); |
1686 |
$sth->execute($itemnumber); |
1688 |
my ($value) = $sth->fetchrow(); |
1687 |
my ($value) = $sth->fetchrow(); |
1689 |
return $value; |
1688 |
return $value; |
1690 |
} |
1689 |
} |
1691 |
|
1690 |
|
1692 |
=head2 _calc_items_cn_sort |
1691 |
=head2 _calc_items_cn_sort |
Lines 1704-1710
sub _calc_items_cn_sort {
Link Here
|
1704 |
$item->{'items.cn_sort'} = GetClassSort($source_values->{'items.cn_source'}, $source_values->{'itemcallnumber'}, ""); |
1703 |
$item->{'items.cn_sort'} = GetClassSort($source_values->{'items.cn_source'}, $source_values->{'itemcallnumber'}, ""); |
1705 |
} |
1704 |
} |
1706 |
|
1705 |
|
1707 |
=head2 _set_defaults_for_add |
1706 |
=head2 _set_defaults_for_add |
1708 |
|
1707 |
|
1709 |
_set_defaults_for_add($item_hash); |
1708 |
_set_defaults_for_add($item_hash); |
1710 |
|
1709 |
|
Lines 1715-1721
columns:
Link Here
|
1715 |
|
1714 |
|
1716 |
=over 2 |
1715 |
=over 2 |
1717 |
|
1716 |
|
1718 |
=item * |
1717 |
=item * |
1719 |
|
1718 |
|
1720 |
C<items.dateaccessioned> |
1719 |
C<items.dateaccessioned> |
1721 |
|
1720 |
|
Lines 1755-1761
Perform the actual insert into the C<items> table.
Link Here
|
1755 |
|
1754 |
|
1756 |
sub _koha_new_item { |
1755 |
sub _koha_new_item { |
1757 |
my ( $item, $barcode ) = @_; |
1756 |
my ( $item, $barcode ) = @_; |
1758 |
my $dbh=C4::Context->dbh; |
1757 |
my $dbh=C4::Context->dbh; |
1759 |
my $error; |
1758 |
my $error; |
1760 |
$item->{permanent_location} //= $item->{location}; |
1759 |
$item->{permanent_location} //= $item->{location}; |
1761 |
_mod_item_dates( $item ); |
1760 |
_mod_item_dates( $item ); |
Lines 1886-1899
sub MoveItemFromBiblio {
Link Here
|
1886 |
if ($return == 1) { |
1885 |
if ($return == 1) { |
1887 |
ModZebra( $tobiblio, "specialUpdate", "biblioserver" ); |
1886 |
ModZebra( $tobiblio, "specialUpdate", "biblioserver" ); |
1888 |
ModZebra( $frombiblio, "specialUpdate", "biblioserver" ); |
1887 |
ModZebra( $frombiblio, "specialUpdate", "biblioserver" ); |
1889 |
# Checking if the item we want to move is in an order |
1888 |
# Checking if the item we want to move is in an order |
1890 |
require C4::Acquisition; |
1889 |
require C4::Acquisition; |
1891 |
my $order = C4::Acquisition::GetOrderFromItemnumber($itemnumber); |
1890 |
my $order = C4::Acquisition::GetOrderFromItemnumber($itemnumber); |
1892 |
if ($order) { |
1891 |
if ($order) { |
1893 |
# Replacing the biblionumber within the order if necessary |
1892 |
# Replacing the biblionumber within the order if necessary |
1894 |
$order->{'biblionumber'} = $tobiblio; |
1893 |
$order->{'biblionumber'} = $tobiblio; |
1895 |
C4::Acquisition::ModOrder($order); |
1894 |
C4::Acquisition::ModOrder($order); |
1896 |
} |
1895 |
} |
1897 |
|
1896 |
|
1898 |
# Update reserves, hold_fill_targets, tmp_holdsqueue and linktracker tables |
1897 |
# Update reserves, hold_fill_targets, tmp_holdsqueue and linktracker tables |
1899 |
for my $table_name ( qw( reserves hold_fill_targets tmp_holdsqueue linktracker ) ) { |
1898 |
for my $table_name ( qw( reserves hold_fill_targets tmp_holdsqueue linktracker ) ) { |
Lines 1904-1910
sub MoveItemFromBiblio {
Link Here
|
1904 |
|, undef, $tobiblio, $itemnumber ); |
1903 |
|, undef, $tobiblio, $itemnumber ); |
1905 |
} |
1904 |
} |
1906 |
return $tobiblio; |
1905 |
return $tobiblio; |
1907 |
} |
1906 |
} |
1908 |
return; |
1907 |
return; |
1909 |
} |
1908 |
} |
1910 |
|
1909 |
|
Lines 2017-2023
routine accepts a hashref specifying the columns to update.
Link Here
|
2017 |
|
2016 |
|
2018 |
sub _koha_modify_item { |
2017 |
sub _koha_modify_item { |
2019 |
my ( $item ) = @_; |
2018 |
my ( $item ) = @_; |
2020 |
my $dbh=C4::Context->dbh; |
2019 |
my $dbh=C4::Context->dbh; |
2021 |
my $error; |
2020 |
my $error; |
2022 |
|
2021 |
|
2023 |
my $query = "UPDATE items SET "; |
2022 |
my $query = "UPDATE items SET "; |
Lines 2108-2119
sub _marc_from_item_hash {
Link Here
|
2108 |
if (@_) { |
2107 |
if (@_) { |
2109 |
$unlinked_item_subfields = shift; |
2108 |
$unlinked_item_subfields = shift; |
2110 |
} |
2109 |
} |
2111 |
|
2110 |
|
2112 |
# Tack on 'items.' prefix to column names so lookup from MARC frameworks will work |
2111 |
# Tack on 'items.' prefix to column names so lookup from MARC frameworks will work |
2113 |
# Also, don't emit a subfield if the underlying field is blank. |
2112 |
# Also, don't emit a subfield if the underlying field is blank. |
2114 |
my $mungeditem = { map { (defined($item->{$_}) and $item->{$_} ne '') ? |
2113 |
my $mungeditem = { map { (defined($item->{$_}) and $item->{$_} ne '') ? |
2115 |
(/^items\./ ? ($_ => $item->{$_}) : ("items.$_" => $item->{$_})) |
2114 |
(/^items\./ ? ($_ => $item->{$_}) : ("items.$_" => $item->{$_})) |
2116 |
: () } keys %{ $item } }; |
2115 |
: () } keys %{ $item } }; |
2117 |
|
2116 |
|
2118 |
my $item_marc = MARC::Record->new(); |
2117 |
my $item_marc = MARC::Record->new(); |
2119 |
foreach my $item_field ( keys %{$mungeditem} ) { |
2118 |
foreach my $item_field ( keys %{$mungeditem} ) { |
Lines 2157-2163
sub _repack_item_errors {
Link Here
|
2157 |
$repacked_error->{'error_code'} = $error_code; |
2156 |
$repacked_error->{'error_code'} = $error_code; |
2158 |
$repacked_error->{'error_information'} = $error_ref->{$error_code}; |
2157 |
$repacked_error->{'error_information'} = $error_ref->{$error_code}; |
2159 |
push @repacked_errors, $repacked_error; |
2158 |
push @repacked_errors, $repacked_error; |
2160 |
} |
2159 |
} |
2161 |
|
2160 |
|
2162 |
return @repacked_errors; |
2161 |
return @repacked_errors; |
2163 |
} |
2162 |
} |
Lines 2180-2186
sub _get_unlinked_item_subfields {
Link Here
|
2180 |
my @fields = $original_item_marc->fields(); |
2179 |
my @fields = $original_item_marc->fields(); |
2181 |
if ($#fields > -1) { |
2180 |
if ($#fields > -1) { |
2182 |
my $field = $fields[0]; |
2181 |
my $field = $fields[0]; |
2183 |
my $tag = $field->tag(); |
2182 |
my $tag = $field->tag(); |
2184 |
foreach my $subfield ($field->subfields()) { |
2183 |
foreach my $subfield ($field->subfields()) { |
2185 |
if (defined $subfield->[1] and |
2184 |
if (defined $subfield->[1] and |
2186 |
$subfield->[1] ne '' and |
2185 |
$subfield->[1] ne '' and |
Lines 2207-2213
sub _get_unlinked_subfields_xml {
Link Here
|
2207 |
# use of tag 999 is arbitrary, and doesn't need to match the item tag |
2206 |
# use of tag 999 is arbitrary, and doesn't need to match the item tag |
2208 |
# used in the framework |
2207 |
# used in the framework |
2209 |
$marc->append_fields(MARC::Field->new('999', ' ', ' ', @$unlinked_item_subfields)); |
2208 |
$marc->append_fields(MARC::Field->new('999', ' ', ' ', @$unlinked_item_subfields)); |
2210 |
$marc->encoding("UTF-8"); |
2209 |
$marc->encoding("UTF-8"); |
2211 |
$xml = $marc->as_xml("USMARC"); |
2210 |
$xml = $marc->as_xml("USMARC"); |
2212 |
} |
2211 |
} |
2213 |
|
2212 |
|
Lines 2239-2245
sub _parse_unlinked_item_subfields_from_xml {
Link Here
|
2239 |
|
2238 |
|
2240 |
$count= &GetAnalyticsCount($itemnumber) |
2239 |
$count= &GetAnalyticsCount($itemnumber) |
2241 |
|
2240 |
|
2242 |
counts Usage of itemnumber in Analytical bibliorecords. |
2241 |
counts Usage of itemnumber in Analytical bibliorecords. |
2243 |
|
2242 |
|
2244 |
=cut |
2243 |
=cut |
2245 |
|
2244 |
|
Lines 2443-2452
sub SearchItems {
Link Here
|
2443 |
my $query = q{ |
2442 |
my $query = q{ |
2444 |
SELECT SQL_CALC_FOUND_ROWS items.* |
2443 |
SELECT SQL_CALC_FOUND_ROWS items.* |
2445 |
FROM items |
2444 |
FROM items |
2446 |
LEFT JOIN biblio ON biblio.biblionumber = items.biblionumber |
2445 |
LEFT JOIN biblio ON biblio.biblionumber = items.biblionumber |
2447 |
LEFT JOIN biblioitems ON biblioitems.biblioitemnumber = items.biblioitemnumber |
2446 |
LEFT JOIN biblioitems ON biblioitems.biblioitemnumber = items.biblioitemnumber |
2448 |
LEFT JOIN biblio_metadata ON biblio_metadata.biblionumber = biblio.biblionumber |
2447 |
LEFT JOIN biblio_metadata ON biblio_metadata.biblionumber = biblio.biblionumber |
2449 |
WHERE items.deleted_at IS NULL |
2448 |
WHERE items.deleted_at IS NULL |
2450 |
}; |
2449 |
}; |
2451 |
if (defined $where_str and $where_str ne '') { |
2450 |
if (defined $where_str and $where_str ne '') { |
2452 |
$query .= qq{ AND $where_str }; |
2451 |
$query .= qq{ AND $where_str }; |
2453 |
- |
|
|