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

(-)a/C4/Items.pm (-135 / +133 lines)
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
- 

Return to bug 20271