Bug 7507 - Audience Subtype limit on OPAC Advanced Search does not have all Audiences
[koha.git] / cataloguing / additem.pl
index d22558f..1bd19a7 100755 (executable)
@@ -32,11 +32,15 @@ use C4::Branch; # XXX subfield_is_koha_internal_p
 use C4::ClassSource;
 use C4::Dates;
 use List::MoreUtils qw/any/;
+use C4::Search;
+use Storable qw(thaw freeze);
+use URI::Escape;
+
 
 use MARC::File::XML;
 use URI::Escape;
 
-my $dbh = C4::Context->dbh;
+our $dbh = C4::Context->dbh;
 
 sub find_value {
     my ($tagfield,$insubfield,$record) = @_;
@@ -103,8 +107,7 @@ sub generate_subfield_form {
   
   my $frameworkcode = &GetFrameworkCode($biblionumber);
         my %subfield_data;
-        my $dbh = C4::Context->dbh;        
-        my $authorised_values_sth = $dbh->prepare("SELECT authorised_value,lib FROM authorised_values WHERE category=? ORDER BY lib");
+        my $dbh = C4::Context->dbh;
         
         my $index_subfield = int(rand(1000000)); 
         if ($subfieldtag eq '@'){
@@ -119,6 +122,7 @@ sub generate_subfield_form {
         $subfield_data{marc_lib}   ="<span id=\"error$i\" title=\"".$subfieldlib->{lib}."\">".$subfieldlib->{lib}."</span>";
         $subfield_data{mandatory}  = $subfieldlib->{mandatory};
         $subfield_data{repeatable} = $subfieldlib->{repeatable};
+        $subfield_data{maxlength}  = $subfieldlib->{maxlength};
         
         $value =~ s/"/&quot;/g;
         if ( ! defined( $value ) || $value eq '')  {
@@ -145,11 +149,11 @@ sub generate_subfield_form {
             }
         }
         
-        if ($frameworkcode eq 'FA' && $subfieldlib->{kohafield} eq 'items.barcode'){
+        if ($frameworkcode eq 'FA' && $subfieldlib->{kohafield} eq 'items.barcode' && !$value){
            my $input = new CGI;
            $value = $input->param('barcode');
        }
-        my $attributes_no_value = qq(tabindex="1" id="$subfield_data{id}" name="field_value" class="input_marceditor" size="67" maxlength="255" );
+        my $attributes_no_value = qq(tabindex="1" id="$subfield_data{id}" name="field_value" class="input_marceditor" size="67" maxlength="$subfield_data{maxlength}" );
         my $attributes          = qq($attributes_no_value value="$value" );
         
         if ( $subfieldlib->{authorised_value} ) {
@@ -198,11 +202,11 @@ sub generate_subfield_form {
                   #---- "true" authorised value
             }
             else {
-                  push @authorised_values, "" unless ( $subfieldlib->{mandatory} );
-                  $authorised_values_sth->execute( $subfieldlib->{authorised_value} );
-                  while ( my ( $value, $lib ) = $authorised_values_sth->fetchrow_array ) {
-                      push @authorised_values, $value;
-                      $authorised_lib{$value} = $lib;
+                  push @authorised_values, qq{} unless ( $subfieldlib->{mandatory} );
+                  my $av = GetAuthorisedValues( $subfieldlib->{authorised_value} );
+                  for my $r ( @$av ) {
+                      push @authorised_values, $r->{authorised_value};
+                      $authorised_lib{$r->{authorised_value}} = $r->{lib};
                   }
             }
 
@@ -242,7 +246,7 @@ sub generate_subfield_form {
                    my $change = index($javascript, 'function Change') > -1 ?
                        "return Change$function_name($subfield_data{random}, '$subfield_data{id}');" :
                        'return 1;';
-                    $subfield_data{marc_value} = qq[<input $attributes
+                    $subfield_data{marc_value} = qq[<input type="text" $attributes
                         onfocus="Focus$function_name($subfield_data{random}, '$subfield_data{id}');"
                        onchange=" $change"
                          onblur=" Blur$function_name($subfield_data{random}, '$subfield_data{id}');" />
@@ -250,7 +254,7 @@ sub generate_subfield_form {
                         $javascript];
                 } else {
                     warn "Plugin Failed: $plugin";
-                    $subfield_data{marc_value} = "<input $attributes />"; # supply default input form
+                    $subfield_data{marc_value} = "<input type=\"text\" $attributes />"; # supply default input form
                 }
         }
         elsif ( $tag eq '' ) {       # it's an hidden field
@@ -269,12 +273,39 @@ sub generate_subfield_form {
             $subfield_data{marc_value} = "<textarea $attributes_no_value>$value</textarea>\n";
         } else {
            # it's a standard field
-           $subfield_data{marc_value} = "<input $attributes />";
+           $subfield_data{marc_value} = "<input type=\"text\" $attributes />";
         }
         
         return \%subfield_data;
 }
 
+# Removes some subfields when prefilling items
+# This function will remove any subfield that is not in the SubfieldsToUseWhenPrefill syspref
+sub removeFieldsForPrefill {
+
+    my $item = shift;
+
+    # Getting item tag
+    my ($tag, $subtag) = GetMarcFromKohaField("items.barcode", '');
+
+    # Getting list of subfields to keep
+    my $subfieldsToUseWhenPrefill = C4::Context->preference('SubfieldsToUseWhenPrefill');
+
+    # Removing subfields that are not in the syspref
+    if ($tag && $subfieldsToUseWhenPrefill) {
+        my $field = $item->field($tag);
+        my @subfieldsToUse= split(/ /,$subfieldsToUseWhenPrefill);
+        foreach my $subfield ($field->subfields()) {
+            if (!grep { $subfield->[0] eq $_ } @subfieldsToUse) {
+                $field->delete_subfield(code => $subfield->[0]);
+            }
+
+        }
+    }
+
+    return $item;
+
+}
 
 my $input        = new CGI;
 my $error        = $input->param('error');
@@ -307,17 +338,32 @@ my ($template, $loggedinuser, $cookie)
 
 
 my $today_iso = C4::Dates->today('iso');
-$template->param(today_iso => $today_iso);
-
 my $tagslib = &GetMarcStructure(1,$frameworkcode);
 my $record = GetMarcBiblio($biblionumber);
 my $oldrecord = TransformMarcToKoha($dbh,$record);
 my $itemrecord;
 my $nextop="additem";
 my @errors; # store errors found while checking data BEFORE saving item.
+
+# Getting last created item cookie
+my $prefillitem = C4::Context->preference('PrefillItem');
+my $justaddeditem;
+my $cookieitemrecord;
+if ($prefillitem) {
+    my $lastitemcookie = $input->cookie('LastCreatedItem');
+    if ($lastitemcookie) {
+        $lastitemcookie = uri_unescape($lastitemcookie);
+        if ( thaw($lastitemcookie) ) {
+            $cookieitemrecord = thaw($lastitemcookie) ;
+            $cookieitemrecord = removeFieldsForPrefill($cookieitemrecord);
+        }
+    }
+}
+
 #-------------------------------------------------------------------------------
 if ($op eq "additem") {
-#-------------------------------------------------------------------------------
+
+    #-------------------------------------------------------------------------------
     # rebuild
     my @tags      = $input->param('tag');
     my @subfields = $input->param('subfield');
@@ -334,26 +380,56 @@ if ($op eq "additem") {
     my $add_multiple_copies_submit = $input->param('add_multiple_copies_submit');
     my $number_of_copies           = $input->param('number_of_copies');
 
+    # This is a bit tricky : if there is a cookie for the last created item and
+    # we just added an item, the cookie value is not correct yet (it will be updated
+    # next page). To prevent the form from being filled with outdated values, we
+    # force the use of "add and duplicate" feature, so the form will be filled with
+    # correct values.
+    $add_duplicate_submit = 1 if ($prefillitem);
+    $justaddeditem = 1;
+
+    # if autoBarcode is set to 'incremental', calculate barcode...
+    if ( C4::Context->preference('autoBarcode') eq 'incremental' ) {
+        $record = _increment_barcode($record, $frameworkcode);
+    }
+
+
     if (C4::Context->preference('autoBarcode') eq 'incremental') {
         $record = _increment_barcode($record, $frameworkcode);
     }
 
-    my $addedolditem = TransformMarcToKoha($dbh,$record);
+    my $addedolditem = TransformMarcToKoha( $dbh, $record );
 
     # If we have to add or add & duplicate, we add the item
-    if ($add_submit || $add_duplicate_submit) {
-       # check for item barcode # being unique
-       my $exist_itemnumber = get_item_from_barcode($addedolditem->{'barcode'});
-       push @errors,"barcode_not_unique" if($exist_itemnumber);
-       # if barcode exists, don't create, but report The problem.
-    unless ($exist_itemnumber) {
-           my ($oldbiblionumber,$oldbibnum,$oldbibitemnum) = AddItemFromMarc($record,$biblionumber);
-        set_item_default_location($oldbibitemnum);
-    }
-       $nextop = "additem";
-       if ($exist_itemnumber) {
-           $itemrecord = $record;
-       }
+    if ( $add_submit || $add_duplicate_submit ) {
+
+        # check for item barcode # being unique
+        my $exist_itemnumber = get_item_from_barcode( $addedolditem->{'barcode'} );
+        push @errors, "barcode_not_unique" if ($exist_itemnumber);
+
+        # if barcode exists, don't create, but report The problem.
+        unless ($exist_itemnumber) {
+            my ( $oldbiblionumber, $oldbibnum, $oldbibitemnum ) = AddItemFromMarc( $record, $biblionumber );
+            set_item_default_location($oldbibitemnum);
+
+            # Pushing the last created item cookie back
+            if ($prefillitem && defined $record) {
+                my $itemcookie = $input->cookie(
+                    -name => 'LastCreatedItem',
+                    # We uri_escape the whole freezed structure so we're sure we won't have any encoding problems
+                    -value   => uri_escape_utf8( freeze( $record ) ),
+                    -HttpOnly => 1,
+                    -expires => ''
+                );
+
+                $cookie = [ $cookie, $itemcookie ];
+            }
+
+        }
+        $nextop = "additem";
+        if ($exist_itemnumber) {
+            $itemrecord = $record;
+        }
     }
 
     # If we have to add & duplicate
@@ -370,6 +446,7 @@ if ($op eq "additem") {
             $fieldItem->delete_subfields($tagsubfield);
             $itemrecord->insert_fields_ordered($fieldItem);
         }
+    $itemrecord = removeFieldsForPrefill($itemrecord) if ($prefillitem);
     }
 
     # If we have to add multiple copies
@@ -564,13 +641,16 @@ if ( C4::Context->preference('EasyAnalyticalRecords') ) {
         $analyticfield = '461';
     }
     foreach my $hostfield ($temp->field($analyticfield)){
-       if ($hostfield->subfield('0')){
-            my $hostrecord = GetMarcBiblio($hostfield->subfield('0'), 1);
-           my ($itemfield, undef) = GetMarcFromKohaField( 'items.itemnumber', GetFrameworkCode($hostfield->subfield('0')) );
-           foreach my $hostitem ($hostrecord->field($itemfield)){
-               if ($hostitem->subfield('9') eq $hostfield->subfield('9')){
-                   push (@fields, $hostitem);
-                    push (@hostitemnumbers, $hostfield->subfield('9'));
+        my $hostbiblionumber = $hostfield->subfield('0');
+        if ($hostbiblionumber){
+            my $hostrecord = GetMarcBiblio($hostbiblionumber, 1);
+            if ($hostrecord) {
+                my ($itemfield, undef) = GetMarcFromKohaField( 'items.itemnumber', GetFrameworkCode($hostbiblionumber) );
+                foreach my $hostitem ($hostrecord->field($itemfield)){
+                    if ($hostitem->subfield('9') eq $hostfield->subfield('9')){
+                        push (@fields, $hostitem);
+                        push (@hostitemnumbers, $hostfield->subfield('9'));
+                    }
                 }
             }
         }
@@ -682,8 +762,6 @@ if($itemrecord){
             next if subfield_is_koha_internal_p($subfieldtag);
             next if ($tagslib->{$tag}->{$subfieldtag}->{'tab'} ne "10");
 
-            $subfieldlib->{hidden} = 1
-              if $tagslib->{$tag}->{$subfieldtag}->{authorised_value} eq 'LOST';
             my $subfield_data = generate_subfield_form($tag, $subfieldtag, $value, $tagslib, $subfieldlib, $branches, $today_iso, $biblionumber, $temp, \@loop_data, $i);        
 
             push @fields, "$tag$subfieldtag";
@@ -695,6 +773,11 @@ if($itemrecord){
             }
     # and now we add fields that are empty
 
+# Using last created item if it exists
+
+$itemrecord = $cookieitemrecord if ($prefillitem and not $justaddeditem and $op ne "edititem");
+
+# We generate form, and fill with values if defined
 foreach my $tag ( keys %{$tagslib}){
     foreach my $subtag (keys %{$tagslib->{$tag}}){
         next if subfield_is_koha_internal_p($subtag);
@@ -722,10 +805,12 @@ $template->param(
     item_header_loop => \@header_value_loop,
     item             => \@loop_data,
     itemnumber       => $itemnumber,
+    barcode          => GetBarcodeFromItemnumber($itemnumber),
     itemtagfield     => $itemtagfield,
     itemtagsubfield  => $itemtagsubfield,
     op      => $nextop,
     opisadd => ($nextop eq "saveitem") ? 0 : 1,
+    popup => $input->param('popup') ? 1: 0,
     C4::Search::enabled_staff_search_views,
 );