Lines 27-33
use Carp;
Link Here
|
27 |
use MARC::Record; |
27 |
use MARC::Record; |
28 |
use MARC::File::USMARC; |
28 |
use MARC::File::USMARC; |
29 |
use MARC::File::XML; |
29 |
use MARC::File::XML; |
30 |
use ZOOM; |
|
|
31 |
use POSIX qw(strftime); |
30 |
use POSIX qw(strftime); |
32 |
|
31 |
|
33 |
use C4::Koha; |
32 |
use C4::Koha; |
Lines 35-43
use C4::Dates qw/format_date/;
Link Here
|
35 |
use C4::Log; # logaction |
34 |
use C4::Log; # logaction |
36 |
use C4::ClassSource; |
35 |
use C4::ClassSource; |
37 |
use C4::Charset; |
36 |
use C4::Charset; |
38 |
require C4::Heading; |
|
|
39 |
require C4::Serials; |
40 |
require C4::Items; |
41 |
|
37 |
|
42 |
use vars qw($VERSION @ISA @EXPORT); |
38 |
use vars qw($VERSION @ISA @EXPORT); |
43 |
|
39 |
|
Lines 131-137
BEGIN {
Link Here
|
131 |
&TransformHtmlToMarc2 |
127 |
&TransformHtmlToMarc2 |
132 |
&TransformHtmlToMarc |
128 |
&TransformHtmlToMarc |
133 |
&TransformHtmlToXml |
129 |
&TransformHtmlToXml |
134 |
&PrepareItemrecordDisplay |
|
|
135 |
&GetNoZebraIndexes |
130 |
&GetNoZebraIndexes |
136 |
); |
131 |
); |
137 |
} |
132 |
} |
Lines 418-426
sub DelBiblio {
Link Here
|
418 |
return $error if $error; |
413 |
return $error if $error; |
419 |
|
414 |
|
420 |
# We delete attached subscriptions |
415 |
# We delete attached subscriptions |
421 |
my $subscriptions = &C4::Serials::GetFullSubscriptionsFromBiblionumber($biblionumber); |
416 |
require C4::Serials; |
|
|
417 |
my $subscriptions = C4::Serials::GetFullSubscriptionsFromBiblionumber($biblionumber); |
422 |
foreach my $subscription (@$subscriptions) { |
418 |
foreach my $subscription (@$subscriptions) { |
423 |
&C4::Serials::DelSubscription( $subscription->{subscriptionid} ); |
419 |
C4::Serials::DelSubscription( $subscription->{subscriptionid} ); |
424 |
} |
420 |
} |
425 |
|
421 |
|
426 |
# Delete in Zebra. Be careful NOT to move this line after _koha_delete_biblio |
422 |
# Delete in Zebra. Be careful NOT to move this line after _koha_delete_biblio |
Lines 478-483
MARC record.
Link Here
|
478 |
=cut |
474 |
=cut |
479 |
|
475 |
|
480 |
sub LinkBibHeadingsToAuthorities { |
476 |
sub LinkBibHeadingsToAuthorities { |
|
|
477 |
require C4::Heading; |
481 |
my $bib = shift; |
478 |
my $bib = shift; |
482 |
|
479 |
|
483 |
my $num_headings_changed = 0; |
480 |
my $num_headings_changed = 0; |
Lines 2445-2676
sub TransformMarcToKohaOneField {
Link Here
|
2445 |
return $result; |
2442 |
return $result; |
2446 |
} |
2443 |
} |
2447 |
|
2444 |
|
2448 |
=head1 OTHER FUNCTIONS |
|
|
2449 |
|
2450 |
|
2451 |
=head2 PrepareItemrecordDisplay |
2452 |
|
2453 |
PrepareItemrecordDisplay($itemrecord,$bibnum,$itemumber,$frameworkcode); |
2454 |
|
2455 |
Returns a hash with all the fields for Display a given item data in a template |
2456 |
|
2457 |
The $frameworkcode returns the item for the given frameworkcode, ONLY if bibnum is not provided |
2458 |
|
2459 |
=cut |
2460 |
|
2461 |
sub PrepareItemrecordDisplay { |
2462 |
|
2463 |
my ( $bibnum, $itemnum, $defaultvalues, $frameworkcode ) = @_; |
2464 |
|
2465 |
my $dbh = C4::Context->dbh; |
2466 |
$frameworkcode = &GetFrameworkCode($bibnum) if $bibnum; |
2467 |
my ( $itemtagfield, $itemtagsubfield ) = &GetMarcFromKohaField( "items.itemnumber", $frameworkcode ); |
2468 |
my $tagslib = &GetMarcStructure( 1, $frameworkcode ); |
2469 |
|
2470 |
# return nothing if we don't have found an existing framework. |
2471 |
return q{} unless $tagslib; |
2472 |
my $itemrecord; |
2473 |
if ($itemnum) { |
2474 |
$itemrecord = C4::Items::GetMarcItem( $bibnum, $itemnum ); |
2475 |
} |
2476 |
my @loop_data; |
2477 |
my $authorised_values_sth = $dbh->prepare( "SELECT authorised_value,lib FROM authorised_values WHERE category=? ORDER BY lib" ); |
2478 |
foreach my $tag ( sort keys %{$tagslib} ) { |
2479 |
my $previous_tag = ''; |
2480 |
if ( $tag ne '' ) { |
2481 |
|
2482 |
# loop through each subfield |
2483 |
my $cntsubf; |
2484 |
foreach my $subfield ( sort keys %{ $tagslib->{$tag} } ) { |
2485 |
next if ( subfield_is_koha_internal_p($subfield) ); |
2486 |
next if ( $tagslib->{$tag}->{$subfield}->{'tab'} ne "10" ); |
2487 |
my %subfield_data; |
2488 |
$subfield_data{tag} = $tag; |
2489 |
$subfield_data{subfield} = $subfield; |
2490 |
$subfield_data{countsubfield} = $cntsubf++; |
2491 |
$subfield_data{kohafield} = $tagslib->{$tag}->{$subfield}->{'kohafield'}; |
2492 |
|
2493 |
# $subfield_data{marc_lib}=$tagslib->{$tag}->{$subfield}->{lib}; |
2494 |
$subfield_data{marc_lib} = $tagslib->{$tag}->{$subfield}->{lib}; |
2495 |
$subfield_data{mandatory} = $tagslib->{$tag}->{$subfield}->{mandatory}; |
2496 |
$subfield_data{repeatable} = $tagslib->{$tag}->{$subfield}->{repeatable}; |
2497 |
$subfield_data{hidden} = "display:none" |
2498 |
if $tagslib->{$tag}->{$subfield}->{hidden}; |
2499 |
my ( $x, $defaultvalue ); |
2500 |
if ($itemrecord) { |
2501 |
( $x, $defaultvalue ) = _find_value( $tag, $subfield, $itemrecord ); |
2502 |
} |
2503 |
$defaultvalue = $tagslib->{$tag}->{$subfield}->{defaultvalue} unless $defaultvalue; |
2504 |
if ( !defined $defaultvalue ) { |
2505 |
$defaultvalue = q||; |
2506 |
} |
2507 |
$defaultvalue =~ s/"/"/g; |
2508 |
|
2509 |
# search for itemcallnumber if applicable |
2510 |
if ( $tagslib->{$tag}->{$subfield}->{kohafield} eq 'items.itemcallnumber' |
2511 |
&& C4::Context->preference('itemcallnumber') ) { |
2512 |
my $CNtag = substr( C4::Context->preference('itemcallnumber'), 0, 3 ); |
2513 |
my $CNsubfield = substr( C4::Context->preference('itemcallnumber'), 3, 1 ); |
2514 |
if ($itemrecord) { |
2515 |
my $temp = $itemrecord->field($CNtag); |
2516 |
if ($temp) { |
2517 |
$defaultvalue = $temp->subfield($CNsubfield); |
2518 |
} |
2519 |
} |
2520 |
} |
2521 |
if ( $tagslib->{$tag}->{$subfield}->{kohafield} eq 'items.itemcallnumber' |
2522 |
&& $defaultvalues |
2523 |
&& $defaultvalues->{'callnumber'} ) { |
2524 |
my $temp; |
2525 |
if ($itemrecord) { |
2526 |
$temp = $itemrecord->field($subfield); |
2527 |
} |
2528 |
unless ($temp) { |
2529 |
$defaultvalue = $defaultvalues->{'callnumber'} if $defaultvalues; |
2530 |
} |
2531 |
} |
2532 |
if ( ( $tagslib->{$tag}->{$subfield}->{kohafield} eq 'items.holdingbranch' || $tagslib->{$tag}->{$subfield}->{kohafield} eq 'items.homebranch' ) |
2533 |
&& $defaultvalues |
2534 |
&& $defaultvalues->{'branchcode'} ) { |
2535 |
my $temp; |
2536 |
if ($itemrecord) { |
2537 |
$temp = $itemrecord->field($subfield); |
2538 |
} |
2539 |
unless ($temp) { |
2540 |
$defaultvalue = $defaultvalues->{branchcode} if $defaultvalues; |
2541 |
} |
2542 |
} |
2543 |
if ( ( $tagslib->{$tag}->{$subfield}->{kohafield} eq 'items.location' ) |
2544 |
&& $defaultvalues |
2545 |
&& $defaultvalues->{'location'} ) { |
2546 |
my $temp = $itemrecord->field($subfield) if ($itemrecord); |
2547 |
unless ($temp) { |
2548 |
$defaultvalue = $defaultvalues->{location} if $defaultvalues; |
2549 |
} |
2550 |
} |
2551 |
if ( $tagslib->{$tag}->{$subfield}->{authorised_value} ) { |
2552 |
my @authorised_values; |
2553 |
my %authorised_lib; |
2554 |
|
2555 |
# builds list, depending on authorised value... |
2556 |
#---- branch |
2557 |
if ( $tagslib->{$tag}->{$subfield}->{'authorised_value'} eq "branches" ) { |
2558 |
if ( ( C4::Context->preference("IndependantBranches") ) |
2559 |
&& ( C4::Context->userenv->{flags} % 2 != 1 ) ) { |
2560 |
my $sth = $dbh->prepare( "SELECT branchcode,branchname FROM branches WHERE branchcode = ? ORDER BY branchname" ); |
2561 |
$sth->execute( C4::Context->userenv->{branch} ); |
2562 |
push @authorised_values, "" |
2563 |
unless ( $tagslib->{$tag}->{$subfield}->{mandatory} ); |
2564 |
while ( my ( $branchcode, $branchname ) = $sth->fetchrow_array ) { |
2565 |
push @authorised_values, $branchcode; |
2566 |
$authorised_lib{$branchcode} = $branchname; |
2567 |
} |
2568 |
} else { |
2569 |
my $sth = $dbh->prepare( "SELECT branchcode,branchname FROM branches ORDER BY branchname" ); |
2570 |
$sth->execute; |
2571 |
push @authorised_values, "" |
2572 |
unless ( $tagslib->{$tag}->{$subfield}->{mandatory} ); |
2573 |
while ( my ( $branchcode, $branchname ) = $sth->fetchrow_array ) { |
2574 |
push @authorised_values, $branchcode; |
2575 |
$authorised_lib{$branchcode} = $branchname; |
2576 |
} |
2577 |
} |
2578 |
|
2579 |
#----- itemtypes |
2580 |
} elsif ( $tagslib->{$tag}->{$subfield}->{authorised_value} eq "itemtypes" ) { |
2581 |
my $sth = $dbh->prepare( "SELECT itemtype,description FROM itemtypes ORDER BY description" ); |
2582 |
$sth->execute; |
2583 |
push @authorised_values, "" |
2584 |
unless ( $tagslib->{$tag}->{$subfield}->{mandatory} ); |
2585 |
while ( my ( $itemtype, $description ) = $sth->fetchrow_array ) { |
2586 |
push @authorised_values, $itemtype; |
2587 |
$authorised_lib{$itemtype} = $description; |
2588 |
} |
2589 |
#---- class_sources |
2590 |
} elsif ( $tagslib->{$tag}->{$subfield}->{authorised_value} eq "cn_source" ) { |
2591 |
push @authorised_values, "" unless ( $tagslib->{$tag}->{$subfield}->{mandatory} ); |
2592 |
|
2593 |
my $class_sources = GetClassSources(); |
2594 |
my $default_source = C4::Context->preference("DefaultClassificationSource"); |
2595 |
|
2596 |
foreach my $class_source (sort keys %$class_sources) { |
2597 |
next unless $class_sources->{$class_source}->{'used'} or |
2598 |
($class_source eq $default_source); |
2599 |
push @authorised_values, $class_source; |
2600 |
$authorised_lib{$class_source} = $class_sources->{$class_source}->{'description'}; |
2601 |
} |
2602 |
|
2603 |
#---- "true" authorised value |
2604 |
} else { |
2605 |
$authorised_values_sth->execute( $tagslib->{$tag}->{$subfield}->{authorised_value} ); |
2606 |
push @authorised_values, "" |
2607 |
unless ( $tagslib->{$tag}->{$subfield}->{mandatory} ); |
2608 |
while ( my ( $value, $lib ) = $authorised_values_sth->fetchrow_array ) { |
2609 |
push @authorised_values, $value; |
2610 |
$authorised_lib{$value} = $lib; |
2611 |
} |
2612 |
} |
2613 |
$subfield_data{marc_value} = CGI::scrolling_list( |
2614 |
-name => 'field_value', |
2615 |
-values => \@authorised_values, |
2616 |
-default => "$defaultvalue", |
2617 |
-labels => \%authorised_lib, |
2618 |
-size => 1, |
2619 |
-tabindex => '', |
2620 |
-multiple => 0, |
2621 |
); |
2622 |
} elsif ( $tagslib->{$tag}->{$subfield}->{value_builder} ) { |
2623 |
# opening plugin |
2624 |
my $plugin = C4::Context->intranetdir . "/cataloguing/value_builder/" . $tagslib->{$tag}->{$subfield}->{'value_builder'}; |
2625 |
if (do $plugin) { |
2626 |
my $temp; |
2627 |
my $extended_param = plugin_parameters( $dbh, $temp, $tagslib, $subfield_data{id}, undef ); |
2628 |
my ( $function_name, $javascript ) = plugin_javascript( $dbh, $temp, $tagslib, $subfield_data{id}, undef ); |
2629 |
$subfield_data{random} = int(rand(1000000)); # why do we need 2 different randoms? |
2630 |
my $index_subfield = int(rand(1000000)); |
2631 |
$subfield_data{id} = "tag_".$tag."_subfield_".$subfield."_".$index_subfield; |
2632 |
$subfield_data{marc_value} = qq[<input tabindex="1" id="$subfield_data{id}" name="field_value" class="input_marceditor" size="67" maxlength="255" |
2633 |
onfocus="Focus$function_name($subfield_data{random}, '$subfield_data{id}');" |
2634 |
onblur=" Blur$function_name($subfield_data{random}, '$subfield_data{id}');" /> |
2635 |
<a href="#" class="buttonDot" onclick="Clic$function_name('$subfield_data{id}'); return false;" title="Tag Editor">...</a> |
2636 |
$javascript]; |
2637 |
} else { |
2638 |
warn "Plugin Failed: $plugin"; |
2639 |
$subfield_data{marc_value} = qq(<input tabindex="1" id="$subfield_data{id}" name="field_value" class="input_marceditor" size="67" maxlength="255" />); # supply default input form |
2640 |
} |
2641 |
} |
2642 |
elsif ( $tag eq '' ) { # it's an hidden field |
2643 |
$subfield_data{marc_value} = qq(<input type="hidden" tabindex="1" id="$subfield_data{id}" name="field_value" class="input_marceditor" size="67" maxlength="255" value="$defaultvalue" />); |
2644 |
} |
2645 |
elsif ( $tagslib->{$tag}->{$subfield}->{'hidden'} ) { # FIXME: shouldn't input type be "hidden" ? |
2646 |
$subfield_data{marc_value} = qq(<input type="text" tabindex="1" id="$subfield_data{id}" name="field_value" class="input_marceditor" size="67" maxlength="255" value="$defaultvalue" />); |
2647 |
} |
2648 |
elsif ( length($defaultvalue) > 100 |
2649 |
or (C4::Context->preference("marcflavour") eq "UNIMARC" and |
2650 |
300 <= $tag && $tag < 400 && $subfield eq 'a' ) |
2651 |
or (C4::Context->preference("marcflavour") eq "MARC21" and |
2652 |
500 <= $tag && $tag < 600 ) |
2653 |
) { |
2654 |
# oversize field (textarea) |
2655 |
$subfield_data{marc_value} = qq(<textarea tabindex="1" id="$subfield_data{id}" name="field_value" class="input_marceditor" size="67" maxlength="255">$defaultvalue</textarea>\n"); |
2656 |
} else { |
2657 |
$subfield_data{marc_value} = "<input type=\"text\" name=\"field_value\" value=\"$defaultvalue\" size=\"50\" maxlength=\"255\" />"; |
2658 |
} |
2659 |
push( @loop_data, \%subfield_data ); |
2660 |
} |
2661 |
} |
2662 |
} |
2663 |
my $itemnumber; |
2664 |
if ( $itemrecord && $itemrecord->field($itemtagfield) ) { |
2665 |
$itemnumber = $itemrecord->subfield( $itemtagfield, $itemtagsubfield ); |
2666 |
} |
2667 |
return { |
2668 |
'itemtagfield' => $itemtagfield, |
2669 |
'itemtagsubfield' => $itemtagsubfield, |
2670 |
'itemnumber' => $itemnumber, |
2671 |
'iteminformation' => \@loop_data |
2672 |
}; |
2673 |
} |
2674 |
|
2445 |
|
2675 |
#" |
2446 |
#" |
2676 |
|
2447 |
|
Lines 2834-2839
sub EmbedItemsInMarcBiblio {
Link Here
|
2834 |
my @item_fields; |
2605 |
my @item_fields; |
2835 |
my ( $itemtag, $itemsubfield ) = GetMarcFromKohaField( "items.itemnumber", $frameworkcode ); |
2606 |
my ( $itemtag, $itemsubfield ) = GetMarcFromKohaField( "items.itemnumber", $frameworkcode ); |
2836 |
while (my ($itemnumber) = $sth->fetchrow_array) { |
2607 |
while (my ($itemnumber) = $sth->fetchrow_array) { |
|
|
2608 |
require C4::Items; |
2837 |
my $item_marc = C4::Items::GetMarcItem($biblionumber, $itemnumber); |
2609 |
my $item_marc = C4::Items::GetMarcItem($biblionumber, $itemnumber); |
2838 |
push @item_fields, $item_marc->field($itemtag); |
2610 |
push @item_fields, $item_marc->field($itemtag); |
2839 |
} |
2611 |
} |
Lines 3627-3738
sub ModBiblioMarc {
Link Here
|
3627 |
return $biblionumber; |
3399 |
return $biblionumber; |
3628 |
} |
3400 |
} |
3629 |
|
3401 |
|
3630 |
=head2 z3950_extended_services |
|
|
3631 |
|
3632 |
z3950_extended_services($serviceType,$serviceOptions,$record); |
3633 |
|
3634 |
z3950_extended_services is used to handle all interactions with Zebra's extended serices package, which is employed to perform all management of the MARC data stored in Zebra. |
3635 |
|
3636 |
C<$serviceType> one of: itemorder,create,drop,commit,update,xmlupdate |
3637 |
|
3638 |
C<$serviceOptions> a has of key/value pairs. For instance, if service_type is 'update', $service_options should contain: |
3639 |
|
3640 |
action => update action, one of specialUpdate, recordInsert, recordReplace, recordDelete, elementUpdate. |
3641 |
|
3642 |
and maybe |
3643 |
|
3644 |
recordidOpaque => Opaque Record ID (user supplied) or recordidNumber => Record ID number (system number). |
3645 |
syntax => the record syntax (transfer syntax) |
3646 |
databaseName = Database from connection object |
3647 |
|
3648 |
To set serviceOptions, call set_service_options($serviceType) |
3649 |
|
3650 |
C<$record> the record, if one is needed for the service type |
3651 |
|
3652 |
A record should be in XML. You can convert it to XML from MARC by running it through marc2xml(). |
3653 |
|
3654 |
=cut |
3655 |
|
3656 |
sub z3950_extended_services { |
3657 |
my ( $server, $serviceType, $action, $serviceOptions ) = @_; |
3658 |
|
3659 |
# get our connection object |
3660 |
my $Zconn = C4::Context->Zconn( $server, 0, 1 ); |
3661 |
|
3662 |
# create a new package object |
3663 |
my $Zpackage = $Zconn->package(); |
3664 |
|
3665 |
# set our options |
3666 |
$Zpackage->option( action => $action ); |
3667 |
|
3668 |
if ( $serviceOptions->{'databaseName'} ) { |
3669 |
$Zpackage->option( databaseName => $serviceOptions->{'databaseName'} ); |
3670 |
} |
3671 |
if ( $serviceOptions->{'recordIdNumber'} ) { |
3672 |
$Zpackage->option( recordIdNumber => $serviceOptions->{'recordIdNumber'} ); |
3673 |
} |
3674 |
if ( $serviceOptions->{'recordIdOpaque'} ) { |
3675 |
$Zpackage->option( recordIdOpaque => $serviceOptions->{'recordIdOpaque'} ); |
3676 |
} |
3677 |
|
3678 |
# this is an ILL request (Zebra doesn't support it, but Koha could eventually) |
3679 |
#if ($serviceType eq 'itemorder') { |
3680 |
# $Zpackage->option('contact-name' => $serviceOptions->{'contact-name'}); |
3681 |
# $Zpackage->option('contact-phone' => $serviceOptions->{'contact-phone'}); |
3682 |
# $Zpackage->option('contact-email' => $serviceOptions->{'contact-email'}); |
3683 |
# $Zpackage->option('itemorder-item' => $serviceOptions->{'itemorder-item'}); |
3684 |
#} |
3685 |
|
3686 |
if ( $serviceOptions->{record} ) { |
3687 |
$Zpackage->option( record => $serviceOptions->{record} ); |
3688 |
|
3689 |
# can be xml or marc |
3690 |
if ( $serviceOptions->{'syntax'} ) { |
3691 |
$Zpackage->option( syntax => $serviceOptions->{'syntax'} ); |
3692 |
} |
3693 |
} |
3694 |
|
3695 |
# send the request, handle any exception encountered |
3696 |
eval { $Zpackage->send($serviceType) }; |
3697 |
if ( $@ && $@->isa("ZOOM::Exception") ) { |
3698 |
return "error: " . $@->code() . " " . $@->message() . "\n"; |
3699 |
} |
3700 |
|
3701 |
# free up package resources |
3702 |
$Zpackage->destroy(); |
3703 |
} |
3704 |
|
3705 |
=head2 set_service_options |
3706 |
|
3707 |
my $serviceOptions = set_service_options($serviceType); |
3708 |
|
3709 |
C<$serviceType> itemorder,create,drop,commit,update,xmlupdate |
3710 |
|
3711 |
Currently, we only support 'create', 'commit', and 'update'. 'drop' support will be added as soon as Zebra supports it. |
3712 |
|
3713 |
=cut |
3714 |
|
3715 |
sub set_service_options { |
3716 |
my ($serviceType) = @_; |
3717 |
my $serviceOptions; |
3718 |
|
3719 |
# FIXME: This needs to be an OID ... if we ever need 'syntax' this sub will need to change |
3720 |
# $serviceOptions->{ 'syntax' } = ''; #zebra doesn't support syntaxes other than xml |
3721 |
|
3722 |
if ( $serviceType eq 'commit' ) { |
3723 |
|
3724 |
# nothing to do |
3725 |
} |
3726 |
if ( $serviceType eq 'create' ) { |
3727 |
|
3728 |
# nothing to do |
3729 |
} |
3730 |
if ( $serviceType eq 'drop' ) { |
3731 |
die "ERROR: 'drop' not currently supported (by Zebra)"; |
3732 |
} |
3733 |
return $serviceOptions; |
3734 |
} |
3735 |
|
3736 |
=head2 get_biblio_authorised_values |
3402 |
=head2 get_biblio_authorised_values |
3737 |
|
3403 |
|
3738 |
find the types and values for all authorised values assigned to this biblio. |
3404 |
find the types and values for all authorised values assigned to this biblio. |