Bug 9988 - DBRev 16.12.00.023
[koha.git] / installer / data / mysql / updatedatabase.pl
index 54a29a1..19b360d 100755 (executable)
@@ -47,7 +47,7 @@ use MARC::File::XML ( BinaryEncoding => 'utf8' );
 
 use File::Path qw[remove_tree]; # perl core module
 use File::Spec;
-use Path::Tiny;
+use File::Slurp;
 
 # FIXME - The user might be installing a new database, so can't rely
 # on /etc/koha.conf anyway.
@@ -8476,6 +8476,7 @@ $DBversion = "3.15.00.049";
 if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) {
     $dbh->do("ALTER TABLE biblioitems DROP INDEX isbn");
     $dbh->do("ALTER TABLE biblioitems DROP INDEX issn");
+    $dbh->do("ALTER TABLE biblioitems DROP INDEX issn_idx");
     $dbh->do("ALTER TABLE biblioitems
               CHANGE isbn isbn MEDIUMTEXT NULL DEFAULT NULL,
               CHANGE issn issn MEDIUMTEXT NULL DEFAULT NULL
@@ -9735,6 +9736,7 @@ if ( CheckVersion($DBversion) ) {
                     MODIFY COLUMN seealso varchar(1100) COLLATE utf8_unicode_ci DEFAULT NULL,
                     MODIFY COLUMN link varchar(80) COLLATE utf8_unicode_ci DEFAULT NULL
                 |);
+                $dbh->do(qq|ALTER TABLE $name CHARACTER SET utf8 COLLATE utf8_unicode_ci|);
             }
             else {
                 $dbh->do(qq|ALTER TABLE $name CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci|);
@@ -10420,15 +10422,21 @@ if ( CheckVersion($DBversion) ) {
 
 $DBversion = "3.19.00.041";
 if ( CheckVersion($DBversion) ) {
-    $dbh->do(q|
-        ALTER IGNORE TABLE suggestions ADD KEY status (STATUS)
-    |);
-    $dbh->do(q|
-        ALTER IGNORE TABLE suggestions ADD KEY biblionumber (biblionumber)
-    |);
-    $dbh->do(q|
-        ALTER IGNORE TABLE suggestions ADD KEY branchcode (branchcode)
-    |);
+    unless ( index_exists( 'suggestions', 'status' ) ) {
+        $dbh->do(q|
+            ALTER TABLE suggestions ADD KEY status (STATUS)
+        |);
+    }
+    unless ( index_exists( 'suggestions', 'biblionumber' ) ) {
+        $dbh->do(q|
+            ALTER TABLE suggestions ADD KEY biblionumber (biblionumber)
+        |);
+    }
+    unless ( index_exists( 'suggestions', 'branchcode' ) ) {
+        $dbh->do(q|
+            ALTER TABLE suggestions ADD KEY branchcode (branchcode)
+        |);
+    }
     print "Upgrade to $DBversion done (Bug 14132: suggestions table is missing indexes)\n";
     SetVersion ($DBversion);
 }
@@ -10442,12 +10450,14 @@ if ( CheckVersion($DBversion) ) {
         WHERE auth_types.authtypecode IS NULL
     });
 
-    $dbh->do(q{
-        ALTER IGNORE TABLE auth_subfield_structure
-        ADD CONSTRAINT auth_subfield_structure_ibfk_1
-        FOREIGN KEY (authtypecode) REFERENCES auth_types(authtypecode)
-        ON DELETE CASCADE ON UPDATE CASCADE
-    });
+    unless ( foreign_key_exists( 'auth_subfield_structure', 'auth_subfield_structure_ibfk_1' ) ) {
+        $dbh->do(q{
+            ALTER TABLE auth_subfield_structure
+            ADD CONSTRAINT auth_subfield_structure_ibfk_1
+            FOREIGN KEY (authtypecode) REFERENCES auth_types(authtypecode)
+            ON DELETE CASCADE ON UPDATE CASCADE
+        });
+    }
 
     print "Upgrade to $DBversion done (Bug 8480: Add foreign key on auth_subfield_structure.authtypecode)\n";
     SetVersion($DBversion);
@@ -10563,31 +10573,58 @@ if ( CheckVersion($DBversion) ) {
 
 $DBversion = "3.21.00.007";
 if ( CheckVersion($DBversion) ) {
-    $dbh->do(q|
-        ALTER IGNORE TABLE aqbasket
-            ADD KEY authorisedby (authorisedby)
-    |);
-    $dbh->do(q|
-        ALTER IGNORE TABLE aqbooksellers
-            ADD KEY name (name(255))
-    |);
-    $dbh->do(q|
-        ALTER IGNORE TABLE aqbudgets
-            ADD KEY budget_parent_id (budget_parent_id),
-            ADD KEY budget_code (budget_code),
-            ADD KEY budget_branchcode (budget_branchcode),
-            ADD KEY budget_period_id (budget_period_id),
-            ADD KEY budget_owner_id (budget_owner_id)
-    |);
-    $dbh->do(q|
-        ALTER IGNORE TABLE aqbudgets_planning
-            ADD KEY budget_period_id (budget_period_id)
-    |);
-    $dbh->do(q|
-        ALTER IGNORE TABLE aqorders
-            ADD KEY parent_ordernumber (parent_ordernumber),
-            ADD KEY orderstatus (orderstatus)
-    |);
+    unless ( index_exists( 'aqbasket', 'authorisedby' ) ) {
+        $dbh->do(q|
+            ALTER TABLE aqbasket
+                ADD KEY authorisedby (authorisedby)
+        |);
+    }
+    unless ( index_exists( 'aqbooksellers', 'name' ) ) {
+        $dbh->do(q|
+            ALTER TABLE aqbooksellers
+                ADD KEY name (name(255))
+        |);
+    }
+    unless ( index_exists( 'aqbudgets', 'budget_parent_id' ) ) {
+        $dbh->do(q|
+            ALTER TABLE aqbudgets
+                ADD KEY budget_parent_id (budget_parent_id)|);
+        }
+    unless ( index_exists( 'aqbudgets', 'budget_code' ) ) {
+        $dbh->do(q|
+            ALTER TABLE aqbudgets
+                ADD KEY budget_code (budget_code)|);
+    }
+    unless ( index_exists( 'aqbudgets', 'budget_branchcode' ) ) {
+        $dbh->do(q|
+            ALTER TABLE aqbudgets
+                ADD KEY budget_branchcode (budget_branchcode)|);
+    }
+    unless ( index_exists( 'aqbudgets', 'budget_period_id' ) ) {
+        $dbh->do(q|
+            ALTER TABLE aqbudgets
+                ADD KEY budget_period_id (budget_period_id)|);
+    }
+    unless ( index_exists( 'aqbudgets', 'budget_owner_id' ) ) {
+        $dbh->do(q|
+            ALTER TABLE aqbudgets
+                ADD KEY budget_owner_id (budget_owner_id)|);
+    }
+    unless ( index_exists( 'aqbudgets_planning', 'budget_period_id' ) ) {
+        $dbh->do(q|
+            ALTER TABLE aqbudgets_planning
+                ADD KEY budget_period_id (budget_period_id)|);
+    }
+    unless ( index_exists( 'aqorders', 'parent_ordernumber' ) ) {
+        $dbh->do(q|
+            ALTER TABLE aqorders
+                ADD KEY parent_ordernumber (parent_ordernumber)|);
+    }
+    unless ( index_exists( 'aqorders', 'orderstatus' ) ) {
+        $dbh->do(q|
+            ALTER TABLE aqorders
+                ADD KEY orderstatus (orderstatus)|);
+    }
     print "Upgrade to $DBversion done (Bug 14053: Acquisition db tables are missing indexes)\n";
     SetVersion ($DBversion);
 }
@@ -10688,9 +10725,12 @@ if ( CheckVersion($DBversion) ) {
         INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type)
         VALUES ('OAI-PMH:DeletedRecord','persistent','Koha\'s deletedbiblio table will never be deleted (persistent) or might be deleted (transient)','transient|persistent','Choice')
     });
-    $dbh->do(q|
-        ALTER TABLE oai_sets_biblios DROP FOREIGN KEY oai_sets_biblios_ibfk_1
-    |);
+
+    if ( foreign_key_exists( 'oai_sets_biblios', 'oai_sets_biblios_ibfk_1' ) ) {
+        $dbh->do(q|
+            ALTER TABLE oai_sets_biblios DROP FOREIGN KEY oai_sets_biblios_ibfk_1
+        |);
+    }
     print "Upgrade to $DBversion done (Bug 3206: OAI repository deleted record support)\n";
     SetVersion ($DBversion);
 }
