Bug 22563: DBRev 19.06.00.012
[koha-equinox.git] / installer / data / mysql / updatedatabase.pl
index cd299de..01a47cb 100755 (executable)
@@ -27,8 +27,7 @@
 
 # NOTE: Please keep the version in kohaversion.pl up-to-date!
 
-use strict;
-use warnings;
+use Modern::Perl;
 
 use feature 'say';
 
@@ -13037,7 +13036,7 @@ if ( CheckVersion($DBversion) ) {
         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";
+    print "Upgrade to $DBversion done (Bug 16276: Add a new pref TrackLastPatronActivity and new column borrowers.lastseen)\n";
     SetVersion($DBversion);
 }
 
@@ -16129,7 +16128,8 @@ if( CheckVersion( $DBversion ) ) {
         unless ( foreign_key_exists('aqorders', 'aqorders_created_by') ) {
             $dbh->do( "ALTER TABLE aqorders ADD CONSTRAINT aqorders_created_by FOREIGN KEY (created_by) REFERENCES borrowers (borrowernumber) ON DELETE SET NULL ON UPDATE CASCADE;" );
         }
-        $dbh->do( "UPDATE aqorders, aqbasket SET aqorders.created_by = aqbasket.authorisedby  WHERE aqorders.basketno = aqbasket.basketno AND aqorders.created_by IS NULL;" );
+        $dbh->do( "UPDATE aqbasket LEFT JOIN borrowers ON ( aqbasket.authorisedby = borrowers.borrowernumber ) SET aqbasket.authorisedby = NULL WHERE borrowers.borrowernumber IS NULL;" );
+        $dbh->do( "UPDATE aqorders LEFT JOIN aqbasket ON ( aqorders.basketno = aqbasket.basketno ) SET aqorders.created_by = aqbasket.authorisedby WHERE aqorders.created_by IS NULL;" );
     }
     SetVersion( $DBversion );
     print "Upgrade to $DBversion done (Bug 12395 - Save order line's creator)\n";
@@ -17082,12 +17082,19 @@ if( CheckVersion( $DBversion ) ) {
             ADD COLUMN class_split_rule varchar(10) NOT NULL default ''
             AFTER class_sort_rule
         |);
+
         $dbh->do(q|
             UPDATE class_sources
             SET class_split_rule = class_sort_rule
         |);
 
         $dbh->do(q|
+            UPDATE class_sources
+            SET class_split_rule = 'generic'
+            WHERE class_split_rule NOT IN('dewey', 'generic', 'lcc')
+        |);
+
+        $dbh->do(q|
             INSERT INTO class_split_rules(class_split_rule, description, split_routine)
             VALUES
             ('dewey', 'Default sorting rules for DDC', 'Dewey'),
@@ -17225,42 +17232,1773 @@ if( CheckVersion( $DBversion ) ) {
     print "Upgrade to $DBversion done (Bug 22030: Add OverDriveUsername syspref)\n";
 }
 
-# SEE bug 13068
-# if there is anything in the atomicupdate, read and execute it.
+$DBversion = '18.12.00.006';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES
+        ('AccountAutoReconcile','0','If enabled, patron balances will get reconciled automatically on each transaction.',NULL,'YesNo');
+    });
+    SetVersion($DBversion);
+    print "Upgrade to $DBversion done (Bug 21915 - Add a way to automatically reconcile balance for patrons)\n";
+}
 
-my $update_dir = C4::Context->config('intranetdir') . '/installer/data/mysql/atomicupdate/';
-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 = read_file( $update_dir . $file );
-        eval $code;
-        say "Atomic update generated errors: $@" if $@;
+$DBversion = '18.12.00.007';
+if( CheckVersion( $DBversion ) ) {
+    if( column_exists( 'issuingrules', 'chargename' ) ) {
+        $dbh->do( "ALTER TABLE issuingrules DROP chargename" );
     }
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 21753: Drop chargename from issuingrules )\n";
 }
 
-=head1 FUNCTIONS
+$DBversion = '18.12.00.008';
+if( CheckVersion( $DBversion ) ) {
+    if( !column_exists( 'subscription', 'mana_id' ) ) {
+        $dbh->do( "ALTER TABLE subscription ADD mana_id int(11) NULL DEFAULT NULL" );
+    }
 
-=head2 TableExists($table)
+    if( !column_exists( 'saved_sql', 'mana_id' ) ) {
+        $dbh->do( "ALTER TABLE saved_sql ADD mana_id int(11) NULL DEFAULT NULL" );
+    }
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `type` ) VALUES
+        ('Mana','2',NULL,'request to Mana Webservice. Mana centralize common information between other Koha to facilitate the creation of new subscriptions, vendors, report queries etc... You can search, share, import and comment the content of Mana.','YesNo');
+    });
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `type` ) VALUES
+        ('AutoShareWithMana','','','defines datas automatically shared with mana','multiple');
+    });
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `type` ) VALUES
+        ('ManaToken','',NULL,'Security token used for authentication on Mana KB service (anti spam)','Textarea');
+    });
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 17047 - Mana knowledge base)\n";
+}
 
-=cut
+$DBversion = '18.12.00.009';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences (variable, value, options, explanation, type) VALUES ('FallbackToSMSIfNoEmail', 0, 'Enable|Disable', 'Send messages by SMS if no patron email is defined', 'YesNo');
+    });
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 21241 - Add FallbackToSMSIfNoEmail syspref )\n";
+}
 
