Bug 13881: DBRev 19.12.00.054
[koha-ffzg.git] / installer / data / mysql / updatedatabase.pl
index af04501..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";
@@ -19919,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
         }
     );
 
@@ -20228,21 +20228,1063 @@ if( CheckVersion( $DBversion ) ) {
 
 $DBversion = '19.11.00.000';
 if( CheckVersion( $DBversion ) ) {
-    SetVersion( $DBversion );
-    print "Upgrade to $DBversion done (19.11.00 release)\n";
+    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' );
+}
+
+$DBversion = '19.12.00.004';
+if ( CheckVersion($DBversion) ) {
+
+    $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)
+        }
+    );
+
+    $dbh->do(qq{
+        INSERT IGNORE INTO account_offset_types ( type ) VALUES ('PAYOUT');
+    });
+
+    $dbh->do(qq{
+        INSERT IGNORE permissions (module_bit, code, description)
+        VALUES
+        (10, 'payout', 'Perform account payout action')
+    });
+
+    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 $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
+        |);
+    }
+
+    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
+        |);
+    }
+
+    NewVersion( $DBversion, 24289, 'Adding foreign keys on *_holidays.branchcode tables' );
+}
+
+$DBversion = '19.12.00.012';
+if( CheckVersion( $DBversion ) ) {
+
+    $dbh->do(qq{
+        UPDATE
+          `permissions`
+        SET
+          `module_bit` = 3
+        WHERE
+          `code` = 'manage_cash_registers'
+    });
+
+    NewVersion( $DBversion, 24481, 'Move permission to correct module_bit' );
+}
+
+$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')
+    });
+
+    NewVersion( $DBversion, 24478, 'Add `EnablePointOfSale` system preference to allow disabling the point of sale feature)' );
+}
+
+$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
+              }
+        );
+    }
+
+    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.000';
+$DBversion = '19.12.00.028';
 if( CheckVersion( $DBversion ) ) {
-    SetVersion( $DBversion );
-    print "Upgrade to $DBversion done (Dobbie is a free elf...)\n";
+    $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.001';
+$DBversion = '19.12.00.029';
 if( CheckVersion( $DBversion ) ) {
-    $dbh->do( "UPDATE marc_subfield_structure SET kohafield = NULL WHERE kohafield = 'bibliosubject.subject';" );
-    SetVersion( $DBversion );
-    print "Upgrade to $DBversion done (Bug 17831 - Remove non-existing bibliosubject.subject from frameworks)\n";
+    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
@@ -20331,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