# CPAN modules
use DBI;
use Getopt::Long;
+use Encode qw( encode_utf8 );
# Koha modules
use C4::Context;
use C4::Installer;
use Koha::Database;
use Koha;
-use Koha::DateUtils;
+use Koha::DateUtils qw( dt_from_string output_pref );
use MARC::Record;
use MARC::File::XML ( BinaryEncoding => 'utf8' );
use File::Path qw[remove_tree]; # perl core module
-use File::Slurp;
# FIXME - The user might be installing a new database, so can't rely
# on /etc/koha.conf anyway.
-my $debug = 0;
-
my (
$sth,
$query,
my $schema = Koha::Database->new()->schema();
-my $silent;
+my ( $silent, $force );
GetOptions(
- 's' =>\$silent
- );
+ 's' => \$silent,
+ 'force' => \$force,
+);
my $dbh = C4::Context->dbh;
$|=1; # flushes output
[% IF checkout.auto_renew_error %]
The following item, [% biblio.title %], has not been renewed because:
[% IF checkout.auto_renew_error == 'too_many' %]
-You have reached the maximum number of checkouts possible.
+You have reached the maximum number of renewals possible.
[% ELSIF checkout.auto_renew_error == 'on_reserve' %]
This item is on hold for another patron.
[% ELSIF checkout.auto_renew_error == 'restriction' %]
for my $frameworkcode (@frameworkcodes) {
Koha::Caches->get_instance->clear_from_cache("MarcSubfieldStructure-$frameworkcode");
}
- Koha::Caches->get_instance->clear_from_cache("default_value_for_mod_marc-");
}
SetVersion( $DBversion );
value="batchmod,moredetail,cronjob,additem"
WHERE variable="MarkLostItemsAsReturned"
});
- } else {
+ } elsif ( $original_value == 0 || !defined($original_value) ) {
$dbh->do(q{
UPDATE systempreferences
SET type="multiple",
unless ( foreign_key_exists( 'serial', 'serial_ibfk_1' ) ) {
my $serials = $dbh->selectall_arrayref(q|
+ SELECT serialid FROM serial JOIN subscription USING (subscriptionid) WHERE serial.biblionumber != subscription.biblionumber
+ |, { Slice => {} });
+ if ( @$serials ) {
+ push @warnings, q|WARNING - The following serials will be updated, they were attached to a different biblionumber than their related subscription: | . join ", ", map { $_->{serialid} } @$serials;
+ $dbh->do(q|
+ UPDATE serial JOIN subscription USING (subscriptionid) SET serial.biblionumber = subscription.biblionumber WHERE serial.biblionumber != subscription.biblionumber
+ |);
+ }
+ $serials = $dbh->selectall_arrayref(q|
SELECT serialid FROM serial WHERE biblionumber NOT IN (SELECT biblionumber FROM biblio)
|, { Slice => {} });
if ( @$serials ) {
unless ( foreign_key_exists( 'subscriptionhistory', 'subscription_history_ibfk_1' ) ) {
$dbh->do(q|
+ UPDATE subscriptionhistory JOIN subscription USING (subscriptionid) SET subscriptionhistory.biblionumber = subscription.biblionumber WHERE subscriptionhistory.biblionumber != subscription.biblionumber
+ |);
+ $dbh->do(q|
DELETE FROM subscriptionhistory WHERE biblionumber NOT IN (SELECT biblionumber FROM biblio)
|);
$dbh->do(q|
for my $order ( @$orders ) {
for my $claim (1..$order->{claims_count}) {
- $insert_claim_sth->execute($order->{ordernumber}, $order->{claimed_on});
+ $insert_claim_sth->execute($order->{ordernumber}, $order->{claimed_date});
}
}
UPDATE letter SET
name = REPLACE(name, "notification on auto renewing", "Notification of automatic renewal"),
title = REPLACE(title, "Auto renewals", "Automatic renewal notice"),
- content = REPLACE(content, "You have reach the maximum of checkouts possible.", "You have reached the maximum number of checkouts possible.")
+ content = REPLACE(content, "You have reach the maximum of checkouts possible.", "You have reached the maximum number of renewals possible.")
WHERE code = 'AUTO_RENEWALS';
});
$dbh->do(q{
});
$dbh->do(q{
UPDATE letter SET
- content = REPLACE(content, "The following item [% biblio.title %] has correctly been renewed and is now due [% checkout.date_due %]", "The following item, [% biblio.title %], has correctly been renewed and is now due on [% checkout.date_due as_due_date => 1 %]
+ content = REPLACE(content, "The following item [% biblio.title %] has correctly been renewed and is now due [% checkout.date_due %]", "The following item, [% biblio.title %], has correctly been renewed and is now due on [% checkout.date_due | $KohaDates as_due_date => 1 %]
")
WHERE code = 'AUTO_RENEWALS';
});
if( CheckVersion( $DBversion ) ) {
# Adding the ON DELETE CASCASE ON UPDATE CASCADE, in case it's missing (from 9016 - 3.15.00.039)
+ if ( foreign_key_exists( 'letter', 'message_transport_type_fk' ) ) {
+ $dbh->do( q{
+ ALTER TABLE letter DROP FOREIGN KEY message_transport_type_fk
+ } );
+ }
$dbh->do( q{
- ALTER TABLE letter DROP FOREIGN KEY message_transport_type_fk
+ ALTER TABLE letter ADD CONSTRAINT message_transport_type_fk FOREIGN KEY (message_transport_type) REFERENCES message_transport_types(message_transport_type) ON DELETE CASCADE ON UPDATE CASCADE
} );
+ # Foreign keys should prevent this, however, it has been found in many production databases
$dbh->do( q{
- ALTER TABLE letter ADD CONSTRAINT message_transport_type_fk FOREIGN KEY (message_transport_type) REFERENCES message_transport_types(message_transport_type) ON DELETE CASCADE ON UPDATE CASCADE
+ DELETE borrower_message_transport_preferences FROM borrower_message_transport_preferences LEFT JOIN borrower_message_preferences USING (borrower_message_preference_id) WHERE borrower_message_preferences.borrower_message_preference_id IS NULL
} );
$dbh->do(q{
NewVersion( $DBversion, 24108, "Add system preference DefaultSaveRecordFileID");
}
-# 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; ## no critic (StringyEval)
- say "Atomic update generated errors: $@" if $@;
+$DBversion = '20.12.00.014';
+if( CheckVersion( $DBversion ) ) {
+
+ sanitize_zero_date('aqorders', 'datecancellationprinted');
+ sanitize_zero_date('old_issues', 'returndate');
+
+ NewVersion( $DBversion, 7806, "Remove remaining possible 0000-00-00 values");
+}
+
+$DBversion = '20.12.00.015';
+if( CheckVersion( $DBversion ) ) {
+ $dbh->do( "UPDATE search_marc_to_field SET sort = 1 WHERE sort IS NULL" );
+ $dbh->do( "ALTER TABLE search_marc_to_field MODIFY COLUMN sort tinyint(1) DEFAULT 1 NOT NULL COMMENT 'Sort defaults to 1 (Yes) and creates sort fields in the index, 0 (no) will prevent this'" );
+ NewVersion( $DBversion, 27316, "In Elastisearch mappings convert NULL (Undef) for sort to 1 (Yes)");
+}
+
+$DBversion = '20.12.00.016';
+if( CheckVersion( $DBversion ) ) {
+
+ unless ( column_exists( 'marc_subfield_structure', 'display_order' ) ) {
+ $dbh->do(q{
+ ALTER TABLE marc_subfield_structure
+ ADD COLUMN display_order INT(2) NOT NULL DEFAULT 0 AFTER maxlength
+ });
}
+
+ unless ( column_exists( 'auth_subfield_structure', 'display_order' ) ) {
+ $dbh->do(q{
+ ALTER TABLE auth_subfield_structure
+ ADD COLUMN display_order INT(2) NOT NULL DEFAULT 0 AFTER defaultvalue
+ });
+ }
+
+ NewVersion( $DBversion, 8976, "Allow setting a default sequence of subfields in cataloguing editor" );
}
-=head1 FUNCTIONS
+$DBversion = '20.12.00.017';
+if( CheckVersion( $DBversion ) ) {
+ $dbh->do(q|
+ INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type)
+ VALUES ('CheckPrevCheckoutDelay','0', 'Maximum number of days that will trigger a warning if the patron has borrowed that item in the past when CheckPrevCheckout is enabled. Disabled if 0 or empty.', NULL, 'free')
+ |);
-=head2 DropAllForeignKeys($table)
+ NewVersion( $DBversion, 26937, "Add CheckPrevCheckoutDelay system preference)" );
+}
-Drop all foreign keys of the table $table
+$DBversion = '20.12.00.018';
+if( CheckVersion( $DBversion ) ) {
-=cut
+ $dbh->do(q|
+ UPDATE items
+ LEFT JOIN issues ON issues.itemnumber=items.itemnumber
+ SET items.onloan=CAST(issues.date_due AS DATE)
+ WHERE items.onloan IS NULL AND issues.issue_id IS NOT NULL
+ |);
-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="";
- }
+ NewVersion( $DBversion, 27808, "Adjust items.onloan if needed" );
+}
+
+$DBversion = '20.12.00.019';
+if( CheckVersion( $DBversion ) ) {
+
+ if( !column_exists( 'branchtransfers', 'datecancelled' ) ) {
+ $dbh->do(q|
+ ALTER TABLE `branchtransfers`
+ ADD COLUMN `datecancelled` datetime default NULL AFTER `datearrived`
+ |);
+ }
+
+ if( !column_exists( 'branchtransfers', 'cancellation_reason' ) ) {
+ $dbh->do(q|
+ ALTER TABLE `branchtransfers`
+ ADD COLUMN `cancellation_reason` ENUM('Manual', 'StockrotationAdvance', 'StockrotationRepatriation', 'ReturnToHome', 'ReturnToHolding', 'RotatingCollection', 'Reserve', 'LostReserve', 'CancelReserve') DEFAULT NULL AFTER `reason`
+ |);
}
+
+ NewVersion( $DBversion, 26057, "Add datecancelled field to branchtransfers");
}
+$DBversion = '20.12.00.020';
+if ( CheckVersion($DBversion) ) {
-=head2 TransformToNum
+ # Update daterequested from datesent for stockrotation
+ $dbh->do(q|
+ UPDATE `branchtransfers`
+ SET
+ `daterequested` = `datesent`,
+ `datesent` = NULL
+ WHERE `reason` LIKE 'Stockrotation%'
+ AND `datearrived` IS NULL
+ |);
-Transform the Koha version from a 4 parts string
-to a number, with just 1 .
+ NewVersion( $DBversion, 24446, "Update stockrotation 'daterequested' field in transfers table" );
+}
-=cut
+$DBversion = '20.12.00.021';
+if( CheckVersion( $DBversion ) ) {
+ $dbh->do(q{
+ UPDATE systempreferences SET type="Free" WHERE variable="OverDriveClientSecret" OR variable="RecordedBooksClientSecret"
+ });
+ $dbh->do(q{
+ UPDATE systempreferences SET type="integer" WHERE variable="UsageStats"
+ });
+ $dbh->do(q{
+ UPDATE systempreferences
+ SET value="0"
+ WHERE ( ( type = "YesNo" AND ( value NOT IN ( "1", "0" ) OR value IS NULL ) ) )
+ });
-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;
+ NewVersion( $DBversion, 22824, "Update syspref values for YesNo");
}
-=head2 SetVersion
+$DBversion = '20.12.00.022';
+if( CheckVersion( $DBversion ) ) {
+ $dbh->do(q{ INSERT IGNORE INTO letter (module, code, branchcode, name, is_html, title, content, message_transport_type) VALUES
+ ('circulation','CHECKINSLIP','','Checkin slip',1,'Checkin slip',
+"<h3>[% branch.branchname %]</h3>
+Checked in items for [% borrower.title %] [% borrower.firstname %] [% borrower.initials %] [% borrower.surname %] <br />
+([% borrower.cardnumber %]) <br />
-set the DBversion in the systempreferences
+[% today | $KohaDates %]<br />
-=cut
+<h4>Checked in today</h4>
+[% FOREACH checkin IN old_checkouts %]
+[% SET item = checkin.item %]
+<p>
+[% item.biblio.title %] <br />
+Barcode: [% item.barcode %] <br />
+</p>
+[% END %]",
+ 'print')
+ });
-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);
+ NewVersion( $DBversion, 12224, "Add CHECKINSLIP notice" );
+}
+
+$DBversion = '20.12.00.023';
+if( CheckVersion( $DBversion ) ) {
+
+ $dbh->do(q{
+ UPDATE systempreferences
+ SET value=REPLACE(value, '|', ',')
+ WHERE variable="OPACHoldsIfAvailableAtPickupExceptions"
+ OR variable="BatchCheckoutsValidCategories"
+ });
+ NewVersion( $DBversion, 27652, "Separate values for OPACHoldsIfAvailableAtPickupExceptions and BatchCheckoutsValidCategories with comma");
+}
+
+$DBversion = '20.12.00.024';
+if( CheckVersion( $DBversion ) ) {
+
+ $dbh->do( q{
+ INSERT IGNORE INTO letter (module, code, name, title, content, message_transport_type) VALUES ('circulation', 'AUTO_RENEWALS_DGST', 'Notification on auto renewals', 'Auto renewals (Digest)',
+ "Dear [% borrower.firstname %] [% borrower.surname %],
+ [% IF error %]
+ There were [% error %] items that were not renewed.
+ [% END %]
+ [% IF success %]
+ There were [% success %] items that were renewed.
+ [% END %]
+ [% FOREACH checkout IN checkouts %]
+ [% checkout.item.biblio.title %] : [% checkout.item.barcode %]
+ [% IF !checkout.auto_renew_error %]
+ was renewed until [% checkout.date_due | $KohaDates as_due_date => 1%]
+ [% ELSIF checkout.auto_renew_error == 'too_many' %]
+ You have reached the maximum number of renewals possible.
+ [% ELSIF checkout.auto_renew_error == 'on_reserve' %]
+ This item is on hold for another patron.
+ [% ELSIF checkout.auto_renew_error == 'restriction' %]
+ You are currently restricted.
+ [% ELSIF checkout.auto_renew_error == 'overdue' %]
+ You have overdue items.
+ [% ELSIF checkout.auto_renew_error == 'auto_too_late' %]
+ It's too late to renew this item.
+ [% ELSIF checkout.auto_renew_error == 'auto_too_much_oweing' %]
+ Your total unpaid fines are too high.
+ [% ELSIF checkout.auto_renew_error == 'too_unseen' %]
+ This item must be renewed at the library.
+ [% END %]
+ [% END %]
+ ", 'email');
+ });
+
+ $dbh->do( q{
+ INSERT IGNORE INTO `message_attributes`
+ (`message_attribute_id`, message_name, `takes_days`)
+ VALUES (9, 'Auto_Renewals', 0)
+ });
+
+ $dbh->do( q{
+ INSERT IGNORE INTO `message_transports`
+ (`message_attribute_id`, `message_transport_type`, `is_digest`, `letter_module`, `letter_code`)
+ VALUES (9, 'email', 0, 'circulation', 'AUTO_RENEWALS'),
+ (9, 'sms', 0, 'circulation', 'AUTO_RENEWALS'),
+ (9, 'email', 1, 'circulation', 'AUTO_RENEWALS_DGST'),
+ (9, 'sms', 1, 'circulation', 'AUTO_RENEWALS_DGST')
+ });
+
+ $dbh->do(q{
+ INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type)
+ VALUES ('AutoRenewalNotices','cron','cron|preferences|never','How should Koha determine whether to end autorenewal notices','Choice')
+ });
+
+ NewVersion( $DBversion, 18532, 'Messaging preferences for auto renewals' );
+}
+
+$DBversion = '20.12.00.025';
+if( CheckVersion( $DBversion ) ) {
+
+ $dbh->do(q|
+ INSERT IGNORE INTO systempreferences (variable,value,options,explanation,type)
+ VALUES ('ChargeFinesOnClosedDays', '0', NULL, 'Charge fines on days the library is closed.', 'YesNo')
+ |);
+
+ NewVersion( $DBversion, 27835, "Add new system preference ChargeFinesOnClosedDays");
+}
+
+$DBversion = '20.12.00.026';
+if( CheckVersion( $DBversion ) ) {
+
+ $dbh->do(q{INSERT IGNORE INTO systempreferences (variable,value,options,explanation,type) VALUES ('DefaultHoldExpirationdate','0','','Automatically set default expiration date for holds','YesNo') });
+ $dbh->do(q{INSERT IGNORE INTO systempreferences (variable,value,options,explanation,type) VALUES ('DefaultHoldExpirationdatePeriod','0','','How long into the future default expiration date is set to be.','integer') });
+ $dbh->do(q{INSERT IGNORE INTO systempreferences (variable,value,options,explanation,type) VALUES ('DefaultHoldExpirationdateUnitOfTime','days','days|months|years','Which unit of time is used when setting the default expiration date. ','choice') });
+
+ NewVersion( $DBversion, 26498, "Bug 26498 - Add option to set a default expire date for holds at reservation time");
+}
+
+$DBversion = '20.12.00.027';
+if( CheckVersion( $DBversion ) ) {
+
+ $dbh->do(q{
+ UPDATE circulation_rules
+ SET
+ rule_value = CASE
+ WHEN rule_value='0' THEN 'not_allowed'
+ WHEN rule_value='1' THEN 'from_home_library'
+ WHEN rule_value='2' THEN 'from_any_library'
+ WHEN rule_value='3' THEN 'from_local_hold_group'
+ END
+ WHERE rule_name='holdallowed' AND rule_value >= 0 AND rule_value <= 3;
+ });
+
+ NewVersion( $DBversion, 27069, "Change holdallowed values from numbers to strings");
+}
+
+$DBversion = '20.12.00.028';
+if ( CheckVersion($DBversion) ) {
+
+ if ( !column_exists( 'letter', 'id' ) ) {
+ $dbh->do(q{
+ ALTER TABLE letter DROP PRIMARY KEY
+ });
+ $dbh->do(q{
+ ALTER TABLE letter ADD COLUMN `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST
+ });
+ $dbh->do(q{
+ ALTER TABLE letter ADD UNIQUE KEY letter_uniq_1 (`module`,`code`,`branchcode`,`message_transport_type`,`lang`)
+ });
}
- C4::Context::clear_syspref_cache(); # invalidate cached preferences
+
+ $dbh->do(q{
+ INSERT IGNORE INTO systempreferences (variable, value, explanation, options, type)
+ VALUES ('NoticesLog','0',NULL,'If enabled, log changes to notice templates','YesNo')
+ });
+
+ NewVersion( $DBversion, 14233, "Add id field to letter table" );
}
-sub NewVersion {
- my ( $DBversion, $bug_number, $descriptions ) = @_;
+$DBversion = '20.12.00.029';
+if( CheckVersion( $DBversion ) ) {
+ $dbh->do("ALTER TABLE problem_reports MODIFY content TEXT NOT NULL");
+
+ NewVersion( $DBversion, 27726, "Increase field size for problem_reports.content");
+}
- SetVersion($DBversion);
+$DBversion = '20.12.00.030';
+if( CheckVersion( $DBversion ) ) {
+ $dbh->do(q|
+ INSERT IGNORE INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `type` )
+ VALUES ('LockExpiredDelay','','','Delay for locking expired patrons (empty means no locking)','Integer')
+ |);
+
+ NewVersion( $DBversion, 21549, "Add new system preference LockExpiredDelay");
+}
+
+$DBversion = '20.12.00.031';
+if( CheckVersion( $DBversion ) ) {
+ $dbh->do(q{
+ INSERT IGNORE INTO systempreferences (variable, value, explanation, options, type)
+ VALUES ('Reference_NFL_Statuses','1|2',NULL,'Contains not for loan statuses considered as available for reference','Free')
+ });
- unless ( ref($descriptions) ) {
- $descriptions = [ $descriptions ];
+ NewVersion( $DBversion, 21260, "Add new system preference Reference_NFL_Statuses");
+}
+
+$DBversion = '20.12.00.032';
+if( CheckVersion( $DBversion ) ) {
+ $dbh->do(q{
+ INSERT IGNORE INTO letter
+ (module,code,branchcode,name,is_html,title,content,message_transport_type,lang)
+ VALUES ('reserves','HOLD_REMINDER','','Waiting hold reminder',0,'You have waiting holds.','Dear [% borrower.firstname %] [% borrower.surname %],\r\n\r\nThe following holds are waiting at [% branch.branchname %]:\r\n\\r\n[% FOREACH hold IN holds %]\r\n [% hold.biblio.title %] : waiting since [% hold.waitingdate | $KohaDates %]\r\n[% END %]','email','default')
+ });
+
+ NewVersion( $DBversion, 15986, "Add sample HOLD_REMINDER notice");
+}
+
+$DBversion = '20.12.00.033';
+if( CheckVersion( $DBversion ) ) {
+ my $debar = $dbh->selectall_arrayref(q|
+ SELECT d.borrowernumber, GROUP_CONCAT(comment SEPARATOR '\n') AS comment
+ FROM borrower_debarments d
+ LEFT JOIN borrowers b ON b.borrowernumber=d.borrowernumber
+ WHERE ( b.debarredcomment IS NULL OR b.debarredcomment = "" ) AND ( expiration > CURRENT_DATE() OR expiration IS NULL )
+ GROUP BY d.borrowernumber
+ |, { Slice => {} });
+
+
+ my $update_sth = $dbh->prepare(q|
+ UPDATE borrowers
+ SET debarredcomment=?
+ WHERE borrowernumber=?
+ |);
+ for my $d ( @$debar ) {
+ $update_sth->execute($d->{comment}, $d->{borrowernumber});
}
- 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;
- }
- } else {
- 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;
+
+ NewVersion( $DBversion, 26940, "Put in sync borrowers.debarredcomment with comments from borrower_debarments");
+}
+
+$DBversion = '20.12.00.034';
+if( CheckVersion( $DBversion ) ) {
+
+ $dbh->do(q{
+ INSERT IGNORE INTO systempreferences (variable, value, options, explanation, type)
+ VALUES ('casServerVersion', '2', '2|3', 'Version of the CAS server Koha will connect to.', 'Choice');
+ });
+
+ NewVersion( $DBversion, 20854, "Add new system preference casServerVersion");
+}
+
+$DBversion = '20.12.00.035';
+if( CheckVersion( $DBversion ) ) {
+ if( !column_exists( 'itemtypes', 'automatic_checkin' ) ) {
+ $dbh->do(q{
+ ALTER TABLE itemtypes
+ ADD COLUMN `automatic_checkin` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'If automatic checkin is enabled for items of this type' AFTER `searchcategory`
+ });
}
+
+ NewVersion( $DBversion, 23207, "Add automatic_checkin to itemtypes table");
+}
+
+$DBversion = '20.12.00.036';
+if( CheckVersion( $DBversion ) ) {
+ $dbh->do(q{
+ ALTER TABLE club_holds_to_patron_holds
+ MODIFY COLUMN error_code
+ ENUM ( 'damaged', 'ageRestricted', 'itemAlreadyOnHold',
+ 'tooManyHoldsForThisRecord', 'tooManyReservesToday',
+ 'tooManyReserves', 'notReservable', 'cannotReserveFromOtherBranches',
+ 'libraryNotFound', 'libraryNotPickupLocation', 'cannotBeTransferred',
+ 'noReservesAllowed'
+ )
+ });
+
+ NewVersion( $DBversion, 16787, "Add noReservesAllowed to club holds error codes");
}
-=head2 CheckVersion
+$DBversion = '20.12.00.037';
+if( CheckVersion( $DBversion ) ) {
+ $dbh->do( q{
+ INSERT IGNORE INTO systempreferences (variable, value, explanation, options, type)
+ VALUES ('AcquisitionLog', '0', 'If enabled, log acquisition activity', '', 'YesNo');
+ });
-Check whether a given update should be run when passed the proposed version
-number. The update will always be run if the proposed version is greater
-than the current database version and less than or equal to the version in
-kohaversion.pl. The update is also run if the version contains XXX, though
-this behavior will be changed following the adoption of non-linear updates
-as implemented in bug 7167.
+ NewVersion( $DBversion, 23971, "Add new system preference AcquisitionLog");
+}
-=cut
+$DBversion = '20.12.00.038';
+if( CheckVersion( $DBversion ) ) {
-sub CheckVersion {
- my ($proposed_version) = @_;
- my $version_number = TransformToNum($proposed_version);
+ # Add 'ItemLost' to reserves cancellation_reason enum
+ $dbh->do(
+ q{
+ ALTER TABLE
+ `branchtransfers`
+ MODIFY COLUMN
+ `cancellation_reason` enum(
+ 'Manual',
+ 'StockrotationAdvance',
+ 'StockrotationRepatriation',
+ 'ReturnToHome',
+ 'ReturnToHolding',
+ 'RotatingCollection',
+ 'Reserve',
+ 'LostReserve',
+ 'CancelReserve',
+ 'ItemLost'
+ )
+ AFTER `comments`
+ }
+ );
- # The following line should be deleted when bug 7167 is pushed
- return 1 if ( $proposed_version =~ m/XXX/ );
+ NewVersion( $DBversion, 27281, "Add 'ItemLost' to branchtransfers.cancellation_reason enum");
+}
- if ( C4::Context->preference("Version") < $version_number
- && $version_number <= TransformToNum( $Koha::VERSION ) )
- {
- return 1;
+$DBversion = '20.12.00.039';
+if( CheckVersion( $DBversion ) ) {
+
+ $dbh->do(
+ q{
+ ALTER TABLE
+ `branchtransfers`
+ MODIFY COLUMN
+ `reason` enum(
+ 'Manual',
+ 'StockrotationAdvance',
+ 'StockrotationRepatriation',
+ 'ReturnToHome',
+ 'ReturnToHolding',
+ 'RotatingCollection',
+ 'Reserve',
+ 'LostReserve',
+ 'CancelReserve',
+ 'TransferCancellation'
+ )
+ AFTER `comments`
+ }
+ );
+
+ NewVersion( $DBversion, 12362, "Add 'TransferCancellation' to branchtransfers.reason enum");
+}
+
+$DBversion = '20.12.00.040';
+if( CheckVersion( $DBversion ) ) {
+ $dbh->do(
+ q{
+ INSERT IGNORE INTO account_debit_types (
+ code,
+ description,
+ can_be_invoiced,
+ can_be_sold,
+ default_amount,
+ is_system
+ )
+ VALUES
+ ('VOID', 'Credit has been voided', 0, 0, NULL, 1)
+ }
+ );
+
+ $dbh->do(q{
+ INSERT IGNORE INTO account_offset_types ( type ) VALUES ('VOID');
+ });
+
+ NewVersion( $DBversion, 27971, "Add VOID debit type code");
+}
+
+$DBversion = '20.12.00.041';
+if ( CheckVersion($DBversion) ) {
+
+ # ACCOUNT_CREDIT UPDATES
+ # backup existing notice to action_logs
+ my $credit_arr = $dbh->selectall_arrayref(q{SELECT lang FROM letter WHERE code = 'ACCOUNT_CREDIT'}, { Slice => {} });
+ my $c_sth = $dbh->prepare(q{
+ INSERT INTO action_logs ( timestamp, module, action, object, info, interface )
+ SELECT NOW(), 'NOTICES', 'UPGRADE', id, content, 'cli'
+ FROM letter
+ WHERE lang = ? AND code = 'ACCOUNT_CREDIT'
+ });
+
+ for my $c ( @{$credit_arr} ) {
+ $c_sth->execute( $c->{lang} );
}
- else {
- return 0;
+
+ # replace notice with default
+ my $c_notice = q{
+[% USE Price %]
+[% PROCESS 'accounts.inc' %]
+<table>
+[% IF ( LibraryName ) %]
+ <tr>
+ <th colspan="4" class="centerednames">
+ <h3>[% LibraryName | html %]</h3>
+ </th>
+ </tr>
+[% END %]
+ <tr>
+ <th colspan="4" class="centerednames">
+ <h2><u>Fee receipt</u></h2>
+ </th>
+ </tr>
+ <tr>
+ <th colspan="4" class="centerednames">
+ <h2>[% Branches.GetName( credit.patron.branchcode ) | html %]</h2>
+ </th>
+ </tr>
+ <tr>
+ <th colspan="4">
+ Received with thanks from [% credit.patron.firstname | html %] [% credit.patron.surname | html %] <br />
+ Card number: [% credit.patron.cardnumber | html %]<br />
+ </th>
+ </tr>
+ <tr>
+ <th>Date</th>
+ <th>Description of charges</th>
+ <th>Note</th>
+ <th>Amount</th>
+ </tr>
+
+ <tr class="highlight">
+ <td>[% credit.date | $KohaDates %]</td>
+ <td>
+ [% PROCESS account_type_description account=credit %]
+ [%- IF credit.description %], [% credit.description | html %][% END %]
+ </td>
+ <td>[% credit.note | html %]</td>
+ <td class="credit">[% credit.amount | $Price %]</td>
+ </tr>
+
+<tfoot>
+ <tr>
+ <td colspan="3">Total outstanding dues as on date: </td>
+ [% IF ( credit.patron.account.balance >= 0 ) %]<td class="credit">[% ELSE %]<td class="debit">[% END %][% credit.patron.account.balance | $Price %]</td>
+ </tr>
+</tfoot>
+</table>
+ };
+
+ $dbh->do(q{UPDATE letter SET content = ?, is_html = 1 WHERE code = 'ACCOUNT_CREDIT'}, undef, $c_notice);
+
+ # ACCOUNT_DEBIT UPDATES
+ # backup existing notice to action_logs
+ my $debit_arr = $dbh->selectall_arrayref(
+ "SELECT lang FROM letter WHERE code = 'ACCOUNT_DEBIT'", { Slice => {} });
+ my $d_sth = $dbh->prepare(q{
+ INSERT INTO action_logs ( timestamp, module, action, object, info, interface )
+ SELECT NOW(), 'NOTICES', 'UPGRADE', id, content, 'cli'
+ FROM letter
+ WHERE lang = ? AND code = 'ACCOUNT_DEBIT'
+ });
+
+ for my $d ( @{$debit_arr} ) {
+ $d_sth->execute( $d->{lang} );
}
+
+ # replace notice with default
+ my $d_notice = q{
+[% USE Price %]
+[% PROCESS 'accounts.inc' %]
+<table>
+ [% IF ( LibraryName ) %]
+ <tr>
+ <th colspan="5" class="centerednames">
+ <h3>[% LibraryName | html %]</h3>
+ </th>
+ </tr>
+ [% END %]
+
+ <tr>
+ <th colspan="5" class="centerednames">
+ <h2><u>INVOICE</u></h2>
+ </th>
+ </tr>
+ <tr>
+ <th colspan="5" class="centerednames">
+ <h2>[% Branches.GetName( debit.patron.branchcode ) | html %]</h2>
+ </th>
+ </tr>
+ <tr>
+ <th colspan="5" >
+ Bill to: [% debit.patron.firstname | html %] [% debit.patron.surname | html %] <br />
+ Card number: [% debit.patron.cardnumber | html %]<br />
+ </th>
+ </tr>
+ <tr>
+ <th>Date</th>
+ <th>Description of charges</th>
+ <th>Note</th>
+ <th style="text-align:right;">Amount</th>
+ <th style="text-align:right;">Amount outstanding</th>
+ </tr>
+
+ <tr class="highlight">
+ <td>[% debit.date | $KohaDates%]</td>
+ <td>
+ [% PROCESS account_type_description account=debit %]
+ [%- IF debit.description %], [% debit.description | html %][% END %]
+ </td>
+ <td>[% debit.note | html %]</td>
+ <td class="debit">[% debit.amount | $Price %]</td>
+ <td class="debit">[% debit.amountoutstanding | $Price %]</td>
+ </tr>
+
+ [% IF ( tendered ) %]
+ <tr>
+ <td colspan="3">Amount tendered: </td>
+ <td>[% tendered | $Price %]</td>
+ </tr>
+ <tr>
+ <td colspan="3">Change given: </td>
+ <td>[% change | $Price %]</td>
+ </tr>
+ [% END %]
+
+ <tfoot>
+ <tr>
+ <td colspan="4">Total outstanding dues as on date: </td>
+ [% IF ( debit.patron.account.balance <= 0 ) %]<td class="credit">[% ELSE %]<td class="debit">[% END %][% debit.patron.account.balance | $Price %]</td>
+ </tr>
+ </tfoot>
+</table>
+ };
+ $dbh->do(q{UPDATE letter SET content = ?, is_html = 1 WHERE code = 'ACCOUNT_DEBIT'}, undef, $d_notice);
+
+ NewVersion( $DBversion, 26734, ["Update notices to use defaults", "WARNING - ACCOUNT_DEBIT and ACCOUNT_CREDIT slip templates have been replaced. Backups have been made to the action logs for your reference."] );
}
-sub sanitize_zero_date {
- my ( $table_name, $column_name ) = @_;
- $dbh->do(qq|
- UPDATE $table_name
- SET $column_name = NULL
- WHERE CAST($column_name AS CHAR(10)) = '0000-00-00';
- |);
+$DBversion = '20.12.00.042';
+if( CheckVersion( $DBversion ) ) {
+ unless( foreign_key_exists( 'collections_tracking', 'collectionst_ibfk_1' ) ) {
+ $dbh->do(q{
+ DELETE FROM collections_tracking WHERE colId NOT IN ( SELECT colId FROM collections )
+ });
+ $dbh->do(q{
+ ALTER TABLE collections_tracking
+ ADD CONSTRAINT `collectionst_ibfk_1` FOREIGN KEY (`colId`) REFERENCES `collections` (`colId`) ON DELETE CASCADE ON UPDATE CASCADE
+ });
+ }
+
+ NewVersion( $DBversion, 17202, "Add FK constraint for collection to collections_tracking");
+}
+
+$DBversion = '20.12.00.043';
+if( CheckVersion( $DBversion ) ) {
+ $dbh->do(q{
+ UPDATE letter SET
+ content = REPLACE(content, "The following item, [% biblio.title %], has correctly been renewed and is now due on [% checkout.date_due as_due_date => 1 %]" , "The following item, [% biblio.title %], has correctly been renewed and is now due on [% checkout.date_due | $KohaDates as_due_date => 1 %]")
+ WHERE code = 'AUTO_RENEWALS';
+ });
+
+ NewVersion( $DBversion, 28258, "Update AUTO_RENEWAL content");
+}
+
+$DBversion = '20.12.00.044';
+if( CheckVersion( $DBversion ) ) {
+ $dbh->do(q{
+ UPDATE language_subtag_registry SET description = 'Ukrainian' WHERE subtag='uk' and type='language' and description='Ukranian'
+ });
+ $dbh->do(q{
+ UPDATE language_descriptions SET description = 'Ukrainian' WHERE subtag='uk' and type='language' and lang='en' and description='Ukranian'
+ });
+
+ NewVersion( $DBversion, 28244, "Fix Ukrainian typo in English");
+}
+
+$DBversion = '20.12.00.045';
+if( CheckVersion( $DBversion ) ) {
+ $dbh->do(q{
+ INSERT IGNORE INTO systempreferences (variable, value, options, explanation, type) VALUES ('SearchLimitLibrary', 'homebranch', 'homebranch|holdingbranch|both', "When limiting search results with a library or library group, use the item's home library, or holding library, or both.", 'Choice')
+ });
+
+ NewVersion( $DBversion, 21249, "Adding new system preference SearchLimitLibrary" );
+}
+
+$DBversion = '20.12.00.046';
+if( CheckVersion( $DBversion ) ) {
+ unless ( column_exists('message_queue', 'delivery_note') ) {
+ $dbh->do(q{
+ ALTER TABLE message_queue ADD delivery_note mediumtext AFTER content_type
+ });
+ }
+
+ NewVersion( $DBversion, 14723, "Additional delivery notes to messages" );
+}
+
+$DBversion = '20.12.00.047';
+if( CheckVersion( $DBversion ) ) {
+
+ $dbh->do(q{
+ DELETE FROM systempreferences
+ WHERE variable IN
+ ('EnablePayPalOpacPayments',
+ 'PayPalChargeDescription',
+ 'PayPalPwd',
+ 'PayPalReturnURL',
+ 'PayPalSandboxMode',
+ 'PayPalSignature',
+ 'PayPalUser');
+ });
+
+ NewVersion( $DBversion, 23215, "Remove core PayPal support in favor of the use of plugins" );
+}
+
+$DBversion = '20.12.00.048';
+if( CheckVersion( $DBversion ) ) {
+
+ # This DB upgrade has been commented out because it removes
+ # actively used data, the relationship columns will be added back
+
+ # if ( column_exists( 'borrowers', 'relationship' ) ) {
+ # $dbh->do(q{
+ # ALTER TABLE borrowers DROP COLUMN relationship
+ # });
+ # }
+
+ # if ( column_exists( 'deletedborrowers', 'relationship' ) ) {
+ # $dbh->do(q{
+ # ALTER TABLE deletedborrowers DROP COLUMN relationship
+ # });
+ # }
+
+ # if ( column_exists( 'borrower_modifications', 'relationship' ) ) {
+ # $dbh->do(q{
+ # ALTER TABLE borrower_modifications DROP COLUMN relationship
+ # });
+ # }
+
+ NewVersion( $DBversion, 26995, "[SKIP] Drop column relationship from borrower tables [not executed]");
+}
+
+$DBversion = '20.12.00.049';
+if ( CheckVersion($DBversion) ) {
+ $dbh->do(q{
+ UPDATE action_logs SET module = 'CLAIMS'
+ WHERE module = 'ACQUISITIONS' AND ( action = 'SERIAL CLAIM' OR action = 'ACQUISITION CLAIM')
+ });
+
+ $dbh->do(q{
+ UPDATE systempreferences SET variable = 'ClaimsLog' WHERE variable = 'LetterLog';
+ });
+
+ NewVersion( $DBversion, 28108, "Move action logs 'SERIAL CLAIM' and 'ACQUISITION CLAIM' to a new 'CLAIMS' module" );
+}
+
+$DBversion = '20.12.00.050';
+if ( CheckVersion($DBversion) ) {
+ $dbh->do(q{
+ INSERT IGNORE INTO systempreferences (variable, value, options, explanation, type) VALUES
+ ('OpacHiddenItemsHidesRecord','1','','Hide bibliographic record when all its items are hidden because of OpacHiddenItems','YesNo')
+ });
+
+ NewVersion( $DBversion, 28108, "Add new systempreference OpacHiddenItemsHidesRecord" );
+}
+
+$DBversion = '21.05.00.000';
+if( CheckVersion( $DBversion ) ) {
+ NewVersion( $DBversion, "", "Koha 21.05.00 release" );
+}
+
+unless ( $ENV{HTTP_HOST} ) { # Is that correct?
+ my $files = get_db_entries;
+ my $report = update( $files, { force => $force } );
+
+ for my $s ( @{ $report->{success} } ) {
+ say Encode::encode_utf8(join "\n", @{$s->{output}});
+ }
+ for my $e ( @{ $report->{error} } ) {
+ say Encode::encode_utf8(join "\n", @{$e->{output}});
+ say Encode::encode_utf8("ERROR - " . $e->{error});
+ }
+
+ my $atomic_update_files = get_atomic_updates;
+ $report = run_atomic_updates($atomic_update_files);
+ for my $s ( @{ $report->{success} } ) {
+ say Encode::encode_utf8(join "\n", @{$s->{output}});
+ }
+ for my $e ( @{ $report->{error} } ) {
+ say Encode::encode_utf8(join "\n", @{$e->{output}});
+ say Encode::encode_utf8("ERROR - " . $e->{error});
+ }
+
+
}
exit;