-sub TableExists {
-    my $table = shift;
-    eval {
-                local $dbh->{PrintError} = 0;
-                local $dbh->{RaiseError} = 1;
-                $dbh->do(qq{SELECT * FROM $table WHERE 1 = 0 });
-            };
-    return 1 unless $@;
-    return 0;
+$DBversion = '18.12.00.010';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences
+            ( variable, value, options, explanation, type )
+        VALUES
+            ('RESTPublicAPI','1',NULL,'If enabled, the REST API will expose the /public endpoints.','YesNo')
+    });
+
+    # Always end with this (adjust the bug info)
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 22061 - Add a /public namespace that can be switched on/off)\n";
+}
+
+$DBversion = '18.12.00.011';
+if( CheckVersion( $DBversion ) ) {
+    if ( column_exists( 'biblio_metadata', 'marcflavour' ) ) {
+        $dbh->do(q{
+            ALTER TABLE biblio_metadata
+                CHANGE COLUMN marcflavour `schema` VARCHAR(16)
+        });
+    }
+    if ( column_exists( 'deletedbiblio_metadata', 'marcflavour' ) ) {
+        $dbh->do(q{
+            ALTER TABLE deletedbiblio_metadata
+                CHANGE COLUMN marcflavour `schema` VARCHAR(16)
+        });
+    }
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 22155 - biblio_metadata.marcflavour should be renamed 'schema')\n";
+}
+
+$DBversion = '18.12.00.012';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences
+            (variable, value, options, explanation, type )
+        VALUES
+            ('RESTBasicAuth','0',NULL,'If enabled, Basic authentication is enabled for the REST API.','YesNo')
+    });
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 22132 - Add Basic authentication)\n";
+}
+
+$DBversion = '18.12.00.013';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO permissions (module_bit, code, description) VALUES ( 3, 'manage_mana', 'Manage Mana KB content sharing');
+    });
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 22198 - Add ghranular permission setting for Mana KB)\n";
+}
+
+$DBversion = '18.12.00.014';
+if( CheckVersion( $DBversion ) ) {
+    unless( foreign_key_exists( 'messages', 'messages_borrowernumber' ) ) {
+        $dbh->do(q|
+            DELETE m FROM messages m
+            LEFT JOIN borrowers b ON m.borrowernumber=b.borrowernumber
+            WHERE b.borrowernumber IS NULL
+        |);
+        $dbh->do(q|
+            ALTER TABLE messages
+            ADD CONSTRAINT messages_borrowernumber
+            FOREIGN KEY (borrowernumber) REFERENCES borrowers (borrowernumber) ON DELETE CASCADE ON UPDATE CASCADE
+        |);
+    }
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 13515 - Add a FOREIGN KEY constaint on messages.borrowernumber)\n";
+}
+
+$DBversion = '18.12.00.015';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( "UPDATE action_logs SET info = REPLACE(info,'cardnumber_replaced','cardnumber') WHERE module='MEMBERS' AND action='MODIFY'" );
+    $dbh->do( "UPDATE action_logs SET info = REPLACE(info,'previous_cardnumber','before') WHERE module='MEMBERS' AND action='MODIFY'" );
+    $dbh->do( "UPDATE action_logs SET info = REPLACE(info,'new_cardnumber','after') WHERE module='MEMBERS' AND action='MODIFY'" );
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 3820 - Update patron modification logs)\n";
+}
+
+$DBversion = '18.12.00.016';
+if( CheckVersion( $DBversion ) ) {
+
+    if ( !column_exists( 'illrequests', 'status_alias' ) ) {
+        # Fresh upgrade, just add the column and constraint
+        $dbh->do( "ALTER TABLE illrequests ADD COLUMN status_alias varchar(80) DEFAULT NULL AFTER status" );
+    } else {
+        # Migrate all existing foreign keys from referencing authorised_values.id
+        # to referencing authorised_values.authorised_value
+        # First remove the foreign key constraint and index
+        if ( foreign_key_exists( 'illrequests', 'illrequests_safk' ) ) {
+            $dbh->do( "ALTER TABLE illrequests DROP FOREIGN KEY illrequests_safk");
+        }
+        if ( index_exists( 'illrequests', 'illrequests_safk' ) ) {
+            $dbh->do( "DROP INDEX illrequests_safk ON illrequests" );
+        }
+        # Now change the illrequests.status_alias column definition from int to varchar
+        $dbh->do( "ALTER TABLE illrequests MODIFY COLUMN status_alias varchar(80)" );
+        # Now replace all references to authorised_values.id with their
+        # corresponding authorised_values.authorised_value
+        my $sth = $dbh->prepare( "SELECT illrequest_id, status_alias FROM illrequests WHERE status_alias IS NOT NULL" );
+        $sth->execute();
+        while (my @row = $sth->fetchrow_array()) {
+            my $r_id = $row[0];
+            my $av_id = $row[1];
+            # Get the authorised value's authorised_value value
+            my ($av_val) = $dbh->selectrow_array( "SELECT authorised_value FROM authorised_values WHERE id = ?", {}, $av_id );
+            # Now update illrequests.status_alias
+            if ($av_val) {
+                $dbh->do( "UPDATE illrequests SET status_alias = ? WHERE illrequest_id = ?", {}, ($av_val, $r_id) );
+            }
+        }
+    }
+    if ( !foreign_key_exists( 'illrequests', 'illrequests_safk' ) ) {
+        $dbh->do( "ALTER TABLE illrequests ADD CONSTRAINT illrequests_safk FOREIGN KEY (status_alias) REFERENCES authorised_values(authorised_value) ON UPDATE CASCADE ON DELETE SET NULL" );
+    }
+    $dbh->do( "INSERT IGNORE INTO authorised_value_categories SET category_name = 'ILLSTATUS'");
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 20581 - Allow manual selection of custom ILL request statuses)\n";
+}
+
+$DBversion = '18.12.00.017';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO account_offset_types ( type ) VALUES ( 'fine_increase' ), ( 'fine_decrease' );
+    });
+    $dbh->do(q{
+        UPDATE account_offsets SET type = 'fine_increase' WHERE type = 'Fine Update' AND amount > 0;
+    });
+    $dbh->do(q{
+        UPDATE account_offsets SET type = 'fine_decrease' WHERE type = 'Fine Update' AND amount < 0;
+    });
+
+    $dbh->do(q{
+        DELETE FROM account_offset_types WHERE type = 'Fine Update';
+    });
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 21747 - Update account_offset_types to include 'fine_increase' and 'fine_decrease')\n";
+}
+
+$DBversion = '18.12.00.018';
+if( CheckVersion( $DBversion ) ) {
+  $dbh->do( "UPDATE `search_field` SET `name` = 'date-of-publication', `label` = 'date-of-publication' WHERE `name` = 'pubdate'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'title-series', `label` = 'title-series' WHERE `name` = 'se'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'identifier-standard', `label` = 'identifier-standard' WHERE `name` = 'identifier-standard'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'author', `label` = 'author' WHERE `name` = 'author'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'control-number', `label` = 'control-number' WHERE `name` = 'control-number'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'place-of-publication', `label` = 'place-of-publication' WHERE `name` = 'place'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'date-of-acquisition', `label` = 'date-of-acquisition' WHERE `name` = 'acqdate'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'isbn', `label` = 'isbn' WHERE `name` = 'isbn'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'koha-auth-number', `label` = 'koha-auth-number' WHERE `name` = 'an'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'subject', `label` = 'subject' WHERE `name` = 'subject'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'publisher', `label` = 'publisher' WHERE `name` = 'publisher'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'record-source', `label` = 'record-source' WHERE `name` = 'record-source'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'title', `label` = 'title' WHERE `name` = 'title'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'local-classification', `label` = 'local-classification' WHERE `name` = 'local-classification'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'bib-level', `label` = 'bib-level' WHERE `name` = 'bib-level'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'microform-generation', `label` = 'microform-generation' WHERE `name` = 'microform-generation'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'material-type', `label` = 'material-type' WHERE `name` = 'material-type'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'bgf-number', `label` = 'bgf-number' WHERE `name` = 'bgf-number'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'number-db', `label` = 'number-db' WHERE `name` = 'number-db'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'number-natl-biblio', `label` = 'number-natl-biblio' WHERE `name` = 'number-natl-biblio'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'number-legal-deposit', `label` = 'number-legal-deposit' WHERE `name` = 'number-legal-deposit'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'issn', `label` = 'issn' WHERE `name` = 'issn'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'local-number', `label` = 'local-number' WHERE `name` = 'local-number'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'suppress', `label` = 'supress' WHERE `name` = 'suppress'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'bnb-card-number', `label` = 'bnb-card-number' WHERE `name` = 'bnb-card-number'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'date/time-last-modified', `label` = 'date/time-last-modified' WHERE `name` = 'date-time-last-modified'" );
+  $dbh->do( "DELETE FROM `search_field` WHERE `name` = 'lc-cardnumber'" );
+  $dbh->do( "DELETE FROM `search_marc_map` WHERE `id` NOT IN(SELECT `search_marc_map_id` FROM `search_marc_to_field`)" );
+  SetVersion( $DBversion );
+  print "Upgrade to $DBversion done (Bug 19575 - Use canonical field names and resolve aliased fields)\n";
+}
+
+$DBversion = '18.12.00.019';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO account_offset_types ( type ) VALUES ( 'Reserve Fee' );
+    });
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 21728 - Add 'Reserve Fee' to the account_offset_types table if missing)\n";
+}
+
+$DBversion = '18.12.00.020';
+if( CheckVersion( $DBversion ) ) {
+    if ( TableExists( 'branch_borrower_circ_rules' ) ) {
+        if ( column_exists( 'branch_borrower_circ_rules', 'maxissueqty' ) ) {
+            $dbh->do("
+                INSERT INTO circulation_rules ( categorycode, branchcode, itemtype, rule_name, rule_value )
+                SELECT categorycode, branchcode, NULL, 'patron_maxissueqty', COALESCE( maxissueqty, '' )
+                FROM branch_borrower_circ_rules
+            ");
+            $dbh->do("
+                INSERT INTO circulation_rules ( categorycode, branchcode, itemtype, rule_name, rule_value )
+                SELECT categorycode, branchcode, NULL, 'patron_maxonsiteissueqty', COALESCE( maxonsiteissueqty, '' )
+                FROM branch_borrower_circ_rules
+            ");
+            $dbh->do("DROP TABLE branch_borrower_circ_rules");
+        }
+    }
+
+    if ( TableExists( 'default_borrower_circ_rules' ) ) {
+        if ( column_exists( 'default_borrower_circ_rules', 'maxissueqty' ) ) {
+            $dbh->do("
+                INSERT INTO circulation_rules ( categorycode, branchcode, itemtype, rule_name, rule_value )
+                SELECT categorycode, NULL, NULL, 'patron_maxissueqty', COALESCE( maxissueqty, '' )
+                FROM default_borrower_circ_rules
+            ");
+            $dbh->do("
+                INSERT INTO circulation_rules ( categorycode, branchcode, itemtype, rule_name, rule_value )
+                SELECT categorycode, NULL, NULL, 'patron_maxonsiteissueqty', COALESCE( maxonsiteissueqty, '' )
+                FROM default_borrower_circ_rules
+            ");
+            $dbh->do("DROP TABLE default_borrower_circ_rules");
+        }
+    }
+
+    if ( column_exists( 'default_circ_rules', 'maxissueqty' ) ) {
+        $dbh->do("
+            INSERT INTO circulation_rules ( categorycode, branchcode, itemtype, rule_name, rule_value )
+            SELECT NULL, NULL, NULL, 'patron_maxissueqty', COALESCE( maxissueqty, '' )
+            FROM default_circ_rules
+        ");
+        $dbh->do("
+            INSERT INTO circulation_rules ( categorycode, branchcode, itemtype, rule_name, rule_value )
+            SELECT NULL, NULL, NULL, 'patron_maxonsiteissueqty', COALESCE( maxonsiteissueqty, '' )
+            FROM default_circ_rules
+        ");
+        $dbh->do("ALTER TABLE default_circ_rules DROP COLUMN maxissueqty, DROP COLUMN maxonsiteissueqty");
+    }
+
+    if ( column_exists( 'default_branch_circ_rules', 'maxissueqty' ) ) {
+        $dbh->do("
+            INSERT INTO circulation_rules ( categorycode, branchcode, itemtype, rule_name, rule_value )
+            SELECT NULL, branchcode, NULL, 'patron_maxissueqty', COALESCE( maxissueqty, '' )
+            FROM default_branch_circ_rules
+        ");
+        $dbh->do("
+            INSERT INTO circulation_rules ( categorycode, branchcode, itemtype, rule_name, rule_value )
+            SELECT NULL, NULL, NULL, 'patron_maxonsiteissueqty', COALESCE( maxonsiteissueqty, '' )
+            FROM default_branch_circ_rules
+        ");
+        $dbh->do("ALTER TABLE default_branch_circ_rules DROP COLUMN maxissueqty, DROP COLUMN maxonsiteissueqty");
+    }
+
+    if ( column_exists( 'issuingrules', 'maxissueqty' ) ) {
+        $dbh->do("
+            INSERT INTO circulation_rules ( categorycode, branchcode, itemtype, rule_name, rule_value )
+            SELECT IF(categorycode='*', NULL, categorycode),
+                   IF(branchcode='*', NULL, branchcode),
+                   IF(itemtype='*', NULL, itemtype),
+                   'maxissueqty',
+                   COALESCE( maxissueqty, '' )
+            FROM issuingrules
+        ");
+        $dbh->do("
+            INSERT INTO circulation_rules ( categorycode, branchcode, itemtype, rule_name, rule_value )
+            SELECT IF(categorycode='*', NULL, categorycode),
+                   IF(branchcode='*', NULL, branchcode),
+                   IF(itemtype='*', NULL, itemtype),
+                   'maxonsiteissueqty',
+                   COALESCE( maxonsiteissueqty, '' )
+            FROM issuingrules
+        ");
+        $dbh->do("ALTER TABLE issuingrules DROP COLUMN maxissueqty, DROP COLUMN maxonsiteissueqty");
+    }
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 18925 - Move maxissueqty and maxonsiteissueqty to circulation_rules)\n";
+}
+
+$DBversion = '18.12.00.021';
+if ( CheckVersion($DBversion) ) {
+
+    if ( !column_exists( 'itemtypes', 'rentalcharge_daily' ) ) {
+        $dbh->do("ALTER TABLE `itemtypes` ADD COLUMN `rentalcharge_daily` decimal(28,6) default NULL AFTER `rentalcharge`");
+    }
+
+    if ( !column_exists( 'itemtypes', 'rentalcharge_hourly' ) ) {
+        $dbh->do("ALTER TABLE `itemtypes` ADD COLUMN `rentalcharge_hourly` decimal(28,6) default NULL AFTER `rentalcharge_daily`");
+    }
+
+    if ( column_exists( 'itemtypes', 'rental_charge_daily' ) ) {
+        $dbh->do("UPDATE `itemtypes` SET `rentalcharge_daily` = `rental_charge_daily`");
+        $dbh->do("ALTER TABLE `itemtypes` DROP COLUMN `rental_charge_daily`");
+    }
+
+    SetVersion($DBversion);
+    print "Upgrade to $DBversion done (Bug 20912 - Support granular rental charges)\n";
+}
+
+$DBversion = '18.12.00.022';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( q{
+        INSERT IGNORE INTO permissions (module_bit,code,description)
+        VALUES
+        (3,'manage_additional_fields','Add, edit, or delete additional custom fields for baskets or subscriptions (also requires order_manage or edit_subscription permissions)')
+    });
+    $dbh->do( q{
+        INSERT INTO user_permissions (borrowernumber, module_bit, code)
+        SELECT borrowernumber, 3, 'manage_additional_fields' FROM borrowers WHERE borrowernumber IN (SELECT DISTINCT borrowernumber FROM user_permissions WHERE code = 'order_manage' OR code = 'edit_subscription');
+    });
+    $dbh->do( q{
+        INSERT INTO user_permissions (borrowernumber, module_bit, code)
+        SELECT borrowernumber, 3, 'manage_additional_fields' FROM borrowers WHERE borrowernumber IN (SELECT borrowernumber FROM borrowers WHERE MOD(flags DIV POWER(2,11),2)=1 OR MOD(flags DIV POWER(2,15),2) =1);
+    });
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 15774 - Add permission for managing additional fields)\n";
+}
+
+$DBversion = '18.12.00.023';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q|
+      INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type)
+      VALUES ('ILLOpacbackends',NULL,NULL,'ILL backends to enabled for OPAC initiated requests','multiple');
+    |);
+
+    # Always end with this (adjust the bug info)
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 20639 - Add ILLOpacbackends syspref)\n";
+}
+
+$DBversion = '18.12.00.024';
+if ( CheckVersion($DBversion) ) {
+
+    # Add constraint for suggestedby
+    unless ( foreign_key_exists( 'suggestions', 'suggestions_ibfk_suggestedby' ) )
+    {
+        $dbh->do(
+"ALTER TABLE suggestions CHANGE COLUMN suggestedby suggestedby INT(11) NULL DEFAULT NULL;"
+        );
+        $dbh->do(
+"UPDATE suggestions LEFT JOIN borrowers ON (suggestions.suggestedby = borrowers.borrowernumber) SET suggestedby = null WHERE borrowernumber IS null"
+        );
+        $dbh->do(
+"ALTER TABLE suggestions ADD CONSTRAINT `suggestions_ibfk_suggestedby` FOREIGN KEY (`suggestedby`) REFERENCES `borrowers` (`borrowernumber`) ON DELETE SET NULL ON UPDATE CASCADE"
+        );
+    }
+
+    # Add constraint for managedby
+    unless ( foreign_key_exists( 'suggestions', 'suggestions_ibfk_managedby' ) )
+    {
+        $dbh->do(
+"UPDATE suggestions LEFT JOIN borrowers ON (suggestions.managedby = borrowers.borrowernumber) SET managedby = null WHERE borrowernumber IS NULL"
+        );
+        $dbh->do(
+"ALTER TABLE suggestions ADD CONSTRAINT `suggestions_ibfk_managedby` FOREIGN KEY (`managedby`) REFERENCES `borrowers` (`borrowernumber`) ON DELETE SET NULL ON UPDATE CASCADE"
+        );
+    }
+
+    # Add constraint for acceptedby
+    unless (
+        foreign_key_exists( 'suggestions', 'suggestions_ibfk_acceptedby' ) )
+    {
+        $dbh->do(
+"UPDATE suggestions LEFT JOIN borrowers ON (suggestions.acceptedby = borrowers.borrowernumber) SET acceptedby = null WHERE borrowernumber IS NULL"
+        );
+        $dbh->do(
+"ALTER TABLE suggestions ADD CONSTRAINT `suggestions_ibfk_acceptedby` FOREIGN KEY (`acceptedby`) REFERENCES `borrowers` (`borrowernumber`) ON DELETE SET NULL ON UPDATE CASCADE"
+        );
+    }
+
+    # Add constraint for rejectedby
+    unless (
+        foreign_key_exists( 'suggestions', 'suggestions_ibfk_rejectedby' ) )
+    {
+        $dbh->do(
+"UPDATE suggestions LEFT JOIN borrowers ON (suggestions.rejectedby = borrowers.borrowernumber) SET rejectedby = null WHERE borrowernumber IS null"
+        );
+        $dbh->do(
+"ALTER TABLE suggestions ADD CONSTRAINT `suggestions_ibfk_rejectedby` FOREIGN KEY (`rejectedby`) REFERENCES `borrowers` (`borrowernumber`) ON DELETE SET NULL ON UPDATE CASCADE"
+        );
+    }
+
+    # Add constraint for biblionumber
+    unless (
+        foreign_key_exists( 'suggestions', 'suggestions_ibfk_biblionumber' ) )
+    {
+        $dbh->do(
+"UPDATE suggestions s LEFT JOIN biblio b ON (s.biblionumber = b.biblionumber) SET s.biblionumber = null WHERE b.biblionumber IS null"
+        );
+        $dbh->do(
+"ALTER TABLE suggestions ADD CONSTRAINT `suggestions_ibfk_biblionumber` FOREIGN KEY (`biblionumber`) REFERENCES `biblio` (`biblionumber`) ON DELETE SET NULL ON UPDATE CASCADE"
+        );
+    }
+
+    # Add constraint for branchcode
+    unless (
+        foreign_key_exists( 'suggestions', 'suggestions_ibfk_branchcode' ) )
+    {
+        $dbh->do(
+"UPDATE suggestions s LEFT JOIN branches b ON (s.branchcode = b.branchcode) SET s.branchcode = null WHERE b.branchcode IS null"
+        );
+        $dbh->do(
+"ALTER TABLE suggestions ADD CONSTRAINT `suggestions_ibfk_branchcode` FOREIGN KEY (`branchcode`) REFERENCES `branches` (`branchcode`) ON DELETE SET NULL ON UPDATE CASCADE"
+        );
+    }
+
+    SetVersion($DBversion);
+    print
+"Upgrade to $DBversion done (Bug 22368 - Add missing constraints to suggestions)\n";
+}
+
+$DBversion = '18.12.00.025';
+if( CheckVersion( $DBversion ) ) {
+
+    $dbh->do('SET FOREIGN_KEY_CHECKS=0');
+
+    # Change columns accordingly
+    $dbh->do(q{
+        ALTER TABLE tags_index
+            MODIFY COLUMN term VARCHAR(191) COLLATE utf8mb4_bin NOT NULL;
+    });
+
+    $dbh->do(q{
+        ALTER TABLE tags_approval
+            MODIFY COLUMN term VARCHAR(191) COLLATE utf8mb4_bin NOT NULL;
+    });
+
+    $dbh->do(q{
+        ALTER TABLE tags_all
+            MODIFY COLUMN term VARCHAR(191) COLLATE utf8mb4_bin NOT NULL;
+    });
+
+    $dbh->do('SET FOREIGN_KEY_CHECKS=1');
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 21846 - Using emoji as tags has broken weights)\n";
+    my $maintenance_script = C4::Context->config("intranetdir") . "/misc/maintenance/fix_tags_weight.pl";
+    print "WARNING: (Bug 21846) You need to manually run $maintenance_script to fix possible issues with tags.\n";
 }
 
+$DBversion = '18.12.00.026';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( "INSERT IGNORE INTO systempreferences (variable, value, explanation, type) VALUES ('IllLog', 0, 'If ON, log information about ILL requests', 'YesNo')" );
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 20750 - Allow timestamped auditing of ILL request events)\n";
+}
+
+$DBversion = '18.12.00.027';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES
+       ('ILLModuleUnmediated','0','','If enabled, try to immediately progress newly placed ILL requests.','YesNo');
+    });
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 18837: Add ILLModuleUnmediated Syspref)\n";
+}
+
+$DBversion = '18.12.00.028';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO account_offset_types ( type ) VALUES ( 'Account Fee' );
+    });
+
+    $dbh->do(q{
+        INSERT IGNORE INTO account_offset_types ( type ) VALUES ( 'Hold Expired' );
+    });
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 21756 - Add 'Account Fee' and 'Hold Expired' to the account_offset_types table if missing)\n";
+}
+
+$DBversion = '18.12.00.029';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( "INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES ('OrderPriceRounding',NULL,'Local preference for rounding orders before calculations to ensure correct calculations','|nearest_cent','Choice')" );
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 18736 - Add syspref to control order rounding)\n";
+}
+
+$DBversion = '18.12.00.030';
+if( CheckVersion( $DBversion ) ) {
+    if( column_exists( 'accountlines', 'accountno' ) ) {
+        $dbh->do( "ALTER TABLE accountlines DROP COLUMN accountno" );
+    }
+    if( column_exists( 'statistics', 'proccode' ) ) {
+        $dbh->do( "ALTER TABLE statistics DROP COLUMN proccode" );
+    }
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 21683 - Remove accountlines.accountno and statistics.proccode fields)\n";
+}
+
+$DBversion = '18.12.00.031';
+if( CheckVersion( $DBversion ) ) {
+
+    # Add constraint for manager_id
+    unless( foreign_key_exists( 'accountlines', 'accountlines_ibfk_borrowers_2' ) ) {
+        $dbh->do("ALTER TABLE accountlines CHANGE COLUMN manager_id manager_id INT(11) NULL DEFAULT NULL");
+        $dbh->do("UPDATE accountlines a LEFT JOIN borrowers b ON ( a.manager_id = b.borrowernumber) SET a.manager_id = NULL WHERE b.borrowernumber IS NULL");
+        $dbh->do("ALTER TABLE accountlines ADD CONSTRAINT `accountlines_ibfk_borrowers_2` FOREIGN KEY (`manager_id`) REFERENCES `borrowers` (`borrowernumber`) ON DELETE SET NULL ON UPDATE CASCADE");
+    }
+
+    # Rename accountlines_ibfk_2 to accountlines_ibfk_items
+    if ( foreign_key_exists( 'accountlines', 'accountlines_ibfk_2' ) && !foreign_key_exists( 'accountlines', 'accountlines_ibfk_items' ) ) {
+        $dbh->do("ALTER TABLE accountlines DROP FOREIGN KEY accountlines_ibfk_2");
+        $dbh->do("ALTER TABLE accountlines ADD CONSTRAINT `accountlines_ibfk_items` FOREIGN KEY (`itemnumber`) REFERENCES `items` (`itemnumber`) ON DELETE SET NULL ON UPDATE CASCADE");
+    }
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 22008 - Add missing constraints for accountlines.manager_id)\n";
+}
+
+$DBversion = '18.12.00.032';
+if( CheckVersion( $DBversion ) ) {
+    if( !column_exists( 'search_field', 'facet_order' ) ) {
+        $dbh->do("ALTER TABLE search_field ADD COLUMN facet_order TINYINT(4) DEFAULT NULL AFTER weight");
+    }
+    $dbh->do("UPDATE search_field SET facet_order=1 WHERE name='author'");
+    $dbh->do("UPDATE search_field SET facet_order=2 WHERE name='itype'");
+    $dbh->do("UPDATE search_field SET facet_order=3 WHERE name='location'");
+    $dbh->do("UPDATE search_field SET facet_order=4 WHERE name='su-geo'");
+    $dbh->do("UPDATE search_field SET facet_order=5 WHERE name='title-series'");
+    $dbh->do("UPDATE search_field SET facet_order=6 WHERE name='subject'");
+    $dbh->do("UPDATE search_field SET facet_order=7 WHERE name='ccode'");
+    $dbh->do("UPDATE search_field SET facet_order=8 WHERE name='holdingbranch'");
+    $dbh->do("UPDATE search_field SET facet_order=9 WHERE name='homebranch'");
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 18235 - Elastic search - make facets configurable)\n";
+}
+
+$DBversion = '18.12.00.033';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( "UPDATE search_field SET facet_order=10 WHERE name='ln'" );
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 18213 - Add language facets to Elasticsearch)\n";
+}
+
+$DBversion = '18.12.00.034';
+if( CheckVersion( $DBversion ) ) {
+
+    if ( column_exists( 'accountlines', 'lastincrement' ) ) {
+        $dbh->do("ALTER TABLE `accountlines` DROP COLUMN `lastincrement`");
+    }
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 22516 - Drop deprecated accountlines.lastincrement field)\n";
+}
+
+$DBversion = '18.12.00.035';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( "INSERT IGNORE INTO systempreferences (variable, value, options, explanation, type)
+               VALUES ('MaxItemsToDisplayForBatchMod','1000',NULL,'Display up to a given number of items in a single item modification batch.','Integer')"
+            );
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 19722 - Add a MaxItemsToDisplayForBatchMod preference)\n";
+}
+
+$DBversion = '18.12.00.036';
+if ( CheckVersion($DBversion) ) {
+
+    my $rows = $dbh->do(
+        qq{
+        UPDATE `accountlines`
+        SET
+          `accounttype` = 'FU'
+        WHERE
+          `accounttype` = 'O'
+      }
+    );
+
+    SetVersion($DBversion);
+    printf "Upgrade to $DBversion done (Bug 22518 - Fix accounttype 'O' to 'FU' - %d updated)\n", $rows;
+}
+
+$DBversion = '18.12.00.037';
+if( CheckVersion( $DBversion ) ) {
+
+    $dbh->do( "UPDATE issues SET renewals = 0 WHERE renewals IS NULL" );
+    $dbh->do( "UPDATE old_issues SET renewals = 0 WHERE renewals IS NULL" );
+
+    $dbh->do( "ALTER TABLE issues MODIFY COLUMN renewals tinyint(4) NOT NULL default 0");
+    $dbh->do( "ALTER TABLE old_issues MODIFY COLUMN renewals tinyint(4) NOT NULL default 0");
+
+    # Always end with this (adjust the bug info)
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 22607 - Set default value of issues.renewals to 0)\n";
+}
+
+$DBversion = '18.12.00.038';
+if ( CheckVersion($DBversion) ) {
+
+    if ( !column_exists( 'accountlines', 'status' ) ) {
+        $dbh->do(
+            qq{
+            ALTER TABLE `accountlines`
+            ADD
+              `status` varchar(16) DEFAULT NULL
+            AFTER
+              `accounttype`
+          }
+        );
+    }
+
+    SetVersion($DBversion);
+    print "Upgrade to $DBversion done (Bug 22512 - Add status to accountlines)\n";
+}
+
+$DBversion = '18.12.00.039';
+if ( CheckVersion($DBversion) ) {
+
+    if ( !column_exists( 'accountlines', 'interface' ) ) {
+        $dbh->do(
+            qq{
+            ALTER TABLE `accountlines`
+            ADD
+              `interface` varchar(16)
+            AFTER
+              `manager_id`;
+          }
+        );
+    }
+
+    $dbh->do(qq{
+        UPDATE
+          `accountlines`
+        SET
+          interface = 'opac'
+        WHERE
+          borrowernumber = manager_id;
+    });
+
+    $dbh->do(qq{
+        UPDATE
+          `accountlines`
+        SET
+          interface = 'cron'
+        WHERE
+          manager_id IS NULL
+        AND
+          branchcode IS NULL;
+    });
+
+    $dbh->do(qq{
+        UPDATE
+          `accountlines`
+        SET
+          interface = 'intranet'
+        WHERE
+          interface IS NULL;
+    });
+
+    $dbh->do(qq{
+        ALTER TABLE `accountlines`
+        MODIFY COLUMN `interface` varchar(16) NOT NULL;
+    });
+
+    SetVersion($DBversion);
+    print "Upgrade to $DBversion done (Bug 22600 - Add interface to accountlines)\n";
+}
+
+$DBversion = '18.12.00.040';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do("UPDATE accountlines SET description = REPLACE(description, 'Reserve Charge - ', '') WHERE description LIKE 'Reserve Charge - %'");
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 12166 - Remove 'Reserve Charge' text from accountlines description)\n";
+}
+
+$DBversion = '18.12.00.041';
+if( CheckVersion( $DBversion ) ) {
+    my $table_sth = $dbh->prepare('SHOW CREATE TABLE `search_marc_map`');
+    $table_sth->execute();
+    my @table = $table_sth->fetchrow_array();
+    unless ( $table[1] =~ /`marc_field`.*COLLATE utf8mb4_bin/ ) { #catches utf8mb4 collated tables
+        $dbh->do("ALTER TABLE `search_marc_map` MODIFY `marc_field` VARCHAR(255) NOT NULL COLLATE utf8mb4_bin COMMENT 'the MARC specifier for this field'");
+    }
+
+    # Always end with this (adjust the bug info)
+    SetVersion( $DBversion );
+       print "Upgrade to $DBversion done (Bug 19670 - Change collation of marc_field to allow mixed case search field mappings)\n";
+}
+
+$DBversion = '18.12.00.042';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( "UPDATE systempreferences SET value = 'default' WHERE variable = 'XSLTDetailsDisplay' AND value = ''" );
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 29891 - Remove non-XSLT detail view in the staff client)\n";
+}
+
+$DBversion = '18.12.00.043';
+if ( CheckVersion($DBversion) ) {
+    $dbh->do("UPDATE accountlines SET description = REPLACE(description, 'Lost Item ', '') WHERE description LIKE 'Lost Item %'");
+    SetVersion($DBversion);
+    print "Upgrade to $DBversion done (Bug 21953 - Remove 'Lost Item' text from accountlines description)\n";
+}
+
+$DBversion = '18.12.00.044';
+if( CheckVersion( $DBversion ) ) {
+
+    if ( !column_exists( 'categories', 'reset_password' ) ) {
+        $dbh->do(q{
+            ALTER TABLE categories
+                ADD COLUMN reset_password TINYINT(1) NULL DEFAULT NULL
+                AFTER checkprevcheckout
+        });
+    }
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 21890 - Patron password reset by category)\n";
+}
+
+$DBversion = '18.12.00.045';
+if( CheckVersion( $DBversion ) ) {
+
+    if ( !column_exists( 'categories', 'change_password' ) ) {
+        $dbh->do(q{
+            ALTER TABLE categories
+                ADD COLUMN change_password TINYINT(1) NULL DEFAULT NULL
+                AFTER reset_password
+        });
+    }
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 10796 - Patron password change by category)\n";
+}
+
+$DBversion = '18.12.00.046';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( "UPDATE systempreferences SET value = 'default' WHERE variable = 'XSLTResultsDisplay' AND value = ''" );
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 22695 - Remove non-XSLT search results view from the staff client)\n";
+}
+
+$DBversion = '18.12.00.047';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q|
+        INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES ('LibrisKey', '', 'This key must be obtained at http://api.libris.kb.se/. It is unique for the IP of the server.', NULL, 'Free');
+    |);
+    $dbh->do(q|
+        INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES ('LibrisURL', 'http://api.libris.kb.se/bibspell/', 'This is the base URL for the Libris spellchecking API.',NULL,'Free');
+    |);
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 14557: Add Libris spellchecking system preferences)\n";
+}
+
+$DBversion = '18.12.00.048';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( q{
+        INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type)
+        VALUES ('NoRenewalBeforePrecision', 'exact_time', 'Calculate "No renewal before" based on date or exact time. Only relevant for loans calculated in days, hourly loans are not affected.', 'date|exact_time', 'Choice');
+    });
+    $dbh->do("UPDATE systempreferences SET value='exact_time' WHERE variable='NoRenewalBeforePrecision' AND value IS NULL;" );
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 22044 - Set a default value for NoRenewalBeforePrecision)\n";
+}
+
+$DBversion = '18.12.00.049';
+if( CheckVersion( $DBversion ) ) {
+
+    $dbh->do(q{
+        ALTER TABLE borrowers
+            ADD COLUMN flgAnonymized tinyint DEFAULT 0
+            AFTER overdrive_auth_token
+    }) if !column_exists('borrowers', 'flgAnonymized');
+
+    $dbh->do(q{
+        ALTER TABLE deletedborrowers
+            ADD COLUMN flgAnonymized tinyint DEFAULT 0
+            AFTER overdrive_auth_token
+    }) if !column_exists('deletedborrowers', 'flgAnonymized');
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 21336 - Add field flgAnonymized)\n";
+}
+
+$DBversion = '18.12.00.050';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( q|
+INSERT IGNORE INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `type` )
+VALUES
+('UnsubscribeReflectionDelay','',NULL,'Delay for locking unsubscribers', 'Integer'),
+('PatronAnonymizeDelay','',NULL,'Delay for anonymizing patrons', 'Integer'),
+('PatronRemovalDelay','',NULL,'Delay for removing anonymized patrons', 'Integer')
+    |);
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 21336 - Add preferences)\n";
+}
+
+$DBversion = '18.12.00.051';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( "UPDATE borrowers SET login_attempts = ? WHERE login_attempts > ?", undef, C4::Context->preference('FailedLoginAttempts'), C4::Context->preference('FailedLoginAttempts') );
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 21336 - Reset login_attempts)\n";
+}
+
+$DBversion = '18.12.00.052';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `type` ) VALUES
+        ('OpacMoreSearches', '', NULL, 'Add additional elements to the OPAC more searches bar', 'Textarea')
+    } );
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 22311 - Add a SysPref to allow adding content to the #moresearches div in the opac)\n";
+}
+
+$DBversion = '18.12.00.053';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO `systempreferences` (`variable`, `value`, `options`, `explanation`, `type`) VALUES
+        ('AutoReturnCheckedOutItems', '0', '', 'If disabled, librarian must confirm return of checked out item when checking out to another.', 'YesNo');
+    });
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 17171 - Add a syspref to allow currently issued items to be issued to a new patron without staff confirmation)\n";
+}
+
+$DBversion = '18.12.00.054';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        INSERT IGNORE permissions (module_bit, code, description)
+        VALUES
+        (9,'advanced_editor','Use the advanced cataloging editor')
+    });
+    if( C4::Context->preference('EnableAdvancedCatalogingEditor') ){
+        $dbh->do(q{
+            INSERT INTO user_permissions (borrowernumber, module_bit, code)
+            SELECT borrowernumber, 9, 'advanced_editor' FROM borrowers WHERE borrowernumber IN (SELECT DISTINCT borrowernumber FROM user_permissions WHERE code = 'edit_catalogue');
+        });
+    }
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 20128: Add permission for Advanced Cataloging Editor)\n";
+}
+
+$DBversion = '18.12.00.055';
+if ( CheckVersion($DBversion) ) {
+
+    $dbh->do(qq{
+        UPDATE
+          `account_offset_types`
+        SET
+          type = 'OVERDUE'
+        WHERE
+          type = 'Fine';
+    });
+
+    $dbh->do(qq{
+        UPDATE
+          `account_offset_types`
+        SET
+          type = 'OVERDUE_INCREASE'
+        WHERE
+          type = 'fine_increase';
+    });
+
+    $dbh->do(qq{
+        UPDATE
+          `account_offset_types`
+        SET
+          type = 'OVERDUE_DECREASE'
+        WHERE
+          type = 'fine_decrease';
+    });
+
+    if ( column_exists( 'accountlines', 'accounttype' ) ) {
+        $dbh->do(
+            qq{
+            ALTER TABLE `accountlines`
+            CHANGE COLUMN `accounttype`
+              `accounttype` varchar(16) DEFAULT NULL;
+          }
+        );
+    }
+
+    $dbh->do(qq{
+        UPDATE
+          accountlines
+        SET
+          accounttype = 'OVERDUE',
+          status = 'UNRETURNED'
+        WHERE
+          accounttype = 'FU';
+    });
+
+    $dbh->do(qq{
+        UPDATE
+          accountlines
+        SET
+          accounttype = 'OVERDUE',
+          status = 'FORGIVEN'
+        WHERE
+          accounttype = 'FFOR';
+    });
+
+    $dbh->do(qq{
+        UPDATE
+          accountlines
+        SET
+          accounttype = 'OVERDUE',
+          status = 'RETURNED'
+        WHERE
+          accounttype = 'F';
+    });
+    SetVersion($DBversion);
+    print "Upgrade to $DBversion done (Bug 22521 - Update accountlines.accounttype to varchar(16), and map new statuses)\n";
+}
+
+$DBversion = '18.12.00.056';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( "UPDATE systempreferences SET explanation = 'This syspref allows to define custom rules for hiding specific items at the OPAC. See http://wiki.koha-community.org/wiki/OpacHiddenItems for more information.' WHERE variable = 'OpacHiddenItems'");
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 8701 - Update OpacHiddenItems system preference description)\n";
+}
+
+$DBversion = '18.12.00.057';
+if( CheckVersion( $DBversion ) ) {
+    if( column_exists('statistics', 'associatedborrower') ) {
+        $dbh->do(q{ ALTER TABLE statistics DROP COLUMN associatedborrower });
+    }
+    if( column_exists('statistics', 'usercode') ) {
+        $dbh->do(q{ ALTER TABLE statistics DROP COLUMN usercode });
+    }
+
+    SetVersion($DBversion);
+    print "Upgrade to $DBversion done (Bug 13795 - Delete unused fields from statistics table)\n";
+}
+
+$DBversion = '18.12.00.058';
+if( CheckVersion( $DBversion ) ) {
+    my $opaclang = C4::Context->preference("opaclanguages");
+    my @langs;
+    push @langs, split ( '\,', $opaclang );
+    # Get any existing value from the OpacNavRight system preference
+    my ($OpacNavRight) = $dbh->selectrow_array( q|
+        SELECT value FROM systempreferences WHERE variable='OpacNavRight';
+    |);
+    if( $OpacNavRight ){
+        # If there is a value in the OpacNavRight preference, insert it into opac_news
+        $dbh->do("INSERT INTO opac_news (branchcode, lang, title, content ) VALUES (NULL, ?, '', ?)", undef, "OpacNavRight_$langs[0]", $OpacNavRight);
+    }
+    # Remove the OpacNavRight system preference
+    $dbh->do("DELETE FROM systempreferences WHERE variable='OpacNavRight'");
+    SetVersion ($DBversion);
+    print "Upgrade to $DBversion done (Bug 22318: Move contents of OpacNavRight preference to Koha news system)\n";
+}
+
+$DBversion = '18.12.00.059';
+if( CheckVersion( $DBversion ) ) {
+    if( column_exists( 'import_records', 'z3950random' ) ) {
+        $dbh->do( "ALTER TABLE import_records DROP COLUMN z3950random" );
+    }
+
+    # Always end with this (adjust the bug info)
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 22532 - Remove import_records z3950random column)\n";
+}
+
+$DBversion = '18.12.00.060';
+if ( CheckVersion($DBversion) ) {
+
+    my $rows = $dbh->do(
+        qq{
+        UPDATE `accountlines`
+        SET
+          `accounttype` = 'L',
+          `status`      = 'REPLACED'
+        WHERE
+          `accounttype` = 'Rep'
+      }
+    );
+
+    SetVersion($DBversion);
+    printf "Upgrade to $DBversion done (Bug 22564 - Fix accounttype 'Rep' - %d updated)\n", $rows;
+}
+
+$DBversion = '18.12.00.061';
+if( CheckVersion( $DBversion ) ) {
+
+    if ( column_exists( 'borrowers', 'flgAnonymized' ) ) {
+        $dbh->do(q{
+            UPDATE borrowers SET flgAnonymized = 0 WHERE flgAnonymized IS NULL
+        });
+        $dbh->do(q{
+            ALTER TABLE borrowers
+                CHANGE `flgAnonymized` `anonymized` TINYINT(1) NOT NULL DEFAULT 0
+        });
+    }
+
+    if ( column_exists( 'deletedborrowers', 'flgAnonymized' ) ) {
+        $dbh->do(q{
+            UPDATE deletedborrowers SET flgAnonymized = 0 WHERE flgAnonymized IS NULL
+        });
+        $dbh->do(q{
+            ALTER TABLE deletedborrowers
+                CHANGE `flgAnonymized` `anonymized` TINYINT(1) NOT NULL DEFAULT 0
+        });
+    }
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 21336 - (follow-up) Rename flgAnonymized column)\n";
+}
+
+$DBversion = '18.12.00.062';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( q|
+        UPDATE search_marc_map SET marc_field='007_/0'
+          WHERE marc_type IN ('marc21', 'normarc') AND marc_field='007_/1' AND id IN
+            (SELECT search_marc_map_id FROM search_marc_to_field WHERE search_field_id IN
+              (SELECT id FROM search_field WHERE label='ff7-00')
+            )
+    |);
+
+    $dbh->do( q|
+        UPDATE search_marc_map SET marc_field='007_/1'
+          WHERE marc_type IN ('marc21', 'normarc') AND marc_field='007_/2' AND id IN
+            (SELECT search_marc_map_id FROM search_marc_to_field WHERE search_field_id IN
+              (SELECT id FROM search_field WHERE label='ff7-01')
+            )
+    |);
+
+    $dbh->do( q|
+        UPDATE search_marc_map SET marc_field='007_/2'
+          WHERE marc_type IN ('marc21', 'normarc') AND marc_field='007_/3' AND id IN
+            (SELECT search_marc_map_id FROM search_marc_to_field WHERE search_field_id IN
+              (SELECT id FROM search_field WHERE label='ff7-02')
+            )
+    |);
+
+    # N.B. ff7-01-02 really is 00-01!
+    $dbh->do( q|
+        UPDATE search_marc_map SET marc_field='007_/0-1'
+          WHERE marc_type IN ('marc21', 'normarc') AND marc_field='007_/1-2' AND id IN
+            (SELECT search_marc_map_id FROM search_marc_to_field WHERE search_field_id IN
+              (SELECT id FROM search_field WHERE label='ff7-01-02')
+            )
+    |);
+
+    $dbh->do( q|
+        UPDATE search_marc_map SET marc_field='008_/0-5'
+          WHERE marc_type IN ('marc21', 'normarc') AND marc_field='008_/1-5' AND id IN
+            (SELECT search_marc_map_id FROM search_marc_to_field WHERE search_field_id IN
+              (SELECT id FROM search_field WHERE label='date-entered-on-file')
+            )
+    |);
+
+    $dbh->do( q|
+        UPDATE search_marc_map SET marc_field='leader_/0-4'
+          WHERE marc_type IN ('marc21', 'normarc') AND marc_field='leader_/1-5' AND id IN
+            (SELECT search_marc_map_id FROM search_marc_to_field WHERE search_field_id IN
+              (SELECT id FROM search_field WHERE label='llength')
+            )
+    |);
+
+    # Always end with this (adjust the bug info)
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 22339 - Fix search field mappings of MARC fixed fields)\n";
+}
+
+$DBversion = '18.12.00.063';
+if ( CheckVersion($DBversion) ) {
+
+    my $types_map = {
+        'Writeoff'      => 'W',
+        'Payment'       => 'Pay',
+        'Lost Item'     => 'CR',
+        'Manual Credit' => 'C',
+        'Forgiven'      => 'FOR'
+    };
+
+    my $sth = $dbh->prepare( "SELECT accountlines_id FROM accountlines WHERE accounttype = 'VOID'" );
+    my $sth2 = $dbh->prepare( "SELECT type FROM account_offsets WHERE credit_id = ? ORDER BY created_on LIMIT 1" );
+    my $sth3 = $dbh->prepare( "UPDATE accountlines SET accounttype = ?, status = 'VOID' WHERE accountlines_id = ?" );
+    $sth->execute();
+    while (my $row = $sth->fetchrow_hashref) {
+        $sth2->execute($row->{accountlines_id});
+        my $result = $sth2->fetchrow_hashref;
+        my $type = $types_map->{$result->{'type'}} // 'Pay';
+        $sth3->execute($type,$row->{accountlines_id});
+    }
+
+    SetVersion($DBversion);
+    print "Upgrade to $DBversion done (Bug 22511 - Update existing VOID accountlines)\n";
+}
+
+$DBversion = '18.12.00.064';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences (variable,value,options,explanation,type) VALUES ('UpdateItemLocationOnCheckin', 'PROC: _PERM_\n', 'NULL', 'This is a list of value pairs.\n Examples:\n PROC: FIC - causes an item in the Processing Center location to be updated into the Fiction location on check in.\n FIC: GEN - causes an item in the Fiction location to be updated into the General stacks location on check in.\n _BLANK_:FIC - causes an item that has no location to be updated into the Fiction location on check in.\nFIC: _BLANK_ - causes an item in location FIC to be updated to a blank location on check in.\n_ALL_:FIC - causes all items to be updated into the Fiction location on check in.\nPROC: _PERM_ - causes an item that is in the Processing Center to be updated to it''s permanent location.\nGeneral rule: if the location value on the left matches the item''s current location, it will be updated to match the location value on the right.\nNote: PROC and CART are special values, for these locations only can location and permanent_location differ, in all other cases an update will affect both. Items in the CART location will be returned to their permanent location on checkout.\nThe special term _BLANK_ may be used on either side of a value pair to update or remove the location from items with no location assigned. The special term _ALL_ is used on the left side of the colon (:) to affect all items.\nThe special term _PERM_ is used on the right side of the colon (:) to return items to their permanent location.', 'Free');
+    });
+    $dbh->do(q{
+        UPDATE systempreferences s1, (SELECT IF(value,'PROC: CART\n','') AS p2c FROM systempreferences WHERE variable='InProcessingToShelvingCart') s2 SET s1.value= CONCAT(s2.p2c, REPLACE(s1.value,'PROC: _PERM_\n','') ) WHERE s1.variable='UpdateItemLocationOnCheckin' AND s1.value NOT LIKE '%PROC: CART%';
+    });
+    $dbh->do(q{
+        DELETE FROM systempreferences WHERE variable='InProcessingToShelvingCart';
+    });
+    $dbh->do(q{
+        UPDATE systempreferences s1, (SELECT IF(value,'_ALL_: CART\n','') AS rtc FROM systempreferences WHERE variable='ReturnToShelvingCart') s2 SET s1.value= CONCAT(s2.rtc,s1.value) WHERE s1.variable='UpdateItemLocationOnCheckin' AND s1.value NOT LIKE '%_ALL_: CART%';
+    });
+    $dbh->do(q{
+        DELETE FROM systempreferences WHERE variable='ReturnToShelvingCart';
+    });
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 14576: Add UpdateItemLocationOnCheckin syspref)\n";
+}
+
+$DBversion = '18.12.00.065';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( q{
+        INSERT IGNORE INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `type` )
+        SELECT 'IndependentBranchesTransfers', value, NULL, 'Allow non-superlibrarians to transfer items between libraries','YesNo'
+        FROM systempreferences WHERE variable = 'IndependentBranches'
+    });
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 10300 - Allow transferring of items to be have separate IndependentBranches syspref)\n";
+}
+
+$DBversion = '18.12.00.066';
+if ( CheckVersion($DBversion) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO `systempreferences` (`variable`, `value`, `explanation`, `options`, `type`) VALUES
+          ('OpenURLResolverURL', '', 'URL of OpenURL Resolver', NULL, 'Free'),
+          ('OpenURLText', '', 'Text of OpenURL links (or image title if OpenURLImageLocation is defined)', NULL, 'Free'),
+          ('OpenURLImageLocation', '', 'Location of image for OpenURL links', NULL, 'Free'),
+          ('OPACShowOpenURL', '', 'Enable display of OpenURL links in OPAC search results and detail page', NULL, 'YesNo'),
+          ('OPACOpenURLItemTypes', '', 'Show the OpenURL link only for these item types', NULL, 'Free');
+    });
+
+    SetVersion($DBversion);
+    print
+"Upgrade to $DBversion done (Bug 8995 - Add new preferences for OpenURLResolvers)\n";
+}
+
+$DBversion = '18.12.00.067';
+if ( CheckVersion($DBversion) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences (variable,value,options,explanation,type)
+        VALUES ('SendAllEmailsTo','',NULL,'All emails will be redirected to this email if it is not empty','free');
+    });
+    SetVersion($DBversion);
+    print
+"Upgrade to $DBversion done (Bug 8000 - Add new preferences for SendAllEmailsTo)\n";
+}
+
+$DBversion = '18.12.00.068';
+if ( CheckVersion($DBversion) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES
+        ('AllowRenewalOnHoldOverride','0','','If on, allow items on hold to be renewed with a specified due date','YesNo');
+    });
+    SetVersion($DBversion);
+    print "Upgrade to $DBversion done (Bug 7088: Cannot renew items on hold even with override)\n";
+}
+
+$DBversion = '18.12.00.069';
+if( CheckVersion( $DBversion ) ) {
+
+    $dbh->do(q{
+        INSERT INTO plugin_data
+            (plugin_class, plugin_key, plugin_value)
+        SELECT
+            plugin_class,
+            '__ENABLED__',
+            1
+        FROM plugin_data
+        WHERE plugin_key='__INSTALLED_VERSION__'
+    });
+
+    # Always end with this (adjust the bug info)
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 22053 - enable all plugins)\n";
+}
+
+$DBversion = '18.12.00.070';
+if ( CheckVersion($DBversion) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences
+            ( `variable`, `value`, `options`, `explanation`, `type` )
+        VALUES
+        ('SelfCheckAllowByIPRanges','',NULL,'(Leave blank if not used. Use ranges or simple ip addresses separated by spaces, like <code>192.168.1.1 192.168.0.0/24</code>.)','Short');
+    });
+    SetVersion($DBversion);
+    print "Upgrade to $DBversion done (Bug 14407 - Limit web-based self-checkout to specific IP addresses)\n";
+}
+
+$DBversion = '18.12.00.071';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+INSERT IGNORE INTO `letter` (`module`, `code`, `branchcode`, `name`, `is_html`, `title`, `content`, `message_transport_type`, `lang`) VALUES
+('circulation', 'ACCOUNT_CREDIT', '', 'Account payment', 0, 'Account payment', '<table>
+[% IF ( LibraryName ) %]
+ <tr>
+    <th colspan="4" class="centerednames">
+        <h3>[% LibraryName | html %]</h3>
+    </th>
+ </tr>
+[% END %]
+ <tr>
+    <th colspan="4" class="centerednames">
+        <h2><u>Fee receipt</u></h2>
+    </th>
+ </tr>
+ <tr>
+    <th colspan="4" class="centerednames">
+        <h2>[% Branches.GetName( patron.branchcode ) | html %]</h2>
+    </th>
+ </tr>
+ <tr>
+    <th colspan="4">
+        Received with thanks from  [% patron.firstname | html %] [% patron.surname | html %] <br />
+        Card number: [% patron.cardnumber | html %]<br />
+    </th>
+ </tr>
+  <tr>
+    <th>Date</th>
+    <th>Description of charges</th>
+    <th>Note</th>
+    <th>Amount</th>
+ </tr>
+
+  [% FOREACH account IN accounts %]
+    <tr class="highlight">
+      <td>[% account.date | $KohaDates %]</td>
+      <td>
+        [% PROCESS account_type_description account=account %]
+        [%- IF account.description %], [% account.description | html %][% END %]
+      </td>
+      <td>[% account.note | html %]</td>
+      [% IF ( account.amountcredit ) %]<td class="credit">[% ELSE %]<td class="debit">[% END %][% account.amount | $Price %]</td>
+    </tr>
+
+  [% END %]
+<tfoot>
+  <tr>
+    <td colspan="3">Total outstanding dues as on date: </td>
+    [% IF ( totalcredit ) %]<td class="credit">[% ELSE %]<td class="debit">[% END %][% total | $Price %]</td>
+  </tr>
+</tfoot>
+</table>', 'print', 'default');
+    });
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 22809 - Move 'ACCOUNT_CREDIT' from template to a slip)\n";
+}
+
+$DBversion = '18.12.00.072';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+INSERT IGNORE INTO `letter` (`module`, `code`, `branchcode`, `name`, `is_html`, `title`, `content`, `message_transport_type`, `lang`) VALUES
+('circulation', 'ACCOUNT_DEBIT', '', 'Account fee', 0, 'Account fee', '<table>
+  [% IF ( LibraryName ) %]
+    <tr>
+      <th colspan="5" class="centerednames">
+        <h3>[% LibraryName | html %]</h3>
+      </th>
+    </tr>
+  [% END %]
+
+  <tr>
+    <th colspan="5" class="centerednames">
+      <h2><u>INVOICE</u></h2>
+    </th>
+  </tr>
+  <tr>
+    <th colspan="5" class="centerednames">
+      <h2>[% Branches.GetName( patron.branchcode ) | html %]</h2>
+    </th>
+  </tr>
+  <tr>
+    <th colspan="5" >
+      Bill to: [% patron.firstname | html %] [% patron.surname | html %] <br />
+      Card number: [% patron.cardnumber | html %]<br />
+    </th>
+  </tr>
+  <tr>
+    <th>Date</th>
+    <th>Description of charges</th>
+    <th>Note</th>
+    <th style="text-align:right;">Amount</th>
+    <th style="text-align:right;">Amount outstanding</th>
+  </tr>
+
+  [% FOREACH account IN accounts %]
+    <tr class="highlight">
+      <td>[% account.date | $KohaDates%]</td>
+      <td>
+        [% PROCESS account_type_description account=account %]
+        [%- IF account.description %], [% account.description | html %][% END %]
+      </td>
+      <td>[% account.note | html %]</td>
+      [% IF ( account.amountcredit ) %]<td class="credit">[% ELSE %]<td class="debit">[% END %][% account.amount | $Price %]</td>
+      [% IF ( account.amountoutstandingcredit ) %]<td class="credit">[% ELSE %]<td class="debit">[% END %][% account.amountoutstanding | $Price %]</td>
+    </tr>
+  [% END %]
+
+  <tfoot>
+    <tr>
+      <td colspan="4">Total outstanding dues as on date: </td>
+      [% IF ( totalcredit ) %]<td class="credit">[% ELSE %]<td class="debit">[% END %][% total | $Price %]</td>
+    </tr>
+  </tfoot>
+</table>', 'print', 'default');
+    });
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 22809 - Move 'INVOICE' from template to a slip)\n";
+}
+
+$DBversion = '18.12.00.073';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( q{
+            INSERT IGNORE INTO systempreferences (variable,value,options,explanation,type) VALUES
+            ('EmailPurchaseSuggestions','0','0|EmailAddressForSuggestions|BranchEmailAddress|KohaAdminEmailAddress','Choose email address that will be sent new purchase suggestions','Choice'),
+            ('EmailAddressForSuggestions','','','If you choose EmailAddressForSuggestions you should enter a valid email address','free')
+    });
+
+    $dbh->do( q{
+            INSERT IGNORE INTO `letter` (module, code, name, title, content, is_html, message_transport_type) VALUES
+            ('suggestions','NEW_SUGGESTION','New suggestion','New suggestion','<h3>Suggestion pending approval</h3>
+                <p><h4>Suggested by</h4>
+                    <ul>
+                        <li><<borrowers.firstname>> <<borrowers.surname>></li>
+                        <li><<borrowers.cardnumber>></li>
+                        <li><<borrowers.phone>></li>
+                        <li><<borrowers.email>></li>
+                    </ul>
+                </p>
+                <p><h4>Title suggested</h4>
+                    <ul>
+                        <li><b>Library:</b> <<branches.branchname>></li>
+                        <li><b>Title:</b> <<suggestions.title>></li>
+                        <li><b>Author:</b> <<suggestions.author>></li>
+                        <li><b>Copyright date:</b> <<suggestions.copyrightdate>></li>
+                        <li><b>Standard number (ISBN, ISSN or other):</b> <<suggestions.isbn>></li>
+                        <li><b>Publisher:</b> <<suggestions.publishercode>></li>
+                        <li><b>Collection title:</b> <<suggestions.collectiontitle>></li>
+                        <li><b>Publication place:</b> <<suggestions.place>></li>
+                        <li><b>Quantity:</b> <<suggestions.quantity>></li>
+                        <li><b>Item type:</b> <<suggestions.itemtype>></li>
+                        <li><b>Reason for suggestion:</b> <<suggestions.patronreason>></li>
+                        <li><b>Notes:</b> <<suggestions.note>></li>
+                    </ul>
+                </p>',1, 'email')
+    });
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 5770 - Email librarian when purchase suggestion made)\n";
+}
+
+$DBversion = '18.12.00.074';
+if( CheckVersion( $DBversion ) ) {
+    unless ( TableExists( 'keyboard_shortcuts' ) ) {
+        $dbh->do(q|
+            CREATE TABLE keyboard_shortcuts (
+            shortcut_name varchar(80) NOT NULL,
+            shortcut_keys varchar(80) NOT NULL,
+            PRIMARY KEY (shortcut_name)
+            ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;|
+        );
+    }
+    $dbh->do(q|
+        INSERT IGNORE INTO keyboard_shortcuts (shortcut_name, shortcut_keys) VALUES
+        ("insert_copyright","Alt-C"),
+        ("insert_copyright_sound","Alt-P"),
+        ("insert_delimiter","Ctrl-D"),
+        ("subfield_help","Ctrl-H"),
+        ("link_authorities","Shift-Ctrl-L"),
+        ("delete_field","Ctrl-X"),
+        ("delete_subfield","Shift-Ctrl-X"),
+        ("new_line","Enter"),
+        ("line_break","Shift-Enter"),
+        ("next_position","Tab"),
+        ("prev_position","Shift-Tab")
+        ;|
+    );
+    $dbh->do(q|
+        INSERT IGNORE permissions (module_bit, code, description)
+        VALUES
+        (3,'manage_keyboard_shortcuts','Manage keyboard shortcuts for advanced cataloging editor')
+        ;|
+    );
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 21411 - Add keyboard_shortcuts table)\n";
+}
+
+$DBversion = '18.12.00.075';
+if( CheckVersion( $DBversion ) ) {
+    # you can use $dbh here like:
+    unless ( foreign_key_exists( 'tmp_holdsqueue', 'tmp_holdsqueue_ibfk_1' ) ) {
+        $dbh->do(q{
+            DELETE t FROM tmp_holdsqueue t
+            LEFT JOIN items i ON t.itemnumber=i.itemnumber
+            WHERE i.itemnumber IS NULL
+        });
+        $dbh->do(q{
+            ALTER TABLE tmp_holdsqueue
+            ADD CONSTRAINT `tmp_holdsqueue_ibfk_1` FOREIGN KEY (`itemnumber`)
+            REFERENCES `items` (`itemnumber`) ON DELETE CASCADE ON UPDATE CASCADE
+        });
+    }
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 22899 - Add items constraint to tmp_holdsqueue)\n";
+}
+
+$DBversion = '19.05.00.000';
+if( CheckVersion( $DBversion ) ) {
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (19.05.00 release)\n";
+}
+
+$DBversion = '19.06.00.000';
+if( CheckVersion( $DBversion ) ) {
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Wingardium Leviosa!)\n";
+}
+
+$DBversion = '19.06.00.001'; 
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( q{
+        UPDATE systempreferences 
+        SET explanation = 'This is a list of value pairs.\n Examples:\n PROC: FIC - causes an item in the Processing Center location to be updated into the Fiction location on check in.\n FIC: GEN - causes an item in the Fiction location to be updated into the General stacks location on check in.\n _BLANK_:FIC - causes an item that has no location to be updated into the Fiction location on check in.\nFIC: _BLANK_ - causes an item in location FIC to be updated to a blank location on check in.\n_ALL_:FIC - causes all items to be updated into the Fiction location on check in.\nPROC: _PERM_ - causes an item that is in the Processing Center to be updated to it''s permanent location.\nGeneral rule: if the location value on the left matches the item''s current location, it will be updated to match the location value on the right.\nNote: PROC and CART are special values, for these locations only can location and permanent_location differ, in all other cases an update will affect both. Items in the CART location will be returned to their permanent location on checkout.\nThe special term _BLANK_ may be used on either side of a value pair to update or remove the location from items with no location assigned. The special term _ALL_ is used on the left side of the colon (:) to affect all items.\nThe special term _PERM_ is used on the right side of the colon (:) to return items to their permanent location.' 
+        WHERE variable = 'UpdateItemLocationOnCheckin'
+    });
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 22960: Fix typo in syspref description)\n";
+}
+
+$DBversion = '19.06.00.002';
+if ( CheckVersion($DBversion) ) {
+
+    $dbh->do(q{ALTER TABLE subscriptionhistory CHANGE opacnote opacnote LONGTEXT NULL});
+    $dbh->do(q{ALTER TABLE subscriptionhistory CHANGE librariannote librariannote LONGTEXT NULL});
+
+    $dbh->do(q{UPDATE subscriptionhistory SET opacnote = NULL WHERE opacnote = ''});
+    $dbh->do(q{UPDATE subscriptionhistory SET librariannote = NULL WHERE librariannote = ''});
+
+    SetVersion ($DBversion);
+    print "Upgrade to $DBversion done (Bug 10215 - Increase the size of opacnote and librariannote for table subscriptionhistory)\n";
+}
+
+$DBversion = '19.06.00.003';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{UPDATE systempreferences SET value = REPLACE( value, ' ', '|' ) WHERE variable = 'UniqueItemFields'; });
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 22867 - UniqueItemFields preference value should be pipe-delimited)\n";
+}
+
+$DBversion = '19.06.00.004';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( 'UPDATE language_descriptions SET description = "Griechisch (Modern 1453-)"
+      WHERE subtag = "el" and type = "language" and lang ="de"' );
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 22770 - Fix typo in language description for el in German)\n";
+}
+
+$DBversion = '19.06.00.005';
+if( CheckVersion( $DBversion ) ) {
+    unless ( column_exists( 'reserves', 'item_level_hold' ) ) {
+        $dbh->do( "ALTER TABLE reserves ADD COLUMN item_level_hold BOOLEAN NOT NULL DEFAULT 0 AFTER itemtype" );
+    }
+    unless ( column_exists( 'old_reserves', 'item_level_hold' ) ) {
+        $dbh->do( "ALTER TABLE old_reserves ADD COLUMN item_level_hold BOOLEAN NOT NULL DEFAULT 0 AFTER itemtype" );
+    }
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 9834 - Add the reserves.item_level_hold column)\n";
+}
+
+$DBversion = '19.06.00.006';
+if( CheckVersion( $DBversion ) ) {
+
+    unless ( TableExists('plugin_methods') ) {
+        $dbh->do(q{
+            CREATE TABLE plugin_methods (
+              plugin_class varchar(255) NOT NULL,
+              plugin_method varchar(255) NOT NULL,
+              PRIMARY KEY ( `plugin_class` (191), `plugin_method` (191) )
+            ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+        });
+    }
+
+    require Koha::Plugins;
+    Koha::Plugins->new({ enable_plugins => 1 })->InstallPlugins;
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 21073 - Improve plugin performance)\n";
+}
+
+$DBversion = '19.06.00.007';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( "DELETE FROM systempreferences WHERE variable = 'RotationPreventTransfers'" );
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 22653 - Remove unimplemented RotationPreventTransfers system preference)\n";
+}
+
+$DBversion = '19.06.00.008';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( "UPDATE userflags SET flagdesc = 'Allow staff members to modify permissions and passwords for other staff members' WHERE flag = 'staffaccess'" );
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 23109 - Improve description of staffaccess permission)\n";
+}
+
+$DBversion = '19.06.00.009';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO keyboard_shortcuts (shortcut_name, shortcut_keys)
+            VALUES ("toggle_keyboard", "Shift-Ctrl-K")
+    });
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 17178 - add shortcut to keyboard_shortcuts)\n";
+}
+
+$DBversion = '19.06.00.010';
+if( CheckVersion( $DBversion ) ) {
+
+    if ( TableExists('default_circ_rules') ) {
+        if ( column_exists( 'default_circ_rules', 'holdallowed' ) ) {
+            $dbh->do("
+                INSERT IGNORE INTO circulation_rules ( categorycode, branchcode, itemtype, rule_name, rule_value )
+                SELECT NULL, NULL, NULL, 'holdallowed', holdallowed
+                FROM default_circ_rules
+            ");
+            $dbh->do("
+                INSERT IGNORE INTO circulation_rules ( categorycode, branchcode, itemtype, rule_name, rule_value )
+                SELECT NULL, NULL, NULL, 'hold_fulfillment_policy', hold_fulfillment_policy
+                FROM default_circ_rules
+            ");
+            $dbh->do("
+                INSERT IGNORE INTO circulation_rules ( categorycode, branchcode, itemtype, rule_name, rule_value )
+                SELECT NULL, NULL, NULL, 'returnbranch', returnbranch
+                FROM default_circ_rules
+            ");
+            $dbh->do("DROP TABLE default_circ_rules");
+        }
+    }
+
+    if ( TableExists('default_branch_circ_rules') ) {
+        if ( column_exists( 'default_branch_circ_rules', 'holdallowed' ) ) {
+            $dbh->do("
+                INSERT IGNORE INTO circulation_rules ( categorycode, branchcode, itemtype, rule_name, rule_value )
+                SELECT NULL, branchcode, NULL, 'holdallowed', holdallowed
+                FROM default_branch_circ_rules
+            ");
+            $dbh->do("
+                INSERT IGNORE INTO circulation_rules ( categorycode, branchcode, itemtype, rule_name, rule_value )
+                SELECT NULL, branchcode, NULL, 'hold_fulfillment_policy', hold_fulfillment_policy
+                FROM default_branch_circ_rules
+            ");
+            $dbh->do("
+                INSERT IGNORE INTO circulation_rules ( categorycode, branchcode, itemtype, rule_name, rule_value )
+                SELECT NULL, branchcode, NULL, 'returnbranch', returnbranch
+                FROM default_branch_circ_rules
+            ");
+            $dbh->do("DROP TABLE default_branch_circ_rules");
+        }
+    }
+
+    if ( TableExists('branch_item_rules') ) {
+        if ( column_exists( 'branch_item_rules', 'holdallowed' ) ) {
+            $dbh->do("
+                INSERT IGNORE INTO circulation_rules ( categorycode, branchcode, itemtype, rule_name, rule_value )
+                SELECT NULL, branchcode, itemtype, 'holdallowed', holdallowed
+                FROM branch_item_rules
+            ");
+            $dbh->do("
+                INSERT IGNORE INTO circulation_rules ( categorycode, branchcode, itemtype, rule_name, rule_value )
+                SELECT NULL, branchcode, itemtype, 'hold_fulfillment_policy', hold_fulfillment_policy
+                FROM branch_item_rules
+            ");
+            $dbh->do("
+                INSERT IGNORE INTO circulation_rules ( categorycode, branchcode, itemtype, rule_name, rule_value )
+                SELECT NULL, branchcode, itemtype, 'returnbranch', returnbranch
+                FROM branch_item_rules
+            ");
+            $dbh->do("DROP TABLE branch_item_rules");
+        }
+    }
+
+    if ( TableExists('default_branch_item_rules') ) {
+        if ( column_exists( 'default_branch_item_rules', 'holdallowed' ) ) {
+            $dbh->do("
+                INSERT IGNORE INTO circulation_rules ( categorycode, branchcode, itemtype, rule_name, rule_value )
+                SELECT NULL, NULL, itemtype, 'holdallowed', holdallowed
+                FROM default_branch_item_rules
+            ");
+            $dbh->do("
+                INSERT IGNORE INTO circulation_rules ( categorycode, branchcode, itemtype, rule_name, rule_value )
+                SELECT NULL, NULL, itemtype, 'hold_fulfillment_policy', hold_fulfillment_policy
+                FROM default_branch_item_rules
+            ");
+            $dbh->do("
+                INSERT IGNORE INTO circulation_rules ( categorycode, branchcode, itemtype, rule_name, rule_value )
+                SELECT NULL, NULL, itemtype, 'returnbranch', returnbranch
+                FROM default_branch_item_rules
+            ");
+            $dbh->do("DROP TABLE default_branch_item_rules");
+        }
+    }
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 18928 - Move holdallowed, hold_fulfillment_policy, returnbranch to circulation_rules)\n";
+}
+
+$DBversion = '19.06.00.011';
+if( CheckVersion( $DBversion ) ) {
+
+    if ( TableExists('refund_lost_item_fee_rules') ) {
+        if ( column_exists( 'refund_lost_item_fee_rules', 'refund' ) ) {
+            $dbh->do("
+                INSERT INTO circulation_rules ( categorycode, branchcode, itemtype, rule_name, rule_value )
+                SELECT NULL, IF(branchcode='*', NULL, branchcode), NULL, 'refund', refund
+                FROM refund_lost_item_fee_rules
+            ");
+            $dbh->do("DROP TABLE refund_lost_item_fee_rules");
+        }
+    }
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 18930 - Move lost item refund rules to circulation_rules table)\n";
+}
+
+$DBversion = '19.06.00.012';
+if ( CheckVersion($DBversion) ) {
+
+    # Find and correct pathological cases of LR becoming a credit
+    my $sth = $dbh->prepare( "SELECT accountlines_id, issue_id, borrowernumber, itemnumber, amount, manager_id FROM accountlines WHERE accounttype = 'LR' AND amount < 0" );
+    $sth->execute();
+    while ( my $row = $sth->fetchrow_hashref ) {
+        $dbh->do(
+            "INSERT INTO accountlines (accounttype, issue_id, borrowernumber, itemnumber, amount, manager_id, interface) VALUES ( ?, ?, ?, ?, ?, ?, ? );",
+            {},
+            (
+                'CR',                   $row->{issue_id},
+                $row->{borrowernumber}, $row->{itemnumber},
+                $row->{amount},         $row->{manager_id},
+                'upgrade'
+            )
+        );
+        my $credit_id = $dbh->last_insert_id(undef, undef, 'accountlines', undef);
+        my $amount = $row->{amount} * -1;
+        $dbh->do("INSERT INTO account_offsets (credit_id, debit_id, type, amount) VALUES (?,?,?,?);",{},($credit_id, $row->{accountlines_id}, 'Lost Item', $amount));
+        $dbh->do("UPDATE accountlines SET amount = '$amount' WHERE accountlines_id = '$row->{accountlines_id}';");
+    }
+
+    $dbh->do(qq{
+        UPDATE
+          accountlines
+        SET
+          accounttype = 'LOST',
+          status = 'RETURNED'
+        WHERE
+          accounttype = 'LR';
+    });
+
+    # Find and correct pathalogical cases of L having been converted to W
+    $sth = $dbh->prepare( "SELECT accountlines_id, issue_id, borrowernumber, itemnumber, amount, manager_id FROM accountlines WHERE accounttype = 'W' AND itemnumber IS NOT NULL" );
+    $sth->execute();
+    while ( my $row = $sth->fetchrow_hashref ) {
+        my $amount = $row->{amount} * -1;
+        $dbh->do(
+            "INSERT INTO accountlines (accounttype, issue_id, borrowernumber, itemnumber, amount, manager_id, interface) VALUES ( ?, ?, ?, ?, ?, ?, ? );",
+            {},
+            (
+                'LOST', $row->{issue_id}, $row->{borrowernumber},
+                $row->{itemnumber}, $amount, $row->{manager_id},
+                'upgrade'
+            )
+        );
+        my $debit_id = $dbh->last_insert_id(undef, undef, 'accountlines', undef);
+        $dbh->do(
+            "INSERT INTO account_offsets (credit_id, debit_id, type, amount) VALUES (?,?,?,?);",
+            {},
+            (
+                $row->{accountlines_id}, $debit_id,
+                'Lost Item',    $amount
+            )
+        );
+    }
+
+    $dbh->do(qq{
+        UPDATE
+          accountlines
+        SET
+          accounttype = 'LOST'
+        WHERE
+          accounttype = 'L';
+    });
+
+    $dbh->do(qq{
+        UPDATE
+          accountlines
+        SET
+          accounttype = 'LOST_RETURNED'
+        WHERE
+          accounttype = 'CR';
+    });
+
+    SetVersion($DBversion);
+    print "Upgrade to $DBversion done (Bug 22563 - Fix accounttypes for 'L', 'LR' and 'CR')\n";
+}
+
+# SEE bug 13068
+# if there is anything in the atomicupdate, read and execute it.
+my $update_dir = C4::Context->config('intranetdir') . '/installer/data/mysql/atomicupdate/';
+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 = read_file( $update_dir . $file );
+        eval $code;
+        say "Atomic update generated errors: $@" if $@;
+    }
+}
+
+=head1 FUNCTIONS
+
 =head2 DropAllForeignKeys($table)
 
 Drop all foreign keys of the table $table