Bug 13881: DBRev 19.12.00.054
[koha-ffzg.git] / installer / data / mysql / updatedatabase.pl
index 0dcf446..0f51b28 100755 (executable)
@@ -17366,9 +17366,9 @@ if( CheckVersion( $DBversion ) ) {
 
 $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'" );
+    $dbh->do( "UPDATE action_logs SET info = REPLACE(info,'cardnumber_replaced','cardnumber'), timestamp = timestamp WHERE module='MEMBERS' AND action='MODIFY'" );
+    $dbh->do( "UPDATE action_logs SET info = REPLACE(info,'previous_cardnumber','before'), timestamp = timestamp WHERE module='MEMBERS' AND action='MODIFY'" );
+    $dbh->do( "UPDATE action_logs SET info = REPLACE(info,'new_cardnumber','after'), timestamp = timestamp WHERE module='MEMBERS' AND action='MODIFY'" );
 
     SetVersion( $DBversion );
     print "Upgrade to $DBversion done (Bug 3820 - Update patron modification logs)\n";
@@ -17632,6 +17632,17 @@ if( CheckVersion( $DBversion ) ) {
 $DBversion = '18.12.00.024';
 if ( CheckVersion($DBversion) ) {
 
+    # Fixup any pre-existing bad suggestedby, manageddate, accepteddate dates
+    $dbh->do(
+        "UPDATE suggestions SET suggesteddate = '1970-01-01' WHERE suggesteddate = '0000-00-00';"    
+    );
+    $dbh->do(
+        "UPDATE suggestions SET manageddate = '1970-01-01' WHERE manageddate = '0000-00-00';"    
+    );
+    $dbh->do(
+        "UPDATE suggestions SET accepteddate = '1970-01-01' WHERE accepteddate = '0000-00-00';"    
+    );
+
     # Add constraint for suggestedby
     unless ( foreign_key_exists( 'suggestions', 'suggestions_ibfk_suggestedby' ) )
     {
@@ -18733,7 +18744,7 @@ if ( CheckVersion($DBversion) ) {
     $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";
+    print "Upgrade to $DBversion done (Bug 10215: Increase the size of opacnote and librariannote for table subscriptionhistory)\n";
 }
 
 $DBversion = '19.06.00.003';
@@ -18741,7 +18752,7 @@ 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";
+    print "Upgrade to $DBversion done (Bug 22867: UniqueItemFields preference value should be pipe-delimited)\n";
 }
 
 $DBversion = '19.06.00.004';
@@ -18749,7 +18760,7 @@ 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";
+    print "Upgrade to $DBversion done (Bug 22770: Fix typo in language description for el in German)\n";
 }
 
 $DBversion = '19.06.00.005';
@@ -18762,7 +18773,7 @@ if( CheckVersion( $DBversion ) ) {
     }
 
     SetVersion( $DBversion );
-    print "Upgrade to $DBversion done (Bug 9834 - Add the reserves.item_level_hold column)\n";
+    print "Upgrade to $DBversion done (Bug  9834: Add the reserves.item_level_hold column)\n";
 }
 
 $DBversion = '19.06.00.006';
@@ -18782,21 +18793,21 @@ if( CheckVersion( $DBversion ) ) {
     Koha::Plugins->new({ enable_plugins => 1 })->InstallPlugins;
 
     SetVersion( $DBversion );
-    print "Upgrade to $DBversion done (Bug 21073 - Improve plugin performance)\n";
+    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";
+    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";
+    print "Upgrade to $DBversion done (Bug 23109: Improve description of staffaccess permission)\n";
 }
 
 $DBversion = '19.06.00.009';
@@ -18807,7 +18818,7 @@ if( CheckVersion( $DBversion ) ) {
     });
 
     SetVersion( $DBversion );
-    print "Upgrade to $DBversion done (Bug 17178 - add shortcut to keyboard_shortcuts)\n";
+    print "Upgrade to $DBversion done (Bug 17178: add shortcut to keyboard_shortcuts)\n";
 }
 
 $DBversion = '19.06.00.010';
@@ -18898,7 +18909,7 @@ if( CheckVersion( $DBversion ) ) {
     }
 
     SetVersion( $DBversion );
-    print "Upgrade to $DBversion done (Bug 18928 - Move holdallowed, hold_fulfillment_policy, returnbranch to circulation_rules)\n";
+    print "Upgrade to $DBversion done (Bug 18928: Move holdallowed, hold_fulfillment_policy, returnbranch to circulation_rules)\n";
 }
 
 $DBversion = '19.06.00.011';
@@ -18916,7 +18927,7 @@ if( CheckVersion( $DBversion ) ) {
     }
 
     SetVersion( $DBversion );
-    print "Upgrade to $DBversion done (Bug 18930 - Move lost item refund rules to circulation_rules table)\n";
+    print "Upgrade to $DBversion done (Bug 18930: Move lost item refund rules to circulation_rules table)\n";
 }
 
 $DBversion = '19.06.00.012';
@@ -18996,7 +19007,7 @@ if ( CheckVersion($DBversion) ) {
     });
 
     SetVersion($DBversion);
-    print "Upgrade to $DBversion done (Bug 22563 - Fix accounttypes for 'L', 'LR' and 'CR')\n";
+    print "Upgrade to $DBversion done (Bug 22563: Fix accounttypes for 'L', 'LR' and 'CR')\n";
 }
 
 $DBversion = '19.06.00.013';
@@ -19005,7 +19016,7 @@ if ( CheckVersion( $DBversion ) ) {
         $dbh->do("ALTER TABLE borrower_modifications ADD changed_fields MEDIUMTEXT AFTER verification_token;");
     }
     SetVersion( $DBversion );
-    print "Upgrade to $DBversion done (Bug 23151 - Add borrower_modifications.changed_fields column)\n";
+    print "Upgrade to $DBversion done (Bug 23151: Add borrower_modifications.changed_fields column)\n";
 }
 
 $DBversion = '19.06.00.014';
@@ -19055,7 +19066,7 @@ if ( CheckVersion($DBversion) ) {
     });
 
     SetVersion($DBversion);
-    print "Upgrade to $DBversion done (Bug 11573 - Fix accounttypes for 'Rent')\n";
+    print "Upgrade to $DBversion done (Bug 11573: Fix accounttypes for 'Rent')\n";
 }
 
 $DBversion = '19.06.00.015';
@@ -19063,7 +19074,7 @@ if( CheckVersion( $DBversion ) ) {
     $dbh->do( "UPDATE `search_field` SET `name` = 'date-time-last-modified', `label` = 'date-time-last-modified' WHERE `name` = 'date/time-last-modified'" );
 
     SetVersion( $DBversion );
-    print "Upgrade to $DBversion done (Bug 22524 - Fix date/time-last-modified search with Elasticsearch)\n";
+    print "Upgrade to $DBversion done (Bug 22524: Fix date/time-last-modified search with Elasticsearch)\n";
 }
 
 $DBversion = '19.06.00.016';
@@ -19086,7 +19097,7 @@ if( CheckVersion( $DBversion ) ) {
     ;|);
 
     SetVersion( $DBversion );
-    print "Upgrade to $DBversion done (Bug 23396 - Fix missing keyboard_shortcuts table)\n";
+    print "Upgrade to $DBversion done (Bug 23396: Fix missing keyboard_shortcuts table)\n";
 }
 
 $DBversion = '19.06.00.017';
@@ -19161,7 +19172,7 @@ if ( CheckVersion($DBversion) ) {
     }
 
     SetVersion($DBversion);
-    print "Upgrade to $DBversion done (Bug 22610 - Fix accounttypes for SIP2 payments)\n";
+    print "Upgrade to $DBversion done (Bug 22610: Fix accounttypes for SIP2 payments)\n";
 }
 
 $DBversion = '19.06.00.018';
@@ -19279,7 +19290,7 @@ if ( CheckVersion($DBversion) ) {
 
     SetVersion($DBversion);
     print
-"Upgrade to $DBversion done (Bug 23228 - Add option to automatically display payment receipt for printing after making a payment)\n";
+"Upgrade to $DBversion done (Bug 23228: Add option to automatically display payment receipt for printing after making a payment)\n";
 }
 
 $DBversion = '19.06.00.020';
