Bug 2060 follow-up DBRev & updatedatabase
[koha_fer] / cataloguing / additem.pl
index 4442ed3..7b7dbac 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) = @_;
@@ -119,6 +123,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 +150,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} ) {
@@ -275,6 +280,33 @@ sub generate_subfield_form {
         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 +339,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 +381,55 @@ 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 ) ),
+                    -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
@@ -381,7 +458,8 @@ if ($op eq "additem") {
         my ($tagfield,$tagsubfield) = &GetMarcFromKohaField("items.barcode",$frameworkcode);
 
        # If there is a barcode and we can't find him new values, we can't add multiple copies
-        my $testbarcode = $barcodeobj->next_value($oldbarcode) if $barcodeobj;
+       my $testbarcode;
+        $testbarcode = $barcodeobj->next_value($oldbarcode) if $barcodeobj;
        if ($oldbarcode && !$testbarcode) {
 
            push @errors, "no_next_barcode";
@@ -480,7 +558,17 @@ if ($op eq "additem") {
             $nextop="additem";
         } 
         else {
-            print $input->redirect("/cgi-bin/koha/catalogue/moredetail.pl?biblionumber=$biblionumber");
+            my $defaultview = C4::Context->preference('IntranetBiblioDefaultView');
+            my $views = { C4::Search::enabled_staff_search_views };
+            if ($defaultview eq 'isbd' && $views->{can_view_ISBD}) {
+                print $input->redirect("/cgi-bin/koha/catalogue/ISBDdetail.pl?biblionumber=$biblionumber");
+            } elsif  ($defaultview eq 'marc' && $views->{can_view_MARC}) {
+                print $input->redirect("/cgi-bin/koha/catalogue/MARCdetail.pl?biblionumber=$biblionumber");
+            } elsif  ($defaultview eq 'labeled_marc' && $views->{can_view_labeledMARC}) {
+                print $input->redirect("/cgi-bin/koha/catalogue/labeledMARCdetail.pl?biblionumber=$biblionumber");
+            } else {
+                print $input->redirect("/cgi-bin/koha/catalogue/detail.pl?biblionumber=$biblionumber");
+            }
             exit;
         }
        }
@@ -545,27 +633,31 @@ my @fields = $temp->fields();
 
 
 my @hostitemnumbers;
-my $analyticfield = '773';
-if ($marcflavour  eq 'MARC21' || $marcflavour eq 'NORMARC') {
-    $analyticfield = '773';
-} elsif ($marcflavour eq 'UNIMARC') {
-    $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'));
+if ( C4::Context->preference('EasyAnalyticalRecords') ) {
+    my $analyticfield = '773';
+    if ($marcflavour  eq 'MARC21' || $marcflavour eq 'NORMARC') {
+        $analyticfield = '773';
+    } elsif ($marcflavour eq 'UNIMARC') {
+        $analyticfield = '461';
+    }
+    foreach my $hostfield ($temp->field($analyticfield)){
+        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'));
+                    }
+                }
             }
         }
     }
 }
 
 
-
 foreach my $field (@fields) {
     next if ( $field->tag() < 10 );
 
@@ -596,18 +688,21 @@ foreach my $field (@fields) {
             }
         }
         $this_row{itemnumber} = $subfieldvalue if ($field->tag() eq $itemtagfield && $subfieldcode eq $itemtagsubfield);
-       foreach my $hostitemnumber (@hostitemnumbers){
+
+       if ( C4::Context->preference('EasyAnalyticalRecords') ) {
+           foreach my $hostitemnumber (@hostitemnumbers){
                if ($this_row{itemnumber} eq $hostitemnumber){
                        $this_row{hostitemflag} = 1;
                        $this_row{hostbiblionumber}= GetBiblionumberFromItemnumber($hostitemnumber);
                        last;
                }
-       }
+           }
 
-#      my $countanalytics=GetAnalyticsCount($this_row{itemnumber});
-#        if ($countanalytics > 0){
+#          my $countanalytics=GetAnalyticsCount($this_row{itemnumber});
+#           if ($countanalytics > 0){
 #                $this_row{countanalytics} = $countanalytics;
-#        }
+#           }
+       }
 
     }
     if (%this_row) {
@@ -650,10 +745,7 @@ my $onlymine = C4::Context->preference('IndependantBranches') &&
                C4::Context->userenv                           && 
                C4::Context->userenv->{flags}!=1               && 
                C4::Context->userenv->{branch};
-my $branch = C4::Context->userenv->{branch};
-if ($frameworkcode eq 'FA'){
-    $branch = $input->param('branch');
-}    
+my $branch = $input->param('branch') || C4::Context->userenv->{branch};
 my $branches = GetBranchesLoop($branch,$onlymine);  # build once ahead of time, instead of multiple times later.
 
 # We generate form, from actuel record
@@ -670,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";
@@ -683,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);
@@ -710,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,
 );