@@ -10771,12 +10811,14 @@ if ( CheckVersion($DBversion) ) {
 
 $DBversion = "3.21.00.019";
 if ( CheckVersion($DBversion) ) {
-    $dbh->do(q{
-        ALTER TABLE reserves DROP constrainttype
-    });
-    $dbh->do(q{
-        ALTER TABLE old_reserves DROP constrainttype
-    });
+    if ( column_exists( 'reserves', 'constrainttype' ) ) {
+        $dbh->do(q{
+            ALTER TABLE reserves DROP constrainttype
+        });
+        $dbh->do(q{
+            ALTER TABLE old_reserves DROP constrainttype
+        });
+    }
     $dbh->do(q{
         DROP TABLE IF EXISTS reserveconstraints
     });
@@ -10816,12 +10858,14 @@ if ( CheckVersion($DBversion) ) {
     my ($print_error) = $dbh->{PrintError};
     $dbh->{RaiseError} = 0;
     $dbh->{PrintError} = 0;
-    $dbh->do(q{ALTER TABLE course_reserves DROP FOREIGN KEY course_reserves_ibfk_2});
-    $dbh->do(q{ALTER TABLE course_reserves DROP INDEX course_reserves_ibfk_2});
+    if ( foreign_key_exists('course_reserves', 'course_reserves_ibfk_2') ) {
+        $dbh->do(q{ALTER TABLE course_reserves DROP FOREIGN KEY course_reserves_ibfk_2});
+        $dbh->do(q{ALTER TABLE course_reserves DROP INDEX course_reserves_ibfk_2});
+    }
     $dbh->{PrintError} = $print_error;
 
     $dbh->do(q{
-        ALTER IGNORE TABLE course_reserves
+        ALTER TABLE course_reserves
             ADD CONSTRAINT course_reserves_ibfk_2
                 FOREIGN KEY (ci_id) REFERENCES course_items (ci_id)
                 ON DELETE CASCADE ON UPDATE CASCADE
@@ -10915,28 +10959,32 @@ if ( CheckVersion($DBversion) ) {
 
 $DBversion = "3.21.00.028";
 if ( CheckVersion($DBversion) ) {
-    $dbh->do(q{
-        ALTER TABLE uploaded_files
-            ADD COLUMN public tinyint,
-            ADD COLUMN permanent tinyint
-    });
-    $dbh->do(q{
-        UPDATE uploaded_files SET public=1, permanent=1
-    });
-    $dbh->do(q{
-        ALTER TABLE uploaded_files
-            CHANGE COLUMN categorycode uploadcategorycode tinytext
-    });
+    unless ( column_exists('uploaded_files', 'public') ) {
+        $dbh->do(q{
+            ALTER TABLE uploaded_files
+                ADD COLUMN public tinyint,
+                ADD COLUMN permanent tinyint
+        });
+        $dbh->do(q{
+            UPDATE uploaded_files SET public=1, permanent=1
+        });
+        $dbh->do(q{
+            ALTER TABLE uploaded_files
+                CHANGE COLUMN categorycode uploadcategorycode tinytext
+        });
+    }
     print "Upgrade to $DBversion done (Bug 14321: Merge UploadedFile and UploadedFiles into Koha::Upload)\n";
     SetVersion($DBversion);
 }
 
 $DBversion = "3.21.00.029";
 if ( CheckVersion($DBversion) ) {
-    $dbh->do(q{
-        ALTER IGNORE TABLE discharges
-            ADD COLUMN discharge_id int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST
-    });
+    unless ( column_exists('discharges', 'discharge_id') ) {
+        $dbh->do(q{
+            ALTER TABLE discharges
+                ADD COLUMN discharge_id int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST
+        });
+    }
     print "Upgrade to $DBversion done (Bug 14368: Add discharges history)\n";
     SetVersion($DBversion);
 }
@@ -11469,13 +11517,19 @@ if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) {
         ADD serialseq_z VARCHAR( 100 ) NULL DEFAULT NULL AFTER serialseq_y
    ");
 
-    my $schema        = Koha::Database->new()->schema();
-    my @subscriptions = $schema->resultset('Subscription')->all();
+    my $sth = $dbh->prepare("SELECT * FROM subscription");
+    $sth->execute();
+
+    my $sth2 = $dbh->prepare("SELECT * FROM subscription_numberpatterns WHERE id = ?");
+
+    my $sth3 = $dbh->prepare("UPDATE serial SET serialseq_x = ?, serialseq_y = ?, serialseq_z = ? WHERE serialid = ?");
 
-    foreach my $subscription (@subscriptions) {
-        my $number_pattern = $subscription->numberpattern();
+    foreach my $subscription ( $sth->fetchrow_hashref() ) {
+        next if !defined($subscription);
+        $sth2->execute( $subscription->{numberpattern} );
+        my $number_pattern = $sth2->fetchrow_hashref();
 
-        my $numbering_method = $number_pattern->numberingmethod();
+        my $numbering_method = $number_pattern->{numberingmethod};
         # Get all the data between the enumeration values, we need
         # to split each enumeration string based on these values.
         my @splits = split( /\{[XYZ]\}/, $numbering_method );
@@ -11487,12 +11541,15 @@ if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) {
         }
         my @indexes = sort { $indexes{$a} <=> $indexes{$b} } keys(%indexes);
 
-        my @serials =
-          $schema->resultset('Serial')
-          ->search( { subscriptionid => $subscription->subscriptionid() } );
+        my @serials = @{
+            $dbh->selectall_arrayref(
+                "SELECT * FROM serial WHERE subscriptionid = $subscription->{subscriptionid}",
+                { Slice => {} }
+            )
+        };
 
         foreach my $serial (@serials) {
-            my $serialseq = $serial->serialseq();
+            my $serialseq = $serial->{serialseq};
             my %enumeration_data;
 
             ## We cannot split on multiple values at once,
@@ -11514,12 +11571,11 @@ if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) {
                 $enumeration_data{ $indexes[0] } = $serialseq;
             }
 
-            $serial->update(
-                {
-                    serialseq_x => $enumeration_data{'X'},
-                    serialseq_y => $enumeration_data{'Y'},
-                    serialseq_z => $enumeration_data{'Z'},
-                }
+            $sth3->execute(
+                    $enumeration_data{'X'},
+                    $enumeration_data{'Y'},
+                    $enumeration_data{'Z'},
+                    $serial->{serialid},
             );
         }
     }
@@ -12265,9 +12321,9 @@ if ( $column_has_been_used ) {
 
 $DBversion = "3.23.00.050";
 if ( CheckVersion($DBversion) ) {
-    use YAML::Syck;
     use Koha::SearchMarcMaps;
     use Koha::SearchFields;
+    use Koha::SearchEngine::Elasticsearch;
 
     $dbh->do(q|INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type)
                     VALUES('SearchEngine','Zebra','Choose Search Engine','','Choice')|);
@@ -12283,7 +12339,7 @@ if ( CheckVersion($DBversion) ) {
              `id` int(11) NOT NULL AUTO_INCREMENT, 
              `name` varchar(255) NOT NULL COMMENT 'the name of the field as it will be stored in the search engine',
              `label` varchar(255) NOT NULL COMMENT 'the human readable name of the field, for display', 
-             `type` ENUM('string', 'date', 'number', 'boolean', 'sum') NOT NULL COMMENT 'what type of data this holds, relevant when storing it in the search engine',
+             `type` ENUM('', 'string', 'date', 'number', 'boolean', 'sum') NOT NULL COMMENT 'what type of data this holds, relevant when storing it in the search engine',
              PRIMARY KEY (`id`),
              UNIQUE KEY (`name`)
              ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
@@ -12329,21 +12385,8 @@ $dbh->do(q|
             ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
         |);
 
-my $mappings_yaml = C4::Context->config('intranetdir') . '/admin/searchengine/elasticsearch/mappings.yaml';
-my $indexes = LoadFile( $mappings_yaml );
-
-while ( my ( $index_name, $fields ) = each %$indexes ) {
-        while ( my ( $field_name, $data ) = each %$fields ) {
-            my $field_type = $data->{type};
-            my $field_label = $data->{label};
-            my $mappings = $data->{mappings};
-            my $search_field = Koha::SearchFields->find_or_create({ name => $field_name, label => $field_label, type => $field_type }, { key => 'name' });
-            for my $mapping ( @$mappings ) {
-                my $marc_field = Koha::SearchMarcMaps->find_or_create({ index_name => $index_name, marc_type => $mapping->{marc_type}, marc_field => $mapping->{marc_field} });
-                $search_field->add_to_search_marc_maps($marc_field, { facet => $mapping->{facet}, suggestible => $mapping->{suggestible}, sort => $mapping->{sort} } );
-            }
-        }
-}
+        # Insert default mappings
+        Koha::SearchEngine::Elasticsearch->reset_elasticsearch_mappings;
 
 print "Upgrade to $DBversion done (Bug 12478 - Elasticsearch support for Koha)\n";
     SetVersion($DBversion);
@@ -12580,6 +12623,9 @@ SetVersion($DBversion);
 
 $DBversion = "3.23.00.063";
 if ( CheckVersion($DBversion) ) {
+    $dbh->do(q{
+        UPDATE letter SET branchcode='' WHERE branchcode IS NULL;
+    });
     $dbh->do(q{
         ALTER TABLE letter MODIFY COLUMN branchcode varchar(10) NOT NULL DEFAULT ''
     });
@@ -12623,18 +12669,20 @@ if ( CheckVersion($DBversion) ) {
 
 $DBversion = "16.06.00.002";
 if ( CheckVersion($DBversion) ) {
-    $dbh->do(q{
-        ALTER TABLE borrowers
-            ADD COLUMN updated_on timestamp NULL DEFAULT CURRENT_TIMESTAMP
-            ON UPDATE CURRENT_TIMESTAMP
-            AFTER privacy_guarantor_checkouts;
-    });
-    $dbh->do(q{
-        ALTER TABLE deletedborrowers
-            ADD COLUMN updated_on timestamp NULL DEFAULT CURRENT_TIMESTAMP
-            ON UPDATE CURRENT_TIMESTAMP
-            AFTER privacy_guarantor_checkouts;
-    });
+    unless ( column_exists('borrowers', 'updated_on') ) {
+        $dbh->do(q{
+            ALTER TABLE borrowers
+                ADD COLUMN updated_on timestamp NULL DEFAULT CURRENT_TIMESTAMP
+                ON UPDATE CURRENT_TIMESTAMP
+                AFTER privacy_guarantor_checkouts;
+        });
+        $dbh->do(q{
+            ALTER TABLE deletedborrowers
+                ADD COLUMN updated_on timestamp NULL DEFAULT CURRENT_TIMESTAMP
+                ON UPDATE CURRENT_TIMESTAMP
+                AFTER privacy_guarantor_checkouts;
+        });
+    }
 
     print "Upgrade to $DBversion done (Bug 10459 - borrowers should have a timestamp)\n";
     SetVersion($DBversion);
@@ -12926,6 +12974,1140 @@ if ( CheckVersion($DBversion) ) {
     SetVersion($DBversion);
 }
 
+$DBversion = "16.06.00.023";
+if ( CheckVersion($DBversion) ) {
+    my $pref = C4::Context->preference('timeout');
+    if( !$pref || $pref eq '12000000' ) {
+        # update if pref is null or equals old default value
+        $dbh->do(q|
+            UPDATE systempreferences SET value = '1d', type = 'Free'
+            WHERE variable = 'timeout'
+        |);
+        print "Upgrade to $DBversion done (Bug 17187)\nNote: Pref value for timeout has been adjusted.\n";
+    } else {
+        # only update pref type
+        $dbh->do(q|
+            UPDATE systempreferences SET type = 'Free'
+            WHERE variable = 'timeout'
+        |);
+        print "Upgrade to $DBversion done (Bug 17187)\nNote: Pref value for timeout has not been adjusted.\n";
+    }
+    SetVersion($DBversion);
+}
+
+$DBversion = "16.06.00.024";
+if ( CheckVersion($DBversion) ) {
+    $dbh->do(q{
+        UPDATE language_descriptions SET description = 'Română' WHERE subtag = 'ro' AND type = 'language' AND lang = 'ro';
+    });
+
+    print "Upgrade to $DBversion done (Bug 16311 - Advanced search language limit typo for Romanian)\n";
+    SetVersion($DBversion);
+}
+
+$DBversion = "16.06.00.025";
+if ( CheckVersion($DBversion) ) {
+    $dbh->do(q{
+        ALTER TABLE `subscription` ADD `itemtype` VARCHAR( 10 ) NULL AFTER reneweddate, ADD `previousitemtype` VARCHAR( 10 ) NULL AFTER itemtype;
+    });
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES
+        ('makePreviousSerialAvailable','0','make previous serial automatically available when collecting a new serial. Please note that the item-level_itypes syspref must be set to specific item.','','YesNo');
+    });
+
+    print "Upgrade to $DBversion done (Bug 7677 - Subscriptions: Ability to define default itemtype and automatically change itemtype of older issues on receive of next issue)\n";
+    SetVersion($DBversion);
+}
+
+$DBversion = "16.06.00.026";
+if ( CheckVersion($DBversion) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES ('PatronSelfRegistrationLibraryList', '', 'Only display libraries listed. If empty, all libraries are displayed.', NULL, 'Free');
+    });
+
+    print "Upgrade to $DBversion done (Bug 16274 - Make the selfregistration branchcode selection configurable)\n";
+    SetVersion($DBversion);
+}
+
+$DBversion = "16.06.00.027";
+if ( CheckVersion($DBversion) ) {
+    unless ( column_exists('borrowers', 'lastseen') ) {
+        $dbh->do(q{
+            ALTER TABLE borrowers ADD COLUMN lastseen datetime default NULL AFTER updated_on;
+        });
+        $dbh->do(q{
+            ALTER TABLE deletedborrowers ADD COLUMN lastseen datetime default NULL AFTER updated_on;
+        });
+    }
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES ('TrackLastPatronActivity', '0', 'If set, the field borrowers.lastseen will be updated everytime a patron is seen', NULL, 'YesNo');
+    });
+
+    print "Upgrade to $DBversion done (Bug 16274 - Make the selfregistration branchcode selection configurable)\n";
+    SetVersion($DBversion);
+}
+
+$DBversion = '16.06.00.028';
+if (C4::Context->preference("Version") < TransformToNum($DBversion)) {
+    {
+        print "Attempting upgrade to $DBversion (Bug 17135) ...\n";
+        my $maintenance_script = C4::Context->config("intranetdir") . "/installer/data/mysql/fix_unclosed_nonaccruing_fines_bug17135.pl";
+        system("perl $maintenance_script --confirm");
+
+        print "Upgrade to $DBversion done (Bug 17135 - Fine for the previous overdue may get overwritten by the next one)\n";
+
+        unless ($original_version < TransformToNum("3.23.00.032")) { ## Bug 15675
+            print "WARNING: There is a possibility (= just a possibility, it's configuration dependent etc.) that - due to regression introduced by Bug 15675 - some old fine records for overdued items (items which got renewed 1+ time while being overdue) may have been overwritten in your production 16.05+ database. See Bugzilla reports for Bug 14390 and Bug 17135 for more details.\n";
+            print "WARNING: Please note that this upgrade does not try to recover such overwitten old fine records (if any) - it's just an follow-up for Bug 14390, its sole purpose is preventing eventual further-on overwrites from happening in the future. Optional recovery of the overwritten fines (again, if any) is like, totally outside of the scope of this particular upgrade!\n";
+        }
+        SetVersion ($DBversion);
+    }
+}
+
+$DBversion = "16.06.00.029";
+if ( CheckVersion($DBversion) ) {
+    $dbh->do(q{
+        UPDATE systempreferences SET type="Choice" WHERE variable="UsageStatsLibraryType";
+    });
+    $dbh->do(q{
+        UPDATE systempreferences SET value="Canada" WHERE variable="UsageStatsCountry" AND value="CANADA";
+    });
+    $dbh->do(q{
+        UPDATE systempreferences SET value="Czech Republic" WHERE variable="UsageStatsCountry" AND value="CZ";
+    });
+    $dbh->do(q{
+        UPDATE systempreferences SET value="United Kingdom" WHERE variable="UsageStatsCountry" AND (value="England" OR value="UK");
+    });
+    $dbh->do(q{
+        UPDATE systempreferences SET value="Spain" WHERE variable="UsageStatsCountry" AND value="España";
+    });
+    $dbh->do(q{
+        UPDATE systempreferences SET value="Greece" WHERE variable="UsageStatsCountry" AND value="GR";
+    });
+    $dbh->do(q{
+        UPDATE systempreferences SET value="Ireland" WHERE variable="UsageStatsCountry" AND value="Irelanbd";
+    });
+    $dbh->do(q{
+        UPDATE systempreferences SET value="Mexico" WHERE variable="UsageStatsCountry" AND value="México";
+    });
+    $dbh->do(q{
+        UPDATE systempreferences SET value="Peru" WHERE variable="UsageStatsCountry" AND value="Perú";
+    });
+    $dbh->do(q{
+        UPDATE systempreferences SET value="Dominican Rep." WHERE variable="UsageStatsCountry" AND value="República Dominicana";
+    });
+    $dbh->do(q{
+        UPDATE systempreferences SET value="Trinidad & Tob." WHERE variable="UsageStatsCountry" AND value="Trinidad";
+    });
+    $dbh->do(q{
+        UPDATE systempreferences SET value="Turkey" WHERE variable="UsageStatsCountry" AND value="Türkiye";
+    });
+    $dbh->do(q{
+        UPDATE systempreferences SET value="USA" WHERE variable="UsageStatsCountry" AND (value="United States" OR value="United States of America" OR value="US");
+    });
+    $dbh->do(q{
+        UPDATE systempreferences SET value="Zimbabwe" WHERE variable="UsageStatsCountry" AND value="Zimbabbwe";
+    });
+
+    print "Upgrade to $DBversion done (Bug 14707 - Change UsageStatsCountry from free text to a dropdown list)\n";
+    SetVersion($DBversion);
+}
+
+$DBversion = "16.06.00.030";
+if ( CheckVersion($DBversion) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `type` ) VALUES
+        ('OPACHoldingsDefaultSortField','first_column','first_column|homebranch|holdingbranch','Default sort field for the holdings table at the OPAC','choice');
+    });
+
+    print "Upgrade to $DBversion done (Bug 16552 - Add the ability to change the default holdings sort)\n";
+    SetVersion($DBversion);
+}
+
+$DBversion = "16.06.00.031";
+if ( CheckVersion($DBversion) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES ('PatronSelfRegistrationPrefillForm', '1', 'Display password and prefill login form after a patron has self registered', NULL, 'YesNo');
+    });
+
+    print "Upgrade to $DBversion done (Bug 16273 - Prevent selfregistration from printing the borrower password and filling the logging form)\n";
+    SetVersion($DBversion);
+}
+
+$DBversion = "16.06.00.032";
+if ( CheckVersion($DBversion) ) {
+    $dbh->do(q{
+        UPDATE marc_subfield_structure SET authorised_value="WITHDRAWN" WHERE authorised_value="WTHDRAWN";
+    });
+
+    print "Upgrade to $DBversion done (Bug 17357 - WTHDRAWN is still used in installer files)\n";
+    SetVersion($DBversion);
+}
+
+
+$DBversion = "16.06.00.033";
+if ( CheckVersion($DBversion) ) {
+    $dbh->do(q{
+        CREATE TABLE authorised_value_categories (
+        category_name VARCHAR(32) NOT NULL,
+        primary key (category_name)
+        ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+        });
+## Add authorised value categories
+    $dbh->do(q{
+    INSERT INTO authorised_value_categories (category_name )
+    SELECT DISTINCT category FROM authorised_values;
+    });
+    
+## Add special categories
+    $dbh->do(q{
+    INSERT IGNORE INTO authorised_value_categories( category_name )
+    VALUES
+    ('Asort1'),
+    ('Asort2'),
+    ('Bsort1'),
+    ('Bsort2'),
+    ('SUGGEST'),
+    ('DAMAGED'),
+    ('LOST'),
+    ('REPORT_GROUP'),
+    ('REPORT_SUBGROUP'),
+    ('DEPARTMENT'),
+    ('TERM'),
+    ('SUGGEST_STATUS'),
+    ('ITEMTYPECAT');
+    });
+
+## Add very special categories
+    $dbh->do(q{
+    INSERT IGNORE INTO authorised_value_categories( category_name )
+    VALUES
+    ('branches'),
+    ('itemtypes'),
+    ('cn_source');
+    });
+
+    $dbh->do(q{
+    INSERT IGNORE INTO authorised_value_categories( category_name )
+    VALUES
+    ('WITHDRAWN'),
+    ('RESTRICTED'),
+    ('NOT_LOAN'),
+    ('CCODE'),
+    ('LOC'),
+    ('STACK');
+    });
+
+## Update the FK
+    $dbh->do(q{
+    ALTER TABLE items_search_fields
+    DROP FOREIGN KEY items_search_fields_authorised_values_category;
+    });
+
+    $dbh->do(q{
+    ALTER TABLE items_search_fields
+    ADD CONSTRAINT `items_search_fields_authorised_values_category` FOREIGN KEY (`authorised_values_category`) REFERENCES `authorised_value_categories` (`category_name`) ON DELETE SET NULL ON UPDATE CASCADE;
+    });
+
+    $dbh->do(q{
+    ALTER TABLE authorised_values
+    ADD CONSTRAINT `authorised_values_authorised_values_category` FOREIGN KEY (`category`) REFERENCES `authorised_value_categories` (`category_name`) ON DELETE CASCADE ON UPDATE CASCADE;
+    });
+
+    $dbh->do(q{
+            INSERT IGNORE INTO authorised_value_categories( category_name ) SELECT DISTINCT(authorised_value) FROM marc_subfield_structure;
+            });
+
+    $dbh->do(q{
+            UPDATE marc_subfield_structure SET authorised_value = NULL WHERE authorised_value = '';
+            });
+
+    # If the DB has been created before 3.19.00.006, the default collate for marc_subfield_structure if not set to utf8_unicode_ci and the new FK will not be create (MariaDB or MySQL will raise err 150)
+    my $table_sth = $dbh->prepare(qq|SHOW CREATE TABLE marc_subfield_structure|);
+    $table_sth->execute;
+    my @table = $table_sth->fetchrow_array;
+    if ( $table[1] !~ /COLLATE=utf8_unicode_ci/ and $table[1] !~ /COLLATE=utf8mb4_unicode_ci/ ) { #catches utf8mb4 collated tables
+        $dbh->do(qq|ALTER TABLE marc_subfield_structure CHARACTER SET utf8 COLLATE utf8_unicode_ci|);
+    }
+    $dbh->do(q{
+            ALTER TABLE marc_subfield_structure
+            MODIFY COLUMN authorised_value VARCHAR(32) DEFAULT NULL,
+            ADD CONSTRAINT marc_subfield_structure_ibfk_1 FOREIGN KEY (authorised_value) REFERENCES authorised_value_categories (category_name) ON UPDATE CASCADE ON DELETE SET NULL;
+            });
+
+      print "Upgrade to $DBversion done (Bug 17216 - Add a new table to store authorized value categories)\n";
+      SetVersion($DBversion);
+}
+
+$DBversion = "16.06.00.034";
+if ( CheckVersion($DBversion) ) {
+    $dbh->do(q{
+        ALTER TABLE biblioitems DROP COLUMN marc;
+    });
+    $dbh->do(q{
+        ALTER TABLE deletedbiblioitems DROP COLUMN marc;
+    });
+
+    print "Upgrade to $DBversion done (Bug 10455 - remove redundant 'biblioitems.marc' field)\n";
+    SetVersion($DBversion);
+}
+
+$DBversion = '16.06.00.035';
+if ( CheckVersion($DBversion) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences ( variable, value, options, explanation, type )
+         SELECT 'AllowItemsOnHoldCheckoutSCO',COALESCE(value,0),'','Do not generate RESERVE_WAITING and RESERVED warning in the SCO module when checking out items reserved to someone else. This allows self checkouts for those items.','YesNo'
+         FROM systempreferences WHERE variable='AllowItemsOnHoldCheckout';
+    });
+
+    print "Upgrade to $DBversion done (Bug 15131: Give SCO separate control for AllowItemsOnHoldCheckout)\n";
+    SetVersion($DBversion);
+}
+
+$DBversion = '16.06.00.036';
+if ( CheckVersion($DBversion) ) {
+    $dbh->do(q{
+        CREATE TABLE IF NOT EXISTS `housebound_profile` (
+          `borrowernumber` int(11) NOT NULL, -- Number of the borrower associated with this profile.
+          `day` text NOT NULL,  -- The preferred day of the week for delivery.
+          `frequency` text NOT NULL, -- The Authorised_Value definining the pattern for delivery.
+          `fav_itemtypes` text default NULL, -- Free text describing preferred itemtypes.
+          `fav_subjects` text default NULL, -- Free text describing preferred subjects.
+          `fav_authors` text default NULL, -- Free text describing preferred authors.
+          `referral` text default NULL, -- Free text indicating how the borrower was added to the service.
+          `notes` text default NULL, -- Free text for additional notes.
+          PRIMARY KEY  (`borrowernumber`),
+          CONSTRAINT `housebound_profile_bnfk`
+            FOREIGN KEY (`borrowernumber`)
+            REFERENCES `borrowers` (`borrowernumber`)
+            ON UPDATE CASCADE ON DELETE CASCADE
+        ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+    });
+    $dbh->do(q{
+        CREATE TABLE IF NOT EXISTS `housebound_visit` (
+          `id` int(11) NOT NULL auto_increment, -- ID of the visit.
+          `borrowernumber` int(11) NOT NULL, -- Number of the borrower, & the profile, linked to this visit.
+          `appointment_date` date default NULL, -- Date of visit.
+          `day_segment` varchar(10),  -- Rough time frame: 'morning', 'afternoon' 'evening'
+          `chooser_brwnumber` int(11) default NULL, -- Number of the borrower to choose items  for delivery.
+          `deliverer_brwnumber` int(11) default NULL, -- Number of the borrower to deliver items.
+          PRIMARY KEY  (`id`),
+          CONSTRAINT `houseboundvisit_bnfk`
+            FOREIGN KEY (`borrowernumber`)
+            REFERENCES `housebound_profile` (`borrowernumber`)
+            ON UPDATE CASCADE ON DELETE CASCADE,
+          CONSTRAINT `houseboundvisit_bnfk_1`
+            FOREIGN KEY (`chooser_brwnumber`)
+            REFERENCES `borrowers` (`borrowernumber`)
+            ON UPDATE CASCADE ON DELETE CASCADE,
+          CONSTRAINT `houseboundvisit_bnfk_2`
+            FOREIGN KEY (`deliverer_brwnumber`)
+            REFERENCES `borrowers` (`borrowernumber`)
+            ON UPDATE CASCADE ON DELETE CASCADE
+        ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+    });
+    $dbh->do(q{
+        CREATE TABLE IF NOT EXISTS `housebound_role` (
+          `borrowernumber_id` int(11) NOT NULL, -- borrowernumber link
+          `housebound_chooser` tinyint(1) NOT NULL DEFAULT 0, -- set to 1 to indicate this patron is a housebound chooser volunteer
+          `housebound_deliverer` tinyint(1) NOT NULL DEFAULT 0, -- set to 1 to indicate this patron is a housebound deliverer volunteer
+          PRIMARY KEY (`borrowernumber_id`),
+          CONSTRAINT `houseboundrole_bnfk`
+            FOREIGN KEY (`borrowernumber_id`)
+            REFERENCES `borrowers` (`borrowernumber`)
+            ON UPDATE CASCADE ON DELETE CASCADE
+        ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+    });
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences
+               (variable,value,options,explanation,type) VALUES
+               ('HouseboundModule',0,'',
+               'If ON, enable housebound module functionality.','YesNo');
+    });
+    $dbh->do(q{
+        INSERT IGNORE INTO authorised_value_categories( category_name ) VALUES
+            ('HSBND_FREQ');
+    });
+    $dbh->do(q{
+        INSERT IGNORE INTO authorised_values (category, authorised_value, lib) VALUES
+               ('HSBND_FREQ','EW','Every week');
+    });
+
+    print "Upgrade to $DBversion done (Bug 5670 - Housebound Readers Module)\n";
+    SetVersion($DBversion);
+}
+
+$DBversion = "16.06.00.037";
+if ( CheckVersion($DBversion) ) {
+    $dbh->do(q{
+        ALTER TABLE `issuingrules` ADD `article_requests` ENUM( 'no', 'yes', 'bib_only', 'item_only' ) NOT NULL DEFAULT 'no' AFTER `opacitemholds`;
+    });
+    $dbh->do(q{
+        INSERT INTO `systempreferences` (`variable`, `value`, `options`, `explanation`, `type`) VALUES
+            ('ArticleRequests', '0', NULL, 'Enables the article request feature', 'YesNo'),
+            ('ArticleRequestsMandatoryFields', '', NULL, 'Comma delimited list of required fields for bibs where article requests rule = ''yes''', 'multiple'),
+            ('ArticleRequestsMandatoryFieldsItemsOnly', '', NULL, 'Comma delimited list of required fields for bibs where article requests rule = ''item_only''', 'multiple'),
+            ('ArticleRequestsMandatoryFieldsRecordOnly', '', NULL, 'Comma delimited list of required fields for bibs where article requests rule = ''bib_only''', 'multiple');
+    });
+    $dbh->do(q{
+        CREATE TABLE IF NOT EXISTS `article_requests` (
+          `id` int(11) NOT NULL AUTO_INCREMENT,
+          `borrowernumber` int(11) NOT NULL,
+          `biblionumber` int(11) NOT NULL,
+          `itemnumber` int(11) DEFAULT NULL,
+          `branchcode` varchar(10) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
+          `title` text,
+          `author` text,
+          `volume` text,
+          `issue` text,
+          `date` text,
+          `pages` text,
+          `chapters` text,
+          `patron_notes` text,
+          `status` enum('PENDING','PROCESSING','COMPLETED','CANCELED') NOT NULL DEFAULT 'PENDING',
+          `notes` text,
+          `created_on` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+          `updated_on` timestamp NULL DEFAULT NULL,
+          PRIMARY KEY (`id`),
+          KEY `borrowernumber` (`borrowernumber`),
+          KEY `biblionumber` (`biblionumber`),
+          KEY `itemnumber` (`itemnumber`),
+          KEY `branchcode` (`branchcode`),
+          CONSTRAINT `article_requests_ibfk_1` FOREIGN KEY (`borrowernumber`) REFERENCES `borrowers` (`borrowernumber`) ON DELETE CASCADE ON UPDATE CASCADE,
+          CONSTRAINT `article_requests_ibfk_2` FOREIGN KEY (`biblionumber`) REFERENCES `biblio` (`biblionumber`) ON DELETE CASCADE ON UPDATE CASCADE,
+          CONSTRAINT `article_requests_ibfk_3` FOREIGN KEY (`itemnumber`) REFERENCES `items` (`itemnumber`) ON DELETE SET NULL ON UPDATE CASCADE,
+          CONSTRAINT `article_requests_ibfk_4` FOREIGN KEY (`branchcode`) REFERENCES `branches` (`branchcode`) ON DELETE SET NULL ON UPDATE CASCADE
+        ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+    });
+    $dbh->do(q{
+        INSERT INTO `letter` (`module`, `code`, `branchcode`, `name`, `is_html`, `title`, `content`, `message_transport_type`) VALUES
+        ('circulation', 'AR_CANCELED', '', 'Article Request - Email - Canceled', 0, 'Article Request Canceled', '<<borrowers.firstname>> <<borrowers.surname>> (<<borrowers.cardnumber>>)\r\n\r\nYour request for an article from <<biblio.title>> (<<items.barcode>>) has been canceled for the following reason:\r\n\r\n<<article_requests.notes>>\r\n\r\nArticle requested:\r\nTitle: <<article_requests.title>>\r\nAuthor: <<article_requests.author>>\r\nVolume: <<article_requests.volume>>\r\nIssue: <<article_requests.issue>>\r\nDate: <<article_requests.date>>\r\nPages: <<article_requests.pages>>\r\nChapters: <<article_requests.chapters>>\r\nNotes: <<article_requests.patron_notes>>\r\n', 'email'),
+        ('circulation', 'AR_COMPLETED', '', 'Article Request - Email - Completed', 0, 'Article Request Completed', '<<borrowers.firstname>> <<borrowers.surname>> (<<borrowers.cardnumber>>)\r\n\r\nWe are have completed your request for an article from <<biblio.title>> (<<items.barcode>>).\r\n\r\nArticle requested:\r\nTitle: <<article_requests.title>>\r\nAuthor: <<article_requests.author>>\r\nVolume: <<article_requests.volume>>\r\nIssue: <<article_requests.issue>>\r\nDate: <<article_requests.date>>\r\nPages: <<article_requests.pages>>\r\nChapters: <<article_requests.chapters>>\r\nNotes: <<article_requests.patron_notes>>\r\n\r\nYou may pick your article up at <<branches.branchname>>.\r\n\r\nThank you!', 'email'),
+        ('circulation', 'AR_PENDING', '', 'Article Request - Email - Open', 0, 'Article Request Received', '<<borrowers.firstname>> <<borrowers.surname>> (<<borrowers.cardnumber>>)\r\n\r\nWe have received your request for an article from <<biblio.title>> (<<items.barcode>>).\r\n\r\nArticle requested:\r\nTitle: <<article_requests.title>>\r\nAuthor: <<article_requests.author>>\r\nVolume: <<article_requests.volume>>\r\nIssue: <<article_requests.issue>>\r\nDate: <<article_requests.date>>\r\nPages: <<article_requests.pages>>\r\nChapters: <<article_requests.chapters>>\r\nNotes: <<article_requests.patron_notes>>\r\n\r\n\r\nThank you!', 'email'),
+        ('circulation', 'AR_SLIP', '', 'Article Request - Print Slip', 0, 'Test', 'Article Request:\r\n\r\n<<borrowers.firstname>> <<borrowers.surname>> (<<borrowers.cardnumber>>)\r\n\r\nTitle: <<biblio.title>>\r\nBarcode: <<items.barcode>>\r\n\r\nArticle requested:\r\nTitle: <<article_requests.title>>\r\nAuthor: <<article_requests.author>>\r\nVolume: <<article_requests.volume>>\r\nIssue: <<article_requests.issue>>\r\nDate: <<article_requests.date>>\r\nPages: <<article_requests.pages>>\r\nChapters: <<article_requests.chapters>>\r\nNotes: <<article_requests.patron_notes>>\r\n', 'print'),
+        ('circulation', 'AR_PROCESSING', '', 'Article Request - Email - Processing', 0, 'Article Request Processing', '<<borrowers.firstname>> <<borrowers.surname>> (<<borrowers.cardnumber>>)\r\n\r\nWe are now processing your request for an article from <<biblio.title>> (<<items.barcode>>).\r\n\r\nArticle requested:\r\nTitle: <<article_requests.title>>\r\nAuthor: <<article_requests.author>>\r\nVolume: <<article_requests.volume>>\r\nIssue: <<article_requests.issue>>\r\nDate: <<article_requests.date>>\r\nPages: <<article_requests.pages>>\r\nChapters: <<article_requests.chapters>>\r\nNotes: <<article_requests.patron_notes>>\r\n\r\nThank you!', 'email');
+    });
+
+    print "Upgrade to $DBversion done (Bug 14610 - Add ability to place article requests in Koha)\n";
+    SetVersion($DBversion);
+}
+
+$DBversion = '16.06.00.038';
+if ( CheckVersion($DBversion) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences (variable,value,options,explanation,type) VALUES ('DefaultPatronSearchFields','surname,firstname,othernames,cardnumber,userid',NULL,'Comma separated list defining the default fields to be used during a patron search','free');
+    });
+
+    print "Upgrade to $DBversion done (Bug 14874 - Add ability to search for patrons by date of birth from checkout and patron quick searches)\n";
+    SetVersion($DBversion);
+}
+
+$DBversion = "16.06.00.039";
+if ( CheckVersion($DBversion) ) {
+
+    my $sth = $dbh->prepare(q{
+        SELECT s.itemnumber, i.itype, b.itemtype
+        FROM
+         ( SELECT DISTINCT itemnumber
+           FROM statistics
+           WHERE ( type = "return" OR type = "localuse" ) AND
+                 itemtype IS NULL
+         ) s
+        LEFT JOIN
+         ( SELECT itemnumber,biblionumber, itype
+             FROM items
+           UNION
+           SELECT itemnumber,biblionumber, itype
+             FROM deleteditems
+         ) i
+        ON (s.itemnumber=i.itemnumber)
+        LEFT JOIN
+         ( SELECT biblionumber, itemtype
+             FROM biblioitems
+           UNION
+           SELECT biblionumber, itemtype
+             FROM deletedbiblioitems
+         ) b
+        ON (i.biblionumber=b.biblionumber);
+    });
+    $sth->execute();
+
+    my $update_sth = $dbh->prepare(q{
+        UPDATE statistics
+        SET itemtype=?
+        WHERE itemnumber=? AND itemtype IS NULL
+    });
+    my $ilevel_itypes = C4::Context->preference('item-level_itypes');
+
+    while ( my ($itemnumber,$item_itype,$biblio_itype) = $sth->fetchrow_array ) {
+
+        my $effective_itemtype = $ilevel_itypes
+                                    ? $item_itype // $biblio_itype
+                                    : $biblio_itype;
+        warn "item-level_itypes set but no itype defined for item ($itemnumber)"
+            if $ilevel_itypes and !defined $item_itype;
+        $update_sth->execute( $effective_itemtype, $itemnumber );
+    }
+
+    print "Upgrade to $DBversion done (Bug 14598: itemtype is not set on statistics by C4::Circulation::AddReturn)\n";
+    SetVersion($DBversion);
+}
+
+$DBversion = '16.06.00.040';
+if ( CheckVersion($DBversion) ) {
+    $dbh->do(q{
+        ALTER TABLE `aqcontacts` ADD `orderacquisition` BOOLEAN NOT NULL DEFAULT 0 AFTER `notes`;
+    });
+    $dbh->do(q{
+        INSERT IGNORE INTO `letter` (module, code, name, title, content, message_transport_type) VALUES
+        ('orderacquisition','ACQORDER','Acquisition order','Order','<<aqbooksellers.name>>\r\n<<aqbooksellers.address1>>\r\n<<aqbooksellers.address2>>\r\n<<aqbooksellers.address3>>\r\n<<aqbooksellers.address4>>\r\n<<aqbooksellers.phone>>\r\n\r\nPlease order for the library:\r\n\r\n<order>Ordernumber <<aqorders.ordernumber>> (<<biblio.title>>) (quantity: <<aqorders.quantity>>) ($<<aqorders.listprice>> each).</order>\r\n\r\nThank you,\n\n<<branches.branchname>>', 'email');
+    });
+
+    print "Upgrade to $DBversion done (Bug 5260 - Add option to send an order by e-mail to the acquisition module)\n";
+    SetVersion($DBversion);
+}
+
+$DBversion = '16.06.00.041';
+if ( CheckVersion($DBversion) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES ('AggressiveMatchOnISSN','0','If enabled, attempt to match aggressively by trying all variations of the ISSNs in the imported record as a phrase in the ISSN fields of already cataloged records when matching on ISSN with the record import tool','','YesNo')
+    });
+
+    print "Upgrade to $DBversion done (Bug 14629 - Add aggressive ISSN matching feature equivalent to the aggressive ISBN matcher)\n";
+    SetVersion($DBversion);
+}
+
+$DBversion = '16.06.00.042';
+if ( CheckVersion($DBversion) ) {
+    $dbh->do(q|
+        ALTER TABLE aqorders
+            ADD COLUMN unitprice_tax_excluded decimal(28,6) default NULL AFTER unitprice,
+            ADD COLUMN unitprice_tax_included decimal(28,6) default NULL AFTER unitprice_tax_excluded,
+            ADD COLUMN rrp_tax_excluded decimal(28,6) default NULL AFTER rrp,
+            ADD COLUMN rrp_tax_included decimal(28,6) default NULL AFTER rrp_tax_excluded,
+            ADD COLUMN ecost_tax_excluded decimal(28,6) default NULL AFTER ecost,
+            ADD COLUMN ecost_tax_included decimal(28,6) default NULL AFTER ecost_tax_excluded,
+            ADD COLUMN tax_value decimal(6,4) default NULL AFTER gstrate
+    |);
+
+    # rename gstrate with tax_rate
+    $dbh->do(q|ALTER TABLE aqorders CHANGE COLUMN gstrate tax_rate decimal(6,4) DEFAULT NULL|);
+    $dbh->do(q|ALTER TABLE aqbooksellers CHANGE COLUMN gstrate tax_rate decimal(6,4) DEFAULT NULL|);
+
+    # Fill the new columns
+    my $orders = $dbh->selectall_arrayref(q|
+        SELECT * FROM aqorders
+    |, { Slice => {} } );
+
+    my $sth_update_order = $dbh->prepare(q|
+        UPDATE aqorders
+        SET unitprice_tax_excluded = ?,
+            unitprice_tax_included = ?,
+            rrp_tax_excluded = ?,
+            rrp_tax_included = ?,
+            ecost_tax_excluded = ?,
+            ecost_tax_included = ?,
+            tax_value = ?
+        WHERE ordernumber = ?
+    |);
+
+    my $sth_get_bookseller = $dbh->prepare(q|
+        SELECT aqbooksellers.*
+        FROM aqbooksellers
+        LEFT JOIN aqbasket ON aqbasket.booksellerid = aqbooksellers.id
+        LEFT JOIN aqorders ON aqorders.basketno = aqbasket.basketno
+        WHERE ordernumber = ?
+    |);
+
+    require Koha::Number::Price;
+    for my $order ( @$orders ) {
+        $sth_get_bookseller->execute( $order->{ordernumber} );
+        my ( $bookseller ) = $sth_get_bookseller->fetchrow_hashref;
+        $order->{rrp}   = Koha::Number::Price->new( $order->{rrp} )->round;
+        $order->{ecost} = Koha::Number::Price->new( $order->{ecost} )->round;
+        $order->{tax_rate} ||= 0 ; # tax_rate can be NULL in DB
+        # Ordering
+        if ( $bookseller->{listincgst} ) {
+            $order->{rrp_tax_included} = $order->{rrp};
+            $order->{rrp_tax_excluded} = Koha::Number::Price->new(
+                $order->{rrp_tax_included} / ( 1 + $order->{tax_rate} ) )->round;
+            $order->{ecost_tax_included} = $order->{ecost};
+            $order->{ecost_tax_excluded} = Koha::Number::Price->new(
+                $order->{ecost} / ( 1 + $order->{tax_rate} ) )->round;
+        }
+        else {
+            $order->{rrp_tax_excluded} = $order->{rrp};
+            $order->{rrp_tax_included} = Koha::Number::Price->new(
+                $order->{rrp} * ( 1 + $order->{tax_rate} ) )->round;
+            $order->{ecost_tax_excluded} = $order->{ecost};
+            $order->{ecost_tax_included} = Koha::Number::Price->new(
+                $order->{ecost} * ( 1 + $order->{tax_rate} ) )->round;
+        }
+
+        #receiving
+        if ( $bookseller->{listincgst} ) {
+            $order->{unitprice_tax_included} = Koha::Number::Price->new( $order->{unitprice} )->round;
+            $order->{unitprice_tax_excluded} = Koha::Number::Price->new(
+              $order->{unitprice_tax_included} / ( 1 + $order->{tax_rate} ) )->round;
+        }
+        else {
+            $order->{unitprice_tax_excluded} = Koha::Number::Price->new( $order->{unitprice} )->round;
+            $order->{unitprice_tax_included} = Koha::Number::Price->new(
+              $order->{unitprice_tax_excluded} * ( 1 + $order->{tax_rate} ) )->round;
+        }
+
+        # If the order is received, the tax is calculated from the unit price
+        if ( $order->{orderstatus} eq 'complete' ) {
+            $order->{tax_value} = Koha::Number::Price->new(
+              ( $order->{unitprice_tax_included} - $order->{unitprice_tax_excluded} )
+              * $order->{quantity} )->round;
+        } else {
+            # otherwise the ecost is used
+            $order->{tax_value} = Koha::Number::Price->new(
+                ( $order->{ecost_tax_included} - $order->{ecost_tax_excluded} ) *
+                  $order->{quantity} )->round;
+        }
+
+        $sth_update_order->execute(
+            $order->{unitprice_tax_excluded},
+            $order->{unitprice_tax_included},
+            $order->{rrp_tax_excluded},
+            $order->{rrp_tax_included},
+            $order->{ecost_tax_excluded},
+            $order->{ecost_tax_included},
+            $order->{tax_value},
+            $order->{ordernumber},
+        );
+    }
+
+    print "Upgrade to $DBversion done (Bug 13321 - Tax and prices calculation need to be fixed)\n";
+    SetVersion($DBversion);
+}
+
+$DBversion = '16.06.00.043';
+if ( CheckVersion($DBversion) ) {
+    # Add the new columns
+    $dbh->do(q|
+        ALTER TABLE aqorders
+            ADD COLUMN tax_rate_on_ordering   decimal(6,4) default NULL AFTER tax_rate,
+            ADD COLUMN tax_rate_on_receiving  decimal(6,4) default NULL AFTER tax_rate_on_ordering,
+            ADD COLUMN tax_value_on_ordering  decimal(28,6) default NULL AFTER tax_value,
+            ADD COLUMN tax_value_on_receiving decimal(28,6) default NULL AFTER tax_value_on_ordering
+    |);
+
+    my $orders = $dbh->selectall_arrayref(q|
+        SELECT * FROM aqorders
+    |, { Slice => {} } );
+
+    my $sth_update_order = $dbh->prepare(q|
+        UPDATE aqorders
+        SET tax_rate_on_ordering = tax_rate,
+            tax_rate_on_receiving = tax_rate,
+            tax_value_on_ordering = ?,
+            tax_value_on_receiving = ?
+        WHERE ordernumber = ?
+    |);
+
+    require Koha::Number::Price;
+    for my $order (@$orders) {
+        my $tax_value_on_ordering =
+          $order->{quantity} *
+          $order->{ecost_tax_excluded} *
+          $order->{tax_rate};
+
+        my $tax_value_on_receiving =
+          ( defined $order->{unitprice_tax_excluded} )
+          ? $order->{quantity} * $order->{unitprice_tax_excluded} * $order->{tax_rate}
+          : undef;
+
+        $sth_update_order->execute( $tax_value_on_ordering,
+            $tax_value_on_receiving, $order->{ordernumber} );
+    }
+
+    # Remove the old columns
+    $dbh->do(q|
+        ALTER TABLE aqorders
+            CHANGE COLUMN tax_value tax_value_bak  decimal(28,6) default NULL,
+            CHANGE COLUMN tax_rate tax_rate_bak decimal(6,4) default NULL
+    |);
+
+    print "Upgrade to $DBversion done (Bug 13323 - Change the tax rate on receiving)\n";
+    SetVersion($DBversion);
+}
+
+$DBversion = '16.06.00.044';
+if ( CheckVersion($DBversion) ) {
+    $dbh->do(q{
+        ALTER TABLE `messages`
+        ADD `manager_id` int(11) NULL,
+        ADD FOREIGN KEY (`manager_id`) REFERENCES `borrowers` (`borrowernumber`) ON DELETE SET NULL;
+    });
+
+    print "Upgrade to $DBversion done (Bug 17397 - Show name of librarian who created circulation message)\n";
+    SetVersion($DBversion);
+}
+
+$DBversion = '16.06.00.045';
+if ( CheckVersion($DBversion) ) {
+    $dbh->do(q{
+        UPDATE systempreferences SET options = "now|dateexpiry|combination", explanation = "Set whether the borrower renewal date should be counted from the dateexpiry, from the current date or by combination: if the dateexpiry is in future use dateexpiry, else use current date " WHERE variable = "BorrowerRenewalPeriodBase";
+    });
+
+    print "Upgrade to $DBversion done (Bug 17443 - Make possible to renew patron by later of expiry and current date)\n";
+    SetVersion($DBversion);
+}
+
+$DBversion = '16.06.00.046';
+if ( CheckVersion($DBversion) ) {
+    $dbh->do(q{
+        ALTER TABLE issuingrules ADD COLUMN no_auto_renewal_after INT(4) DEFAULT NULL AFTER auto_renew;
+    });
+
+    print "Upgrade to $DBversion done (Bug 15581 - Add a circ rule to not allow auto-renewals after defined loan period)\n";
+    SetVersion($DBversion);
+}
+
+$DBversion = '16.06.00.047';
+if ( CheckVersion($DBversion) ) {
+    $dbh->do(q{
+        UPDATE language_descriptions SET description = 'Čeština' WHERE subtag = 'cs' AND type = 'language' AND lang = 'cs'
+    });
+
+    print "Upgrade to $DBversion done (Bug 17518: Displayed language name for Czech is wrong)\n";
+    SetVersion($DBversion);
+}
+
+$DBversion = '16.06.00.048';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q|
+        INSERT IGNORE INTO permissions (module_bit, code, description) VALUES
+        (13, 'upload_general_files', 'Upload any file'),
+        (13, 'upload_manage', 'Manage uploaded files');
+    |);
+
+    # Update user_permissions for current users (check count in uploaded_files)
+    # Note 9 == edit_catalogue and 13 == tools
+    # We do not insert if someone is superlibrarian, does not have edit_catalogue,
+    # or already has all tools
+    $dbh->do(q|
+        INSERT IGNORE INTO user_permissions (borrowernumber, module_bit, code)
+        SELECT borrowernumber, 13, 'upload_general_files'
+        FROM borrowers bo
+        WHERE flags<>1 AND flags & POW(2,13) = 0 AND
+            ( flags & POW(2,9) > 0 OR (
+                SELECT COUNT(*) FROM user_permissions
+                WHERE borrowernumber=bo.borrowernumber AND module_bit=9 ) > 0 )
+            AND ( SELECT COUNT(*) FROM uploaded_files ) > 0;
+    |);
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 17663 - Forgotten userpermissions)\n";
+}
+
+$DBversion = '16.06.00.049';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q|
+        INSERT IGNORE INTO systempreferences (variable,value,options,explanation,type) 
+        VALUES ('ReplytoDefault',  '',  NULL,  'The default email address to be set as replyto.',  'Free');
+    |);
+
+    $dbh->do(q|
+        INSERT IGNORE INTO systempreferences (variable,value,options,explanation,type)
+        VALUES ('ReturnpathDefault',  '',  NULL,  'The default email address to be set as return-path',  'Free');
+    |);
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 17391 - ReturnpathDefault and ReplyToDefault missing from syspref.sql)\n";
+}
+
+$DBversion = "16.06.00.050";
+if ( CheckVersion($DBversion) ) {
+
+    # If index issn_idx still exists, we assume that dbrev 3.15.00.049 failed,
+    # and we repeat it (partially).
+    # Note: the db rev only pertains to biblioitems and is not needed for
+    # deletedbiblioitems.
+
+    my $temp = $dbh->selectall_arrayref( "SHOW INDEXES FROM biblioitems WHERE key_name = 'issn_idx'" );
+
+    if( @$temp > 0 ) {
+        $dbh->do( "ALTER TABLE biblioitems DROP INDEX isbn" );
+        $dbh->do( "ALTER TABLE biblioitems DROP INDEX issn" );
+        $dbh->do( "ALTER TABLE biblioitems DROP INDEX issn_idx" );
+        $dbh->do( "ALTER TABLE biblioitems CHANGE isbn isbn MEDIUMTEXT NULL DEFAULT NULL, CHANGE issn issn MEDIUMTEXT NULL DEFAULT NULL" );
+        $dbh->do( "ALTER TABLE biblioitems ADD INDEX isbn ( isbn ( 255 ) ), ADD INDEX issn ( issn ( 255 ) )" );
+        print "Upgrade to $DBversion done (Bug 8835). Removed issn_idx.\n";
+    } else {
+        print "Upgrade to $DBversion done (Bug 8835). Everything is fine.\n";
+    }
+
+    SetVersion($DBversion);
+}
+
+$DBversion = "16.11.00.000";
+if ( CheckVersion($DBversion) ) {
+    print "Upgrade to $DBversion done (Koha 16.11)\n";
+    SetVersion($DBversion);
+}
+
+$DBversion = "16.12.00.000";
+if ( CheckVersion($DBversion) ) {
+    print "Upgrade to $DBversion done (Koha 16.12 - Our battered suitcases were piled on the sidewalk again; we had longer ways to go. But no matter, the road is life.)\n";
+    SetVersion($DBversion);
+}
+
+$DBversion = "16.12.00.001";
+if ( CheckVersion($DBversion) ) {
+    $dbh->do(q{
+        ALTER TABLE borrower_modifications
+        ADD COLUMN extended_attributes text DEFAULT NULL
+        AFTER privacy
+    });
+
+    print "Upgrade to $DBversion done (Bug 17767 - Let Koha::Patron::Modification handle extended attributes)\n";
+    SetVersion($DBversion);
+}
+
+$DBversion = '16.12.00.002';
+if ( CheckVersion($DBversion) ) {
+    unless (column_exists( 'branchtransfers', 'branchtransfer_id' )
+        and index_exists( 'branchtransfers', 'PRIMARY' ) )
+    {
+        $dbh->do(
+            "ALTER TABLE branchtransfers
+                 ADD COLUMN branchtransfer_id int(12) NOT NULL auto_increment FIRST, ADD CONSTRAINT PRIMARY KEY (branchtransfer_id);"
+        );
+    }
+
+    SetVersion($DBversion);
+    print "Upgrade to $DBversion done (Bug 14187 - branchtransfer needs a primary key (id) for DBIx and common sense.)\n";
+}
+
+$DBversion = '16.12.00.003';
+if ( CheckVersion($DBversion) ) {
+    $dbh->do(q{DELETE FROM systempreferences WHERE variable="Persona"});
+    SetVersion($DBversion);
+    print "Upgrade to $DBversion done (Bug 17486 - Remove 'Mozilla Persona' as an authentication method)\n";
+}
+
+$DBversion = '16.12.00.004';
+if ( CheckVersion($DBversion) ) {
+    $dbh->do(q{
+        CREATE TABLE biblio_metadata (
+            `id` INT(11) NOT NULL AUTO_INCREMENT,
+            `biblionumber` INT(11) NOT NULL,
+            `format` VARCHAR(16) NOT NULL,
+            `marcflavour` VARCHAR(16) NOT NULL,
+            `metadata` LONGTEXT NOT NULL,
+            PRIMARY KEY(id),
+            UNIQUE KEY `biblio_metadata_uniq_key` (`biblionumber`,`format`,`marcflavour`),
+            CONSTRAINT `biblio_metadata_fk_1` FOREIGN KEY (biblionumber) REFERENCES biblio (biblionumber) ON DELETE CASCADE ON UPDATE CASCADE
+        ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+    });
+    $dbh->do(q{
+        CREATE TABLE deletedbiblio_metadata (
+            `id` INT(11) NOT NULL AUTO_INCREMENT,
+            `biblionumber` INT(11) NOT NULL,
+            `format` VARCHAR(16) NOT NULL,
+            `marcflavour` VARCHAR(16) NOT NULL,
+            `metadata` LONGTEXT NOT NULL,
+            PRIMARY KEY(id),
+            UNIQUE KEY `deletedbiblio_metadata_uniq_key` (`biblionumber`,`format`,`marcflavour`),
+            CONSTRAINT `deletedbiblio_metadata_fk_1` FOREIGN KEY (biblionumber) REFERENCES deletedbiblio (biblionumber) ON DELETE CASCADE ON UPDATE CASCADE
+        ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+    });
+    $dbh->do(q{
+        INSERT INTO biblio_metadata ( biblionumber, format, marcflavour, metadata ) SELECT biblionumber, 'marcxml', 'CHANGEME', marcxml FROM biblioitems;
+    });
+    $dbh->do(q{
+        INSERT INTO deletedbiblio_metadata ( biblionumber, format, marcflavour, metadata ) SELECT biblionumber, 'marcxml', 'CHANGEME', marcxml FROM deletedbiblioitems;
+    });
+    $dbh->do(q{
+        UPDATE biblio_metadata SET marcflavour = (SELECT value FROM systempreferences WHERE variable="marcflavour");
+    });
+    $dbh->do(q{
+        UPDATE deletedbiblio_metadata SET marcflavour = (SELECT value FROM systempreferences WHERE variable="marcflavour");
+    });
+    $dbh->do(q{
+        ALTER TABLE biblioitems DROP COLUMN marcxml;
+    });
+    $dbh->do(q{
+        ALTER TABLE deletedbiblioitems DROP COLUMN marcxml;
+    });
+    SetVersion($DBversion);
+    print "Upgrade to $DBversion done (Bug 17196 - Move marcxml out of the biblioitems table)\n";
+}
+
+$DBversion = '16.12.00.005';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( "INSERT IGNORE INTO systempreferences (variable,value,options,explanation,type) VALUES('AuthorityMergeMode','loose','loose|strict','Authority merge mode','Choice')");
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 17913 - AuthorityMergeMode)\n";
+}
+
+$DBversion = "16.12.00.006";
+if ( CheckVersion($DBversion) ) {
+    unless (     column_exists( 'borrower_attributes', 'id' )
+             and index_exists( 'borrower_attributes', 'PRIMARY' ) )
+    {
+        $dbh->do(q{
+            ALTER TABLE `borrower_attributes`
+                ADD `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST
+        });
+    }
+
+    print "Upgrade to $DBversion done (Bug 17813: Table borrower_attributes needs a primary key\n";
+    SetVersion($DBversion);
+}
+
+$DBversion = "16.12.00.007";
+if( CheckVersion( $DBversion ) ) {
+
+    if ( column_exists('opac_news', 'new' ) ) {
+        $dbh->do(q|ALTER TABLE opac_news CHANGE COLUMN new content text NOT NULL|);
+    }
+
+    $dbh->do(q|
+        UPDATE letter SET content = REPLACE(content, "<<opac_news.new>>", "<<opac_news.content>>") WHERE content LIKE "%<<opac_news.new>>%"
+    |);
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 17960 - Rename opac_news with opac_news.content (template notices have been updated!))\n";
+}
+
+$DBversion = "16.12.00.008";
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES
+        ('MarcItemFieldsToOrder','','Set the mapping values for new item records created from a MARC record in a staged file. In a YAML format.', NULL, 'textarea');
+    });
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 15503 - Grab Item Information from Order Files)\n";
+}
+
+$DBversion = "16.12.00.009";
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES
+        ('OPACHoldsIfAvailableAtPickup','1','','Allow to pickup up holds at libraries where the item is available','YesNo');
+    });
+
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES
+        ('OPACHoldsIfAvailableAtPickupExceptions','','','List the patron categories not affected by OPACHoldsIfAvailableAtPickup if off','Free');
+    });
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 17453 - Inter-site holds improvement)\n";
+}
+
+$DBversion = "16.12.00.010";
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        ALTER TABLE borrowers ADD overdrive_auth_token text default NULL AFTER lastseen;
+    });
+
+    $dbh->do(q{
+        ALTER TABLE deletedborrowers ADD overdrive_auth_token text default NULL AFTER lastseen;
+    });
+
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type)
+        VALUES ('OverDriveCirculation','0','Enable client to see their OverDrive account','','YesNo');
+    });
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 16034 - Integration with OverDrive Patron API)\n";
+}
+
+$DBversion = "16.12.00.011";
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        ALTER TABLE search_field CHANGE COLUMN type type ENUM('', 'string', 'date', 'number', 'boolean', 'sum') NOT NULL
+        COMMENT 'what type of data this holds, relevant when storing it in the search engine';
+    });
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 17260 - updatedatabase.pl fails on invalid entries in ENUM and BOOLEAN columns)\n";
+}
+
+$DBversion = "16.12.00.012";
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO `systempreferences` (`variable`, `value`, `options`, `explanation`, `type`)
+        VALUES ('OpacNewsLibrarySelect', '0', '', 'Show selector for branches on OPAC news page', 'YesNo');
+    });
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 14764 - Add OPAC News branch selector)\n";
+}
+
+$DBversion = "16.12.00.013";
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences (`variable`, `value`, `options`, `explanation`, `type`)
+        VALUES ('CircSidebar','0','','Activate or deactivate the navigation sidebar on all Circulation pages','YesNo');
+    });
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 16530 - Add a circ sidebar navigation menu)\n";
+}
+
+$DBversion = "16.12.00.014";
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+            INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `type` ) VALUES
+            ('LoadSearchHistoryToTheFirstLoggedUser', '1', NULL, 'If ON, the next user will automatically get the last searches in his history', 'YesNo');
+            });
+            SetVersion( $DBversion );
+            print "Upgrade to $DBversion done (Bug 8010 - Search history can be added to the wrong patron)\n";
+            }
+
+$DBversion = "16.12.00.015";
+if( CheckVersion( $DBversion ) ) {
+    unless( column_exists( 'branches', 'geolocation' ) ) {
+        $dbh->do(q|
+                ALTER TABLE branches ADD COLUMN geolocation VARCHAR(255) DEFAULT NULL after opac_info
+                |);
+    }
+
+    $dbh->do(q|
+            INSERT IGNORE INTO systempreferences (variable, value, options, explanation, type ) VALUES ('UsageStatsGeolocation', '', NULL, 'Geolocation of the main library', 'Free');
+            |);
+    $dbh->do(q|
+            INSERT IGNORE INTO systempreferences (variable, value, options, explanation, type ) VALUES ('UsageStatsLibrariesInfo', '', NULL, 'Share libraries information', 'YesNo');
+            |);
+    $dbh->do(q|
+            INSERT IGNORE INTO systempreferences (variable, value, options, explanation, type ) VALUES ('UsageStatsPublicID', '', NULL, 'Public ID for Hea website', 'Free');
+            |);
+        
+        SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 18066 - Hea version 2)\n";
+}
+
+$DBversion = "16.12.00.016";
+if ( CheckVersion($DBversion) ) {
+    unless ( column_exists( 'borrower_attribute_types', 'opac_editable' ) )
+    {
+        $dbh->do(q{
+            ALTER TABLE borrower_attribute_types
+                ADD COLUMN `opac_editable` tinyint(1) NOT NULL default 0 AFTER `opac_display`
+        });
+    }
+
+    print "Upgrade to $DBversion done (Bug 13757: Make patron attributes editable in the opac if set to 'editable in OPAC)'\n";
+    SetVersion($DBversion);
+}
+
+$DBversion = "16.12.00.017";
+if ( CheckVersion($DBversion) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences (variable,value,options,explanation,type)
+        VALUES ('CumulativeRestrictionPeriods',  0,  NULL,  'Cumulate the restriction periods instead of keeping the highest',  'YesNo')
+    });
+
+    print "Upgrade to $DBversion done (Bug 14146 - Additional days are not added to restriction period when checking-in several overdues for same patron)'\n";
+    SetVersion($DBversion);
+}
+
+$DBversion = "16.12.00.018";
+if ( CheckVersion($DBversion) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences ( variable, value, options, explanation, type )
+            SELECT 'ExportCircHistory', COUNT(*), NULL, "Display the export circulation options",  'YesNo'
+            FROM systempreferences
+            WHERE ( variable = 'ExportRemoveFields' AND value != "" AND value IS NOT NULL )
+                OR ( variable = 'ExportWithCsvProfile' AND value != "" AND value IS NOT NULL );
+    });
+
+    $dbh->do(q{
+        DELETE FROM systempreferences WHERE variable="ExportWithCsvProfile";
+    });
+
+    print "Upgrade to $DBversion done (Bug 15498 - Replace ExportWithCsvProfile with ExportCircHistory)'\n";
+    SetVersion($DBversion);
+}
+
+$DBversion = "16.12.00.019";
+if( CheckVersion( $DBversion ) ) {
+    if ( column_exists( 'issues', 'return' ) ) {
+        $dbh->do(q|ALTER TABLE issues DROP column `return`|);
+    }
+
+    if ( column_exists( 'old_issues', 'return' ) ) {
+        $dbh->do(q|ALTER TABLE old_issues DROP column `return`|);
+    }
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 18173 - Remove issues.return DB field)\n";
+}
+
+$DBversion = "16.12.00.020";
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        UPDATE systempreferences SET options="any_time_is_placed|not_always|any_time_is_collected" WHERE variable="HoldFeeMode";
+    });
+
+    $dbh->do(q{
+        UPDATE systempreferences SET value="any_time_is_placed" WHERE variable="HoldFeeMode" AND value="always";
+    });
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 17560 - Hold fee placement at point of checkout)\n";
+}
+
+$DBversion = "16.12.00.021";
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `type` ) VALUES
+        ('RenewalLog','0','','If ON, log information about renewals','YesNo');
+    });
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 17708 - Renewal log seems empty)\n";
+}
+
+$DBversion = "16.12.00.022";
+if( CheckVersion( $DBversion ) ) {
+    print "NOTE: The sender for claim notifications has been corrected. The email address of the staff member is no longer used. We will use the branch email address or KohaAdminEmailAddress, as is done for other notices.\n";
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 17866 - Change sender for serial claim notifications)\n";
+}
+
+$DBversion = '16.12.00.023';
+if( CheckVersion( $DBversion ) ) {
+    my $oldval = C4::Context->preference('dontmerge');
+    my $newval = $oldval ? 0 : 50;
+
+    # Remove dontmerge, add AuthorityMergeLimit
+    $dbh->do(q{
+        DELETE FROM systempreferences WHERE variable = 'dontmerge';
+    });
+    $dbh->do(qq{
+        INSERT IGNORE INTO systempreferences ( variable, value, options, explanation, type ) VALUES ('AuthorityMergeLimit','$newval',NULL,'Maximum number of biblio records updated immediately when an authority record has been modified.','integer');
+    });
+
+    $dbh->do(q{
+        ALTER TABLE need_merge_authorities
+            ADD COLUMN authid_new BIGINT AFTER authid,
+            ADD COLUMN reportxml text AFTER authid_new,
+            ADD COLUMN timestamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
+    });
+
+    $dbh->do(q{
+        UPDATE need_merge_authorities SET authid_new=authid WHERE done <> 1
+    });
+
+    SetVersion( $DBversion );
+    if( $newval == 0 ) {
+        print "NOTE: Since dontmerge was enabled, we have initialized AuthorityMergeLimit to 0 records. Please consider raising this value. This will allow for performing smaller merges directly and only postponing larger merges.\n";
+    }
+    print "IMPORTANT NOTE: If you are not using a Debian package install, please verify that you no longer use misc/migration_tools/merge_authority.pl in your cron files AND add misc/cronjobs/merge_authorities.pl to cron now. This job is no longer optional! You need it to perform larger authority merges.\n";
+    print "Upgrade to $DBversion done (Bug 9988 - Add AuthorityMergeLimit)\n";
+}
+
 # DEVELOPER PROCESS, search for anything to execute in the db_update directory
 # SEE bug 13068
 # if there is anything in the atomicupdate, read and execute it.
@@ -12934,12 +14116,13 @@ my $update_dir = C4::Context->config('intranetdir') . '/installer/data/mysql/ato
 opendir( my $dirh, $update_dir );
 foreach my $file ( sort readdir $dirh ) {
     next if $file !~ /\.(sql|perl)$/;  #skip other files
+    next if $file eq 'skeleton.perl'; # skip the skeleton file
     print "DEV atomic update: $file\n";
     if ( $file =~ /\.sql$/ ) {
         my $installer = C4::Installer->new();
         my $rv = $installer->load_sql( $update_dir . $file ) ? 0 : 1;
     } elsif ( $file =~ /\.perl$/ ) {
-        my $code = path( $update_dir . $file )->slurp_utf8;
+        my $code = read_file( $update_dir . $file );
         eval $code;
         say "Atomic update generated errors: $@" if $@;
     }