@@ -19290,7 +19301,7 @@ if( CheckVersion( $DBversion ) ) {
     |);
 
     SetVersion( $DBversion );
-    print "Upgrade to $DBversion done (Bug 23416 - Add PreserveSerialNotes syspref)\n";
+    print "Upgrade to $DBversion done (Bug 23416: Add PreserveSerialNotes syspref)\n";
 }
 
 $DBversion = '19.06.00.021';
@@ -19301,7 +19312,7 @@ if( CheckVersion( $DBversion ) ) {
     |);
     # Always end with this (adjust the bug info)
     SetVersion( $DBversion );
-    print "Upgrade to $DBversion done (Bug 23309 - Can't add new subfields to bibliographic frameworks in strict mode)\n";
+    print "Upgrade to $DBversion done (Bug 23309: Can't add new subfields to bibliographic frameworks in strict mode)\n";
 }
 
 $DBversion = '19.06.00.022';
@@ -19369,7 +19380,7 @@ if ( CheckVersion($DBversion) ) {
     }
 
     SetVersion($DBversion);
-    print "Upgrade to $DBversion done (Bug 14570 - Make it possible to add multiple guarantors to a record)\n";
+    print "Upgrade to $DBversion done (Bug 14570: Make it possible to add multiple guarantors to a record)\n";
 }
 
 $DBversion = '19.06.00.023';
@@ -19380,7 +19391,7 @@ if( CheckVersion( $DBversion ) ) {
     });
 
     SetVersion( $DBversion );
-    print "Upgrade to $DBversion done (Bug 22258 - Add ElasticsearchMARCFormat preference)\n";
+    print "Upgrade to $DBversion done (Bug 22258: Add ElasticsearchMARCFormat preference)\n";
 }
 
 $DBversion = '19.06.00.024';
@@ -19388,14 +19399,14 @@ if( CheckVersion( $DBversion ) ) {
     $dbh->do(q{ALTER TABLE accountlines CHANGE COLUMN accounttype accounttype varchar(80) default NULL});
 
     SetVersion( $DBversion );
-    print "Upgrade to $DBversion done (Bug 23539 - accountlines.accounttype should match authorised_values.authorised_value in size)\n";
+    print "Upgrade to $DBversion done (Bug 23539: accountlines.accounttype should match authorised_values.authorised_value in size)\n";
 }
 
 $DBversion = '19.06.00.025';
 if( CheckVersion( $DBversion ) ) {
     $dbh->do( q/INSERT IGNORE INTO systempreferences (variable,value,options,explanation,type) VALUES (?, ?, ?, ?, ?)/, undef, 'BarcodeSeparators','\s\r\n','','Splitting characters for barcodes','Free' );
     SetVersion( $DBversion );
-    print "Upgrade to $DBversion done (Bug 22996 - Add pref BarcodeSeparators)\n";
+    print "Upgrade to $DBversion done (Bug 22996: Add pref BarcodeSeparators)\n";
 }
 
 $DBversion = '19.06.00.026';
@@ -19427,7 +19438,7 @@ if( CheckVersion( $DBversion ) ) {
     });
 
     SetVersion( $DBversion );
-    print "Upgrade to $DBversion done (Bug 20691 - Add ability for guarantors to view guarantee's fines in OPAC)\n";
+    print "Upgrade to $DBversion done (Bug 20691: Add ability for guarantors to view guarantee's fines in OPAC)\n";
 }
 
 $DBversion = '19.06.00.027';
@@ -19445,7 +19456,7 @@ if( CheckVersion( $DBversion ) ) {
     }
 
     SetVersion( $DBversion );
-    print "Upgrade to $DBversion done (Bug 15497 - Add itemtypes_branches table)\n";
+    print "Upgrade to $DBversion done (Bug 15497: Add itemtypes_branches table)\n";
 }
 
 $DBversion = '19.06.00.028';
@@ -19461,7 +19472,7 @@ if ( CheckVersion($DBversion) ) {
     });
 
     SetVersion($DBversion);
-    print "Upgrade to $DBversion done (Bug 11573 - Fix accounttypes for 'A')\n";
+    print "Upgrade to $DBversion done (Bug 11573: Fix accounttypes for 'A')\n";
 }
 
 $DBversion = '19.06.00.029';
@@ -19510,7 +19521,7 @@ if ( CheckVersion($DBversion) ) {
     });
 
     SetVersion($DBversion);
-    print "Upgrade to $DBversion done (Bug 23321 - Add cash_registers table, permissions and preferences)\n";
+    print "Upgrade to $DBversion done (Bug 23321: Add cash_registers table, permissions and preferences)\n";
 }
 
 $DBversion = '19.06.00.030';
@@ -19553,7 +19564,7 @@ if( CheckVersion( $DBversion ) ) {
 
     # Always end with this (adjust the bug info)
     SetVersion( $DBversion );
-    print "Upgrade to $DBversion done (Bug 19618 - add club_holds tables)\n";
+    print "Upgrade to $DBversion done (Bug 19618: add club_holds tables)\n";
 }
 
 $DBversion = '19.06.00.031';
@@ -19564,7 +19575,7 @@ if( CheckVersion( $DBversion ) ) {
     |);
 
     SetVersion( $DBversion );
-    print "Upgrade to $DBversion done (Bug 23566 - Add OPACDetailQRCode system preference)\n";
+    print "Upgrade to $DBversion done (Bug 23566: Add OPACDetailQRCode system preference)\n";
 }
 
 $DBversion = '19.06.00.032';
@@ -19587,7 +19598,7 @@ if ( CheckVersion($DBversion) ) {
 
     SetVersion($DBversion);
     print
-"Upgrade to $DBversion done (Bug 20589 - Add field boosting and use elastic query fields parameter instead of depricated _all)\n";
+"Upgrade to $DBversion done (Bug 20589: Add field boosting and use elastic query fields parameter instead of depricated _all)\n";
 }
 
 $DBversion = '19.06.00.033';
@@ -19651,14 +19662,14 @@ if( CheckVersion( $DBversion ) ) {
     });
 
     SetVersion( $DBversion );
-    print "Upgrade to $DBversion done (Bug 21701 - PayPal return URL option)\n";
+    print "Upgrade to $DBversion done (Bug 21701: PayPal return URL option)\n";
 }
 
 $DBversion = '19.06.00.038';
 if( CheckVersion( $DBversion ) ) {
     $dbh->do( "UPDATE systempreferences SET variable='PatronAutoComplete' WHERE variable='CircAutocompl' LIMIT 1" );
     SetVersion( $DBversion );
-    print "Upgrade to $DBversion done (Bug 23697 - Rename CircAutocompl system preference to PatronAutoComplete)\n";
+    print "Upgrade to $DBversion done (Bug 23697: Rename CircAutocompl system preference to PatronAutoComplete)\n";
 }
 
 $DBversion = '19.06.00.039';
@@ -19672,7 +19683,7 @@ if( CheckVersion( $DBversion ) ) {
         ;
     |);
     SetVersion( $DBversion );
-    print "Upgrade to $DBversion done (Bug 17179 - Add additional keyboard_shortcuts)\n";
+    print "Upgrade to $DBversion done (Bug 17179: Add additional keyboard_shortcuts)\n";
 }
 
 $DBversion = '19.06.00.040';
@@ -19685,7 +19696,7 @@ if( CheckVersion( $DBversion ) ) {
     |);
 
     SetVersion( $DBversion );
-    print "Upgrade to $DBversion done (Bug 17140 - Add pref to allow rounding fines at payment)\n";
+    print "Upgrade to $DBversion done (Bug 17140: Add pref to allow rounding fines at payment)\n";
 }
 
 $DBversion = '19.06.00.041';
@@ -19715,7 +19726,7 @@ if( CheckVersion( $DBversion ) ) {
     });
 
     SetVersion( $DBversion );
-    print "Upgrade to $DBversion done (Bug 22445 - Add new pref *CustomCoverImages*)\n";
+    print "Upgrade to $DBversion done (Bug 22445: Add new pref *CustomCoverImages*)\n";
 }
 
 $DBversion = '19.06.00.043';
