bug 9784: add koha-shell to the koha-common man page
[koha.git] / cataloguing / additem.pl
index f970890..a8a8649 100755 (executable)
@@ -33,11 +33,14 @@ 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) = @_;
@@ -104,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 '@'){
@@ -200,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};
                   }
             }
 
@@ -244,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}');" />
@@ -252,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
@@ -271,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');
@@ -285,6 +314,12 @@ my $itemnumber   = $input->param('itemnumber');
 my $op           = $input->param('op');
 my $hostitemnumber = $input->param('hostitemnumber');
 my $marcflavour  = C4::Context->preference("marcflavour");
+# fast cataloguing datas
+my $fa_circborrowernumber = $input->param('circborrowernumber');
+my $fa_barcode            = $input->param('barcode');
+my $fa_branch             = $input->param('branch');
+my $fa_stickyduedate      = $input->param('stickyduedate');
+my $fa_duedatespec        = $input->param('duedatespec');
 
 my $frameworkcode = &GetFrameworkCode($biblionumber);
 
@@ -315,9 +350,26 @@ 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 +386,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 +452,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
@@ -430,13 +513,15 @@ if ($op eq "additem") {
            undef($itemrecord);
        }
     }  
-    if ($frameworkcode eq 'FA' && $input->param('borrowernumber')){
-       my $redirect_string = 'borrowernumber=' . uri_escape($input->param('borrowernumber')) .
-         '&barcode=' . uri_escape($input->param('barcode'));
-       $redirect_string .= '&duedatespec=' . uri_escape($input->param('duedatespec')) . 
-         '&stickyduedate=1';
-       print $input->redirect("/cgi-bin/koha/circ/circulation.pl?" . $redirect_string);
-       exit;
+    if ($frameworkcode eq 'FA' && $fa_circborrowernumber){
+        print $input->redirect(
+           '/cgi-bin/koha/circ/circulation.pl?'
+           .'borrowernumber='.$fa_circborrowernumber
+           .'&barcode='.uri_escape($fa_barcode)
+           .'&duedatespec='.$fa_duedatespec
+           .'&stickyduedate=1'
+        );
+        exit;
     }
 
 
@@ -564,13 +649,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'));
+                    }
                 }
             }
         }
@@ -693,6 +781,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);
@@ -720,6 +813,7 @@ $template->param(
     item_header_loop => \@header_value_loop,
     item             => \@loop_data,
     itemnumber       => $itemnumber,
+    barcode          => GetBarcodeFromItemnumber($itemnumber),
     itemtagfield     => $itemtagfield,
     itemtagsubfield  => $itemtagsubfield,
     op      => $nextop,
@@ -729,11 +823,15 @@ $template->param(
 );
 
 if ($frameworkcode eq 'FA'){
-    $template->{VARS}->{'borrowernumber'}=$input->param('borrowernumber');
-    $template->{VARS}->{'barcode'}=$input->param('barcode');
-    $template->{VARS}->{'stickyduedate'}=$input->param('stickduedate');
-    $template->{VARS}->{'duedatespec'}=$input->param('duedatespec');
-}    
+    # fast cataloguing datas
+    $template->param(
+        'circborrowernumber' => $fa_circborrowernumber,
+        'barcode'            => $fa_barcode,
+        'branch'             => $fa_branch,
+        'stickyduedate'      => $fa_stickyduedate,
+        'duedatespec'        => $fa_duedatespec,
+    );
+}
 
 foreach my $error (@errors) {
     $template->param($error => 1);