@@ -19887,7 +19898,7 @@ if ( CheckVersion($DBversion) ) {
     unless ( column_exists('accountlines', 'debit_type_code') ) {
         $dbh->do(
             qq{
-                ALTER IGNORE TABLE accountlines
+                ALTER TABLE accountlines
                 ADD
                   debit_type_code varchar(80) DEFAULT NULL
                 AFTER
@@ -19908,7 +19919,7 @@ if ( CheckVersion($DBversion) ) {
     # Populating debit_type_code
     $dbh->do(
         qq{
-        UPDATE accountlines SET debit_type_code = accounttype, accounttype = NULL WHERE accounttype IN (SELECT code from account_debit_types)
+        UPDATE accountlines SET debit_type_code = accounttype, accounttype = NULL WHERE accounttype IN (SELECT code from account_debit_types) AND amount >= 0
         }
     );
 
@@ -19938,7 +19949,7 @@ if ( CheckVersion($DBversion) ) {
     );
 
     SetVersion($DBversion);
-    print "Upgrade to $DBversion done (Bug 23049 - Add account debit_types)\n";
+    print "Upgrade to $DBversion done (Bug 23049: Add account debit_types)\n";
 }
 
 $DBversion = '19.06.00.044';
@@ -19991,7 +20002,7 @@ if ( CheckVersion($DBversion) ) {
     unless ( column_exists('accountlines', 'credit_type_code') ) {
         $dbh->do(
             qq{
-                ALTER IGNORE TABLE accountlines
+                ALTER TABLE accountlines
                 ADD
                   credit_type_code varchar(80) DEFAULT NULL
                 AFTER
@@ -20083,7 +20094,7 @@ if ( CheckVersion($DBversion) ) {
     );
 
     SetVersion($DBversion);
-    print "Upgrade to $DBversion done (Bug 23805 - Add account credit_types)\n";
+    print "Upgrade to $DBversion done (Bug 23805: Add account credit_types)\n";
 }
 
 $DBversion = '19.06.00.045';
@@ -20091,7 +20102,7 @@ if( CheckVersion( $DBversion ) ) {
     $dbh->do( "UPDATE systempreferences SET value = '2' WHERE value = '0' AND variable = 'UsageStats'" );
 
     SetVersion( $DBversion );
-    print "Upgrade to $DBversion done (Bug 23866 - Set HEA syspref to prompt for review)\n";
+    print "Upgrade to $DBversion done (Bug 23866: Set HEA syspref to prompt for review)\n";
 }
 
 $DBversion = '19.06.00.046';
@@ -20107,7 +20118,7 @@ if( CheckVersion( $DBversion ) ) {
 
     # Always end with this (adjust the bug info)
     SetVersion( $DBversion );
-    print "Upgrade to $DBversion done (Bug 15260 - Option for extended loan with useDaysMode)\n";
+    print "Upgrade to $DBversion done (Bug 15260: Option for extended loan with useDaysMode)\n";
 }
 
 $DBversion = '19.06.00.047';
@@ -20169,7 +20180,7 @@ if ( CheckVersion($DBversion) ) {
 
     SetVersion($DBversion);
     print
-"Upgrade to $DBversion done (Bug 14697 - Extend and enhance 'Claims returned' lost status)\n";
+"Upgrade to $DBversion done (Bug 14697: Extend and enhance 'Claims returned' lost status)\n";
 }
 
 $DBversion = '19.06.00.048';
@@ -20182,7 +20193,7 @@ if( CheckVersion( $DBversion ) ) {
     } );
 
     SetVersion( $DBversion );
-    print "Upgrade to $DBversion done (Bug 22581 - add new OPACShowMusicalInscripts and OPACPlayMusicalInscripts system preferences)\n";
+    print "Upgrade to $DBversion done (Bug 22581: add new OPACShowMusicalInscripts and OPACPlayMusicalInscripts system preferences)\n";
 }
 
 $DBversion = '19.06.00.049';
@@ -20201,88 +20212,1160 @@ if( CheckVersion( $DBversion ) ) {
     });
 
     SetVersion( $DBversion );
-    print "Upgrade to $DBversion done (Bug 13958 - Add a SuspensionsCalendar syspref)\n";
+    print "Upgrade to $DBversion done (Bug 13958: Add a SuspensionsCalendar syspref)\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 $@;
+$DBversion = '19.06.00.050';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( q{
+            INSERT IGNORE INTO systempreferences (variable,value,options,explanation,type)
+            VALUES ('OPACFineNoRenewalsIncludeCredits','1',NULL,'If enabled the value specified in OPACFineNoRenewals should include any unapplied account credits in the calculation','YesNo')
+    });
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 23293: Add 'OPACFineNoRenewalsIncludeCredits' system preference)\n";
+}
+
+$DBversion = '19.11.00.000';
+if( CheckVersion( $DBversion ) ) {
+    NewVersion( $DBversion, undef, '19.11.00 release' );
+}
+
+$DBversion = '19.12.00.000';
+if( CheckVersion( $DBversion ) ) {
+    NewVersion( $DBversion, undef, 'Dobbie is a free elf...' );
+}
+
+$DBversion = '19.12.00.001';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( "UPDATE marc_subfield_structure SET kohafield = NULL WHERE kohafield = 'bibliosubject.subject';" );
+    NewVersion( $DBversion, 17831, 'Remove non-existing bibliosubject.subject from frameworks' );
+}
+
+$DBversion = '19.12.00.002';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        UPDATE systempreferences SET
+        variable = 'AllowItemsOnHoldCheckoutSIP',
+        explanation = 'Do not generate RESERVE_WAITING and RESERVED warning when checking out items reserved to someone else via SIP. This allows self checkouts for those items.'
+        WHERE variable = 'AllowItemsOnHoldCheckout'
+    });
+
+    NewVersion( $DBversion, 23233, 'Rename AllowItemsOnHoldCheckout syspref' );
+}
+
+$DBversion = '19.12.00.003';
+if( CheckVersion( $DBversion ) ) {
+
+    if( !column_exists( 'library_groups', 'ft_local_hold_group' ) ) {
+        $dbh->do( "ALTER TABLE library_groups ADD COLUMN ft_local_hold_group tinyint(1) NOT NULL DEFAULT 0 AFTER ft_search_groups_staff" );
     }
+
+    NewVersion( $DBversion, 22284, 'Add ft_local_hold_group column to library_groups' );
 }
 
-=head1 FUNCTIONS
+$DBversion = '19.12.00.004';
+if ( CheckVersion($DBversion) ) {
 
-=head2 DropAllForeignKeys($table)
+    $dbh->do(
+        qq{
+            INSERT IGNORE INTO account_debit_types (
+              code,
+              description,
+              can_be_added_manually,
+              default_amount,
+              is_system
+            )
+            VALUES
+              ('PAYOUT', 'Payment from library to patron', 0, NULL, 1)
+        }
+    );
 
-Drop all foreign keys of the table $table
+    $dbh->do(qq{
+        INSERT IGNORE INTO account_offset_types ( type ) VALUES ('PAYOUT');
+    });
 
-=cut
+    $dbh->do(qq{
+        INSERT IGNORE permissions (module_bit, code, description)
+        VALUES
+        (10, 'payout', 'Perform account payout action')
+    });
 
-sub DropAllForeignKeys {
-    my ($table) = @_;
-    # get the table description
-    my $sth = $dbh->prepare("SHOW CREATE TABLE $table");
+    NewVersion( $DBversion, 24080, ['Add PAYOUT account_debit_type', 'Add PAYOUT account_offset_type', 'Add accounts payout permission'] );
+}
+
+$DBversion = '19.12.00.005';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( "ALTER TABLE action_logs MODIFY COLUMN `timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP" );
+
+    NewVersion( $DBversion, 24329, 'Do not update action_log.timestamp' );
+}
+
+$DBversion = '19.12.00.006';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( q|
+        UPDATE borrowers SET relationship = NULL
+        WHERE relationship = ""
+    |);
+
+    NewVersion( $DBversion, 24263, 'Replace relationship with NULL when empty string' );
+}
+
+$DBversion = '19.12.00.007';
+if ( CheckVersion($DBversion) ) {
+
+    $dbh->do(
+        qq{
+            INSERT IGNORE INTO account_credit_types (code, description, can_be_added_manually, is_system)
+            VALUES
+              ('REFUND', 'A refund applied to a patrons fine', 0, 1)
+        }
+    );
+
+    $dbh->do(qq{
+        INSERT IGNORE INTO account_offset_types ( type ) VALUES ('REFUND');
+    });
+
+    $dbh->do(qq{
+        INSERT IGNORE permissions (module_bit, code, description)
+        VALUES
+        (10, 'refund', 'Perform account refund action')
+    });
+
+    NewVersion( $DBversion, 23442, ['Add REFUND to account_credit_types', 'Add REFUND to account_offset_types', 'Add accounts refund permission'] );
+}
+
+$DBversion = '19.12.00.008';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( 'UPDATE systempreferences SET value = REPLACE(value, "http://worldcat.org", "https://worldcat.org") WHERE variable = "OPACSearchForTitleIn"' );
+    $dbh->do( 'UPDATE systempreferences SET value = REPLACE(value, "http://www.bookfinder.com", "https://www.bookfinder.com") WHERE variable = "OPACSearchForTitleIn"' );
+    $dbh->do( 'UPDATE systempreferences SET value = REPLACE(value, "https://openlibrary.org/search/?", "https://openlibrary.org/search?") WHERE variable = "OPACSearchForTitleIn"' );
+
+    NewVersion( $DBversion, 24206, 'Update OpacSearchForTitleIn system preference' );
+}
+
+$DBversion = '19.12.00.009';
+if( CheckVersion( $DBversion ) ) {
+
+    $dbh->do(q{
+        INSERT IGNORE INTO account_offset_types ( type ) VALUES ( 'Purchase' );
+    });
+
+    $dbh->do(q{
+        INSERT IGNORE INTO account_credit_types ( code, description, can_be_added_manually, is_system )
+        VALUES ('PURCHASE', 'Purchase', 0, 1);
+    });
+
+    my $sth = $dbh->prepare(q{
+        SELECT COUNT(*) FROM authorised_values WHERE category = 'PAYMENT_TYPE' AND authorised_value = 'CASH'
+    });
     $sth->execute;
-    my $vsc_structure = $sth->fetchrow;
-    # split on CONSTRAINT keyword
-    my @fks = split /CONSTRAINT /,$vsc_structure;
-    # parse each entry
-    foreach (@fks) {
-        # isolate what is before FOREIGN KEY, if there is something, it's a foreign key to drop
-        $_ = /(.*) FOREIGN KEY.*/;
-        my $id = $1;
-        if ($id) {
-            # we have found 1 foreign, drop it
-            $dbh->do("ALTER TABLE $table DROP FOREIGN KEY $id");
-            $id="";
+    my $already_exists = $sth->fetchrow;
+    if ( not $already_exists ) {
+        $dbh->do(q{
+           INSERT INTO authorised_values (category,authorised_value,lib) VALUES ('PAYMENT_TYPE','CASH','Cash')
+        });
+    }
+
+    # Updating field in account_debit_types
+    unless ( column_exists('account_debit_types', 'can_be_invoiced') ) {
+        $dbh->do(
+            qq{
+                ALTER TABLE account_debit_types
+                CHANGE COLUMN
+                  can_be_added_manually can_be_invoiced tinyint(1) NOT NULL DEFAULT 1
+              }
+        );
+    }
+    unless ( column_exists('account_debit_types', 'can_be_sold') ) {
+        $dbh->do(
+            qq{
+                ALTER TABLE account_debit_types
+                ADD
+                  can_be_sold tinyint(1) DEFAULT 0
+                AFTER
+                  can_be_invoiced
+              }
+        );
+    }
+
+    $dbh->do(q{
+INSERT IGNORE INTO `letter` (`module`, `code`, `branchcode`, `name`, `is_html`, `title`, `content`, `message_transport_type`, `lang`) VALUES
+('pos', 'RECEIPT', '', 'Point of sale receipt', 0, 'Receipt', '[% PROCESS "accounts.inc" %]
+<table>
+[% IF ( LibraryName ) %]
+ <tr>
+    <th colspan="2" class="centerednames">
+        <h3>[% LibraryName | html %]</h3>
+    </th>
+ </tr>
+[% END %]
+ <tr>
+    <th colspan="2" class="centerednames">
+        <h2>[% Branches.GetName( payment.branchcode ) | html %]</h2>
+    </th>
+ </tr>
+<tr>
+    <th colspan="2" class="centerednames">
+        <h3>[% payment.date | $KohaDates %]</h3>
+</tr>
+<tr>
+  <td>Transaction ID: </td>
+  <td>[% payment.accountlines_id %]</td>
+</tr>
+<tr>
+  <td>Operator ID: </td>
+  <td>[% payment.manager_id %]</td>
+</tr>
+<tr>
+  <td>Payment type: </td>
+  <td>[% payment.payment_type %]</td>
+</tr>
+ <tr></tr>
+ <tr>
+    <th colspan="2" class="centerednames">
+        <h2><u>Fee receipt</u></h2>
+    </th>
+ </tr>
+ <tr></tr>
+ <tr>
+    <th>Description of charges</th>
+    <th>Amount</th>
+  </tr>
+
+  [% FOREACH offset IN offsets %]
+    <tr>
+        <td>[% PROCESS account_type_description account=offset.debit %]</td>
+        <td>[% offset.amount * -1 | $Price %]</td>
+    </tr>
+  [% END %]
+
+<tfoot>
+  <tr class="highlight">
+    <td>Total: </td>
+    <td>[% payment.amount * -1| $Price %]</td>
+  </tr>
+  <tr>
+    <td>Tendered: </td>
+    <td>[% collected | $Price %]</td>
+  </tr>
+  <tr>
+    <td>Change: </td>
+    <td>[% change | $Price %]</td>
+    </tr>
+</tfoot>
+</table>', 'print', 'default');
+    });
+
+    $dbh->do(qq{
+        INSERT IGNORE permissions (module_bit, code, description)
+        VALUES
+        (25, 'takepayment', 'Access the point of sale page and take payments')
+    });
+
+    NewVersion( $DBversion, 23354, [q|Add 'Purchase' account offset type|, q|Add 'RECEIPT' notice for Point of Sale|, q|Add point of sale permissions|] );
+}
+
+$DBversion = '19.12.00.010';
+if( CheckVersion( $DBversion ) ) {
+    if( !column_exists( 'oai_sets_mappings', 'rule_order' ) ) {
+        $dbh->do( "ALTER TABLE oai_sets_mappings ADD COLUMN rule_order INT AFTER set_id, ADD COLUMN rule_operator VARCHAR(3) AFTER rule_order" );
+        $dbh->do( "UPDATE oai_sets_mappings SET rule_operator='or'" );
+        my $sets = $dbh->selectall_arrayref("SELECT * from oai_sets_mappings ORDER BY set_id", { Slice => {} });
+        my $i = 0;
+        my $previous_set_id;
+        for my $set ( @{$sets}) {
+            my $set_id = $set->{set_id};
+    
+            if ($previous_set_id && $previous_set_id != $set_id) {
+                $i = 0;
+            }
+    
+            if ($i == 0) {
+                $dbh->do("UPDATE oai_sets_mappings SET rule_operator=NULL WHERE set_id=? LIMIT 1", {}, $set_id);
+            }
+    
+            $dbh->do("UPDATE oai_sets_mappings SET rule_order=? WHERE set_id=? AND rule_order IS NULL LIMIT 1", {}, $i, $set_id);
+    
+            $i++;
+            $previous_set_id = $set_id;
         }
     }
+
+    NewVersion( $DBversion, 21520, 'Add rule_order and rule_operator fields to oai_sets_mappings table' );
 }
 
+$DBversion = '19.12.00.011';
+if( CheckVersion( $DBversion ) ) {
+    if( !foreign_key_exists( 'repeatable_holidays', 'repeatable_holidays_ibfk_1' ) ) {
+        $dbh->do(q|
+            DELETE h
+            FROM repeatable_holidays h
+            LEFT JOIN branches b ON h.branchcode=b.branchcode
+            WHERE b.branchcode IS NULL;
+        |);
+        $dbh->do(q|
+            ALTER TABLE repeatable_holidays
+            ADD FOREIGN KEY repeatable_holidays_ibfk_1 (branchcode) REFERENCES branches (branchcode) ON DELETE CASCADE ON UPDATE CASCADE
+        |);
+    }
 
-=head2 TransformToNum
+    if( !foreign_key_exists( 'special_holidays', 'special_holidays_ibfk_1' ) ) {
+        $dbh->do(q|
+            DELETE h
+            FROM special_holidays h
+            LEFT JOIN branches b ON h.branchcode=b.branchcode
+            WHERE b.branchcode IS NULL;
+        |);
+        $dbh->do(q|
+            ALTER TABLE special_holidays
+            ADD FOREIGN KEY special_holidays_ibfk_1 (branchcode) REFERENCES branches (branchcode) ON DELETE CASCADE ON UPDATE CASCADE
+        |);
+    }
 
-Transform the Koha version from a 4 parts string
-to a number, with just 1 .
+    NewVersion( $DBversion, 24289, 'Adding foreign keys on *_holidays.branchcode tables' );
+}
 
-=cut
+$DBversion = '19.12.00.012';
+if( CheckVersion( $DBversion ) ) {
 
-sub TransformToNum {
-    my $version = shift;
-    # remove the 3 last . to have a Perl number
-    $version =~ s/(.*\..*)\.(.*)\.(.*)/$1$2$3/;
-    # three X's at the end indicate that you are testing patch with dbrev
-    # change it into 999
-    # prevents error on a < comparison between strings (should be: lt)
-    $version =~ s/XXX$/999/;
-    return $version;
+    $dbh->do(qq{
+        UPDATE
+          `permissions`
+        SET
+          `module_bit` = 3
+        WHERE
+          `code` = 'manage_cash_registers'
+    });
+
+    NewVersion( $DBversion, 24481, 'Move permission to correct module_bit' );
 }
 
-=head2 SetVersion
+$DBversion = '19.12.00.013';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(qq{
+        INSERT IGNORE INTO 
+          systempreferences (variable,value,options,explanation,type)
+        VALUES
+          ('EnablePointOfSale','0',NULL,'Enable the point of sale feature to allow anonymous transactions with the accounting system. (Requires UseCashRegisters)','YesNo')
+    });
 
-set the DBversion in the systempreferences
+    NewVersion( $DBversion, 24478, 'Add `EnablePointOfSale` system preference to allow disabling the point of sale feature)' );
+}
 
-=cut
+$DBversion = '19.12.00.014';
+if( CheckVersion( $DBversion ) ) {
+    unless ( column_exists('branchtransfers', 'reason') ) {
+        $dbh->do(
+            qq{
+                ALTER TABLE branchtransfers
+                ADD
+                  `reason` enum('Manual')
+                AFTER
+                  comments
+              }
+        );
+    }
 
-sub SetVersion {
-    return if $_[0]=~ /XXX$/;
-      #you are testing a patch with a db revision; do not change version
-    my $kohaversion = TransformToNum($_[0]);
-    if (C4::Context->preference('Version')) {
-      my $finish=$dbh->prepare("UPDATE systempreferences SET value=? WHERE variable='Version'");
-      $finish->execute($kohaversion);
+    NewVersion( $DBversion, 24287, q|Add 'reason' field to transfers table| );
+}
+
+$DBversion = '19.12.00.015';
+if( CheckVersion( $DBversion ) ) {
+
+    # Add stockrotation states to reason enum
+    $dbh->do(
+        qq{
+            ALTER TABLE
+                `branchtransfers`
+            MODIFY COLUMN
+                `reason` enum(
+                    'Manual',
+                    'StockrotationAdvance',
+                    'StockrotationRepatriation'
+                )
+            AFTER `comments`
+          }
+    );
+
+    # Move stockrotation states to reason field
+    $dbh->do(
+        qq{
+            UPDATE
+              `branchtransfers`
+            SET
+              `reason` = 'StockrotationAdvance',
+              `comments` = NULL
+            WHERE
+              `comments` = 'StockrotationAdvance'
+          }
+    );
+    $dbh->do(
+        qq{
+            UPDATE
+              `branchtransfers`
+            SET
+              `reason` = 'StockrotationRepatriation',
+              `comments` = NULL
+            WHERE
+              `comments` = 'StockrotationRepatriation'
+          }
+    );
+
+    NewVersion( $DBversion, 24296, q|Update stockrotation to use 'reason' field in transfers table| );
+}
+
+$DBversion = '19.12.00.016';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO `userflags` (`bit`, `flag`, `flagdesc`, `defaulton`)
+        VALUES (12, 'suggestions', 'Suggestion management', 0)
+    });
+
+    $dbh->do(q{
+        UPDATE permissions SET module_bit=12
+        WHERE code="suggestions_manage"
+    });
+
+    $dbh->do(q{
+        UPDATE borrowers SET flags = flags + (1<<12) WHERE flags & (1 << 11)
+    });
+
+    NewVersion( $DBversion, 22868, 'Move suggestions_manage subpermission out of acquisition permission' );
+}
+
+$DBversion = '19.12.00.017';
+if( CheckVersion( $DBversion ) ) {
+    if( !index_exists( 'library_groups', 'library_groups_uniq_2' ) ) {
+        $dbh->do(q|
+            DELETE FROM library_groups
+            WHERE id NOT IN (
+                SELECT MIN(id)
+                FROM ( SELECT * FROM library_groups ) AS lg
+                GROUP BY parent_id, branchcode
+            )
+            AND NOT(parent_id IS NULL OR branchcode IS NULL);
+        |);
+        $dbh->do(q|
+            ALTER TABLE library_groups
+            ADD UNIQUE KEY library_groups_uniq_2 (parent_id, branchcode)
+        |);
+    }
+
+    NewVersion( $DBversion, 21674, 'Add unique key (parent_id, branchcode) to library_group' );
+}
+
+$DBversion = '19.12.00.018';
+if( CheckVersion( $DBversion ) ) {
+    my @columns = qw(
+        restrictedtype
+        rentaldiscount
+        fine
+        finedays
+        maxsuspensiondays
+        suspension_chargeperiod
+        firstremind
+        chargeperiod
+        chargeperiod_charge_at
+        accountsent
+        issuelength
+        lengthunit
+        hardduedate
+        hardduedatecompare
+        renewalsallowed
+        renewalperiod
+        norenewalbefore
+        auto_renew
+        no_auto_renewal_after
+        no_auto_renewal_after_hard_limit
+        reservesallowed
+        holds_per_record
+        holds_per_day
+        onshelfholds
+        opacitemholds
+        overduefinescap
+        cap_fine_to_replacement_price
+        article_requests
+        note
+    );
+
+    if ( column_exists( 'issuingrules', 'categorycode' ) ) {
+        foreach my $column ( @columns ) {
+            $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), \'$column\', COALESCE( $column, '' )
+                FROM issuingrules
+            ");
+        }
+        $dbh->do("DROP TABLE issuingrules");
+    }
+
+    NewVersion( $DBversion, 18936, 'Convert issuingrules fields to circulation_rules' );
+}
+
+$DBversion = '19.12.00.019';
+if( CheckVersion( $DBversion ) ) {
+
+    $dbh->do("ALTER TABLE message_queue MODIFY time_queued timestamp NULL");
+
+    if( !column_exists( 'message_queue', 'updated_on' ) ) {
+        $dbh->do("ALTER TABLE message_queue ADD COLUMN updated_on timestamp NOT NULL default CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP AFTER time_queued");
+        $dbh->do("UPDATE message_queue SET updated_on=time_queued");
+    }
+
+    NewVersion( $DBversion, 23673, 'modify time_queued and add updated_on to message_queue' );
+}
+
+$DBversion = '19.12.00.020';
+if ( CheckVersion($DBversion) ) {
+    if ( !column_exists( 'marc_subfield_structure', 'important') ){
+        $dbh->do("ALTER TABLE marc_subfield_structure ADD COLUMN important TINYINT(4) NOT NULL DEFAULT 0  AFTER mandatory");
+    }
+    if ( !column_exists( 'marc_tag_structure', 'important') ){
+        $dbh->do("ALTER TABLE marc_tag_structure ADD COLUMN important TINYINT(4) NOT NULL DEFAULT 0  AFTER mandatory");
+    }
+
+    NewVersion( $DBversion, 8643, 'Add important constraint to marc subfields' );
+}
+
+$DBversion = '19.12.00.021';
+if( CheckVersion( $DBversion ) ) {
+
+    # Add LOST_FOUND debit type
+    $dbh->do(qq{
+        INSERT IGNORE INTO
+          account_credit_types ( code, description, can_be_added_manually, is_system )
+        VALUES
+          ('LOST_FOUND', 'Lost item fee refund', 0, 1)
+    });
+
+    # Migrate LOST_RETURN to LOST_FOUND
+    $dbh->do(qq{
+        UPDATE
+          accountlines
+        SET
+          credit_type_code = 'LOST_FOUND'
+        WHERE
+          credit_type_code = 'LOST_RETURN'
+    });
+
+    # Migrate LOST + RETURNED to LOST + FOUND
+    $dbh->do(qq{
+        UPDATE
+          accountlines
+        SET
+          status = 'FOUND'
+        WHERE
+          debit_type_code = 'LOST'
+        AND
+          status = 'RETURNED'
+    });
+
+    # Drop LOST_RETURNED credit type
+    $dbh->do(qq{
+        DELETE FROM account_credit_types WHERE code = 'LOST_RETURN'
+    });
+
+    # Add Lost Item Found offset type
+    $dbh->do(qq{
+        INSERT IGNORE INTO
+          account_offset_types ( type )
+        VALUES
+          ( 'Lost Item Found' )
+    });
+
+    NewVersion( $DBversion, 24592, 'Update LOST_RETURN to LOST_FOUND');
+}
+
+$DBversion = '19.12.00.022';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( "ALTER TABLE items MODIFY COLUMN uri MEDIUMTEXT" );
+    $dbh->do( "ALTER TABLE deleteditems MODIFY COLUMN uri MEDIUMTEXT" );
+
+    NewVersion( $DBversion, 20882, 'items.uri to MEDIUMTEXT');
+}
+
+$DBversion = '19.12.00.023';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( "ALTER TABLE quotes MODIFY timestamp datetime NULL" );
+
+    NewVersion( $DBversion, 24640, 'Allow quotes.timestamp to be NULL');
+}
+
+$DBversion = '19.12.00.024';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        UPDATE systempreferences SET value = 'off'
+        WHERE variable = 'finesMode' AND (value <> 'production' OR value IS NULL)
+    });
+    $dbh->do(q{
+        UPDATE systempreferences SET options = 'off|production',
+        explanation = "Choose the fines mode, 'off' (do not accrue fines) or 'production' (accrue overdue fines).  Requires accruefines cronjob or CalculateFinesOnReturn system preference."
+        WHERE variable = 'finesMode'
+    });
+
+    NewVersion( $DBversion, 21633, 'Remove finesMode "test"');
+}
+
+$DBversion = '19.12.00.025';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO `systempreferences` (variable,value,options,explanation,type)
+        VALUES ('DumpSearchQueryTemplate',0,'','Add the search query being passed to the search engine into the template for debugging','YesNo')
+    });
+
+    NewVersion( $DBversion, 24103, 'add DumpSearchQueryTemplate syspref');
+}
+
+$DBversion = '19.12.00.026';
+if( CheckVersion( $DBversion ) ) {
+    if( !column_exists( 'z3950servers', 'attributes' ) ) {
+        $dbh->do( "ALTER TABLE z3950servers ADD COLUMN attributes VARCHAR(255) after add_xslt" );
+    }
+
+    NewVersion( $DBversion, 11297, 'Add support for custom PQF attributes for Z39.50 server searches');
+}
+
+$DBversion = '19.12.00.027';
+if( CheckVersion( $DBversion ) ) {
+
+    # Add any pathalogical incorrect debit_types as credit_types as appropriate
+    $dbh->do(
+        qq{
+          INSERT IGNORE INTO account_credit_types (
+            code,
+            description,
+            can_be_added_manually,
+            is_system
+          )
+          SELECT
+            DISTINCT(debit_type_code),
+            "Unexpected type found during upgrade",
+            1,
+            0
+          FROM
+            accountlines
+          WHERE
+            amount < 0
+          AND
+            debit_type_code IS NOT NULL
+        }
+    );
+
+    # Correct any pathalogical cases
+    $dbh->do( qq{
+      UPDATE
+        accountlines
+      SET
+        credit_type_code = debit_type_code,
+        debit_type_code = NULL
+      WHERE
+        amount < 0
+      AND
+        debit_type_code IS NOT NULL
+    });
+
+    NewVersion( $DBversion, 24532, 'Fix pathological cases of negative debits');
+}
+
+$DBversion = '19.12.00.028';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences (variable,value,options,explanation,type)
+        VALUES
+        ('OpacBrowseSearch', '0',NULL, "Elasticsearch only: add a page allowing users to 'browse' all items in the collection",'YesNo')
+    });
+
+    NewVersion( $DBversion, 14567, 'Add OpacBrowseSearch syspref');
+}
+
+$DBversion = '19.12.00.029';
+if( CheckVersion( $DBversion ) ) {
+    if (!column_exists('account_credit_types', 'archived')) {
+        $dbh->do('ALTER TABLE account_credit_types ADD COLUMN archived tinyint(1) NOT NULL DEFAULT 0 AFTER is_system');
+    }
+
+    NewVersion( $DBversion, 17702, 'Add column account_credit_types.archived');
+}
+
+$DBversion = '19.12.00.030';
+if( CheckVersion( $DBversion ) ) {
+
+    # get list of installed translations
+    require C4::Languages;
+    my @langs;
+    my $tlangs = C4::Languages::getTranslatedLanguages();
+
+    foreach my $language ( @$tlangs ) {
+        foreach my $sublanguage ( @{$language->{'sublanguages_loop'}} ) {
+            push @langs, $sublanguage->{'rfc4646_subtag'};
+        }
+    }
+
+    # Get any existing value from the opacheader system preference
+    my ($opacheader) = $dbh->selectrow_array( q|
+        SELECT value FROM systempreferences WHERE variable='opacheader';
+    |);
+
+    my @detail;
+    if( $opacheader ){
+        foreach my $lang ( @langs ) {
+            # If there is a value in the opacheader preference, insert it into opac_news
+            $dbh->do("INSERT INTO opac_news (branchcode, lang, title, content ) VALUES (NULL, ?, '', ?)", undef, "opacheader_$langs[0]", $opacheader);
+            push @detail, "Inserted opacheader contents into $lang news item...\n";
+        }
+    }
+    # Remove the opacheader system preference
+    $dbh->do("DELETE FROM systempreferences WHERE variable='opacheader'");
+
+    unshift @detail, 'Move contents of opacheader preference to Koha news system';
+    NewVersion( $DBversion, 22880, \@detail);
+}
+
+$DBversion = '19.12.00.031';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( q|
+ALTER TABLE article_requests MODIFY COLUMN created_on timestamp NULL, MODIFY COLUMN updated_on timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp()
+    |);
+
+    NewVersion( $DBversion, 22273, "Column article_requests.created_on should not be updated" );
+}
+
+$DBversion = '19.12.00.032';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( q|
+        DELETE FROM systempreferences WHERE variable="UseQueryParser"
+    |);
+
+    NewVersion( $DBversion, 24735, "Remove UseQueryParser system preference" );
+}
+
+$DBversion = '19.12.00.033';
+if ( CheckVersion($DBversion) ) {
+
+    # Add cash_register_actions table
+    $dbh->do(qq{
+        CREATE TABLE  IF NOT EXISTS `cash_register_actions` (
+          `id` int(11) NOT NULL auto_increment, -- unique identifier for each account register action
+          `code` varchar(24) NOT NULL, -- action code denoting the type of action recorded (enum),
+          `register_id` int(11) NOT NULL, -- id of cash_register this action belongs to,
+          `manager_id` int(11) NOT NULL, -- staff member performing the action
+          `amount` decimal(28,6) DEFAULT NULL, -- amount recorded in action (signed)
+          `timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+          PRIMARY KEY (`id`),
+          CONSTRAINT `cash_register_actions_manager` FOREIGN KEY (`manager_id`) REFERENCES `borrowers` (`borrowernumber`) ON DELETE CASCADE ON UPDATE CASCADE,
+          CONSTRAINT `cash_register_actions_register` FOREIGN KEY (`register_id`) REFERENCES `cash_registers` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
+        ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
+    });
+
+    # Add cashup permission
+    $dbh->do(qq{
+        INSERT IGNORE permissions (module_bit, code, description)
+        VALUES
+        (25, 'cashup', 'Perform cash register cashup action')
+    });
+
+    NewVersion( $DBversion, 23355, [ "Add cash_register_actions table", "Add cash register cashup permissions" ] );
+}
+
+$DBversion = '19.12.00.034';
+if ( CheckVersion($DBversion) ) {
+
+    $dbh->do(
+        qq{
+            INSERT IGNORE INTO account_credit_types (code, description, can_be_added_manually, is_system)
+            VALUES
+              ('DISCOUNT', 'A discount applied to a patrons fine', 0, 1)
+        }
+    );
+
+    $dbh->do(
+        qq{
+        INSERT IGNORE INTO account_offset_types ( type ) VALUES ('DISCOUNT');
+    }
+    );
+
+    $dbh->do(
+        qq{
+        INSERT IGNORE permissions (module_bit, code, description)
+        VALUES
+        (10, 'discount', 'Perform account discount action')
+    }
+    );
+
+    NewVersion( $DBversion, 24081, "Add DISCOUNT to account_credit_types and account_offset_types, Add accounts discount permission");
+}
+
+$DBversion = '19.12.00.035';
+if ( CheckVersion($DBversion) ) {
+
+    $dbh->do(qq{
+        INSERT IGNORE permissions (module_bit, code, description)
+        VALUES
+        (25, 'anonymous_refund', 'Perform refund actions from cash registers')
+    });
+
+    NewVersion( $DBversion, 23442, "Add a refund option to the point of sale system" );
+}
+
+$DBversion = '19.12.00.036';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO `systempreferences`
+            (`variable`, `value`, `options`, `explanation`, `type`)
+        VALUES
+            ('AccessControlAllowOrigin', '', NULL, 'Set the Access-Control-Allow-Origin header to the specified value', 'Free');
+    });
+
+    NewVersion( $DBversion, 24369, "Add CORS support to Koha");
+}
+
+$DBversion = '19.12.00.037';
+if( CheckVersion( $DBversion ) ) {
+
+    $dbh->do( q| INSERT IGNORE INTO systempreferences (variable, value, explanation, options, type) VALUES ('RenewAccruingItemInOpac', '0', 'If enabled, when the fines on an item accruing is paid off in the OPAC via a payment plugin, attempt to renew that item. If the syspref "RenewalPeriodBase" is set to "due date", renewed items may still be overdue', '', 'YesNo'); | );
+    
+    $dbh->do( q| INSERT IGNORE INTO systempreferences (variable, value, explanation, options, type) VALUES ('RenewAccruingItemWhenPaid', '0', 'If enabled, when the fines on an item accruing is paid off, attempt to renew that item. If the syspref "RenewalPeriodBase" is set to "due date", renewed items may still be overdue', '', 'YesNo'); | );
+
+    NewVersion( $DBversion, 23051, [ "Add RenewAccruingItemInOpac syspref", "Add RenewAccruingItemWhenPaid syspref" ]);
+}
+
+$DBversion = '19.12.00.038';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( q| INSERT IGNORE INTO systempreferences (variable, value, explanation, options, type) VALUES ('CirculateILL', '0', 'If enabled, it is possible to circulate ILL requested items from within ILL', '', 'YesNo'); | );
+
+    NewVersion( $DBversion, 23112, "Add CirculateILL syspref");
+}
+
+$DBversion = '19.12.00.039';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( "DROP TABLE IF EXISTS printers" );
+
+    if( column_exists( 'branches', 'branchprinter' ) ) {
+        $dbh->do( "ALTER TABLE branches DROP COLUMN branchprinter" );
+    }
+
+    $dbh->do(qq{ DELETE FROM systempreferences WHERE variable = "printcirculationslips"} );
+
+    NewVersion( $DBversion, 17845, "Drop unused table printers and branchprinter column");
+}
+
+$DBversion = '19.12.00.040';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( "UPDATE systempreferences SET  explanation = 'Comma separated list defining the default fields to be used during a patron search using the \"standard\" option. If empty Koha will default to \"surname,firstname,othernames,cardnumber,userid\". Additional fields added to this preference will be added as search options in the dropdown menu on the patron search page.' WHERE variable='DefaultPatronSearchFields' " );
+
+    NewVersion( $DBversion, 17374, "Update description of DefaultPatronSearchFields");
+}
+
+$DBversion = '19.12.00.041';
+if( CheckVersion( $DBversion ) ) {
+
+    # Update existing NULL priorities
+    $dbh->do(q|
+        UPDATE reserves SET priority = 1 WHERE priority IS NULL
+    |);
+
+    $dbh->do(q|
+        ALTER TABLE reserves MODIFY priority SMALLINT(6) NOT NULL DEFAULT 1
+    |);
+
+    $dbh->do(q|
+        UPDATE old_reserves SET priority = 1 WHERE priority IS NULL
+    |);
+
+    $dbh->do(q|
+        ALTER TABLE old_reserves MODIFY priority SMALLINT(6) NOT NULL DEFAULT 1
+    |);
+
+    NewVersion( $DBversion, 24722, "Enforce NOT NULL constraint for reserves.priority");
+}
+
+$DBversion = '19.12.00.042';
+if( CheckVersion( $DBversion ) ) {
+    if (!column_exists('message_queue', 'reply_address')) {
+        $dbh->do('ALTER TABLE message_queue ADD COLUMN reply_address LONGTEXT AFTER from_address');
+    }
+
+    NewVersion( $DBversion, 22821, "Add reply_address to message_queue");
+}
+
+$DBversion = '19.12.00.043';
+if( CheckVersion( $DBversion ) ) {
+
+    # Add return reasons to enum
+    $dbh->do(
+        qq{
+            ALTER TABLE
+                `branchtransfers`
+            MODIFY COLUMN
+                `reason` enum(
+                    'Manual',
+                    'StockrotationAdvance',
+                    'StockrotationRepatriation',
+                    'ReturnToHome',
+                    'ReturnToHolding'
+                )
+            AFTER `comments`
+          }
+    );
+
+    NewVersion( $DBversion, 24296, "Add 'return' reasons to branchtransfers enum");
+}
+
+$DBversion = '19.12.00.044';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(qq{
+        INSERT IGNORE permissions (module_bit, code, description)
+        VALUES
+        (13, 'batch_extend_due_dates', 'Perform batch extend due dates')
+    });
+
+    NewVersion( $DBversion, 24846, "Add a new permission for new tool batch extend due dates");
+}
+
+$DBversion = '19.12.00.045';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences (variable,value,options,explanation,type) 
+        VALUES
+        ('CollapseFieldsPatronAddForm','',NULL,'Collapse these fields by default when adding a new patron. These fields can still be expanded.','Multiple') 
+    });
+
+    NewVersion( $DBversion, 4461, "Add CollapseFieldsPatronAddForm system preference");
+}
+
+$DBversion = '19.12.00.046';
+if( CheckVersion( $DBversion ) ) {
+
+    $dbh->do( "ALTER TABLE accountlines MODIFY COLUMN date TIMESTAMP NULL" );
+
+    NewVersion( $DBversion, 24818, "Update 'accountlines.date' from DATE to TIMESTAMP");
+}
+
+$DBversion = '19.12.00.047';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        ALTER TABLE biblioimages
+        ADD `timestamp` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
+        AFTER `thumbnail`;
+    });
+
+    NewVersion( $DBversion, 22987, "Add biblioimages.timestamp");
+}
+
+$DBversion = '19.12.00.048';
+if( CheckVersion( $DBversion ) ) {
+
+    # Add rotating collection states to reason enum
+    $dbh->do(
+        qq{
+            ALTER TABLE
+                `branchtransfers`
+            MODIFY COLUMN
+                `reason` enum(
+                    'Manual',
+                    'StockrotationAdvance',
+                    'StockrotationRepatriation',
+                    'ReturnToHome',
+                    'ReturnToHolding',
+                    'RotatingCollection'
+                )
+            AFTER `comments`
+          }
+    );
+
+    NewVersion( $DBversion, 24299, "Add 'collection' reasons to branchtransfers enum");
+}
+
+$DBversion = '19.12.00.049';
+if( CheckVersion( $DBversion ) ) {
+
+    # Add reserve reasons enum
+    $dbh->do(
+        qq{
+            ALTER TABLE
+                `branchtransfers`
+            MODIFY COLUMN
+                `reason` enum(
+                    'Manual',
+                    'StockrotationAdvance',
+                    'StockrotationRepatriation',
+                    'ReturnToHome',
+                    'ReturnToHolding',
+                    'RotatingCollection',
+                    'Reserve',
+                    'LostReserve',
+                    'CancelReserve'
+                )
+            AFTER `comments`
+          }
+    );
+
+    NewVersion( $DBversion, 24299, "Add 'reserve' reasons to branchtransfers enum");
+}
+
+$DBversion = '19.12.00.050';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( "DELETE FROM systempreferences WHERE variable in ('IDreamBooksReadometer','IDreamBooksResults','IDreamBooksReviews')" );
+
+    NewVersion( $DBversion, 24854, "Remove IDreamBooks* system preferences");
+}
+
+$DBversion = '19.12.00.051';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        UPDATE systempreferences SET options = 'itemhomebranch|patronhomebranch|checkoutbranch|none' WHERE variable='OpacRenewalBranch'
+    });
+    $dbh->do(q{
+        UPDATE systempreferences SET value = "none" WHERE variable='OpacRenewalBranch'
+        AND value = 'NULL'
+    });
+    $dbh->do(q{
+        UPDATE systempreferences SET value = 'opacrenew' WHERE variable='OpacRenewalBranch'
+        AND value NOT IN ('checkoutbranch','itemhomebranch','opacrenew','patronhomebranch','none')
+    });
+
+    NewVersion( $DBversion, 24759, "Cleanup OpacRenewalBranch");
+}
+
+$DBversion = '19.12.00.052';
+if( CheckVersion( $DBversion ) ) {
+    if( !column_exists( 'itemtypes', 'rentalcharge_daily_calendar' ) ) {
+        $dbh->do(q{
+            ALTER TABLE itemtypes ADD COLUMN
+            rentalcharge_daily_calendar tinyint(1) NOT NULL DEFAULT 1
+            AFTER rentalcharge_daily;
+        });
+    }
+
+    if( !column_exists( 'itemtypes', 'rentalcharge_hourly_calendar' ) ) {
+        $dbh->do(q{
+            ALTER TABLE itemtypes ADD COLUMN
+            rentalcharge_hourly_calendar tinyint(1) NOT NULL DEFAULT 1
+            AFTER rentalcharge_hourly;
+        });
+    }
+
+    my $finesCalendar = C4::Context->preference('finesCalendar');
+    my $value = $finesCalendar eq 'noFinesWhenClosed' ? 1 : 0;
+    $dbh->do("UPDATE itemtypes SET rentalcharge_hourly_calendar = $value, rentalcharge_daily_calendar = $value");
+
+    NewVersion( $DBversion, 21443, "Add ability to exclude holidays when calculating rentals fees by time period");
+}
+
+$DBversion = '19.12.00.053';
+if( CheckVersion( $DBversion ) ) {
+    unless( column_exists('borrowers','autorenew_checkouts') ){
+        $dbh->do( "ALTER TABLE borrowers ADD COLUMN autorenew_checkouts TINYINT(1) NOT NULL DEFAULT 1 AFTER anonymized" );
+    }
+    unless( column_exists('deletedborrowers','autorenew_checkouts') ){
+        $dbh->do( "ALTER TABLE deletedborrowers ADD COLUMN autorenew_checkouts TINYINT(1) NOT NULL DEFAULT 1 AFTER anonymized" );
+    }
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences
+        ( `variable`, `value`, `options`, `explanation`, `type` )
+        VALUES
+        ('AllowPatronToControlAutorenewal','0',NULL,'If enabled, patrons will have a field in their account to choose whether their checkouts are auto renewed or not','YesNo')
+    });
+
+    NewVersion( $DBversion, 24476, "Allow patrons to opt-out of autorenewal");
+}
+
+$DBversion = '19.12.00.054';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(qq{
+             CREATE TABLE desks ( -- desks available in a library
+             desk_id int(11) NOT NULL auto_increment, -- unique identifier added by Koha
+             desk_name varchar(100) NOT NULL default '', -- name of the desk
+             branchcode varchar(10) NOT NULL,       -- library the desk is located at
+             PRIMARY KEY  (desk_id),
+             KEY `fk_desks_branchcode` (branchcode),
+             CONSTRAINT `fk_desks_branchcode` FOREIGN KEY (branchcode) REFERENCES branches (branchcode) ON DELETE CASCADE ON UPDATE CASCADE
+             ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+    });
+
+    NewVersion( $DBversion, 13881, "Add desk management");
+}
+
+# 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
+
+=cut
+
+sub DropAllForeignKeys {
+    my ($table) = @_;
+    # get the table description
+    my $sth = $dbh->prepare("SHOW CREATE TABLE $table");
+    $sth->execute;
+    my $vsc_structure = $sth->fetchrow;
+    # split on CONSTRAINT keyword
+    my @fks = split /CONSTRAINT /,$vsc_structure;
+    # parse each entry
+    foreach (@fks) {
+        # isolate what is before FOREIGN KEY, if there is something, it's a foreign key to drop
+        $_ = /(.*) FOREIGN KEY.*/;
+        my $id = $1;
+        if ($id) {
+            # we have found 1 foreign, drop it
+            $dbh->do("ALTER TABLE $table DROP FOREIGN KEY $id");
+            $id="";
+        }
+    }
+}
+
+
+=head2 TransformToNum
+
+Transform the Koha version from a 4 parts string
+to a number, with just 1 .
+
+=cut
+
+sub TransformToNum {
+    my $version = shift;
+    # remove the 3 last . to have a Perl number
+    $version =~ s/(.*\..*)\.(.*)\.(.*)/$1$2$3/;
+    # three X's at the end indicate that you are testing patch with dbrev
+    # change it into 999
+    # prevents error on a < comparison between strings (should be: lt)
+    $version =~ s/XXX$/999/;
+    return $version;
+}
+
+=head2 SetVersion
+
+set the DBversion in the systempreferences
+
+=cut
+
+sub SetVersion {
+    return if $_[0]=~ /XXX$/;
+      #you are testing a patch with a db revision; do not change version
+    my $kohaversion = TransformToNum($_[0]);
+    if (C4::Context->preference('Version')) {
+      my $finish=$dbh->prepare("UPDATE systempreferences SET value=? WHERE variable='Version'");
+      $finish->execute($kohaversion);
     } else {
       my $finish=$dbh->prepare("INSERT into systempreferences (variable,value,explanation) values ('Version',?,'The Koha database version. WARNING: Do not change this value manually, it is maintained by the webinstaller')");
       $finish->execute($kohaversion);
@@ -20290,6 +21373,37 @@ sub SetVersion {
     C4::Context::clear_syspref_cache(); # invalidate cached preferences
 }
 
+sub NewVersion {
+    my ( $DBversion, $bug_number, $descriptions ) = @_;
+
+    SetVersion($DBversion);
+
+    unless ( ref($descriptions) ) {
+        $descriptions = [ $descriptions ];
+    }
+    my $first = 1;
+    my $time = POSIX::strftime("%H:%M:%S",localtime);
+    for my $description ( @$descriptions ) {
+        if ( @$descriptions > 1 ) {
+            if ( $first ) {
+                unless ( $bug_number ) {
+                    say sprintf "Upgrade to %s done [%s]: %s", $DBversion, $time, $description;
+                } else {
+                    say sprintf "Upgrade to %s done [%s]: Bug %5s - %s", $DBversion, $time, $bug_number, $description;
+                }
+            }
+            say sprintf "\t\t\t\t\t\t   - %s", $description;
+        } else {
+            unless ( $bug_number ) {
+                say sprintf "Upgrade to %s done [%s]: %s", $DBversion, $time, $description;
+            } else {
+                say sprintf "Upgrade to %s done [%s]: Bug %5s - %s", $DBversion, $time, $bug_number, $description;
+            }
+        }
+        $first = 0;
+    }
+}
+
 =head2 CheckVersion
 
 Check whether a given update should be run when passed the proposed version