Bugzilla – Attachment 184422 Details for
Bug 16631
Show groups/categories of reports to authorized staff
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
koha patch file
patch-16631-reports-libraries.patch (text/plain), 336.71 KB, created by
Casey Conlin
on 2025-07-21 02:06:01 UTC
(
hide
)
Description:
koha patch file
Filename:
MIME Type:
Creator:
Casey Conlin
Created:
2025-07-21 02:06:01 UTC
Size:
336.71 KB
patch
obsolete
>diff --git a/C4/Biblio.pm b/C4/Biblio.pm >index 00f481cf96..d847fe8f61 100644 >--- a/C4/Biblio.pm >+++ b/C4/Biblio.pm >@@ -62,6 +62,7 @@ BEGIN { > TransformMarcToKoha > TransformHtmlToMarc > TransformHtmlToXml >+ prepare_host_field > ); > > # Internal functions >@@ -2997,6 +2998,141 @@ sub ModBiblioMarc { > return $biblionumber; > } > >+=head2 prepare_host_field >+ >+$marcfield = prepare_host_field( $hostbiblioitem, $marcflavour ); >+Generate the host item entry for an analytic child entry >+ >+=cut >+ >+sub prepare_host_field { >+ my ( $hostbiblio, $marcflavour ) = @_; >+ $marcflavour ||= C4::Context->preference('marcflavour'); >+ >+ my $biblio = Koha::Biblios->find($hostbiblio); >+ my $host = $biblio->metadata->record; >+ >+ # unfortunately as_string does not 'do the right thing' >+ # if field returns undef >+ my %sfd; >+ my $field; >+ my $host_field; >+ if ( $marcflavour eq 'MARC21' ) { >+ if ( $field = $host->field('100') || $host->field('110') || $host->field('11') ) { >+ my $s = $field->as_string('ab'); >+ if ($s) { >+ $sfd{a} = $s; >+ } >+ } >+ if ( $field = $host->field('245') ) { >+ my $s = $field->as_string('a'); >+ if ($s) { >+ $sfd{t} = $s; >+ } >+ } >+ if ( $field = $host->field('260') ) { >+ my $s = $field->as_string('abc'); >+ if ($s) { >+ $sfd{d} = $s; >+ } >+ } >+ if ( $field = $host->field('240') ) { >+ my $s = $field->as_string(); >+ if ($s) { >+ $sfd{b} = $s; >+ } >+ } >+ if ( $field = $host->field('022') ) { >+ my $s = $field->as_string('a'); >+ if ($s) { >+ $sfd{x} = $s; >+ } >+ } >+ if ( $field = $host->field('020') ) { >+ my $s = $field->as_string('a'); >+ if ($s) { >+ $sfd{z} = $s; >+ } >+ } >+ if ( $field = $host->field('001') ) { >+ $sfd{w} = $field->data(),; >+ } >+ $host_field = MARC::Field->new( 773, '0', ' ', %sfd ); >+ return $host_field; >+ } elsif ( $marcflavour eq 'UNIMARC' ) { >+ >+ #author >+ if ( $field = $host->field('700') || $host->field('710') || $host->field('720') ) { >+ my $s = $field->as_string('ab'); >+ if ($s) { >+ $sfd{a} = $s; >+ } >+ } >+ >+ #title >+ if ( $field = $host->field('200') ) { >+ my $s = $field->as_string('a'); >+ if ($s) { >+ $sfd{t} = $s; >+ } >+ } >+ >+ #place of publicaton >+ if ( $field = $host->field('210') ) { >+ my $s = $field->as_string('a'); >+ if ($s) { >+ $sfd{c} = $s; >+ } >+ } >+ >+ #date of publication >+ if ( $field = $host->field('210') ) { >+ my $s = $field->as_string('d'); >+ if ($s) { >+ $sfd{d} = $s; >+ } >+ } >+ >+ #edition statement >+ if ( $field = $host->field('205') ) { >+ my $s = $field->as_string(); >+ if ($s) { >+ $sfd{e} = $s; >+ } >+ } >+ >+ #URL >+ if ( $field = $host->field('856') ) { >+ my $s = $field->as_string('u'); >+ if ($s) { >+ $sfd{u} = $s; >+ } >+ } >+ >+ #ISSN >+ if ( $field = $host->field('011') ) { >+ my $s = $field->as_string('a'); >+ if ($s) { >+ $sfd{x} = $s; >+ } >+ } >+ >+ #ISBN >+ if ( $field = $host->field('010') ) { >+ my $s = $field->as_string('a'); >+ if ($s) { >+ $sfd{y} = $s; >+ } >+ } >+ if ( $field = $host->field('001') ) { >+ $sfd{0} = $field->data(),; >+ } >+ $host_field = MARC::Field->new( 461, '0', ' ', %sfd ); >+ return $host_field; >+ } >+ return; >+} >+ > =head2 UpdateTotalIssues > > UpdateTotalIssues($biblionumber, $increase, [$value]) >@@ -3046,7 +3182,7 @@ sub UpdateTotalIssues { > if ( defined $value ) { > $totalissues = $value; > } else { >- $totalissues = $current_issues + $increase; >+ $totalissues = $biblioitem->totalissues + $increase; > } > return 0 if $current_issues == $totalissues; # No need to update if no changes > >diff --git a/C4/Circulation.pm b/C4/Circulation.pm >index f9cf48a605..bf93c32a59 100644 >--- a/C4/Circulation.pm >+++ b/C4/Circulation.pm >@@ -4442,7 +4442,7 @@ sub ProcessOfflineOperation { > if ( $operation->{action} eq 'return' ) { > $report = ProcessOfflineReturn($operation); > } elsif ( $operation->{action} eq 'issue' ) { >- ($report) = ProcessOfflineIssue($operation); >+ $report = ProcessOfflineIssue($operation); > } elsif ( $operation->{action} eq 'payment' ) { > $report = ProcessOfflinePayment($operation); > } >@@ -4513,15 +4513,15 @@ sub ProcessOfflineIssue { > $operation->{timestamp}, > ); > } >- my $checkout = AddIssue( >+ AddIssue( > $patron, >- $operation->{barcode}, >- $operation->{due_date}, >+ $operation->{'barcode'}, >+ undef, > undef, > $operation->{timestamp}, > undef, > ); >- return ( "Success.", $checkout ); >+ return "Success."; > } else { > return "Borrower not found."; > } >diff --git a/C4/ClassSplitRoutine/LCC.pm b/C4/ClassSplitRoutine/LCC.pm >index a2ee632960..12901ba3e3 100644 >--- a/C4/ClassSplitRoutine/LCC.pm >+++ b/C4/ClassSplitRoutine/LCC.pm >@@ -46,7 +46,7 @@ sub split_callnumber { > # lccn examples: 'HE8700.7 .P6T44 1983', 'BS2545.E8 H39 1996'; > my @lines = Library::CallNumber::LC->new($cn_item)->components(); > unless ( scalar @lines && defined $lines[0] ) { >- Koha::Logger->get->debug( sprintf( 'regexp failed to match string: %s', $cn_item // q{} ) ); >+ Koha::Logger->get->debug( sprintf( 'regexp failed to match string: %s', $cn_item ) ); > @lines = $cn_item; # if no match, just use the whole string. > } > my $LastPiece = pop @lines; >diff --git a/C4/Koha.pm b/C4/Koha.pm >index bee096db9f..13e7a5da7d 100644 >--- a/C4/Koha.pm >+++ b/C4/Koha.pm >@@ -513,7 +513,7 @@ sub GetAuthorisedValues { > my $opac = shift ? 1 : 0; # normalise to be safe > > # Is this cached already? >- my $branch_limit = C4::Context::mybranch(); >+ my $branch_limit = C4::Context->userenv ? C4::Context->userenv->{"branch"} : ""; > my $cache_key = "AuthorisedValues-$category-$opac-$branch_limit"; > my $cache = Koha::Caches->get_instance(); > my $result = $cache->get_from_cache($cache_key); >diff --git a/C4/Labels/Label.pm b/C4/Labels/Label.pm >index dd289083ee..842cfb051a 100644 >--- a/C4/Labels/Label.pm >+++ b/C4/Labels/Label.pm >@@ -385,12 +385,8 @@ sub draw_label_text { > my $font = $self->{'font'}; > my $item = _get_label_item( $self->{'item_number'} ); > my $label_fields = _get_text_fields( $self->{'format_string'} ); >- my $biblio = Koha::Biblios->find( $item->{'biblionumber'} ); >- my $record; >- >- if ( defined $biblio ) { >- $record = $biblio->metadata->record; >- } >+ my $biblio = Koha::Biblios->find( $item->{biblionumber} ); >+ my $record = $biblio->metadata->record; > > # FIXME - returns all items, so you can't get data from an embedded holdings field. > # TODO - add a GetMarcBiblio1item(bibnum,itemnum) or a GetMarcItem(itemnum). >diff --git a/C4/SIP/ILS/Transaction/Checkout.pm b/C4/SIP/ILS/Transaction/Checkout.pm >index 4909400493..247ba86ca3 100644 >--- a/C4/SIP/ILS/Transaction/Checkout.pm >+++ b/C4/SIP/ILS/Transaction/Checkout.pm >@@ -156,15 +156,13 @@ sub do_checkout { > > if ($no_block_due_date) { > $overridden_duedate = $no_block_due_date; >- my ( $msg, $checkout ) = ProcessOfflineIssue( >+ ProcessOfflineIssue( > { > cardnumber => $patron->cardnumber, > barcode => $barcode, >- due_date => $no_block_due_date, >- timestamp => dt_from_string, >+ timestamp => $no_block_due_date, > } > ); >- $self->{due} = $self->duedatefromissue( $checkout, $itemnumber ); > } else { > > # can issue >diff --git a/C4/Search.pm b/C4/Search.pm >index bf0a485286..08903e7fc5 100644 >--- a/C4/Search.pm >+++ b/C4/Search.pm >@@ -40,8 +40,6 @@ use URI::Escape; > use Business::ISBN; > use MARC::Record; > use MARC::Field; >-use POSIX qw(setlocale LC_COLLATE); >-use Unicode::Collate::Locale; > > our ( @ISA, @EXPORT_OK ); > >@@ -293,40 +291,6 @@ See verbose embedded documentation. > > =cut > >-=head2 _sort_facets_zebra >- >- my $sorted_facets = _sort_facets_zebra($facets, $locale); >- >-Sorts facets using a configurable locale for Zebra search engine. >- >-=cut >- >-sub _sort_facets_zebra { >- my ( $facets, $locale ) = @_; >- >- if ( !$locale ) { >- >- # Get locale from system preference, falling back to system LC_COLLATE >- $locale = C4::Context->preference('FacetSortingLocale') || 'default'; >- if ( $locale eq 'default' || !$locale ) { >- >- #NOTE: When setlocale is run with only the 1st parameter, it is a "get" not a "set" function. >- $locale = setlocale(LC_COLLATE) || 'default'; >- } >- } >- >- my $collator = Unicode::Collate::Locale->new( locale => $locale ); >- if ( $collator && $facets ) { >- my @sorted_facets = sort { $collator->cmp( $a->{facet_label_value}, $b->{facet_label_value} ) } @{$facets}; >- if (@sorted_facets) { >- return \@sorted_facets; >- } >- } >- >- #NOTE: If there was a problem, at least return the not sorted facets >- return $facets; >-} >- > sub getRecords { > my ( > $koha_query, $simple_query, $sort_by_ref, $servers_ref, >@@ -590,10 +554,8 @@ sub getRecords { > if (@facets_loop) { > foreach my $f (@facets_loop) { > if ( C4::Context->preference('FacetOrder') eq 'Alphabetical' ) { >- my $sorted_facets = _sort_facets_zebra( $f->{facets} ); >- if ($sorted_facets) { >- $f->{facets} = $sorted_facets; >- } >+ $f->{facets} = >+ [ sort { uc( $a->{facet_label_value} ) cmp uc( $b->{facet_label_value} ) } @{ $f->{facets} } ]; > } > } > } >diff --git a/Koha.pm b/Koha.pm >index db34a6358d..f10b89be43 100644 >--- a/Koha.pm >+++ b/Koha.pm >@@ -29,7 +29,7 @@ use vars qw{ $VERSION }; > # - #4 : the developer version. The 4th number is the database subversion. > # used by developers when the database changes. updatedatabase take care of the changes itself > # and is automatically called by Auth.pm when needed. >-$VERSION = "25.06.00.004"; >+$VERSION = "25.06.00.003"; > > sub version { > return $VERSION; >diff --git a/Koha/Acquisition/Order/Claims.pm b/Koha/Acquisition/Order/Claims.pm >index 7cee67ff75..eef991990e 100644 >--- a/Koha/Acquisition/Order/Claims.pm >+++ b/Koha/Acquisition/Order/Claims.pm >@@ -25,7 +25,7 @@ use base qw(Koha::Objects); > > =head1 NAME > >-Koha::Acquisition::Order::Claims - Koha Claims Object set class >+Koha::Cities - Koha Claim Object set class > > =head1 API > >diff --git a/Koha/Biblio.pm b/Koha/Biblio.pm >index 4c88bcd8a5..0df2b489a7 100644 >--- a/Koha/Biblio.pm >+++ b/Koha/Biblio.pm >@@ -1921,195 +1921,164 @@ sub generate_marc_host_field { > > my $marcflavour = C4::Context->preference('marcflavour'); > my $marc_host = $self->metadata->record; >- >- my @sfd; >+ my %sfd; > my $host_field; > my $link_field; > > if ( $marcflavour eq 'MARC21' ) { > >- # Attempt to clone the main entry (100, 110, or 111) >- my $main_entry = $marc_host->field('100') || $marc_host->field('110') || $marc_host->field('111'); >- $main_entry = $main_entry ? $main_entry->clone : undef; >- >- # Clean unwanted subfields based on tag type >- if ($main_entry) { >- if ( $main_entry->tag eq '111' ) { >- $main_entry->delete_subfield( code => qr/[94j]/ ); >- } else { >- $main_entry->delete_subfield( code => qr/[94e]/ ); >- } >- } >- >- # Construct subfield 7 from leader and main entry tag >- my $s7 = "nn" . substr( $marc_host->leader, 6, 2 ); >- if ($main_entry) { >- my $c1 = 'n'; >- if ( $main_entry->tag =~ /^1[01]/ ) { >- $c1 = $main_entry->indicator('1'); >- $c1 = $main_entry->tag eq '100' ? 1 : 2 unless $c1 =~ /\d/; >- } >- my $c0 = >- ( $main_entry->tag eq '100' ) ? 'p' >- : ( $main_entry->tag eq '110' ) ? 'c' >- : ( $main_entry->tag eq '111' ) ? 'm' >- : 'u'; >- substr( $s7, 0, 2, $c0 . $c1 ); >- } >- push @sfd, ( '7' => $s7 ); >- >- # Subfield a - cleaned main entry string >- if ($main_entry) { >- my $a = $main_entry->as_string; >- $a =~ s/\.$// unless $a =~ /\b[a-z]{1,2}\.$/i; >- push @sfd, ( 'a' => $a ); >- } >- >- # Subfield t - title from 245, cleaned >- if ( my $f245 = $marc_host->field('245') ) { >- my $f245c = $f245->clone; >- $f245c->delete_subfield( code => 'c' ); >- my $t = $f245c->as_string; >- $t =~ s/[\s\/\\.]+$//; >- my $nonfiling = $f245c->indicator('2') // 0; >- $nonfiling = 0 unless $nonfiling =~ /^\d+$/; >- $t = ucfirst substr( $t, $nonfiling ); >- push @sfd, ( 't' => $t ); >- } >- >- # Subfield b - edition from 250 >- if ( my $f250 = $marc_host->field('250') ) { >- my $b = $f250->as_string; >- $b =~ s/\.$//; >- if ($b) { >- push @sfd, ( 'b' => $b ); >+ # Author >+ if ( $host_field = $marc_host->field('100') || $marc_host->field('110') || $marc_host->field('111') ) { >+ my $s = $host_field->as_string('ab'); >+ if ($s) { >+ $sfd{a} = $s; > } > } > >- # Subfield s - uniform title from 240 >- if ( my $f240 = $marc_host->field('240') ) { >- my $s = $f240->as_string('a'); >+ # Edition >+ if ( $host_field = $marc_host->field('250') ) { >+ my $s = $host_field->as_string('ab'); > if ($s) { >- push @sfd, ( 's' => $s ); >+ $sfd{b} = $s; > } > } > >- # Subfield d - publication info from 264/260 >- my $d; >+ # Publication > my @publication_fields = $marc_host->field('264'); > @publication_fields = $marc_host->field('260') unless (@publication_fields); > my $index = 0; >- for my $publication_field (@publication_fields) { >+ for my $host_field (@publication_fields) { > > # Use first entry unless we find a preferred indicator1 = 3 > if ( $index == 0 ) { >- my $s = $publication_field->as_string('abc'); >- $s =~ s/\.$//; >+ my $s = $host_field->as_string('abc'); > if ($s) { >- $d = $s; >+ $sfd{d} = $s; > } > $index++; > } >- if ( $publication_field->indicator(1) && ( $publication_field->indicator(1) eq '3' ) ) { >- my $s = $publication_field->as_string('abc'); >- $s =~ s/\.$//; >+ if ( $host_field->indicator(1) && ( $host_field->indicator(1) eq '3' ) ) { >+ my $s = $host_field->as_string('abc'); > if ($s) { >- $d = $s; >+ $sfd{d} = $s; > } > last; > } > } >- push @sfd, ( d => $d ) if $d; >- >- # Subfield k - host info from 800-830 fields >- for my $f ( $marc_host->field('8[013][01]') ) { >- my $k = $f->as_string('abcdnjltnp'); >- $k .= ', ISSN ' . $f->subfield('x') if $f->subfield('x'); >- $k .= ' ; ' . $f->subfield('v') if $f->subfield('v'); >- push @sfd, ( 'k' => $k ); >+ >+ # Uniform title >+ if ( $host_field = $marc_host->field('240') ) { >+ my $s = $host_field->as_string('a'); >+ if ($s) { >+ $sfd{s} = $s; >+ } > } > >- # Subfield x - ISSN from 022 >- for my $f ( $marc_host->field('022') ) { >- push @sfd, ( 'x' => $f->subfield('a') ) if $f->subfield('a'); >+ # Title >+ if ( $host_field = $marc_host->field('245') ) { >+ my $s = $host_field->as_string('abnp'); >+ if ($s) { >+ $sfd{t} = $s; >+ } > } > >- # Subfield z - ISBN from 020 >- for my $f ( $marc_host->field('020') ) { >- push @sfd, ( 'z' => $f->subfield('a') ) if $f->subfield('a'); >+ # ISSN >+ if ( $host_field = $marc_host->field('022') ) { >+ my $s = $host_field->as_string('a'); >+ if ($s) { >+ $sfd{x} = $s; >+ } > } > >- # Subfield w - control number (001 and optionally 003) >- if ( C4::Context->preference('UseControlNumber') ) { >- if ( my $f001 = $marc_host->field('001') ) { >- my $w = $f001->data; >- if ( my $f003 = $marc_host->field('003') ) { >- $w = '(' . $f003->data . ')' . $w; >- } >- push @sfd, ( 'w' => $w ); >+ # ISBN >+ if ( $host_field = $marc_host->field('020') ) { >+ my $s = $host_field->as_string('a'); >+ if ($s) { >+ $sfd{z} = $s; > } > } >+ if ( C4::Context->preference('UseControlNumber') ) { > >- # Construct 773 link field >- $link_field = MARC::Field->new( 773, '0', ' ', @sfd ); >+ # Control number >+ if ( $host_field = $marc_host->field('001') ) { >+ $sfd{w} = $host_field->data(); >+ } > >+ # Control number identifier >+ if ( $host_field = $marc_host->field('003') ) { >+ $sfd{w} = '(' . $host_field->data() . ')' . $sfd{w}; >+ } >+ } >+ $link_field = MARC::Field->new( 773, '0', ' ', %sfd ); > } elsif ( $marcflavour eq 'UNIMARC' ) { > >- # Author (700/710/720) >+ # Author > if ( $host_field = $marc_host->field('700') || $marc_host->field('710') || $marc_host->field('720') ) { > my $s = $host_field->as_string('ab'); >- push @sfd, ( 'a' => $s ) if $s; >- } >- >- # Title (200) >- if ( $host_field = $marc_host->field('200') ) { >- my $s = $host_field->as_string('a'); >- push @sfd, ( 't' => $s ) if $s; >+ if ($s) { >+ $sfd{a} = $s; >+ } > } > >- # Place of publication (210$a) >+ # Place of publication > if ( $host_field = $marc_host->field('210') ) { > my $s = $host_field->as_string('a'); >- push @sfd, ( 'c' => $s ) if $s; >+ if ($s) { >+ $sfd{c} = $s; >+ } > } > >- # Date of publication (210$d) >+ # Date of publication > if ( $host_field = $marc_host->field('210') ) { > my $s = $host_field->as_string('d'); >- push @sfd, ( 'd' => $s ) if $s; >+ if ($s) { >+ $sfd{d} = $s; >+ } > } > >- # Edition statement (205) >+ # Edition statement > if ( $host_field = $marc_host->field('205') ) { >- my $s = $host_field->as_string; >- push @sfd, ( 'e' => $s ) if $s; >+ my $s = $host_field->as_string(); >+ if ($s) { >+ $sfd{e} = $s; >+ } > } > >- # URL (856$u) >+ # Title >+ if ( $host_field = $marc_host->field('200') ) { >+ my $s = $host_field->as_string('a'); >+ if ($s) { >+ $sfd{t} = $s; >+ } >+ } >+ >+ #URL > if ( $host_field = $marc_host->field('856') ) { > my $s = $host_field->as_string('u'); >- push @sfd, ( u => $s ) if ($s); >+ if ($s) { >+ $sfd{u} = $s; >+ } > } > >- # ISSN (011$a) >+ # ISSN > if ( $host_field = $marc_host->field('011') ) { > my $s = $host_field->as_string('a'); >- push @sfd, ( x => $s ) if ($s); >+ if ($s) { >+ $sfd{x} = $s; >+ } > } > >- # ISBN (010$a) >+ # ISBN > if ( $host_field = $marc_host->field('010') ) { > my $s = $host_field->as_string('a'); >- push @sfd, ( y => $s ) if ($s); >+ if ($s) { >+ $sfd{y} = $s; >+ } > } >- >- # Control number (001) > if ( $host_field = $marc_host->field('001') ) { >- push @sfd, ( 0 => $host_field->data() ); >+ $sfd{0} = $host_field->data(); > } >- >- # Construct 461 link field >- $link_field = MARC::Field->new( 461, '0', ' ', @sfd ); >+ $link_field = MARC::Field->new( 461, '0', ' ', %sfd ); > } > > return $link_field; >diff --git a/Koha/Course.pm b/Koha/Course.pm >index e4b800f043..6b67a2b592 100644 >--- a/Koha/Course.pm >+++ b/Koha/Course.pm >@@ -2,18 +2,18 @@ package Koha::Course; > > # This file is part of Koha. > # >-# Koha is free software; you can redistribute it and/or modify it >-# under the terms of the GNU General Public License as published by >-# the Free Software Foundation; either version 3 of the License, or >-# (at your option) any later version. >+# Koha is free software; you can redistribute it and/or modify it under the >+# terms of the GNU General Public License as published by the Free Software >+# Foundation; either version 3 of the License, or (at your option) any later >+# version. > # >-# Koha is distributed in the hope that it will be useful, but >-# WITHOUT ANY WARRANTY; without even the implied warranty of >-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >-# GNU General Public License for more details. >+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY >+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR >+# A PARTICULAR PURPOSE. See the GNU General Public License for more details. > # >-# You should have received a copy of the GNU General Public License >-# along with Koha; if not, see <http://www.gnu.org/licenses>. >+# You should have received a copy of the GNU General Public License along >+# with Koha; if not, write to the Free Software Foundation, Inc., >+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. > > use Modern::Perl; > >diff --git a/Koha/Course/Instructor.pm b/Koha/Course/Instructor.pm >index da9864fe17..4b6f8a262d 100644 >--- a/Koha/Course/Instructor.pm >+++ b/Koha/Course/Instructor.pm >@@ -2,18 +2,18 @@ package Koha::Course::Instructor; > > # This file is part of Koha. > # >-# Koha is free software; you can redistribute it and/or modify it >-# under the terms of the GNU General Public License as published by >-# the Free Software Foundation; either version 3 of the License, or >-# (at your option) any later version. >+# Koha is free software; you can redistribute it and/or modify it under the >+# terms of the GNU General Public License as published by the Free Software >+# Foundation; either version 3 of the License, or (at your option) any later >+# version. > # >-# Koha is distributed in the hope that it will be useful, but >-# WITHOUT ANY WARRANTY; without even the implied warranty of >-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >-# GNU General Public License for more details. >+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY >+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR >+# A PARTICULAR PURPOSE. See the GNU General Public License for more details. > # >-# You should have received a copy of the GNU General Public License >-# along with Koha; if not, see <http://www.gnu.org/licenses>. >+# You should have received a copy of the GNU General Public License along >+# with Koha; if not, write to the Free Software Foundation, Inc., >+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. > > use Modern::Perl; > >diff --git a/Koha/Course/Instructors.pm b/Koha/Course/Instructors.pm >index 95e13bb9c3..82a0191b34 100644 >--- a/Koha/Course/Instructors.pm >+++ b/Koha/Course/Instructors.pm >@@ -2,18 +2,18 @@ package Koha::Course::Instructors; > > # This file is part of Koha. > # >-# Koha is free software; you can redistribute it and/or modify it >-# under the terms of the GNU General Public License as published by >-# the Free Software Foundation; either version 3 of the License, or >-# (at your option) any later version. >+# Koha is free software; you can redistribute it and/or modify it under the >+# terms of the GNU General Public License as published by the Free Software >+# Foundation; either version 3 of the License, or (at your option) any later >+# version. > # >-# Koha is distributed in the hope that it will be useful, but >-# WITHOUT ANY WARRANTY; without even the implied warranty of >-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >-# GNU General Public License for more details. >+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY >+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR >+# A PARTICULAR PURPOSE. See the GNU General Public License for more details. > # >-# You should have received a copy of the GNU General Public License >-# along with Koha; if not, see <http://www.gnu.org/licenses>. >+# You should have received a copy of the GNU General Public License along >+# with Koha; if not, write to the Free Software Foundation, Inc., >+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. > > use Modern::Perl; > >diff --git a/Koha/Course/Item.pm b/Koha/Course/Item.pm >index 6d6f3b626a..d13be0ba55 100644 >--- a/Koha/Course/Item.pm >+++ b/Koha/Course/Item.pm >@@ -2,18 +2,18 @@ package Koha::Course::Item; > > # This file is part of Koha. > # >-# Koha is free software; you can redistribute it and/or modify it >-# under the terms of the GNU General Public License as published by >-# the Free Software Foundation; either version 3 of the License, or >-# (at your option) any later version. >+# Koha is free software; you can redistribute it and/or modify it under the >+# terms of the GNU General Public License as published by the Free Software >+# Foundation; either version 3 of the License, or (at your option) any later >+# version. > # >-# Koha is distributed in the hope that it will be useful, but >-# WITHOUT ANY WARRANTY; without even the implied warranty of >-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >-# GNU General Public License for more details. >+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY >+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR >+# A PARTICULAR PURPOSE. See the GNU General Public License for more details. > # >-# You should have received a copy of the GNU General Public License >-# along with Koha; if not, see <http://www.gnu.org/licenses>. >+# You should have received a copy of the GNU General Public License along >+# with Koha; if not, write to the Free Software Foundation, Inc., >+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. > > use Modern::Perl; > >diff --git a/Koha/Course/Items.pm b/Koha/Course/Items.pm >index b6feda4f77..f563998515 100644 >--- a/Koha/Course/Items.pm >+++ b/Koha/Course/Items.pm >@@ -2,18 +2,18 @@ package Koha::Course::Items; > > # This file is part of Koha. > # >-# Koha is free software; you can redistribute it and/or modify it >-# under the terms of the GNU General Public License as published by >-# the Free Software Foundation; either version 3 of the License, or >-# (at your option) any later version. >+# Koha is free software; you can redistribute it and/or modify it under the >+# terms of the GNU General Public License as published by the Free Software >+# Foundation; either version 3 of the License, or (at your option) any later >+# version. > # >-# Koha is distributed in the hope that it will be useful, but >-# WITHOUT ANY WARRANTY; without even the implied warranty of >-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >-# GNU General Public License for more details. >+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY >+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR >+# A PARTICULAR PURPOSE. See the GNU General Public License for more details. > # >-# You should have received a copy of the GNU General Public License >-# along with Koha; if not, see <http://www.gnu.org/licenses>. >+# You should have received a copy of the GNU General Public License along >+# with Koha; if not, write to the Free Software Foundation, Inc., >+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. > > use Modern::Perl; > >diff --git a/Koha/Course/Reserve.pm b/Koha/Course/Reserve.pm >index 0fb1906c9b..6493ba90a3 100644 >--- a/Koha/Course/Reserve.pm >+++ b/Koha/Course/Reserve.pm >@@ -2,18 +2,18 @@ package Koha::Course::Reserve; > > # This file is part of Koha. > # >-# Koha is free software; you can redistribute it and/or modify it >-# under the terms of the GNU General Public License as published by >-# the Free Software Foundation; either version 3 of the License, or >-# (at your option) any later version. >+# Koha is free software; you can redistribute it and/or modify it under the >+# terms of the GNU General Public License as published by the Free Software >+# Foundation; either version 3 of the License, or (at your option) any later >+# version. > # >-# Koha is distributed in the hope that it will be useful, but >-# WITHOUT ANY WARRANTY; without even the implied warranty of >-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >-# GNU General Public License for more details. >+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY >+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR >+# A PARTICULAR PURPOSE. See the GNU General Public License for more details. > # >-# You should have received a copy of the GNU General Public License >-# along with Koha; if not, see <http://www.gnu.org/licenses>. >+# You should have received a copy of the GNU General Public License along >+# with Koha; if not, write to the Free Software Foundation, Inc., >+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. > > use Modern::Perl; > >diff --git a/Koha/Course/Reserves.pm b/Koha/Course/Reserves.pm >index 5bd38a2fe7..b824a78da2 100644 >--- a/Koha/Course/Reserves.pm >+++ b/Koha/Course/Reserves.pm >@@ -2,18 +2,18 @@ package Koha::Course::Reserves; > > # This file is part of Koha. > # >-# Koha is free software; you can redistribute it and/or modify it >-# under the terms of the GNU General Public License as published by >-# the Free Software Foundation; either version 3 of the License, or >-# (at your option) any later version. >+# Koha is free software; you can redistribute it and/or modify it under the >+# terms of the GNU General Public License as published by the Free Software >+# Foundation; either version 3 of the License, or (at your option) any later >+# version. > # >-# Koha is distributed in the hope that it will be useful, but >-# WITHOUT ANY WARRANTY; without even the implied warranty of >-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >-# GNU General Public License for more details. >+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY >+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR >+# A PARTICULAR PURPOSE. See the GNU General Public License for more details. > # >-# You should have received a copy of the GNU General Public License >-# along with Koha; if not, see <http://www.gnu.org/licenses>. >+# You should have received a copy of the GNU General Public License along >+# with Koha; if not, write to the Free Software Foundation, Inc., >+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. > > use Modern::Perl; > >diff --git a/Koha/Courses.pm b/Koha/Courses.pm >index 7604deab0b..6a3f396daa 100644 >--- a/Koha/Courses.pm >+++ b/Koha/Courses.pm >@@ -2,18 +2,18 @@ package Koha::Courses; > > # This file is part of Koha. > # >-# Koha is free software; you can redistribute it and/or modify it >-# under the terms of the GNU General Public License as published by >-# the Free Software Foundation; either version 3 of the License, or >-# (at your option) any later version. >+# Koha is free software; you can redistribute it and/or modify it under the >+# terms of the GNU General Public License as published by the Free Software >+# Foundation; either version 3 of the License, or (at your option) any later >+# version. > # >-# Koha is distributed in the hope that it will be useful, but >-# WITHOUT ANY WARRANTY; without even the implied warranty of >-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >-# GNU General Public License for more details. >+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY >+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR >+# A PARTICULAR PURPOSE. See the GNU General Public License for more details. > # >-# You should have received a copy of the GNU General Public License >-# along with Koha; if not, see <http://www.gnu.org/licenses>. >+# You should have received a copy of the GNU General Public License along >+# with Koha; if not, write to the Free Software Foundation, Inc., >+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. > > use Modern::Perl; > >diff --git a/Koha/CoverImages.pm b/Koha/CoverImages.pm >index 26e9fc5e5e..774d36ada8 100644 >--- a/Koha/CoverImages.pm >+++ b/Koha/CoverImages.pm >@@ -25,7 +25,7 @@ use base qw(Koha::Objects); > > =head1 NAME > >-Koha::CoverImages - Koha CoverImage Object set class >+Koha::Cities - Koha CoverImage Object set class > > =head1 API > >diff --git a/Koha/Devel/Files.pm b/Koha/Devel/Files.pm >deleted file mode 100644 >index df1bba620b..0000000000 >--- a/Koha/Devel/Files.pm >+++ /dev/null >@@ -1,192 +0,0 @@ >-package Koha::Devel::Files; >- >-use Modern::Perl; >-our ( @ISA, @EXPORT_OK ); >- >-=head1 NAME >- >-Koha::Devel::Files - A utility module for managing and filtering file lists in the Koha codebase >- >-=head1 SYNOPSIS >- >- use Koha::Devel::Files; >- >- my $file_manager = Koha::Devel::Files->new({ context => 'tidy' }); >- >- my @perl_files = $file_manager->ls_perl_files($git_range); >- my @js_files = $file_manager->ls_js_files(); >- my @tt_files = $file_manager->ls_tt_files(); >- >- my $filetype = $file_manager->get_filetype($filename); >- >-=head1 DESCRIPTION >- >-Koha::Devel::Files is a utility module designed to assist in managing and filtering lists of files in the Koha codebase. It provides methods to list Perl, JavaScript, and Template Toolkit files, with options to exclude specific files based on a given context. >- >-=head1 EXCEPTIONS >- >-The module defines a set of exceptions for different file types and contexts. These exceptions are used to exclude specific files or directories from the file listings. >- >-=cut >- >-my $exceptions = { >- pl => { >- tidy => [ >- qw( >- Koha/Schema/Result >- Koha/Schema.pm >- ) >- ], >- valid => [ >- qw( >- Koha/Account/Credit.pm >- Koha/Account/Debit.pm >- Koha/Old/Hold.pm >- misc/translator/TmplTokenizer.pm >- ) >- ], >- codespell => [ >- qw( >- installer/data/mysql/updatedatabase.pl >- installer/data/mysql/update22to30.pl >- installer/data/mysql/db_revs/241200035.pl >- misc/cronjobs/build_browser_and_cloud.pl >- ) >- ], >- }, >- js => { >- tidy => [ >- qw( >- koha-tmpl/intranet-tmpl/lib >- koha-tmpl/intranet-tmpl/js/Gettext.js >- koha-tmpl/opac-tmpl/lib >- Koha/ILL/Backend/ >- ) >- ], >- codespell => [ >- qw( >- koha-tmpl/intranet-tmpl/lib >- koha-tmpl/intranet-tmpl/js/Gettext.js >- koha-tmpl/opac-tmpl/lib >- koha-tmpl/opac-tmpl/bootstrap/js/Gettext.js >- ) >- ], >- }, >- tt => { >- tidy => [ >- qw( >- Koha/ILL/Backend/ >- *doc-head-open.inc >- misc/cronjobs/rss >- ) >- ], >- codespell => [], >- }, >-}; >- >-=head1 METHODS >- >-=cut >- >-=head2 new >- >- my $file_manager = Koha::Devel::Files->new({ context => 'tidy' }); >- >-Creates a new instance of Koha::Devel::Files. The constructor accepts a hash reference with a 'context' key, which specifies the context for file exclusions. >- >-=cut >- >-sub new { >- my ( $class, $args ) = @_; >- my $self = { context => $args->{context} }; >- bless $self, $class; >- return $self; >-} >- >-=head2 build_git_exclude >- >- my $exclude_pattern = $file_manager->build_git_exclude($filetype); >- >-Builds a Git exclude pattern for a given file type based on the context provided during object creation. >- >-=cut >- >-sub build_git_exclude { >- my ( $self, $filetype ) = @_; >- return $self->{context} && exists $exceptions->{$filetype}->{ $self->{context} } >- ? join( " ", map( "':(exclude)$_'", @{ $exceptions->{$filetype}->{ $self->{context} } } ) ) >- : q{}; >-} >- >-=head2 ls_perl_files >- >- my @perl_files = $file_manager->ls_perl_files($git_range); >- >-Lists Perl files (with extensions .pl, .PL, .pm, .t) that have been modified within a specified Git range. If no range is provided, it lists all Perl files, excluding those specified in the exceptions. >- >-=cut >- >-sub ls_perl_files { >- my ($self) = @_; >- my $cmd = sprintf q{git ls-files '*.pl' '*.PL' '*.pm' '*.t' svc opac/svc debian/build-git-snapshot %s}, >- $self->build_git_exclude('pl'); >- my @files = qx{$cmd}; >- chomp for @files; >- return @files; >-} >- >-=head2 ls_js_files >- >- my @js_files = $file_manager->ls_js_files(); >- >-Lists JavaScript and TypeScript files (with extensions .js, .ts, .vue) in the repository, excluding those specified in the exceptions. >- >-=cut >- >-sub ls_js_files { >- my ($self) = @_; >- my $cmd = sprintf q{git ls-files '*.js' '*.ts' '*.vue' %s}, $self->build_git_exclude('js'); >- my @files = qx{$cmd}; >- chomp for @files; >- return @files; >-} >- >-=head2 ls_tt_files >- >- my @tt_files = $file_manager->ls_tt_files(); >- >-Lists Template Toolkit files (with extensions .tt, .inc) in the repository, excluding those specified in the exceptions. >- >-=cut >- >-sub ls_tt_files { >- my ($self) = @_; >- my $cmd = sprintf q{git ls-files '*.tt' '*.inc' %s}, $self->build_git_exclude('tt'); >- my @files = qx{$cmd}; >- chomp for @files; >- return @files; >-} >- >-=head2 get_filetype >- >- my $filetype = $file_manager->get_filetype($filename); >- >-Determines the file type of a given file based on its extension or path. Returns 'pl' for Perl files, 'js' for JavaScript/TypeScript files, and 'tt' for Template Toolkit files. Dies with an error message if the file type cannot be determined. >- >-=cut >- >-sub get_filetype { >- my ( $self, $file ) = @_; >- return 'pl' if $file =~ m{^svc} || $file =~ m{^opac/svc}; >- return 'pl' if $file =~ m{\.pl$} || $file =~ m{\.pm} || $file =~ m{\.t$}; >- return 'pl' if $file =~ m{\.PL$}; >- return 'pl' if $file =~ m{debian/build-git-snapshot}; >- >- return 'js' if $file =~ m{\.js$} || $file =~ m{\.ts$} || $file =~ m{\.vue$}; >- >- return 'tt' if $file =~ m{\.inc$} || $file =~ m{\.tt$}; >- >- die sprintf 'Cannot guess filetype for %s', $file; >-} >- >-1; >diff --git a/Koha/Encryption.pm b/Koha/Encryption.pm >index 4cecb6e282..b18f75a9d4 100644 >--- a/Koha/Encryption.pm >+++ b/Koha/Encryption.pm >@@ -61,9 +61,8 @@ sub new { > ); > } > return $class->SUPER::new( >- -key => $encryption_key, >- -cipher => 'Cipher::AES', >- -nodeprecate => 1, >+ -key => $encryption_key, >+ -cipher => 'Cipher::AES' > ); > } > >diff --git a/Koha/Exceptions/MarcOverlayRule.pm b/Koha/Exceptions/MarcOverlayRule.pm >index 2cedb3526a..d2e44970af 100644 >--- a/Koha/Exceptions/MarcOverlayRule.pm >+++ b/Koha/Exceptions/MarcOverlayRule.pm >@@ -2,18 +2,18 @@ package Koha::Exceptions::MarcOverlayRule; > > # This file is part of Koha. > # >-# Koha is free software; you can redistribute it and/or modify it >-# under the terms of the GNU General Public License as published by >-# the Free Software Foundation; either version 3 of the License, or >-# (at your option) any later version. >+# Koha is free software; you can redistribute it and/or modify it under the >+# terms of the GNU General Public License as published by the Free Software >+# Foundation; either version 3 of the License, or (at your option) any later >+# version. > # >-# Koha is distributed in the hope that it will be useful, but >-# WITHOUT ANY WARRANTY; without even the implied warranty of >-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >-# GNU General Public License for more details. >+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY >+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR >+# A PARTICULAR PURPOSE. See the GNU General Public License for more details. > # >-# You should have received a copy of the GNU General Public License >-# along with Koha; if not, see <http://www.gnu.org/licenses>. >+# You should have received a copy of the GNU General Public License along >+# with Koha; if not, write to the Free Software Foundation, Inc., >+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. > > use Modern::Perl; > >diff --git a/Koha/Filter/MARC/TrimFields.pm b/Koha/Filter/MARC/TrimFields.pm >index 00244cab29..99a5f0dfa3 100644 >--- a/Koha/Filter/MARC/TrimFields.pm >+++ b/Koha/Filter/MARC/TrimFields.pm >@@ -60,15 +60,9 @@ sub filter { > my $value = $subfield->[1]; > $value =~ s/[\n\r]+/ /g; > $value =~ s/^\s+|\s+$//g; >- $field->add_subfields( $key => $value ) >- if $value ne q{} >- ; # add subfield to the end of the subfield list, but only if there is still a non empty value there >- $field->delete_subfield( pos => 0 ); # delete the subfield at the top of the subfield list >+ $field->add_subfields( $key => $value ); # add subfield to the end of the subfield list >+ $field->delete_subfield( pos => 0 ); # delete the subfield at the top of the subfield list > } >- >- # if it happed that all existing subfields had whitespaces only, >- # the field would be empty now and should be removed from the record >- $record->delete_fields($field) unless scalar( $field->subfields ); > } > } > return $record; >diff --git a/Koha/I18N.pm b/Koha/I18N.pm >index 3fbbabe685..c957e9df40 100644 >--- a/Koha/I18N.pm >+++ b/Koha/I18N.pm >@@ -53,51 +53,8 @@ our @EXPORT = qw( > N__np > ); > >-our @EXPORT_OK = qw( >- available_locales >-); >- > our $textdomain = 'Koha'; > >-=head1 NAME >- >-Koha::I18N - Internationalization functions for Koha >- >-=head1 SYNOPSIS >- >- use Koha::I18N; >- >- # Basic translation functions >- my $translated = __('Hello world'); >- my $with_vars = __x('Hello {name}', name => 'World'); >- my $plural = __n('one item', '{count} items', $count, count => $count); >- >- # Context-aware translations >- my $context = __p('menu', 'File'); >- >- # Get available system locales (explicitly imported) >- use Koha::I18N qw(available_locales); >- my $locales = available_locales(); >- >-=head1 DESCRIPTION >- >-This module provides internationalization (i18n) functions for Koha using the >-GNU gettext system. It handles locale setup, message translation, and provides >-utility functions for working with system locales. >- >-The module automatically initializes the locale environment and provides a set >-of translation functions that support variable substitution, plural forms, and >-contextual translations. >- >-=head1 FUNCTIONS >- >-=head2 init >- >-Initializes the internationalization system by setting up locale environment >-variables and configuring gettext. This is called automatically when needed. >- >-=cut >- > sub init { > my $cache = Koha::Cache::Memory::Lite->get_instance(); > my $cache_key = 'i18n:initialized'; >@@ -135,14 +92,6 @@ sub init { > } > } > >-=head2 __ >- >- my $translated = __('Text to translate'); >- >-Basic translation function. Returns the translated text for the given message ID. >- >-=cut >- > sub __ { > my ($msgid) = @_; > >@@ -151,15 +100,6 @@ sub __ { > return _gettext( \&gettext, [$msgid] ); > } > >-=head2 __x >- >- my $translated = __x('Hello {name}', name => 'World'); >- >-Translation with variable substitution. Variables in {brackets} are replaced >-with the corresponding values from the provided hash. >- >-=cut >- > sub __x { > my ( $msgid, %vars ) = @_; > >@@ -168,14 +108,6 @@ sub __x { > return _gettext( \&gettext, [$msgid], %vars ); > } > >-=head2 __n >- >- my $translated = __n('one item', '{count} items', $count); >- >-Plural-aware translation. Returns singular or plural form based on the count. >- >-=cut >- > sub __n { > my ( $msgid, $msgid_plural, $count ) = @_; > >@@ -185,14 +117,6 @@ sub __n { > return _gettext( \&ngettext, [ $msgid, $msgid_plural, $count ] ); > } > >-=head2 __nx >- >- my $translated = __nx('one item', '{count} items', $count, count => $count); >- >-Plural-aware translation with variable substitution. >- >-=cut >- > sub __nx { > my ( $msgid, $msgid_plural, $count, %vars ) = @_; > >@@ -202,25 +126,10 @@ sub __nx { > return _gettext( \&ngettext, [ $msgid, $msgid_plural, $count ], %vars ); > } > >-=head2 __xn >- >-Alias for __nx. >- >-=cut >- > sub __xn { > return __nx(@_); > } > >-=head2 __p >- >- my $translated = __p('context', 'Text to translate'); >- >-Context-aware translation. Allows the same text to be translated differently >-based on context (e.g., 'File' in a menu vs 'File' as a document type). >- >-=cut >- > sub __p { > my ( $msgctxt, $msgid ) = @_; > >@@ -230,14 +139,6 @@ sub __p { > return _gettext( \&pgettext, [ $msgctxt, $msgid ] ); > } > >-=head2 __px >- >- my $translated = __px('context', 'Hello {name}', name => 'World'); >- >-Context-aware translation with variable substitution. >- >-=cut >- > sub __px { > my ( $msgctxt, $msgid, %vars ) = @_; > >@@ -247,14 +148,6 @@ sub __px { > return _gettext( \&pgettext, [ $msgctxt, $msgid ], %vars ); > } > >-=head2 __np >- >- my $translated = __np('context', 'one item', '{count} items', $count); >- >-Context-aware plural translation. >- >-=cut >- > sub __np { > my ( $msgctxt, $msgid, $msgid_plural, $count ) = @_; > >@@ -265,14 +158,6 @@ sub __np { > return _gettext( \&npgettext, [ $msgctxt, $msgid, $msgid_plural, $count ] ); > } > >-=head2 __npx >- >- my $translated = __npx('context', 'one item', '{count} items', $count, count => $count); >- >-Context-aware plural translation with variable substitution. >- >-=cut >- > sub __npx { > my ( $msgctxt, $msgid, $msgid_plural, $count, %vars ) = @_; > >@@ -283,51 +168,18 @@ sub __npx { > return _gettext( \&npgettext, [ $msgctxt, $msgid, $msgid_plural, $count ], %vars ); > } > >-=head2 N__ >- >- my $msgid = N__('Text for later translation'); >- >-No-operation translation marker. Returns the original text unchanged but marks >-it for extraction by translation tools. >- >-=cut >- > sub N__ { > return $_[0]; > } > >-=head2 N__n >- >- my $msgid = N__n('singular', 'plural'); >- >-No-operation plural translation marker. >- >-=cut >- > sub N__n { > return $_[0]; > } > >-=head2 N__p >- >- my $msgid = N__p('context', 'Text for later translation'); >- >-No-operation context translation marker. >- >-=cut >- > sub N__p { > return $_[1]; > } > >-=head2 N__np >- >- my $msgid = N__np('context', 'singular', 'plural'); >- >-No-operation context plural translation marker. >- >-=cut >- > sub N__np { > return $_[1]; > } >@@ -372,118 +224,4 @@ sub _expand { > return $text; > } > >-=head2 available_locales >- >- my $locales = Koha::I18N::available_locales(); >- >-Returns an arrayref of available system locales for use in system preferences. >- >-Each locale is a hashref with: >- - C<value>: The locale identifier (e.g., 'en_US.utf8', 'default') >- - C<text>: Human-readable description (e.g., 'English (United States) - en_US.utf8') >- >-Always includes 'default' as the first option. Additional locales are detected >-from the system using C<locale -a> and filtered for UTF-8 locales. >- >-=cut >- >-sub available_locales { >- my @available_locales = (); >- >- # Always include default option >- push @available_locales, { >- value => 'default', >- text => 'Default Unicode collation' >- }; >- >- # Get system locales using the same approach as init() >- my @system_locales = grep { chomp; not( /^C/ || $_ eq 'POSIX' ) } qx/locale -a/; >- >- my @filtered_locales = (); >- for my $locale (@system_locales) { >- >- # Filter for useful locales (UTF-8 ones and common patterns) >- if ( $locale =~ /^[a-z]{2}_[A-Z]{2}\.utf8?$/i || $locale =~ /^[a-z]{2}_[A-Z]{2}$/i ) { >- >- # Create friendly display names >- my $display_name = $locale; >- if ( $locale =~ /^([a-z]{2})_([A-Z]{2})/ ) { >- my %lang_names = ( >- 'en' => 'English', >- 'fr' => 'French', >- 'de' => 'German', >- 'es' => 'Spanish', >- 'it' => 'Italian', >- 'pt' => 'Portuguese', >- 'nl' => 'Dutch', >- 'pl' => 'Polish', >- 'fi' => 'Finnish', >- 'sv' => 'Swedish', >- 'da' => 'Danish', >- 'no' => 'Norwegian', >- 'ru' => 'Russian', >- 'ja' => 'Japanese', >- 'zh' => 'Chinese', >- 'ar' => 'Arabic', >- 'hi' => 'Hindi' >- ); >- my %country_names = ( >- 'US' => 'United States', >- 'GB' => 'United Kingdom', >- 'FR' => 'France', >- 'DE' => 'Germany', >- 'ES' => 'Spain', >- 'IT' => 'Italy', >- 'PT' => 'Portugal', >- 'BR' => 'Brazil', >- 'NL' => 'Netherlands', >- 'PL' => 'Poland', >- 'FI' => 'Finland', >- 'SE' => 'Sweden', >- 'DK' => 'Denmark', >- 'NO' => 'Norway', >- 'RU' => 'Russia', >- 'JP' => 'Japan', >- 'CN' => 'China', >- 'TW' => 'Taiwan', >- 'SA' => 'Saudi Arabia', >- 'IN' => 'India' >- ); >- my $lang = $lang_names{$1} || uc($1); >- my $country = $country_names{$2} || $2; >- $display_name = "$lang ($country) - $locale"; >- } >- push @filtered_locales, { >- value => $locale, >- text => $display_name >- }; >- } >- } >- >- # Sort locales by display name and add to available list >- @filtered_locales = sort { $a->{text} cmp $b->{text} } @filtered_locales; >- push @available_locales, @filtered_locales; >- >- return \@available_locales; >-} >- >-=head1 AUTHOR >- >-Koha Development Team >- >-=head1 COPYRIGHT >- >-Copyright 2012-2014 BibLibre >- >-=head1 LICENSE >- >-This file is part of Koha. >- >-Koha is free software; you can redistribute it and/or modify it under the >-terms of the GNU General Public License as published by the Free Software >-Foundation; either version 3 of the License, or (at your option) any later >-version. >- >-=cut >- > 1; >diff --git a/Koha/ILL/Request.pm b/Koha/ILL/Request.pm >index 4c8453d4dd..9b151e3924 100644 >--- a/Koha/ILL/Request.pm >+++ b/Koha/ILL/Request.pm >@@ -1776,8 +1776,6 @@ sub send_patron_notice { > ); > my @transports = keys %{ $borrower_preferences->{transports} }; > >- return { result => { fail => [ 'email', 'sms' ], success => [] } } unless @transports; >- > # Notice should come from the library where the request was placed, > # not the patrons home library > my $branch = Koha::Libraries->find( $self->branchcode ); >diff --git a/Koha/Import/OAI/Authorities.pm b/Koha/Import/OAI/Authorities.pm >index 9b78afefb4..cdff207854 100644 >--- a/Koha/Import/OAI/Authorities.pm >+++ b/Koha/Import/OAI/Authorities.pm >@@ -13,7 +13,6 @@ package Koha::Import::OAI::Authorities; > # GNU General Public License for more details. > # > # You should have received a copy of the GNU General Public License >-# along with Koha; if not, see <http://www.gnu.org/licenses>. > > use Modern::Perl; > >diff --git a/Koha/Import/OAI/Authority.pm b/Koha/Import/OAI/Authority.pm >index 965851d39c..f4e3a0d31f 100644 >--- a/Koha/Import/OAI/Authority.pm >+++ b/Koha/Import/OAI/Authority.pm >@@ -13,7 +13,6 @@ package Koha::Import::OAI::Authority; > # GNU General Public License for more details. > # > # You should have received a copy of the GNU General Public License >-# along with Koha; if not, see <http://www.gnu.org/licenses>. > > use Modern::Perl; > >diff --git a/Koha/Import/OAI/Biblio.pm b/Koha/Import/OAI/Biblio.pm >index 3478a348eb..42ad046e72 100644 >--- a/Koha/Import/OAI/Biblio.pm >+++ b/Koha/Import/OAI/Biblio.pm >@@ -13,7 +13,6 @@ package Koha::Import::OAI::Biblio; > # GNU General Public License for more details. > # > # You should have received a copy of the GNU General Public License >-# along with Koha; if not, see <http://www.gnu.org/licenses>. > > use Modern::Perl; > >diff --git a/Koha/Import/OAI/Biblios.pm b/Koha/Import/OAI/Biblios.pm >index 4a7a04cf79..59ceba9cd3 100644 >--- a/Koha/Import/OAI/Biblios.pm >+++ b/Koha/Import/OAI/Biblios.pm >@@ -13,7 +13,6 @@ package Koha::Import::OAI::Biblios; > # GNU General Public License for more details. > # > # You should have received a copy of the GNU General Public License >-# along with Koha; if not, see <http://www.gnu.org/licenses>. > > use Modern::Perl; > >diff --git a/Koha/Installer.pm b/Koha/Installer.pm >index 48a50df2b6..235eac3247 100644 >--- a/Koha/Installer.pm >+++ b/Koha/Installer.pm >@@ -29,7 +29,7 @@ sub needs_update { > my $koha_version = Koha->version; > my $code_version = TransformToNum($koha_version); > >- if ( $db_version && $db_version == $code_version ) { >+ if ( $db_version == $code_version ) { > $needs_update = 0; > } > >diff --git a/Koha/Manual.pm b/Koha/Manual.pm >index fe5cc2c5b3..e811c64867 100644 >--- a/Koha/Manual.pm >+++ b/Koha/Manual.pm >@@ -117,6 +117,7 @@ our $mapping = { > 'admin/preferences#logs' => '/logspreferences.html', > 'admin/preferences#opac' => '/opacpreferences.html', > 'admin/preferences#patrons' => '/patronspreferences.html', >+ 'admin/preferences#reports' => '/reportspreferences.html', > 'admin/preferences#searching' => '/searchingpreferences.html', > 'admin/preferences#serials' => '/serialspreferences.html', > 'admin/preferences#staff_interface' => '/staffclientpreferences.html', >diff --git a/Koha/Patron.pm b/Koha/Patron.pm >index 203fa212c3..14d5838e6b 100644 >--- a/Koha/Patron.pm >+++ b/Koha/Patron.pm >@@ -388,7 +388,7 @@ sub store { > > if ( C4::Context->preference('ChildNeedsGuarantor') > and ( $self->is_child or $self->category->can_be_guarantee ) >- and ( !defined $self->contactname || $self->contactname eq "" ) >+ and $self->contactname eq "" > and !@$guarantors ) > { > Koha::Exceptions::Patron::Relationship::NoGuarantor->throw(); >@@ -2677,8 +2677,6 @@ sub _anonymize_column { > $val = $nullable ? undef : 0; > } elsif ( $type =~ /date|time/ ) { > $val = $nullable ? undef : dt_from_string; >- } elsif ( $type eq 'enum' ) { >- $val = $nullable ? undef : $col_info->{default_value}; > } > $self->$col($val); > } >diff --git a/Koha/Patrons/Import.pm b/Koha/Patrons/Import.pm >index f36495d76a..23b6f57803 100644 >--- a/Koha/Patrons/Import.pm >+++ b/Koha/Patrons/Import.pm >@@ -267,10 +267,7 @@ LINE: while ( my $borrowerline = <$handle> ) { > > # Remove warning for int datatype that cannot be null > # Argument "" isn't numeric in numeric eq (==) at /usr/share/perl5/DBIx/Class/Row.pm line 1018 >- for my $field ( >- qw( privacy privacy_guarantor_fines privacy_guarantor_checkouts anonymized login_attempts checkprevcheckout autorenew_checkouts ) >- ) >- { >+ for my $field (qw( privacy privacy_guarantor_fines privacy_guarantor_checkouts anonymized login_attempts )) { > delete $borrower{$field} > if exists $borrower{$field} and $borrower{$field} eq ""; > } >@@ -307,8 +304,7 @@ LINE: while ( my $borrowerline = <$handle> ) { > next if $col eq 'password' && !$overwrite_passwords; > next if $col eq 'dateexpiry' && $update_dateexpiry; > >- $borrower{$col} = $member->{$col} >- if $col eq 'dateexpiry' && ( !$csvkeycol{$col} || !$columns[ $csvkeycol{$col} ] ); >+ $borrower{$col} = $member->{$col} if $col eq 'dateexpiry' && !$columns[ $csvkeycol{$col} ]; > > unless ( exists( $csvkeycol{$col} ) || $defaults->{$col} ) { > $borrower{$col} = $member->{$col} if ( $member->{$col} ); >diff --git a/Koha/REST/V1/CirculationRules.pm b/Koha/REST/V1/CirculationRules.pm >index 81bd51fc81..74c54b813d 100644 >--- a/Koha/REST/V1/CirculationRules.pm >+++ b/Koha/REST/V1/CirculationRules.pm >@@ -2,18 +2,18 @@ package Koha::REST::V1::CirculationRules; > > # This file is part of Koha. > # >-# Koha is free software; you can redistribute it and/or modify it >-# under the terms of the GNU General Public License as published by >-# the Free Software Foundation; either version 3 of the License, or >-# (at your option) any later version. >+# Koha is free software; you can redistribute it and/or modify it under the >+# terms of the GNU General Public License as published by the Free Software >+# Foundation; either version 3 of the License, or (at your option) any later >+# version. > # >-# Koha is distributed in the hope that it will be useful, but >-# WITHOUT ANY WARRANTY; without even the implied warranty of >-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >-# GNU General Public License for more details. >+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY >+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR >+# A PARTICULAR PURPOSE. See the GNU General Public License for more details. > # >-# You should have received a copy of the GNU General Public License >-# along with Koha; if not, see <http://www.gnu.org/licenses>. >+# You should have received a copy of the GNU General Public License along >+# with Koha; if not, write to the Free Software Foundation, Inc., >+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. > > use Modern::Perl; > >diff --git a/Koha/REST/V1/Suggestions.pm b/Koha/REST/V1/Suggestions.pm >index 442a36a8ec..9c3a0a0d50 100644 >--- a/Koha/REST/V1/Suggestions.pm >+++ b/Koha/REST/V1/Suggestions.pm >@@ -2,18 +2,17 @@ package Koha::REST::V1::Suggestions; > > # This file is part of Koha. > # >-# Koha is free software; you can redistribute it and/or modify it >-# under the terms of the GNU General Public License as published by >-# the Free Software Foundation; either version 3 of the License, or >-# (at your option) any later version. >+# Koha is free software; you can redistribute it and/or modify it under the >+# terms of the GNU General Public License as published by the Free Software >+# Foundation; either version 3 of the License, or (at your option) any later >+# version. > # >-# Koha is distributed in the hope that it will be useful, but >-# WITHOUT ANY WARRANTY; without even the implied warranty of >-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >-# GNU General Public License for more details. >+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY >+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR >+# A PARTICULAR PURPOSE. See the GNU General Public License for more details. > # > # You should have received a copy of the GNU General Public License >-# along with Koha; if not, see <http://www.gnu.org/licenses>. >+# along with Koha; if not, see <http:°www.gnu.org/licenses>. > > use Modern::Perl; > >diff --git a/Koha/Report.pm b/Koha/Report.pm >index 54511cdc4c..8c292a16a8 100644 >--- a/Koha/Report.pm >+++ b/Koha/Report.pm >@@ -20,9 +20,13 @@ use Modern::Perl; > use Koha::Database; > use Koha::Reports; > >+use Koha::Object; >+use Koha::Object::Limit::Library; >+ >+use base qw(Koha::Object Koha::Object::Limit::Library); >+ > #use Koha::DateUtils qw( dt_from_string output_pref ); > >-use base qw(Koha::Object); > # > # FIXME We could only return an error code instead of the arrayref > # Only 1 error is returned >@@ -268,4 +272,18 @@ sub _type { > return 'SavedSql'; > } > >+=head3 _library_limits >+ >+Configurable library limits >+ >+=cut >+ >+sub _library_limits { >+ return { >+ class => "ReportsBranch", >+ id => "report_id", >+ library => "branchcode", >+ }; >+} >+ > 1; >diff --git a/Koha/Reports.pm b/Koha/Reports.pm >index 7d99232b9b..387c72abb1 100644 >--- a/Koha/Reports.pm >+++ b/Koha/Reports.pm >@@ -21,7 +21,7 @@ use Koha::Database; > > use Koha::Report; > >-use base qw(Koha::Objects); >+use base qw(Koha::Objects Koha::Objects::Limit::Library); > > =head1 NAME > >@@ -33,6 +33,33 @@ Koha::Reports - Koha Report Object set class > > =cut > >+=head3 search_with_localization >+ >+my $itemtypes = Koha::ItemTypes->search_with_localization >+ >+=cut >+ >+sub search_with_localization { >+ my ( $self, $params, $attributes ) = @_; >+ >+ my $language = C4::Languages::getlanguage(); >+ $Koha::Schema::Result::Itemtype::LANGUAGE = $language; >+ $attributes->{order_by} = 'translated_description' unless exists $attributes->{order_by}; >+ $attributes->{join} = 'localization'; >+ $attributes->{'+select'} = [ >+ { >+ coalesce => [qw( localization.translation me.description )], >+ -as => 'translated_description' >+ } >+ ]; >+ if ( defined $params->{branchcode} ) { >+ my $branchcode = delete $params->{branchcode}; >+ $self->search_with_library_limits( $params, $attributes, $branchcode ); >+ } else { >+ $self->SUPER::search( $params, $attributes ); >+ } >+} >+ > =head3 _type > > Returns name of corresponding DBIC resultset >diff --git a/Koha/Schema/Result/Borrower.pm b/Koha/Schema/Result/Borrower.pm >index 1e1fa11cd4..2e1a5e9d51 100644 >--- a/Koha/Schema/Result/Borrower.pm >+++ b/Koha/Schema/Result/Borrower.pm >@@ -582,10 +582,10 @@ controls if relatives can see this patron's checkouts > > =head2 checkprevcheckout > >- data_type: 'enum' >+ data_type: 'varchar' > default_value: 'inherit' >- extra: {list => ["yes","no","inherit"]} > is_nullable: 0 >+ size: 7 > > produce a warning for this patron if this item has previously been checked out to this patron if 'yes', not if 'no', defer to category setting if 'inherit'. > >@@ -832,10 +832,10 @@ __PACKAGE__->add_columns( > { data_type => "tinyint", default_value => 0, is_nullable => 0 }, > "checkprevcheckout", > { >- data_type => "enum", >+ data_type => "varchar", > default_value => "inherit", >- extra => { list => ["yes", "no", "inherit"] }, > is_nullable => 0, >+ size => 7, > }, > "updated_on", > { >@@ -2197,8 +2197,8 @@ Composing rels: L</user_permissions> -> permission > __PACKAGE__->many_to_many("permissions", "user_permissions", "permission"); > > >-# Created by DBIx::Class::Schema::Loader v0.07051 @ 2025-07-10 07:11:31 >-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:XFOe2X4k2DUziaNS5pWd/Q >+# Created by DBIx::Class::Schema::Loader v0.07051 @ 2025-04-28 16:41:47 >+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:J1oaW0hFRihEJZ6U+XSwag > > __PACKAGE__->belongs_to( > "library", >diff --git a/Koha/Schema/Result/Category.pm b/Koha/Schema/Result/Category.pm >index 9cb9622295..62c6e3fb4d 100644 >--- a/Koha/Schema/Result/Category.pm >+++ b/Koha/Schema/Result/Category.pm >@@ -136,10 +136,10 @@ Default privacy setting for this patron category > > =head2 checkprevcheckout > >- data_type: 'enum' >+ data_type: 'varchar' > default_value: 'inherit' >- extra: {list => ["yes","no","inherit"]} > is_nullable: 0 >+ size: 7 > > produce a warning for this patron category if this item has previously been checked out to this patron if 'yes', not if 'no', defer to syspref setting if 'inherit'. > >@@ -274,10 +274,10 @@ __PACKAGE__->add_columns( > }, > "checkprevcheckout", > { >- data_type => "enum", >+ data_type => "varchar", > default_value => "inherit", >- extra => { list => ["yes", "no", "inherit"] }, > is_nullable => 0, >+ size => 7, > }, > "can_place_ill_in_opac", > { data_type => "tinyint", default_value => 1, is_nullable => 0 }, >@@ -410,8 +410,8 @@ __PACKAGE__->has_many( > ); > > >-# Created by DBIx::Class::Schema::Loader v0.07051 @ 2025-07-10 07:11:31 >-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:ADt+iDjteg9Jb81L2FMIvg >+# Created by DBIx::Class::Schema::Loader v0.07051 @ 2024-12-03 15:46:23 >+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:jiQq3bW+ZfdYpUpfZq1Rzw > > # You can replace this text with custom code or comments, and it will be preserved on regeneration > >diff --git a/Koha/Schema/Result/Deletedborrower.pm b/Koha/Schema/Result/Deletedborrower.pm >index 5d0f10facb..b2decd87d2 100644 >--- a/Koha/Schema/Result/Deletedborrower.pm >+++ b/Koha/Schema/Result/Deletedborrower.pm >@@ -579,10 +579,10 @@ controls if relatives can see this patron's checkouts > > =head2 checkprevcheckout > >- data_type: 'enum' >+ data_type: 'varchar' > default_value: 'inherit' >- extra: {list => ["yes","no","inherit"]} > is_nullable: 0 >+ size: 7 > > produce a warning for this patron if this item has previously been checked out to this patron if 'yes', not if 'no', defer to category setting if 'inherit'. > >@@ -817,10 +817,10 @@ __PACKAGE__->add_columns( > { data_type => "tinyint", default_value => 0, is_nullable => 0 }, > "checkprevcheckout", > { >- data_type => "enum", >+ data_type => "varchar", > default_value => "inherit", >- extra => { list => ["yes", "no", "inherit"] }, > is_nullable => 0, >+ size => 7, > }, > "updated_on", > { >@@ -857,8 +857,8 @@ __PACKAGE__->add_columns( > ); > > >-# Created by DBIx::Class::Schema::Loader v0.07051 @ 2025-07-10 07:11:31 >-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:vAkNNQagJcYfZ0/6mDOw8g >+# Created by DBIx::Class::Schema::Loader v0.07051 @ 2025-04-28 16:41:47 >+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:5QA+/eORyEKhkG++0f3Hvw > > __PACKAGE__->add_columns( > '+anonymized' => { is_boolean => 1 }, >diff --git a/Koha/Schema/Result/ReportsBranch.pm b/Koha/Schema/Result/ReportsBranch.pm >new file mode 100644 >index 0000000000..970c25eabc >--- /dev/null >+++ b/Koha/Schema/Result/ReportsBranch.pm >@@ -0,0 +1,85 @@ >+use utf8; >+ >+package Koha::Schema::Result::ReportsBranch; >+ >+# Created by DBIx::Class::Schema::Loader >+# DO NOT MODIFY THE FIRST PART OF THIS FILE >+ >+=head1 NAME >+ >+Koha::Schema::Result::ReportsBranch >+ >+=cut >+ >+use strict; >+use warnings; >+ >+use base 'DBIx::Class::Core'; >+ >+=head1 TABLE: C<reports_branches> >+ >+=cut >+ >+__PACKAGE__->table("reports_branches"); >+ >+=head1 ACCESSORS >+ >+=head2 report_id >+ >+ data_type: 'integer' >+ is_foreign_key: 1 >+ is_nullable: 0 >+ >+=head2 branchcode >+ >+ data_type: 'varchar' >+ is_foreign_key: 1 >+ is_nullable: 0 >+ size: 10 >+ >+=cut >+ >+__PACKAGE__->add_columns( >+ "report_id", >+ { data_type => "integer", is_foreign_key => 1, is_nullable => 0 }, >+ "branchcode", >+ { data_type => "varchar", is_foreign_key => 1, is_nullable => 0, size => 10 }, >+); >+ >+=head1 RELATIONS >+ >+=head2 branchcode >+ >+Type: belongs_to >+ >+Related object: L<Koha::Schema::Result::Branch> >+ >+=cut >+ >+__PACKAGE__->belongs_to( >+ "branchcode", >+ "Koha::Schema::Result::Branch", >+ { branchcode => "branchcode" }, >+ { is_deferrable => 1, on_delete => "CASCADE", on_update => "RESTRICT" }, >+); >+ >+=head2 report >+ >+Type: belongs_to >+ >+Related object: L<Koha::Schema::Result::SavedSql> >+ >+=cut >+ >+__PACKAGE__->belongs_to( >+ "report", >+ "Koha::Schema::Result::SavedSql", >+ { id => "report_id" }, >+ { is_deferrable => 1, on_delete => "CASCADE", on_update => "RESTRICT" }, >+); >+ >+# Created by DBIx::Class::Schema::Loader v0.07051 @ 2025-07-06 17:02:11 >+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:SJqUxMgLJHAjbX3GJlpB+A >+ >+# You can replace this text with custom code or comments, and it will be preserved on regeneration >+1; >diff --git a/Koha/Schema/Result/SavedSql.pm b/Koha/Schema/Result/SavedSql.pm >index 6f75ae3b31..4f063e8d67 100644 >--- a/Koha/Schema/Result/SavedSql.pm >+++ b/Koha/Schema/Result/SavedSql.pm >@@ -185,6 +185,221 @@ __PACKAGE__->add_columns( > > __PACKAGE__->set_primary_key("id"); > >+=head1 RELATIONS >+ >+=head2 reports_branches >+ >+Type: has_many >+ >+Related object: L<Koha::Schema::Result::ReportsBranch> >+ >+=cut >+ >+__PACKAGE__->has_many( >+ "reports_branches", >+ "Koha::Schema::Result::ReportsBranch", >+ { "foreign.report_id" => "self.id" }, >+ { cascade_copy => 0, cascade_delete => 0 }, >+); >+ >+ >+# Created by DBIx::Class::Schema::Loader v0.07051 @ 2025-07-06 17:02:11 >+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:qFqDaOxgdm2I12cJEiCieg >+# These lines were loaded from '/kohadevbox/koha/Koha/Schema/Result/SavedSql.pm' found in @INC. >+# They are now part of the custom portion of this file >+# for you to hand-edit. If you do not either delete >+# this section or remove that file from @INC, this section >+# will be repeated redundantly when you re-create this >+# file again via Loader! See skip_load_external to disable >+# this feature. >+ >+use utf8; >+package Koha::Schema::Result::SavedSql; >+ >+# Created by DBIx::Class::Schema::Loader >+# DO NOT MODIFY THE FIRST PART OF THIS FILE >+ >+=head1 NAME >+ >+Koha::Schema::Result::SavedSql >+ >+=cut >+ >+use strict; >+use warnings; >+ >+use base 'DBIx::Class::Core'; >+ >+=head1 TABLE: C<saved_sql> >+ >+=cut >+ >+__PACKAGE__->table("saved_sql"); >+ >+=head1 ACCESSORS >+ >+=head2 id >+ >+ data_type: 'integer' >+ is_auto_increment: 1 >+ is_nullable: 0 >+ >+unique id and primary key assigned by Koha >+ >+=head2 borrowernumber >+ >+ data_type: 'integer' >+ is_nullable: 1 >+ >+the staff member who created this report (borrowers.borrowernumber) >+ >+=head2 date_created >+ >+ data_type: 'datetime' >+ datetime_undef_if_invalid: 1 >+ is_nullable: 1 >+ >+the date this report was created >+ >+=head2 last_modified >+ >+ data_type: 'datetime' >+ datetime_undef_if_invalid: 1 >+ is_nullable: 1 >+ >+the date this report was last edited >+ >+=head2 savedsql >+ >+ data_type: 'mediumtext' >+ is_nullable: 1 >+ >+the SQL for this report >+ >+=head2 last_run >+ >+ data_type: 'datetime' >+ datetime_undef_if_invalid: 1 >+ is_nullable: 1 >+ >+=head2 report_name >+ >+ data_type: 'varchar' >+ default_value: (empty string) >+ is_nullable: 0 >+ size: 255 >+ >+the name of this report >+ >+=head2 type >+ >+ data_type: 'varchar' >+ is_nullable: 1 >+ size: 255 >+ >+always 1 for tabular >+ >+=head2 notes >+ >+ data_type: 'mediumtext' >+ is_nullable: 1 >+ >+the notes or description given to this report >+ >+=head2 cache_expiry >+ >+ data_type: 'integer' >+ default_value: 300 >+ is_nullable: 0 >+ >+=head2 public >+ >+ data_type: 'tinyint' >+ default_value: 0 >+ is_nullable: 0 >+ >+=head2 report_area >+ >+ data_type: 'varchar' >+ is_nullable: 1 >+ size: 6 >+ >+=head2 report_group >+ >+ data_type: 'varchar' >+ is_nullable: 1 >+ size: 80 >+ >+=head2 report_subgroup >+ >+ data_type: 'varchar' >+ is_nullable: 1 >+ size: 80 >+ >+=head2 mana_id >+ >+ data_type: 'integer' >+ is_nullable: 1 >+ >+=cut >+ >+__PACKAGE__->add_columns( >+ "id", >+ { data_type => "integer", is_auto_increment => 1, is_nullable => 0 }, >+ "borrowernumber", >+ { data_type => "integer", is_nullable => 1 }, >+ "date_created", >+ { >+ data_type => "datetime", >+ datetime_undef_if_invalid => 1, >+ is_nullable => 1, >+ }, >+ "last_modified", >+ { >+ data_type => "datetime", >+ datetime_undef_if_invalid => 1, >+ is_nullable => 1, >+ }, >+ "savedsql", >+ { data_type => "mediumtext", is_nullable => 1 }, >+ "last_run", >+ { >+ data_type => "datetime", >+ datetime_undef_if_invalid => 1, >+ is_nullable => 1, >+ }, >+ "report_name", >+ { data_type => "varchar", default_value => "", is_nullable => 0, size => 255 }, >+ "type", >+ { data_type => "varchar", is_nullable => 1, size => 255 }, >+ "notes", >+ { data_type => "mediumtext", is_nullable => 1 }, >+ "cache_expiry", >+ { data_type => "integer", default_value => 300, is_nullable => 0 }, >+ "public", >+ { data_type => "tinyint", default_value => 0, is_nullable => 0 }, >+ "report_area", >+ { data_type => "varchar", is_nullable => 1, size => 6 }, >+ "report_group", >+ { data_type => "varchar", is_nullable => 1, size => 80 }, >+ "report_subgroup", >+ { data_type => "varchar", is_nullable => 1, size => 80 }, >+ "mana_id", >+ { data_type => "integer", is_nullable => 1 }, >+); >+ >+=head1 PRIMARY KEY >+ >+=over 4 >+ >+=item * L</id> >+ >+=back >+ >+=cut >+ >+__PACKAGE__->set_primary_key("id"); >+ > > # Created by DBIx::Class::Schema::Loader v0.07049 @ 2021-01-21 13:39:29 > # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:198dNG9DGQzop+s5IHy7sw >@@ -214,3 +429,8 @@ sub koha_objects_class { > } > > 1; >+# End of lines loaded from '/kohadevbox/koha/Koha/Schema/Result/SavedSql.pm' >+ >+ >+# You can replace this text with custom code or comments, and it will be preserved on regeneration >+1; >\ No newline at end of file >diff --git a/Koha/SearchEngine/Elasticsearch/Search.pm b/Koha/SearchEngine/Elasticsearch/Search.pm >index e81d1df84e..c88345bb58 100644 >--- a/Koha/SearchEngine/Elasticsearch/Search.pm >+++ b/Koha/SearchEngine/Elasticsearch/Search.pm >@@ -54,9 +54,6 @@ use MARC::File::XML; > use MIME::Base64 qw( decode_base64 ); > use JSON; > >-use POSIX qw(setlocale LC_COLLATE); >-use Unicode::Collate::Locale; >- > Koha::SearchEngine::Elasticsearch::Search->mk_accessors(qw( store )); > > =head2 search >@@ -456,42 +453,6 @@ sub max_result_window { > return $max_result_window; > } > >-=head2 _sort_facets >- >- my $facets = _sort_facets($facets); >- >-Sorts facets using a locale. >- >-=cut >- >-sub _sort_facets { >- my ( $self, $args ) = @_; >- my $facets = $args->{facets}; >- my $locale = $args->{locale}; >- >- if ( !$locale ) { >- >- # Get locale from system preference, falling back to system LC_COLLATE >- $locale = C4::Context->preference('FacetSortingLocale') || 'default'; >- if ( $locale eq 'default' || !$locale ) { >- >- #NOTE: When setlocale is run with only the 1st parameter, it is a "get" not a "set" function. >- $locale = setlocale(LC_COLLATE) || 'default'; >- } >- } >- >- my $collator = Unicode::Collate::Locale->new( locale => $locale ); >- if ( $collator && $facets ) { >- my @sorted_facets = sort { $collator->cmp( $a->{facet_label_value}, $b->{facet_label_value} ) } @{$facets}; >- if (@sorted_facets) { >- return \@sorted_facets; >- } >- } >- >- #NOTE: If there was a problem, at least return the not sorted facets >- return $facets; >-} >- > =head2 _convert_facets > > my $koha_facets = _convert_facets($es_facets); >@@ -565,16 +526,14 @@ sub _convert_facets { > facet_count => $c, > facet_link_value => $t, > facet_title_value => $t, >- facet_label_value => $label || q{}, # TODO either truncate this, >- # or make the template do it like it should anyway >+ facet_label_value => $label, # TODO either truncate this, >+ # or make the template do it like it should anyway > type_link_value => $type, > }; > } > if ( C4::Context->preference('FacetOrder') eq 'Alphabetical' ) { >- my $sorted_facets = $self->_sort_facets( { facets => $facet->{facets} } ); >- if ($sorted_facets) { >- $facet->{facets} = $sorted_facets; >- } >+ @{ $facet->{facets} } = >+ sort { $a->{facet_label_value} cmp $b->{facet_label_value} } @{ $facet->{facets} }; > } > push @facets, $facet if exists $facet->{facets}; > } >diff --git a/acqui/basket.pl b/acqui/basket.pl >index 57621b4e7a..791acd3250 100755 >--- a/acqui/basket.pl >+++ b/acqui/basket.pl >@@ -613,20 +613,16 @@ sub edi_close_and_order { > } > exit; > } else { >- >- my $ean_description = $query->param('ean_description'); >- my $ean_branch = $query->param('ean_branch'); >- > $template->param( > edi_confirm => 1, > booksellerid => $booksellerid, > basketno => $basket->{basketno}, > basketname => $basket->{basketname}, > basketgroupname => $basket->{basketname}, >- ean => $ean ? $ean : '', >- ean_description => $ean_description ? $ean_description : '', >- ean_branch => $ean_branch ? $ean_branch : '', > ); >+ if ($ean) { >+ $template->param( ean => $ean ); >+ } > > } > return; >diff --git a/admin/preferences.pl b/admin/preferences.pl >index bf67c87e74..34ddca9497 100755 >--- a/admin/preferences.pl >+++ b/admin/preferences.pl >@@ -122,18 +122,6 @@ sub _get_chunk { > } > $chunk->{'languages'} = getTranslatedLanguages( $interface, $theme ); > $chunk->{'type'} = 'languages'; >- } elsif ( $options{'type'} && $options{'type'} eq 'locale-list' ) { >- >- # Dynamic locale detection for facet sorting using Koha::I18N >- require Koha::I18N; >- my $locales = Koha::I18N::available_locales(); >- foreach my $locale (@$locales) { >- if ( $locale->{value} && $value && $locale->{value} eq $value ) { >- $locale->{selected} = 1; >- } >- } >- $chunk->{'CHOICES'} = $locales; >- $chunk->{'type'} = 'select'; > } elsif ( $options{'choices'} ) { > my $add_blank; > if ( $options{'choices'} && ref( $options{'choices'} ) eq '' ) { >diff --git a/api/v1/swagger/definitions/item.yaml b/api/v1/swagger/definitions/item.yaml >index f43c8ef1a8..fd1bbd11c9 100644 >--- a/api/v1/swagger/definitions/item.yaml >+++ b/api/v1/swagger/definitions/item.yaml >@@ -12,7 +12,6 @@ properties: > - string > - "null" > description: The item's barcode >- maxLength: 20 > acquisition_date: > type: > - string >@@ -37,7 +36,6 @@ properties: > - string > - "null" > description: Internal library id for the library the item belongs to >- maxLength: 10 > purchase_price: > type: > - number >@@ -105,13 +103,11 @@ properties: > - string > - "null" > description: Call number for this item >- maxLength: 255 > coded_location_qualifier: > type: > - string > - "null" > description: Coded location qualifier >- maxLength: 10 > checkouts_count: > type: > - integer >@@ -152,7 +148,6 @@ properties: > - string > - "null" > description: Library that is currently in possession item >- maxLength: 10 > timestamp: > type: string > format: date-time >@@ -169,7 +164,6 @@ properties: > description: > Linked to the CART and PROC temporary locations feature, stores the > permanent shelving location >- maxLength: 80 > checked_out_date: > type: > - string >@@ -183,19 +177,16 @@ properties: > - string > - "null" > description: Classification source used on this item >- maxLength: 10 > call_number_sort: > type: > - string > - "null" > description: "?" >- maxLength: 255 > collection_code: > type: > - string > - "null" > description: Authorized value for the collection code associated with this item >- maxLength: 80 > materials_notes: > type: > - string >@@ -216,7 +207,6 @@ properties: > - string > - "null" > description: Itemtype defining the type for this item >- maxLength: 10 > effective_item_type_id: > type: > - string >@@ -237,19 +227,16 @@ properties: > - string > - "null" > description: Copy number >- maxLength: 32 > inventory_number: > type: > - string > - "null" > description: Inventory number >- maxLength: 80 > new_status: > type: > - string > - "null" > description: "'new' value, whatever free-text information." >- maxLength: 32 > exclude_from_local_holds_priority: > type: boolean > description: Exclude this item from local holds priority. >diff --git a/api/v1/swagger/definitions/library.yaml b/api/v1/swagger/definitions/library.yaml >index c4debe94b5..0fc7967358 100644 >--- a/api/v1/swagger/definitions/library.yaml >+++ b/api/v1/swagger/definitions/library.yaml >@@ -29,7 +29,6 @@ properties: > - string > - "null" > description: the postal code of the library >- maxLength: 25 > city: > type: > - string >@@ -85,7 +84,6 @@ properties: > - string > - "null" > description: the IP address for your library or branch >- maxLength: 15 > notes: > type: > - string >@@ -103,7 +101,6 @@ properties: > description: MARC Organization Code, see > http://www.loc.gov/marc/organizations/orgshome.html, when empty defaults > to syspref MARCOrgCode >- maxLength: 16 > pickup_location: > type: boolean > description: If the library can act as a pickup location >diff --git a/api/v1/swagger/definitions/patron.yaml b/api/v1/swagger/definitions/patron.yaml >index 0895ffdbe8..4b61ae2d46 100644 >--- a/api/v1/swagger/definitions/patron.yaml >+++ b/api/v1/swagger/definitions/patron.yaml >@@ -178,11 +178,9 @@ properties: > library_id: > type: string > description: Internal identifier for the patron's home library >- maxLength: 10 > category_id: > type: string > description: Internal identifier for the patron's category >- maxLength: 10 > date_enrolled: > type: > - string >@@ -229,13 +227,11 @@ properties: > - string > - "null" > description: used for children to include the relationship to their guarantor >- maxLength: 100 > gender: > type: > - string > - "null" > description: patron's gender >- maxLength: 1 > userid: > type: > - string >@@ -251,19 +247,16 @@ properties: > - string > - "null" > description: a note related to patron's alternate address >- maxLength: 255 > statistics_1: > type: > - string > - "null" > description: a field that can be used for any information unique to the library >- maxLength: 80 > statistics_2: > type: > - string > - "null" > description: a field that can be used for any information unique to the library >- maxLength: 80 > autorenew_checkouts: > type: boolean > description: indicate whether auto-renewal is allowed for patron >@@ -318,7 +311,6 @@ properties: > - "null" > description: the mobile phone number where the patron would like to receive notices (if > SMS turned on) >- maxLength: 50 > sms_provider_id: > type: > - integer >@@ -335,10 +327,6 @@ properties: > description: controls if relatives can see this patron's fines > check_previous_checkout: > type: string >- enum: >- - yes >- - no >- - inherit > description: produce a warning for this patron if this item has previously been checked > out to this patron if 'yes', not if 'no', defer to category setting if > 'inherit' >diff --git a/api/v1/swagger/definitions/patron_category.yaml b/api/v1/swagger/definitions/patron_category.yaml >index da548a6980..7f2d4a3288 100644 >--- a/api/v1/swagger/definitions/patron_category.yaml >+++ b/api/v1/swagger/definitions/patron_category.yaml >@@ -4,7 +4,6 @@ properties: > patron_category_id: > type: string > description: Internal patron category identifier >- maxLength: 10 > name: > type: > - string >@@ -57,11 +56,9 @@ properties: > category_type: > type: string > description: Type of Koha patron (Adult, Child, Professional, Organizational, Statistical, Staff) >- maxLength: 1 > block_expired_patron_opac_actions: > type: string > description: Specific actions expired patrons of this category are blocked from performing. OPAC actions blocked based on the patron category take priority over this preference >- maxLength: 128 > default_privacy: > type: string > enum: >@@ -71,10 +68,6 @@ properties: > description: Default privacy setting for this patron category > check_prev_checkout: > type: string >- enum: >- - yes >- - no >- - inherit > description: Produce a warning for this patron category if this item has previously been checked out to this patron if ''yes'', not if ''no'', defer to syspref setting if ''inherit''.' > can_place_ill_in_opac: > type: boolean >diff --git a/cataloguing/addbiblio.pl b/cataloguing/addbiblio.pl >index 51fbb1a31d..58f555d6de 100755 >--- a/cataloguing/addbiblio.pl >+++ b/cataloguing/addbiblio.pl >@@ -33,6 +33,7 @@ use C4::Biblio qw( > GetMarcStructure > GetUsedMarcStructure > ModBiblio >+ prepare_host_field > PrepHostMarcField > TransformHtmlToMarc > ApplyMarcOverlayRules >@@ -644,10 +645,8 @@ if ($hostbiblionumber) { > if ($parentbiblio) { > my $marcflavour = C4::Context->preference('marcflavour'); > $record = MARC::Record->new(); >- $record->leader(' naa a22 i 4500'); > SetMarcUnicodeFlag( $record, $marcflavour ); >- my $parent = Koha::Biblios->find($parentbiblio); >- my $hostfield = $parent->generate_marc_host_field; >+ my $hostfield = prepare_host_field( $parentbiblio, $marcflavour ); > if ($hostfield) { > $record->append_fields($hostfield); > } >diff --git a/cpanfile b/cpanfile >index 84d6e4ede0..c0fc0ef00b 100644 >--- a/cpanfile >+++ b/cpanfile >@@ -107,7 +107,6 @@ requires 'Storable', '2.20'; > requires 'String::Random', '0.22'; > requires 'Template', '>= 2.27, != 3.008'; > requires 'Template::Plugin::HtmlToText', '0.03'; >-requires 'Template::Plugin::JSON', '0.08', > requires 'Template::Plugin::JSON::Escape', '0.02'; > requires 'Term::ANSIColor', '1.1'; > requires 'Test', '1.25'; >diff --git a/cypress.config.ts b/cypress.config.ts >index e67eb344f3..e90da4e019 100644 >--- a/cypress.config.ts >+++ b/cypress.config.ts >@@ -15,5 +15,13 @@ export default defineConfig({ > baseUrl: "http://localhost:8081", > specPattern: "t/cypress/integration/**/*.*", > supportFile: "t/cypress/support/e2e.js", >+ env: { >+ db: { >+ host: "db", >+ user: "koha_kohadev", >+ password: "password", >+ database: "koha_kohadev", >+ }, >+ }, > }, > }); >diff --git a/debian/build-git-snapshot b/debian/build-git-snapshot >index a426507fef..dd473325b7 100755 >--- a/debian/build-git-snapshot >+++ b/debian/build-git-snapshot >@@ -24,45 +24,46 @@ > use Modern::Perl; > > use Getopt::Long qw(:config no_ignore_case); >-use POSIX qw/strftime/; >+use POSIX qw/strftime/; > > my $basetgz; > my $buildresult; >-my $distribution = 'testing'; >-my $git_checks = 'all'; >-my $version = '16.06~git'; >-my $auto_version = 1; >-my $auto_changelog = 1; >+my $distribution='testing'; >+my $git_checks='all'; >+my $version='16.06~git'; >+my $auto_version=1; >+my $auto_changelog=1; > my $need_help; > my $incr; >-my $urgency = 'medium'; >+my $urgency='medium'; > my $debug; > > my $release_str; > > GetOptions( >- 'basetgz|b=s' => \$basetgz, >- 'buildresult|r=s' => \$buildresult, >- 'distribution|D=s' => \$distribution, >- 'git-checks|g=s' => \$git_checks, >- 'version|v=s' => \$version, >- 'incr|i=s' => \$incr, >- 'urgency|u=s' => \$urgency, >- 'autoversion!' => \$auto_version, >- 'autochangelog!' => \$auto_changelog, >- 'help|h' => \$need_help, >- 'debug|d' => \$debug, >+ 'basetgz|b=s' => \$basetgz, >+ 'buildresult|r=s' => \$buildresult, >+ 'distribution|D=s' => \$distribution, >+ 'git-checks|g=s' => \$git_checks, >+ 'version|v=s' => \$version, >+ 'incr|i=s' => \$incr, >+ 'urgency|u=s' => \$urgency, >+ 'autoversion!' => \$auto_version, >+ 'autochangelog!' => \$auto_changelog, >+ 'help|h' => \$need_help, >+ 'debug|d' => \$debug, > ); > > help_and_exit() if $need_help; > >+ > sub sys_command_output { > my ($command) = @_; > > print "$command\n" if $debug; > my $command_output; >- open( $command_output, "-|", "$command " ) >- or die qq{Cannot execute "$command": $!"}; >+ open($command_output, "-|", "$command ") >+ or die qq{Cannot execute "$command": $!"}; > return map { chomp; $_ } <$command_output>; > } > >@@ -77,17 +78,17 @@ sub everything_is_committed { > my $filter; > for ($git_checks) { > $_ eq "none" >- and return 1; >+ and return 1; > > $_ eq "modified" >- and $filter = "no", >- last; >+ and $filter = "no", >+ last; > > $_ eq "all" >- and $filter = "normal", >- last; >+ and $filter = "normal", >+ last; > >- help_and_exit("$0: --git-checks/-g must be one of 'all', 'modified', or 'none'"); >+ help_and_exit("$0: --git-checks/-g must be one of 'all', 'modified', or 'none'"); > } > my $has_changes = grep /^xxx/, sys_command_output("git status --porcelain -u${filter}"); > >@@ -95,13 +96,13 @@ sub everything_is_committed { > } > > sub help_and_exit { >- my $msg = shift; >- if ($msg) { >- print "$msg\n\n"; >+ my $msg = shift; >+ if ($msg) { >+ print "$msg\n\n"; > } > print <<EOH; > This builds Koha deb packages, from a git snapshot. It's not suitable for >-making upstreamable versions, but handy for your own local packages. >+making upstreamable verions, but handy for your own local packages. > > Options: > --buildresult, -r >@@ -138,39 +139,36 @@ sub latest_sha1 { > > sub adjust_debian_changelog { > my ($newversion) = @_; >- $newversion .= $incr ? "-$incr" : "-1"; >+ $newversion .= $incr ? "-$incr" : "-1"; > > $release_str = "New upstream "; > $release_str .= 'SECURITY ' if $urgency eq 'high'; > $release_str .= "release ($version)"; > >- sys_command_output( >- qq{dch --urgency $urgency -b --force-distribution -D "$distribution" -v "$newversion" "$release_str"}); >- sys_command_output(qq{dch -r "$release_str"}); >+ sys_command_output( qq{dch --urgency $urgency -b --force-distribution -D "$distribution" -v "$newversion" "$release_str"} ); >+ sys_command_output( qq{dch -r "$release_str"} ); > } > > sub reset_debian_changelog { >- sys_command_output(qq{git checkout -- debian/changelog}); >+ sys_command_output( qq{git checkout -- debian/changelog} ); > } > > sub build_package { > my ($newversion) = @_; >- sys_command_output( >- qq{git archive --format=tar --prefix="koha-$newversion/" HEAD | gzip -9 > "../koha_$newversion.orig.tar.gz"}); >+ sys_command_output( qq{git archive --format=tar --prefix="koha-$newversion/" HEAD | gzip -9 > "../koha_$newversion.orig.tar.gz"} ); > >- my $pdebuildopts = $buildresult ? "--buildresult $buildresult" : ""; >- my $pdebuildbasetgz = $basetgz ? "-- --use-network yes --basetgz /var/cache/pbuilder/" . $basetgz . ".tgz" : ""; >- sys_command_output_screen("pdebuild --debbuildopts -sa $pdebuildbasetgz $pdebuildopts"); >+ my $pdebuildopts = $buildresult ? "--buildresult $buildresult" : ""; >+ my $pdebuildbasetgz = $basetgz ? "-- --use-network yes --basetgz /var/cache/pbuilder/" . $basetgz . ".tgz" : ""; >+ sys_command_output_screen( "pdebuild --debbuildopts -sa $pdebuildbasetgz $pdebuildopts" ); > } > >-everything_is_committed() or die "cannot build: uncommitted changes"; >+everything_is_committed() or die "cannot build: uncommited changes"; > >-my $newversion = >- $auto_version >- ? sprintf( '%s%s.%s', $version, strftime( "+%Y%m%d%H%M%S", localtime ), latest_sha1() ) >- : $version; >+my $newversion = $auto_version >+ ? sprintf ('%s%s.%s', $version, strftime("+%Y%m%d%H%M%S", localtime), latest_sha1()) >+ : $version; > >-adjust_debian_changelog($newversion) if $auto_changelog; >-build_package($newversion); >+adjust_debian_changelog( $newversion ) if $auto_changelog; >+build_package( $newversion ); > reset_debian_changelog(); > >diff --git a/debian/control b/debian/control >index 1e13743535..9ff48a08aa 100644 >--- a/debian/control >+++ b/debian/control >@@ -137,7 +137,6 @@ Build-Depends: libalgorithm-checkdigits-perl, > libtemplate-plugin-gettext-perl, > libtemplate-plugin-htmltotext-perl, > libtemplate-plugin-json-escape-perl, >- libtemplate-plugin-json-perl, > libtemplate-plugin-stash-perl, > libtest-deep-perl, > libtest-exception-perl, >@@ -371,7 +370,6 @@ Depends: libalgorithm-checkdigits-perl, > libpdf-table-perl, > libplack-middleware-logwarn-perl, > libplack-middleware-reverseproxy-perl, >- libpod-coverage-perl, > libreadonly-perl, > libscalar-list-utils-perl, > libschedule-at-perl, >@@ -388,7 +386,6 @@ Depends: libalgorithm-checkdigits-perl, > libtemplate-plugin-gettext-perl, > libtemplate-plugin-htmltotext-perl, > libtemplate-plugin-json-escape-perl, >- libtemplate-plugin-json-perl, > libtemplate-plugin-stash-perl, > libtest-deep-perl, > libtest-exception-perl, >diff --git a/debian/templates/zebra-authorities-dom-site.cfg.in b/debian/templates/zebra-authorities-dom-site.cfg.in >index 01d446b8d6..be2e0c3ae6 100644 >--- a/debian/templates/zebra-authorities-dom-site.cfg.in >+++ b/debian/templates/zebra-authorities-dom-site.cfg.in >@@ -8,7 +8,7 @@ profilePath:/etc/koha/sites/__KOHASITE__:/etc/koha/zebradb/authorities/etc:/etc/ > > encoding: UTF-8 > # modulePath - where to look for loadable zebra modules >-modulePath: /usr/lib64/idzebra-2.0/modules:/usr/lib/idzebra-2.0/modules:/usr/lib/x86_64-linux-gnu/idzebra-2.0/modules:/usr/lib/i386-linux-gnu/idzebra-2.0/modules:/usr/lib/aarch64-linux-gnu/idzebra-2.0/modules:/usr/lib/arm-linux-gnueabi/idzebra-2.0/modules:/usr/lib/arm-linux-gnueabihf/idzebra-2.0/modules:/usr/lib/mips-linux-gnu/idzebra-2.0/modules:/usr/lib/mipsel-linux-gnu/idzebra-2.0/modules:/usr/lib/powerpc-linux-gnu/idzebra-2.0/modules:/usr/lib/powerpc64le-linux-gnu/idzebra-2.0/modules:/usr/lib/s390x-linux-gnu/idzebra-2.0/modules >+modulePath: /usr/lib/idzebra-2.0/modules:/usr/lib/x86_64-linux-gnu/idzebra-2.0/modules:/usr/lib/i386-linux-gnu/idzebra-2.0/modules:/usr/lib/aarch64-linux-gnu/idzebra-2.0/modules:/usr/lib/arm-linux-gnueabi/idzebra-2.0/modules:/usr/lib/arm-linux-gnueabihf/idzebra-2.0/modules:/usr/lib/mips-linux-gnu/idzebra-2.0/modules:/usr/lib/mipsel-linux-gnu/idzebra-2.0/modules:/usr/lib/powerpc-linux-gnu/idzebra-2.0/modules:/usr/lib/powerpc64le-linux-gnu/idzebra-2.0/modules:/usr/lib/s390x-linux-gnu/idzebra-2.0/modules > > # Files that describe the attribute sets supported. > attset: bib1.att >diff --git a/debian/templates/zebra-biblios-dom-site.cfg.in b/debian/templates/zebra-biblios-dom-site.cfg.in >index 29bf9a8473..7b5e52c153 100644 >--- a/debian/templates/zebra-biblios-dom-site.cfg.in >+++ b/debian/templates/zebra-biblios-dom-site.cfg.in >@@ -5,7 +5,7 @@ > # Where are the config files located? > profilePath:/etc/koha/sites/__KOHASITE__:/etc/koha/zebradb/biblios/etc:/etc/koha/zebradb/etc:/etc/koha/zebradb/marc_defs/__ZEBRA_MARC_FORMAT__/biblios:/etc/koha/zebradb/lang_defs/__ZEBRA_LANGUAGE__:/etc/koha/zebradb/xsl > # modulePath - where to look for loadable zebra modules >-modulePath: /usr/lib64/idzebra-2.0/modules:/usr/lib/idzebra-2.0/modules:/usr/lib/x86_64-linux-gnu/idzebra-2.0/modules:/usr/lib/i386-linux-gnu/idzebra-2.0/modules:/usr/lib/aarch64-linux-gnu/idzebra-2.0/modules:/usr/lib/arm-linux-gnueabi/idzebra-2.0/modules:/usr/lib/arm-linux-gnueabihf/idzebra-2.0/modules:/usr/lib/mips-linux-gnu/idzebra-2.0/modules:/usr/lib/mipsel-linux-gnu/idzebra-2.0/modules:/usr/lib/powerpc-linux-gnu/idzebra-2.0/modules:/usr/lib/powerpc64le-linux-gnu/idzebra-2.0/modules:/usr/lib/s390x-linux-gnu/idzebra-2.0/modules >+modulePath: /usr/lib/idzebra-2.0/modules:/usr/lib/x86_64-linux-gnu/idzebra-2.0/modules:/usr/lib/i386-linux-gnu/idzebra-2.0/modules:/usr/lib/aarch64-linux-gnu/idzebra-2.0/modules:/usr/lib/arm-linux-gnueabi/idzebra-2.0/modules:/usr/lib/arm-linux-gnueabihf/idzebra-2.0/modules:/usr/lib/mips-linux-gnu/idzebra-2.0/modules:/usr/lib/mipsel-linux-gnu/idzebra-2.0/modules:/usr/lib/powerpc-linux-gnu/idzebra-2.0/modules:/usr/lib/powerpc64le-linux-gnu/idzebra-2.0/modules:/usr/lib/s390x-linux-gnu/idzebra-2.0/modules > > encoding: UTF-8 > # Files that describe the attribute sets supported. >diff --git a/etc/zebradb/zebra-authorities-dom.cfg b/etc/zebradb/zebra-authorities-dom.cfg >index f1b5a6a9e1..f3b267b4fe 100644 >--- a/etc/zebradb/zebra-authorities-dom.cfg >+++ b/etc/zebradb/zebra-authorities-dom.cfg >@@ -8,7 +8,7 @@ profilePath:__ZEBRA_CONF_DIR__/authorities/etc:__ZEBRA_CONF_DIR__/etc:__ZEBRA_CO > > encoding: UTF-8 > # modulePath - where to look for loadable zebra modules >-modulePath: /usr/lib64/idzebra-2.0/modules:/usr/lib/idzebra-2.0/modules:/usr/lib/x86_64-linux-gnu/idzebra-2.0/modules:/usr/lib/i386-linux-gnu/idzebra-2.0/modules:/usr/lib/aarch64-linux-gnu/idzebra-2.0/modules:/usr/lib/arm-linux-gnueabi/idzebra-2.0/modules:/usr/lib/arm-linux-gnueabihf/idzebra-2.0/modules:/usr/lib/mips-linux-gnu/idzebra-2.0/modules:/usr/lib/mipsel-linux-gnu/idzebra-2.0/modules:/usr/lib/powerpc-linux-gnu/idzebra-2.0/modules:/usr/lib/powerpc64le-linux-gnu/idzebra-2.0/modules:/usr/lib/s390x-linux-gnu/idzebra-2.0/modules >+modulePath: /usr/lib/idzebra-2.0/modules:/usr/lib64/idzebra-2.0/modules:/usr/lib/x86_64-linux-gnu/idzebra-2.0/modules/ > > # Files that describe the attribute sets supported. > attset: bib1.att >diff --git a/etc/zebradb/zebra-biblios-dom.cfg b/etc/zebradb/zebra-biblios-dom.cfg >index 494666e82c..76ed216990 100644 >--- a/etc/zebradb/zebra-biblios-dom.cfg >+++ b/etc/zebradb/zebra-biblios-dom.cfg >@@ -5,7 +5,7 @@ > # Where are the config files located? > profilePath:__ZEBRA_CONF_DIR__/biblios/etc:__ZEBRA_CONF_DIR__/etc:__ZEBRA_CONF_DIR__/marc_defs/__ZEBRA_MARC_FORMAT__/biblios:__ZEBRA_CONF_DIR__/lang_defs/__ZEBRA_LANGUAGE__:__ZEBRA_CONF_DIR__/xsl > # modulePath - where to look for loadable zebra modules >-modulePath: /usr/lib64/idzebra-2.0/modules:/usr/lib/idzebra-2.0/modules:/usr/lib/x86_64-linux-gnu/idzebra-2.0/modules:/usr/lib/i386-linux-gnu/idzebra-2.0/modules:/usr/lib/aarch64-linux-gnu/idzebra-2.0/modules:/usr/lib/arm-linux-gnueabi/idzebra-2.0/modules:/usr/lib/arm-linux-gnueabihf/idzebra-2.0/modules:/usr/lib/mips-linux-gnu/idzebra-2.0/modules:/usr/lib/mipsel-linux-gnu/idzebra-2.0/modules:/usr/lib/powerpc-linux-gnu/idzebra-2.0/modules:/usr/lib/powerpc64le-linux-gnu/idzebra-2.0/modules:/usr/lib/s390x-linux-gnu/idzebra-2.0/modules >+modulePath: /usr/lib/idzebra-2.0/modules:/usr/lib64/idzebra-2.0/modules:/usr/lib/x86_64-linux-gnu/idzebra-2.0/modules/ > > encoding: UTF-8 > # Files that describe the attribute sets supported. >diff --git a/ill/ill-requests.pl b/ill/ill-requests.pl >index 8bb8c255c6..0db9c09b1e 100755 >--- a/ill/ill-requests.pl >+++ b/ill/ill-requests.pl >@@ -117,7 +117,7 @@ if ($backends_available) { > $template->param( > notices => $notices, > request => $request, >- ( $params->{tran_fail} ? ( tran_fail => $params->{tran_fail} ) : () ), >+ ( $params->{tran_error} ? ( tran_error => $params->{tran_error} ) : () ), > ( $params->{tran_success} ? ( tran_success => $params->{tran_success} ) : () ), > ); > >@@ -478,7 +478,7 @@ if ($backends_available) { > $append .= '&tran_success=' . join( ',', @{ $ret->{result}->{success} } ); > } > if ( $ret->{result} && scalar @{ $ret->{result}->{fail} } > 0 ) { >- $append .= '&tran_fail=' . join( ',', @{ $ret->{result}->{fail} } ); >+ $append .= '&tran_fail=' . join( ',', @{ $ret->{result}->{fail} } . join(',') ); > } > > # Redirect to view the whole request >diff --git a/installer/data/mysql/db_revs/250600003.pl b/installer/data/mysql/db_revs/250600003.pl >deleted file mode 100755 >index 951097d56d..0000000000 >--- a/installer/data/mysql/db_revs/250600003.pl >+++ /dev/null >@@ -1,32 +0,0 @@ >-use Modern::Perl; >-use Koha::Installer::Output qw(say_warning say_success say_info); >- >-return { >- bug_number => "40337", >- description => "Define checkprevcheckout as ENUM", >- up => sub { >- my ($args) = @_; >- my ( $dbh, $out ) = @$args{qw(dbh out)}; >- >- $dbh->do( >- q{ >- ALTER TABLE borrowers >- MODIFY COLUMN `checkprevcheckout` enum('yes', 'no', 'inherit') NOT NULL DEFAULT 'inherit' COMMENT 'produce a warning for this patron if this item has previously been checked out to this patron if ''yes'', not if ''no'', defer to category setting if ''inherit''.' >- } >- ); >- >- $dbh->do( >- q{ >- ALTER TABLE categories >- MODIFY COLUMN `checkprevcheckout` enum('yes', 'no', 'inherit') NOT NULL DEFAULT 'inherit' COMMENT 'produce a warning for this patron category if this item has previously been checked out to this patron if ''yes'', not if ''no'', defer to syspref setting if ''inherit''.' >- } >- ); >- >- $dbh->do( >- q{ >- ALTER TABLE deletedborrowers >- MODIFY COLUMN `checkprevcheckout` enum('yes', 'no', 'inherit') NOT NULL DEFAULT 'inherit' COMMENT 'produce a warning for this patron if this item has previously been checked out to this patron if ''yes'', not if ''no'', defer to category setting if ''inherit''.' >- } >- ); >- }, >-}; >diff --git a/installer/data/mysql/db_revs/250600004.pl b/installer/data/mysql/db_revs/250600004.pl >deleted file mode 100755 >index 7f871c7388..0000000000 >--- a/installer/data/mysql/db_revs/250600004.pl >+++ /dev/null >@@ -1,22 +0,0 @@ >-use Modern::Perl; >-use Koha::Installer::Output qw(say_warning say_success say_info); >- >-return { >- bug_number => "36947", >- description => "Add FacetSortingLocale system preference for locale-based facet sorting", >- up => sub { >- my ($args) = @_; >- my ( $dbh, $out ) = @$args{qw(dbh out)}; >- >- $dbh->do( >- q{ >- INSERT IGNORE INTO systempreferences (`variable`,`value`,`options`,`explanation`,`type`) >- VALUES ('FacetSortingLocale','default','', >- 'Choose the locale for sorting facet names when FacetOrder is set to Alphabetical. This enables proper Unicode-aware sorting of accented characters and locale-specific alphabetical ordering.', >- 'Choice') >- } >- ); >- >- say_success( $out, "Added new system preference 'FacetSortingLocale'" ); >- }, >-}; >diff --git a/installer/data/mysql/en/optional/sample_news.yml b/installer/data/mysql/en/optional/sample_news.yml >index 39432d9d7d..988d927005 100644 >--- a/installer/data/mysql/en/optional/sample_news.yml >+++ b/installer/data/mysql/en/optional/sample_news.yml >@@ -80,12 +80,12 @@ tables: > content: > - "Now that you've installed Koha, what's next? Here are some suggestions:" > - "<ul>" >- - "<li><a href=\"https://koha-community.org/documentation/\">Read Koha Documentation</a></li>" >- - "<li><a href=\"https://wiki.koha-community.org\">Read/Write to the Koha Wiki</a></li>" >- - "<li><a href=\"https://koha-community.org/support/\">Read and Contribute to Discussions</a></li>" >- - "<li><a href=\"https://bugs.koha-community.org\">Report Koha Bugs</a></li>" >- - "<li><a href=\"https://wiki.koha-community.org/wiki/Version_Control_Using_Git\">Submit Patches to Koha using Git (Version Control System)</a></li>" >- - "<li><a href=\"https://koha-community.org/support/\">Chat with Koha users and developers</a></li>" >+ - "<li><a href=\"http://koha-community.org/documentation/\">Read Koha Documentation</a></li>" >+ - "<li><a href=\"http://wiki.koha-community.org\">Read/Write to the Koha Wiki</a></li>" >+ - "<li><a href=\"http://koha-community.org/support/\">Read and Contribute to Discussions</a></li>" >+ - "<li><a href=\"http://bugs.koha-community.org\">Report Koha Bugs</a></li>" >+ - "<li><a href=\"http://wiki.koha-community.org/wiki/Version_Control_Using_Git\">Submit Patches to Koha using Git (Version Control System)</a></li>" >+ - "<li><a href=\"http://koha-community.org/support/\">Chat with Koha users and developers</a></li>" > - "</ul>" > - "" > lang: "default" >diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql >index 11018d4f7b..179cc2fef6 100644 >--- a/installer/data/mysql/kohastructure.sql >+++ b/installer/data/mysql/kohastructure.sql >@@ -1598,7 +1598,7 @@ CREATE TABLE `borrowers` ( > `privacy` int(11) NOT NULL DEFAULT 1 COMMENT 'patron/borrower''s privacy settings related to their checkout history', > `privacy_guarantor_fines` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'controls if relatives can see this patron''s fines', > `privacy_guarantor_checkouts` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'controls if relatives can see this patron''s checkouts', >- `checkprevcheckout` enum('yes', 'no', 'inherit') NOT NULL DEFAULT 'inherit' COMMENT 'produce a warning for this patron if this item has previously been checked out to this patron if ''yes'', not if ''no'', defer to category setting if ''inherit''.', >+ `checkprevcheckout` varchar(7) NOT NULL DEFAULT 'inherit' COMMENT 'produce a warning for this patron if this item has previously been checked out to this patron if ''yes'', not if ''no'', defer to category setting if ''inherit''.', > `updated_on` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp() COMMENT 'time of last change could be useful for synchronization with external systems (among others)', > `lastseen` datetime DEFAULT NULL COMMENT 'last time a patron has been seen (connected at the OPAC or staff interface)', > `lang` varchar(25) NOT NULL DEFAULT 'default' COMMENT 'lang to use to send notices to this patron', >@@ -1808,7 +1808,7 @@ CREATE TABLE `categories` ( > `category_type` varchar(1) NOT NULL DEFAULT 'A' COMMENT 'type of Koha patron (Adult, Child, Professional, Organizational, Statistical, Staff)', > `BlockExpiredPatronOpacActions` varchar(128) NOT NULL DEFAULT 'follow_syspref_BlockExpiredPatronOpacActions' COMMENT 'specific actions expired patrons of this category are blocked from performing or if the BlockExpiredPatronOpacActions system preference is to be followed', > `default_privacy` enum('default','never','forever') NOT NULL DEFAULT 'default' COMMENT 'Default privacy setting for this patron category', >- `checkprevcheckout` enum('yes', 'no', 'inherit') NOT NULL DEFAULT 'inherit' COMMENT 'produce a warning for this patron category if this item has previously been checked out to this patron if ''yes'', not if ''no'', defer to syspref setting if ''inherit''.', >+ `checkprevcheckout` varchar(7) NOT NULL DEFAULT 'inherit' COMMENT 'produce a warning for this patron category if this item has previously been checked out to this patron if ''yes'', not if ''no'', defer to syspref setting if ''inherit''.', > `can_place_ill_in_opac` tinyint(1) NOT NULL DEFAULT 1 COMMENT 'can this patron category place interlibrary loan requests', > `can_be_guarantee` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'if patrons of this category can be guarantees', > `reset_password` tinyint(1) DEFAULT NULL COMMENT 'if patrons of this category can do the password reset flow,', >@@ -2760,7 +2760,7 @@ CREATE TABLE `deletedborrowers` ( > `privacy` int(11) NOT NULL DEFAULT 1 COMMENT 'patron/borrower''s privacy settings related to their checkout history KEY `borrowernumber` (`borrowernumber`),', > `privacy_guarantor_fines` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'controls if relatives can see this patron''s fines', > `privacy_guarantor_checkouts` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'controls if relatives can see this patron''s checkouts', >- `checkprevcheckout` enum('yes', 'no', 'inherit') NOT NULL DEFAULT 'inherit' COMMENT 'produce a warning for this patron if this item has previously been checked out to this patron if ''yes'', not if ''no'', defer to category setting if ''inherit''.', >+ `checkprevcheckout` varchar(7) NOT NULL DEFAULT 'inherit' COMMENT 'produce a warning for this patron if this item has previously been checked out to this patron if ''yes'', not if ''no'', defer to category setting if ''inherit''.', > `updated_on` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp() COMMENT 'time of last change could be useful for synchronization with external systems (among others)', > `lastseen` datetime DEFAULT NULL COMMENT 'last time a patron has been seen (connected at the OPAC or staff interface)', > `lang` varchar(25) NOT NULL DEFAULT 'default' COMMENT 'lang to use to send notices to this patron', >@@ -5772,6 +5772,19 @@ CREATE TABLE `saved_reports` ( > ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; > /*!40101 SET character_set_client = @saved_cs_client */; > >+DROP TABLE IF EXISTS `reports_branches`; >+/*!40101 SET @saved_cs_client = @@character_set_client */; >+/*!40101 SET character_set_client = utf8mb4 */; >+CREATE TABLE `reports_branches` ( >+ `report_id` int(11) NOT NULL, >+ `branchcode` varchar(10) NOT NULL, >+ KEY `report_id` (`report_id`), >+ KEY `branchcode` (`branchcode`), >+ CONSTRAINT `reports_branches_ibfk_1` FOREIGN KEY (`report_id`) REFERENCES `saved_sql` (`id`) ON DELETE CASCADE, >+ CONSTRAINT `reports_branches_ibfk_2` FOREIGN KEY (`branchcode`) REFERENCES `branches` (`branchcode`) ON DELETE CASCADE >+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; >+/*!40101 SET character_set_client = @saved_cs_client */; >+ > -- > -- Table structure for table `saved_sql` > -- >diff --git a/installer/data/mysql/mandatory/sysprefs.sql b/installer/data/mysql/mandatory/sysprefs.sql >index f2b6d940cc..f9f419c39d 100644 >--- a/installer/data/mysql/mandatory/sysprefs.sql >+++ b/installer/data/mysql/mandatory/sysprefs.sql >@@ -278,7 +278,6 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` > ('FacetLabelTruncationLength','20',NULL,'Specify the facet max length in OPAC','Integer'), > ('FacetMaxCount','20',NULL,'Specify the max facet count for each category','Integer'), > ('FacetOrder','Alphabetical','Alphabetical|Usage','Specify the order of facets within each category','Choice'), >-('FacetSortingLocale','default','','Choose the locale for sorting facet names when FacetOrder is set to Alphabetical. This enables proper Unicode-aware sorting of accented characters and locale-specific alphabetical ordering.','Choice'), > ('FailedLoginAttempts','','','Number of login attempts before lockout the patron account','Integer'), > ('FallbackToSMSIfNoEmail', 0, 'Enable|Disable', 'Send messages by SMS if no patron email is defined', 'YesNo'), > ('FeeOnChangePatronCategory','1','','If set, when a patron changes to a category with enrolment fee, a fee is charged','YesNo'), >@@ -507,7 +506,7 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` > ('OPACFineNoRenewalsIncludeCredits','1',NULL,'If enabled the value specified in OPACFineNoRenewals should include any unapplied account credits in the calculation','YesNo'), > ('OPACFinesTab','1','','If OFF the patron fines tab in the OPAC is disabled.','YesNo'), > ('OPACFRBRizeEditions','0','','If ON, the OPAC will query one or more ISBN web services for associated ISBNs and display an Editions tab on the details pages','YesNo'), >-('OpacHiddenItems','','','This syspref allows to define custom rules for hiding specific items at the OPAC. See https://wiki.koha-community.org/wiki/OpacHiddenItems for more information.','Textarea'), >+('OpacHiddenItems','','','This syspref allows to define custom rules for hiding specific items at the OPAC. See http://wiki.koha-community.org/wiki/OpacHiddenItems for more information.','Textarea'), > ('OpacHiddenItemsExceptions','',NULL,'List of borrower categories, separated by comma, that can see items otherwise hidden by OpacHiddenItems','Textarea'), > ('OpacHiddenItemsHidesRecord','1','','Hide biblio record when all its items are hidden because of OpacHiddenItems','YesNo'), > ('OpacHighlightedWords','1','','If Set, then queried words are higlighted in OPAC','YesNo'), >diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl >index adbd5e4c50..b234d7cfad 100755 >--- a/installer/data/mysql/updatedatabase.pl >+++ b/installer/data/mysql/updatedatabase.pl >@@ -29455,6 +29455,22 @@ if ( CheckVersion($DBversion) ) { > NewVersion( $DBversion, 28108, "Add new systempreference OpacHiddenItemsHidesRecord" ); > } > >+$DBversion = '25.06.00.003'; >+if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) { >+ $dbh->do( >+ "CREATE TABLE `reports_branches` ( >+ `report_id` int(11) NOT NULL, >+ `branchcode` varchar(10) NOT NULL, >+ KEY `report_id` (`report_id`), >+ KEY `branchcode` (`branchcode`), >+ CONSTRAINT `reports_branches_ibfk_1` FOREIGN KEY (`report_id`) REFERENCES `saved_sql` (`id`) ON DELETE CASCADE, >+ CONSTRAINT `reports_branches_ibfk_2` FOREIGN KEY (`branchcode`) REFERENCES `branches` (`branchcode`) ON DELETE CASCADE >+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;" >+ ); >+ print "Upgrade to $DBversion done (reports_branches added)\n"; >+ SetVersion($DBversion); >+} >+ > $DBversion = '21.05.00.000'; > if ( CheckVersion($DBversion) ) { > NewVersion( $DBversion, "", "Koha 21.05.00 release" ); >diff --git a/koha-tmpl/intranet-tmpl/prog/css/src/staff-global.scss b/koha-tmpl/intranet-tmpl/prog/css/src/staff-global.scss >index ae6c2b9739..5798abfd15 100644 >--- a/koha-tmpl/intranet-tmpl/prog/css/src/staff-global.scss >+++ b/koha-tmpl/intranet-tmpl/prog/css/src/staff-global.scss >@@ -2192,16 +2192,6 @@ li { > td { > &.actions { > white-space: nowrap; >- >- a, >- button { >- display: inline-block; >- margin-left: .3rem; >- >- &:first-child { >- margin-left: 0; >- } >- } > } > > &.bookcoverimg { >diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/guided-reports-view.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/guided-reports-view.inc >index 59e416f7b8..4461581ba1 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/includes/guided-reports-view.inc >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/guided-reports-view.inc >@@ -10,12 +10,12 @@ > </ul> > <h5>Useful resources</h5> > <ul> >- <li><a href="https://wiki.koha-community.org/wiki/SQL_Reports_Library" target="blank">Koha report library</a></li> >+ <li><a href="http://wiki.koha-community.org/wiki/SQL_Reports_Library" target="blank">Koha report library</a></li> > [% SET koha_version = Koha.Version %] > [% IF koha_version.development %] >- <li><a href="https://schema.koha-community.org/main" target="blank">Koha database schema</a></li> >+ <li><a href="http://schema.koha-community.org/main" target="blank">Koha database schema</a></li> > [% ELSE %] >- <li><a href="https://schema.koha-community.org/[% koha_version.major | uri %]_[% koha_version.minor | uri %]" target="blank">Koha database schema</a></li> >+ <li><a href="http://schema.koha-community.org/[% koha_version.major | uri %]_[% koha_version.minor | uri %]" target="blank">Koha database schema</a></li> > [% END %] > </ul> > </div> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/header.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/header.inc >index 16ed39f758..15e1f17ce5 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/includes/header.inc >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/header.inc >@@ -104,16 +104,14 @@ > </span> > <span id="logged-in-info-full"> > [% SET is_superlibrarian = CAN_user_superlibrarian ? 'is_superlibrarian' : '' %] >- <span class="loggedinusername [% is_superlibrarian | html %]" data-loggedinusername="[% logged_in_user.userid | html %]" data-is-superlibrarian="[% is_superlibrarian | html %]" >- >[% logged_in_user.userid | html %]</span >- > >- <span class="loggedincategorycode content_hidden" data-loggedincategorycode="[% logged_in_user.categorycode | html %]">[% logged_in_user.categorycode | html %]</span> >+ <span class="loggedinusername [% is_superlibrarian | html %]">[% logged_in_user.userid | html %]</span> >+ <span class="loggedincategorycode content_hidden">[% logged_in_user.categorycode | html %]</span> > [% IF ( StaffLoginRestrictLibraryByIP ) %] > <brand> [% Branches.GetLoggedInBranchname | html %] </brand> > [% ELSE %] > <strong> >- <span class="logged-in-branch-name" data-logged-in-branch-name="[% Branches.GetLoggedInBranchname | html %]">[% Branches.GetLoggedInBranchname | html %]</span> >- <span class="logged-in-branch-code content_hidden" data-logged-in-branch-code="[% Branches.GetLoggedInBranchcode | html %]">[% Branches.GetLoggedInBranchcode | html %]</span> >+ <span class="logged-in-branch-name">[% Branches.GetLoggedInBranchname | html %]</span> >+ <span class="logged-in-branch-code content_hidden">[% Branches.GetLoggedInBranchcode | html %]</span> > </strong> > [% END %] > [% IF Koha.Preference('UseCirculationDesks') && Desks.ListForLibrary.count %] >@@ -122,16 +120,16 @@ > [% IF ( Desks.GetLoggedInDeskName == '' ) %] > <span class="logged-in-desk-name">NO DESK SET</span> > [% ELSE %] >- <span class="logged-in-desk-name" data-logged-in-desk-name="[% Desks.GetLoggedInDeskName | html %]">[% Desks.GetLoggedInDeskName | html %]</span> >- <span class="logged-in-desk-id content_hidden" data-logged-in-desk-id="[% Desks.GetLoggedInDeskId | html %]">[% Desks.GetLoggedInDeskId | html %]</span> >+ <span class="logged-in-desk-name">[% Desks.GetLoggedInDeskName | html %]</span> >+ <span class="logged-in-desk-id content_hidden">[% Desks.GetLoggedInDeskId | html %]</span> > [% END %] > </strong> > [% END %] > [% IF Koha.Preference('UseCashRegisters') && !(Registers.session_register_name == '') %] > <span class="separator">|</span> > <strong> >- <span class="logged-in-register-name" data-logged-in-register-name="[% Registers.session_register_name | html %]">[% Registers.session_register_name | html %]</span> >- <span class="logged-in-register-id content_hidden" data-logged-in-register-id="[% Registers.session_register_id | html %]">[% Registers.session_register_id | html %]</span> >+ <span class="logged-in-register-name">[% Registers.session_register_name | html %]</span> >+ <span class="logged-in-register-id content_hidden">[% Registers.session_register_id | html %]</span> > </strong> > [% END %] > </span> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/member-display-address-style.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/member-display-address-style.inc >index 3e0bb172e0..7f29640ceb 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/includes/member-display-address-style.inc >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/member-display-address-style.inc >@@ -29,18 +29,10 @@ > [%~ END ~%] > [%~ IF ( patron.city || patron.zipcode || patron.state || patron.country ) ~%] > <li class="patroncity"> >- <span class="city">[%~ patron.city |html ~%]</span> >- [%~ IF ( patron.state ) %] >- [%~ IF ( patron.city ) ~%] >- , >- [% END ~%] >- <span class="state">[% patron.state |html ~%]</span> >- [%~ END ~%] >- [%~ IF ( patron.zipcode ) %]<span class="zipcode">[%~ " " _ patron.zipcode |html ~%]</span>[% END %] >- [%~ IF ( patron.country ) %] >- [% line_break | $raw %] >- <span class="country">[% patron.country |html ~%]</span> >- [%~ END ~%] >+ <span class="city">[%~ patron.city |html ~%]</span>[%~ IF ( patron.state ) %][%~ IF ( patron.city ) ~%],[% END ~%]<span class="state">[% patron.state |html ~%]</span>[%~ END ~%] >+ [%~ IF ( patron.zipcode ) %]<span class="zipcode">[%~ " " _ patron.zipcode |html ~%]</span>[% END %][%~ IF ( patron.country ) %][%~ IF ( patron.zipcode || patron.state || patron.city ) ~%] >+ <span class="comma">,</span> >+ [% END ~%]<span class="country">[% patron.country |html ~%]</span>[%~ END ~%] > </li> > [%~ END ~%] > [%~ END ~%] >@@ -52,15 +44,11 @@ > [%~ IF patron.streettype ~%] > [%~ SET roadtype_desc = AuthorisedValues.GetByCode('ROADTYPE', patron.streettype) ~%] > [%~ END ~%] >- <li class="patronaddress1"> >- <span class="address1">[%~ patron.address | html ~%]</span> >- [%~ IF roadtype_desc %] >- <span class="roadtype">[% roadtype_desc | html ~%]</span> >- [%~ END ~%] >- [%~ IF patron.streetnumber %] >+ <li class="patronaddress1" >+ ><span class="address1">[%~ patron.address | html ~%]</span>[%~ IF roadtype_desc %]<span class="roadtype">[% roadtype_desc | html ~%]</span>[%~ END ~%][%~ IF patron.streetnumber %] > <span class="streetnumber">[% patron.streetnumber | html ~%]</span> >- [%~ END ~%] >- </li> >+ [%~ END ~%]</li >+ > > [%~ END ~%] > [%~ IF ( patron.address2 ) ~%] > <li class="patronaddress2">[%~ patron.address2 | html ~%]</li> >@@ -68,11 +56,7 @@ > [%~ END ~%] > [%~ IF ( patron.city || patron.zipcode || patron.state || patron.country ) ~%] > <li class="patroncity"> >- [%~ IF ( patron.zipcode ) ~%] >- <span class="zipcode">[%~ patron.zipcode | html %]</span> >- [% END ~%] >- <span class="city">[%~ patron.city | html ~%]</span> >- [%~ IF ( patron.state ) ~%] >+ [%~ IF ( patron.zipcode ) ~%]<span class="zipcode">[%~ patron.zipcode | html %]</span>[% END ~%]<span class="city">[%~ patron.city | html ~%]</span>[%~ IF ( patron.state ) ~%] > [% line_break | $raw %]<span class="state">[%~ patron.state | html ~%]</span> > [%~ END ~%] > [%~ IF ( patron.country ) ~%][% line_break | $raw %]<span class="country">[%~ patron.country | html ~%]</span>[%~ END ~%] >@@ -87,13 +71,9 @@ > [%~ IF patron.streettype ~%] > [%~ SET roadtype_desc = AuthorisedValues.GetByCode('ROADTYPE', patron.streettype) ~%] > [%~ END ~%] >- <li class="patronaddress1"> >- [%~ IF patron.streetnumber ~%] >- <span class="streetnumber">[%~ patron.streetnumber | html %]</span> >- [% END ~%] >- [%~ IF roadtype_desc ~%] >- <span class="roadtype">[%~ roadtype_desc | html %]</span> >- [% END ~%] >+ <li class="patronaddress1" >+ >[%~ IF patron.streetnumber ~%]<span class="streetnumber">[%~ patron.streetnumber | html %]</span>[% END ~%] >+ [%~ IF roadtype_desc ~%]<span class="roadtype">[%~ roadtype_desc | html %]</span>[% END ~%] > <span class="address1">[%~ patron.address | html ~%]</span> > </li> > [%~ END ~%] >@@ -103,11 +83,7 @@ > [%~ END ~%] > [%~ IF ( patron.city || patron.zipcode || patron.state || patron.country ) ~%] > <li class="patroncity"> >- [%~ IF ( patron.zipcode ) ~%] >- <span class="zipcode">[%~ patron.zipcode | html %]</span> >- [% END ~%] >- <span class="city">[%~ patron.city | html ~%]</span> >- [%~ IF ( patron.state ) ~%] >+ [%~ IF ( patron.zipcode ) ~%]<span class="zipcode">[%~ patron.zipcode | html %]</span>[% END ~%]<span class="city">[%~ patron.city | html ~%]</span>[%~ IF ( patron.state ) ~%] > [% line_break | $raw %]<span class="state">[%~ patron.state | html ~%]</span> > [%~ END ~%] > [%~ IF ( patron.country ) ~%][% line_break | $raw %]<span class="country">[%~ patron.country | html ~%]</span>[%~ END ~%] >diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/prefs-menu.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/prefs-menu.inc >index 937e174112..2b17d1f079 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/includes/prefs-menu.inc >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/prefs-menu.inc >@@ -165,6 +165,17 @@ > </li> > [% END %] > >+ [% IF ( reports ) %] >+ <li class="active"> >+ <a title="Reports" href="/cgi-bin/koha/admin/preferences.pl?tab=reports">Reports</a> >+ [% PROCESS subtabs %] >+ </li> >+ [% ELSE %] >+ <li> >+ <a title="Reports" href="/cgi-bin/koha/admin/preferences.pl?tab=reports">Reports</a> >+ </li> >+ [% END %] >+ > [% IF ( searching ) %] > <li class="active"> > <a title="Searching" href="/cgi-bin/koha/admin/preferences.pl?tab=searching">Searching</a> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/tools-menu.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/tools-menu.inc >index 29a626aa1d..28cd71f6b7 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/includes/tools-menu.inc >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/tools-menu.inc >@@ -6,7 +6,7 @@ > <ul> > <li><a href="/cgi-bin/koha/tools/tools-home.pl">Tools home</a></li> > </ul> >- [% IF ( CAN_user_tools_manage_patron_lists || CAN_user_clubs || CAN_user_tools_moderate_comments || CAN_user_tools_import_patrons || CAN_user_tools_edit_notices || CAN_user_tools_edit_notice_status_triggers || CAN_user_tools_label_creator || CAN_user_tools_delete_anonymize_patrons || CAN_user_tools_edit_patrons || CAN_user_tools_batch_extend_due_dates || CAN_user_tools_moderate_tags || ( CAN_user_tools_batch_upload_patron_images && Koha.Preference('patronimages') ) || CAN_user_tools_rotating_collections ) %] >+ [% IF ( CAN_user_tools_manage_patron_lists || CAN_user_clubs || CAN_user_tools_moderate_comments || CAN_user_tools_import_patrons || CAN_user_tools_edit_notices || CAN_user_tools_edit_notice_status_triggers || CAN_user_tools_label_creator || CAN_user_tools_delete_anonymize_patrons || CAN_user_tools_edit_patrons || CAN_user_tools_moderate_tags || ( CAN_user_tools_batch_upload_patron_images && Koha.Preference('patronimages') ) || CAN_user_tools_rotating_collections ) %] > <h5>Patrons and circulation</h5> > <ul> > [% IF ( CAN_user_tools_manage_patron_lists ) %] >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/about.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/about.tt >index 853ef8d27d..94488c61da 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/about.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/about.tt >@@ -806,7 +806,11 @@ > </div> > [% IF db_audit.diff_found %] > <div> >- <pre><code>[% db_audit.diff | html %]</code></pre> >+ <p>Run the following SQL to fix the database:</p> >+ <pre> >+ <code>[% db_audit.diff | $raw %]</code> >+ </pre >+ > > </div> > [% END %] > [% END # tab=database %] >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basket.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basket.tt >index 8561c5fe75..b35ab76042 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basket.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basket.tt >@@ -150,8 +150,6 @@ > class="btn btn-default btn-xs submit-form-link" > href="#" > data-ean="[% eanacct.ean | html %]" >- data-ean_description="[% eanacct.description | html %]" >- data-ean_branch="[% eanacct.branch.branchname | html %]" > data-basketno="[% basketno | html %]" > data-action="basket.pl" > data-method="post" >@@ -1030,11 +1028,7 @@ > <div id="closebasket_needsconfirmation" class="alert alert-warning"> > <form action="/cgi-bin/koha/acqui/basket.pl" method="post"> > [% INCLUDE 'csrf-token.inc' %] >- <h1>Are you sure you want to generate this EDIFACT order?</h1> >- <ul> >- <li> An EDIFACT order will be generated for <b> [% ean_branch | html %] ([% ean | html %]) [% IF ean_description %][% ean_description | html %][% END %]</b></li> >- <li> The basket <b>[% basketname | html %]</b> will be closed </li> >- </ul> >+ <h1>Are you sure you want to generate an EDIFACT order and close basket [% basketname | html %]?</h1> > [% IF CAN_user_acquisition_group_manage %] > <p> > <label for="createbasketgroup">Attach this basket to a new basket group with the same name</label> >@@ -1047,11 +1041,11 @@ > <input type="hidden" name="booksellerid" value="[% booksellerid | html %]" /> > <input type="hidden" name="confirm" value="1" /> > <input type="hidden" name="basketgroupname" value="[% basketgroupname | html %]" /> >- <button type="submit" class="btn btn-default approve" accesskey="Y"><i class="fa fa-fw fa-check"></i> Yes, generate order and close basket (Y)</button> >+ <button type="submit" class="btn btn-default approve" accesskey="Y"><i class="fa fa-fw fa-check"></i> Yes, close (Y)</button> > </form> > <form action="/cgi-bin/koha/acqui/basket.pl" method="get"> > <input type="hidden" name="basketno" value="[% basketno | html %]" /> >- <button type="submit" class="btn btn-default deny" accesskey="N"><i class="fa fa-fw fa-times"></i> Cancel (C)</button> >+ <button type="submit" class="btn btn-default deny" accesskey="N"><i class="fa fa-fw fa-times"></i> No, don't close (N)</button> > </form> > </div> > <!-- /#closebasket_needsconfirmation --> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/marctagstructure.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/marctagstructure.tt >index 5bdc3777c9..f307644d51 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/marctagstructure.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/marctagstructure.tt >@@ -94,9 +94,7 @@ > [% IF ( else ) %] > <div id="toolbar" class="btn-toolbar"> > <a class="btn btn-default" id="addtag" href="/cgi-bin/koha/admin/marctagstructure.pl?op=add_form&frameworkcode=[% framework.frameworkcode | uri %]"><i class="fa fa-plus"></i> New tag</a> >- [% IF framework %] >- <a class="btn btn-default" href="/cgi-bin/koha/admin/biblio_framework.pl?op=add_form&frameworkcode=[% framework.frameworkcode | uri %]"><i class="fa-solid fa-pencil" aria-hidden="true"></i> Edit framework</a> >- [% END %] >+ <a class="btn btn-default" href="/cgi-bin/koha/admin/biblio_framework.pl?op=add_form&frameworkcode=[% framework.frameworkcode | uri %]"><i class="fa-solid fa-pencil" aria-hidden="true"></i> Edit framework</a> > </div> > [% END %] > >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/acquisitions.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/acquisitions.pref >index 7f1a886095..523c30b896 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/acquisitions.pref >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/acquisitions.pref >@@ -9,7 +9,7 @@ Acquisitions: > cataloguing: cataloging the record. > - This is only the default behavior, and can be changed per-basket. > - >- - "The following <a href='https://schema.koha-community.org/__VERSION__/tables/items.html' target='blank'>database columns</a> should be unique in an item:" >+ - "The following <a href='http://schema.koha-community.org/__VERSION__/tables/items.html' target='blank'>database columns</a> should be unique in an item:" > - pref: UniqueItemFields > type: modalselect > source: items >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/i18n_l10n.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/i18n_l10n.pref >index e95b345434..34a9d54211 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/i18n_l10n.pref >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/i18n_l10n.pref >@@ -63,11 +63,6 @@ I18N/L10N: > de: German style ([Address] [Street number] - [ZIP/Postal Code] [City] - [Country]) > fr: French style ([Street number] [Address] - [ZIP/Postal Code] [City] - [Country]) > - . >- - >- - Sort facet names using >- - pref: FacetSortingLocale >- type: locale-list >- - locale when FacetOrder is set to Alphabetical. This enables proper Unicode-aware sorting of accented characters and locale-specific alphabetical ordering. > - > - pref: TranslateNotices > choices: >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref >index f15aad0b93..5441fd7e11 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref >@@ -668,7 +668,7 @@ OPAC: > type: textarea > syntax: text/x-yaml > class: code >- - Define custom rules to hide specific items from search and view on the OPAC. How to write these rules is documented on the <a href="https://wiki.koha-community.org/wiki/OpacHiddenItems" target="_blank">Koha wiki</a>. >+ - Define custom rules to hide specific items from search and view on the OPAC. How to write these rules is documented on the <a href="http://wiki.koha-community.org/wiki/OpacHiddenItems" target="_blank">Koha wiki</a>. > - > - 'List of patron categories, that can see items otherwise hidden by <a href="/cgi-bin/koha/admin/preferences.pl?op=search&searchfield=OpacHiddenItems">OpacHiddenItems</a>:' > - pref: OpacHiddenItemsExceptions >@@ -851,19 +851,19 @@ OPAC: > - "days after account creation." > - "<br><strong>NOTE:</strong> This system preference requires the <code>misc/cronjobs/cleanup_database.pl</code> cronjob. Ask your system administrator to schedule it.<br>No patrons will be deleted if you set the pref to zero or make it empty." > - >- - "The following <a href='https://schema.koha-community.org/__VERSION__/tables/borrowers.html' target='blank'>database columns</a> must be filled in on the patron modification screen:" >+ - "The following <a href='http://schema.koha-community.org/__VERSION__/tables/borrowers.html' target='blank'>database columns</a> must be filled in on the patron modification screen:" > - pref: PatronSelfModificationMandatoryField > type: modalselect > source: borrowers > exclusions: password|cardnumber|dateexpiry|categorycode|sort1|sort2|opacnote|borrowernotes|gonenoaddress|lost|flags > - >- - "The following <a href='https://schema.koha-community.org/__VERSION__/tables/borrowers.html' target='blank'>database columns</a> must be filled in on the patron entry screen:" >+ - "The following <a href='http://schema.koha-community.org/__VERSION__/tables/borrowers.html' target='blank'>database columns</a> must be filled in on the patron entry screen:" > - pref: PatronSelfRegistrationBorrowerMandatoryField > type: modalselect > source: borrowers > exclusions: sort1|sort2|opacnote|borrowernotes|gonenoaddress|lost|flags > - >- - "The following <a href='https://schema.koha-community.org/__VERSION__/tables/borrowers.html' target='blank'>database columns</a> will not appear on the patron self-registration screen:" >+ - "The following <a href='http://schema.koha-community.org/__VERSION__/tables/borrowers.html' target='blank'>database columns</a> will not appear on the patron self-registration screen:" > - pref: PatronSelfRegistrationBorrowerUnwantedField > type: modalselect > source: borrowers >@@ -871,7 +871,7 @@ OPAC: > inclusions: categorycode|dateexpiry > - '<br /> NOTE: preferred_name will be set to firstname if not included in the form.' > - >- - "The following <a href='https://schema.koha-community.org/__VERSION__/tables/borrowers.html' target='blank'>database columns</a> will not appear on the patron self-modification screen:" >+ - "The following <a href='http://schema.koha-community.org/__VERSION__/tables/borrowers.html' target='blank'>database columns</a> will not appear on the patron self-modification screen:" > - pref: PatronSelfModificationBorrowerUnwantedField > type: modalselect > source: borrowers >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref >index 2ca8899ec3..424b3eee9b 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref >@@ -211,7 +211,7 @@ Patrons: > - pref: EmailFieldPrecedence > class: multi > - '<br><strong>NOTE:</strong> All patron fields can be used, but to work correctly they must contain a valid email address or an empty string.' >- - "Valid options are the <a href='https://schema.koha-community.org/__VERSION__/tables/borrowers.html' target='blank'>database columns</a> of the borrowers table, separated by | (pipe)." >+ - "Valid options are the <a href='http://schema.koha-community.org/__VERSION__/tables/borrowers.html' target='blank'>database columns</a> of the borrowers table, separated by | (pipe)." > - "Example: email|emailpro|B_email" > - > - "When <a href='/cgi-bin/koha/admin/preferences.pl?op=search&searchfield=EmailFieldPrimary'>EmailFieldPrimary</a> is set to '<strong>selected addresses</strong>', send email to all valid email addresses in the selected fields:" >@@ -274,14 +274,14 @@ Patrons: > cron: (Deprecated) according to --send-notices cron switch > Patron forms: > - >- - "The following <a href='https://schema.koha-community.org/__VERSION__/tables/borrowers.html' target='blank'>database columns</a> must be filled in on the patron entry screen:" >+ - "The following <a href='http://schema.koha-community.org/__VERSION__/tables/borrowers.html' target='blank'>database columns</a> must be filled in on the patron entry screen:" > - pref: BorrowerMandatoryField > type: modalselect > source: borrowers > exclusions: flags > - '<strong>NOTE:</strong> If <a href="/cgi-bin/koha/admin/preferences.pl?op=search&searchfield=autoMemberNum">autoMemberNum</a> is enabled, the system preference <a href="/cgi-bin/koha/admin/preferences.pl?op=search&searchfield=BorrowerMandatoryField">BorrowerMandatoryField</a> must not contain the field <code>cardnumber</code>.' > - >- - "The following <a href='https://schema.koha-community.org/__VERSION__/tables/borrowers.html' target='blank'>database columns</a> will not appear on the patron entry screen:" >+ - "The following <a href='http://schema.koha-community.org/__VERSION__/tables/borrowers.html' target='blank'>database columns</a> will not appear on the patron entry screen:" > - pref: BorrowerUnwantedField > type: modalselect > source: borrowers >@@ -311,7 +311,7 @@ Patrons: > 0: "Don't" > - store and display surnames in upper case. > - >- - "The following <a href='https://schema.koha-community.org/__VERSION__/tables/borrowers.html' target='blank'>database columns</a>:" >+ - "The following <a href='http://schema.koha-community.org/__VERSION__/tables/borrowers.html' target='blank'>database columns</a>:" > - pref: PatronQuickAddFields > type: modalselect > source: borrowers >@@ -337,7 +337,7 @@ Patrons: > messaging: "Patron messaging preferences" > - . > - >- - "The following <a href='https://schema.koha-community.org/__VERSION__/tables/borrowers.html' target='blank'>database columns</a>:" >+ - "The following <a href='http://schema.koha-community.org/__VERSION__/tables/borrowers.html' target='blank'>database columns</a>:" > - pref: PatronDuplicateMatchingAddFields > type: modalselect > source: borrowers >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/reports.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/reports.pref >new file mode 100644 >index 0000000000..1579aaf090 >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/reports.pref >@@ -0,0 +1,9 @@ >+Reports: >+ Reports Access: >+ - >+ - pref: EnableFilteringReports >+ choices: >+ 1: Enable >+ 0: Disable >+ - "filtering report access based on staff home library." >+ - "<br><strong>NOTE:</strong> A NOTE ABOUT THE EFFECTS OF THIS PREFERENCE / SETTING" >\ No newline at end of file >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/search_filters.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/search_filters.tt >index 1aea30fc4e..f822751a8f 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/search_filters.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/search_filters.tt >@@ -30,9 +30,11 @@ > [% END #/ WRAPPER sub-header.inc %] > > [% WRAPPER 'main-container.inc' aside='admin-menu' %] >- <h1>Search filters</h1> >+ > [% IF filters_count %] >- <div id="search_filters_list" class="page-section"> >+ <div id="search_filters_list"> >+ <h2>Search filters</h2> >+ > <table id="search_filters_table"> > <thead> > <tr> >@@ -42,7 +44,7 @@ > <th>Limits</th> > <th>OPAC</th> > <th>Staff interface</th> >- <th data-class-name="actions noExport">Actions</th> >+ <th> </th> > </tr> > </thead> > </table> >@@ -60,16 +62,14 @@ > <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> > </div> > <div class="modal-body"> >- <div class="mb-3"> >+ <div class="form-group"> > <input type="hidden" id="filter_edit_id" name="filter_edit_id" /> > <label for="filter_edit_name">Name:</label> > <input id="filter_edit_name" name="filter_edit_name" type="text" /> >- </div> >- <div class="mb-3"> >- <label for="filter_edit_opac"><input type="checkbox" id="filter_edit_opac" name="filter_edit_opac" /> Show in OPAC?</label> >- </div> >- <div class="mb-3"> >- <label for="filter_edit_staff_client"><input type="checkbox" id="filter_edit_staff_client" name="filter_edit_staff_client" /> Show in staff interface?</label> >+ <label for="filter_edit_opac">Show in OPAC?</label> >+ <input type="checkbox" id="filter_edit_opac" name="filter_edit_opac" /> >+ <label for="filter_edit_staff_client">Show in staff interface?</label> >+ <input type="checkbox" id="filter_edit_staff_client" name="filter_edit_staff_client" /> > </div> > </div> > <div class="modal-footer"> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/auth.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/auth.tt >index 4a0a210904..e46d7ad41a 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/auth.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/auth.tt >@@ -59,7 +59,7 @@ > [% INCLUDE 'messages.inc' %] > > <div id="login"> >- <h1><a href="https://koha-community.org">Koha</a></h1> >+ <h1><a href="http://koha-community.org">Koha</a></h1> > > [% SET StaffLoginInstructions = AdditionalContents.get( location => "StaffLoginInstructions", lang => lang ) %] > >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/authorities/authorities.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/authorities/authorities.tt >index d9e91e55c0..09f997a2af 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/authorities/authorities.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/authorities/authorities.tt >@@ -242,7 +242,7 @@ > if ( elt.nodeName == 'SELECT' ) { > $(elt).siblings('.select2').find("span[role='combobox']").addClass(notFilledClass); > } else { >- elt.setAttribute('class','input_marceditor noEnterSubmit framework_plugin ' + notFilledClass); >+ elt.setAttribute('class','input_marceditor noEnterSubmit ' + notFilledClass); > } > $('#' + subfields[i]).focus(); > tabflag[tag+subfield+tagnumber][1]=label[i]; >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/addbiblio.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/addbiblio.tt >index 7d75f7970c..003358530c 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/addbiblio.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/addbiblio.tt >@@ -576,7 +576,7 @@ > if ( elt.nodeName == 'SELECT' ) { > $(elt).siblings('.select2').find("span[role='combobox']").addClass(notFilledClass); > } else { >- elt.setAttribute('class','input_marceditor noEnterSubmit framework_plugin ' + notFilledClass); >+ elt.setAttribute('class','input_marceditor noEnterSubmit ' + notFilledClass); > } > $('#' + subfields[i]).focus(); > tabflag[tag+subfield+tagnumber][1]=label[i]; >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/transferstoreceive.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/transferstoreceive.tt >index 2bec7d4239..ef9960ffcc 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/transferstoreceive.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/transferstoreceive.tt >@@ -78,9 +78,6 @@ > [% BLOCK subject %]Hold:[% END %] > <a href="mailto:[% reser.patron.notice_email_address | uri %]?subject=[% INCLUDE subject %] [% reser.title | uri %]"> [% reser.patron.notice_email_address | html %] </a> > [% END %] >- [% IF reser.patron.cardnumber %] >- <div class="cardnumber">Card number: [% reser.patron.cardnumber | html %]</div> >- [% END %] > [% ELSIF ( reser.recall ) %] > Recall requested by > <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% reser.recall.patron_id | uri %]" >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt >index 4f86e49e18..361a178107 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt >@@ -489,12 +489,12 @@ > <li class="guarantor-details" data-borrowernumber="[% r.guarantor_id | $raw %]"> > <span class="label">Guarantor:</span> > [% INCLUDE 'patron-title.inc' patron=r.guarantor hide_patron_infos_if_needed=1 %] >- <input type="hidden" class="guarantor_id relation-[% r.id | html %]" name="guarantor_id" value="[% r.guarantor_id | html %]" /> >+ <input type="hidden" class="new_guarantor_id relation-[% r.id | html %]" name="new_guarantor_id" value="[% r.guarantor_id | html %]" /> > </li> > <li> > <span class="label">Relationship:</span> > <span>[% r.relationship | html %]</span> >- <input type="hidden" class="guarantor_relationship relation-[% r.id | html %]" name="guarantor_relationship" value="[% r.relationship | html %]" /> >+ <input type="hidden" class="new_guarantor_relationship relation-[% r.id | html %]" name="new_guarantor_relationship" value="[% r.relationship | html %]" /> > </li> > > <li> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/guided_reports_start.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/guided_reports_start.tt >index b954e48a9d..ade44dd2c7 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/guided_reports_start.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/guided_reports_start.tt >@@ -3,6 +3,7 @@ > [% USE AuthorisedValues %] > [% USE KohaDates %] > [% USE Koha %] >+[% USE Branches %] > [% USE TablesSettings %] > [% USE HtmlScrubber %] > [% USE JSON.Escape %] >@@ -850,6 +851,7 @@ > <input type="hidden" name="reportname" value="[% reportname | html %]" /> > <input type="hidden" name="group" value="[% group | html %]" /> > <input type="hidden" name="subgroup" value="[% subgroup | html %]" /> >+ <input type="hidden" name="branches" value="[% branches | html %] /> > <input type="hidden" name="notes" value="[% notes | scrub_html type => 'note' | $raw %]" /> > <input type="hidden" name="cache_expiry" value="[% cache_expiry | html %]" /> > <input type="hidden" name="cache_expiry_units" value="[% cache_expiry_units | html %]" /> >@@ -1434,7 +1436,18 @@ > <span class="required">Required</span> > </div> > </fieldset> >- >+ [% IF ( Koha.Preference('EnableFilteringReports') ) %] >+ <fieldset class="rows"> >+ <legend>Library limitation:</legend> >+ <div >+ ><label for="library_limitation">Library limitation: </label> >+ <select id="library_limitation" name="branches" multiple size="10"> >+ [% PROCESS options_for_libraries libraries => Branches.all( selected => report.get_library_limits, unfiltered => 1, do_not_select_my_library => 1 ) %] >+ </select> >+ <div class="hint">Limits the use of this report to the selected libraries.</div> >+ </div> >+ </fieldset> >+ [% END %] > <fieldset class="action"> > <input type="hidden" name="op" value="cud-save" /> > <input type="submit" name="submit" class="btn btn-primary" value="Save report" /> >@@ -1548,7 +1561,18 @@ > <br /> > <span class="required" style="margin-left:30px;">Required</span> > </fieldset> >- >+ [% IF ( Koha.Preference('EnableFilteringReports') ) %] >+ <fieldset class="rows"> >+ <legend>Library limitation:</legend> >+ <div >+ ><label for="library_limitation">Library limitation: </label> >+ <select id="library_limitation" name="branches" multiple size="10"> >+ [% PROCESS options_for_libraries libraries => Branches.all( selected => report.get_library_limits, unfiltered => 1, do_not_select_my_library => 1 ) %] >+ </select> >+ <div class="hint">Limits the use of this report to the selected libraries.</div> >+ </div> >+ </fieldset> >+ [% END %] > <fieldset class="action"> > <button class="btn btn-primary" type="submit" name="op" value="cud-update_sql">Update SQL</button> > <button class="btn btn-default" type="submit" name="op" value="cud-update_and_run_sql">Update and run SQL</button> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/issues_stats.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/issues_stats.tt >index 53036c74e5..4ef937e635 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/issues_stats.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/issues_stats.tt >@@ -1,9 +1,6 @@ > [% USE raw %] > [% USE Koha %] > [% USE Branches %] >-[% USE Categories %] >-[% USE ItemTypes %] >-[% USE AuthorisedValues %] > [% PROCESS 'i18n.inc' %] > [% SET footerjs = 1 %] > [% INCLUDE 'doc-head-open.inc' %] >@@ -70,66 +67,37 @@ > [% END %] > [% SWITCH loopfilte.crit %] > [% CASE 0 %] >- <strong>Period from:</strong> [% loopfilte.filter | html %] >+ <span>Period from [% loopfilte.filter | html %]</span> > [% CASE 1 %] >- <strong>Period to:</strong> [% loopfilte.filter | html %] >+ <span>Period to [% loopfilte.filter | html %]</span> > [% CASE 2 %] >- <strong>Patron category:</strong> [% Categories.GetName( loopfilte.filter ) | html %] >+ <span>Patron category = [% loopfilte.filter | html %]</span> > [% CASE 3 %] >- <strong>Item type:</strong> [% ItemTypes.GetDescription( loopfilte.filter ) | html %] >+ <span>Item type = [% loopfilte.filter | html %]</span> > [% CASE 4 %] >- <strong>Issuing library:</strong> [% Branches.GetName( loopfilte.filter ) | html %] >+ <span>Issuing library = [% loopfilte.filter | html %]</span> > [% CASE 5 %] >- <strong>Collection:</strong> [% AuthorisedValues.GetByCode( 'CCODE', loopfilte.filter ) | html %] >+ <span>Collection = [% loopfilte.filter | html %]</span> > [% CASE 6 %] >- <strong>Location:</strong> [% AuthorisedValues.GetByCode( 'LOC', loopfilte.filter ) | html %] >+ <span>Location = [% loopfilte.filter | html %]</span> > [% CASE 7 %] >- <strong>Item call number > [% loopfilte.filter | html %] </strong> >+ <span>Item call number >= [% loopfilte.filter | html %]</span> > [% CASE 8 %] >- <strong>Item call number < [% loopfilte.filter | html %] </strong> >+ <span>Item call number < [% loopfilte.filter | html %]</span> > [% CASE 9 %] >- <strong>Patron sort1:</strong> [% AuthorisedValues.GetByCode('Bsort1', loopfilte.filter ) | html %] >+ <span>Patron sort1 = [% loopfilte.filter | html %]</span> > [% CASE 10 %] >- <strong>Patron sort2:</strong> [% AuthorisedValues.GetByCode('Bsort2', loopfilte.filter ) | html %] >+ <span>Patron sort2 = [% loopfilte.filter | html %]</span> > [% CASE 11 %] >- <strong>Home library:</strong> [% Branches.GetName( loopfilte.filter ) | html %] >+ <span>Home library = [% loopfilte.filter | html %]</span> > [% CASE 12 %] >- <strong>Holding library:</strong> [% Branches.GetName( loopfilte.filter ) | html %] >+ <span>Holding library = [% loopfilte.filter | html %]</span> > [% CASE 13 %] >- <strong>Patron library:</strong> [% Branches.GetName( loopfilte.filter ) | html %] >+ <span>Patron library = [% loopfilte.filter | html %]</span> > [% CASE 14 %] >- <strong>Issuing library:</strong> [% Branches.GetName( loopfilte.filter ) | html %] >- [% CASE "Event" %] >- <strong>Event:</strong> >- [% SWITCH ( loopfilte.filter ) %] >- [% CASE "issue" %] >- <span>Checkout</span> >- [% CASE "return" %] >- <span>Check-in</span> >- [% CASE "renew" %] >- <span>Renewal</span> >- [% CASE %] >- [% loopfilte.filter | html %] >- [% END %] >- [% CASE "Select Day" %] >- <strong>Select day:</strong> [% loopfilte.filter | html %] >- [% CASE "Select Month" %] >- <strong>Select month:</strong> [% loopfilte.filter | html %] >- [% CASE "Display by" %] >- <strong>Group by:</strong> >- [% SWITCH ( loopfilte.filter ) %] >- [% CASE "1" %] >- <span>Day of week</span> >- [% CASE "2" %] >- <span>Month</span> >- [% CASE "3" %] >- <span>Year</span> >- [% CASE "4" %] >- <span>Hour</span> >- [% END %] >+ <span>Issuing library = [% loopfilte.filter | html %]</span> > [% CASE %] >- [% loopfilte.crit | html %]: >- [% loopfilte.filter | html %] >+ <span>[% loopfilte.crit | html %] = [% loopfilte.filter | html %]</span> > [% END %] > </li> > [% END %] >@@ -368,9 +336,11 @@ > <td><input type="radio" name="Line" value="borrowers.branchcode" /></td> > <td><input type="radio" name="Column" value="borrowers.branchcode" /></td> > <td> >- <select name="Filter" id="patron_library"> >- <option value=""> </option> >- [% PROCESS options_for_libraries libraries => Branches.all() %] >+ <select name="Filter" id="patronbranch"> >+ <option value=""> </option> >+ [% FOREACH branch IN branchloop %] >+ <option value="[% branch.value | html %]"> [% branch.branchname | html %] </option> >+ [% END %] > </select> > </td> > </tr> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/itemslost.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/itemslost.tt >index 8f87e2161b..88538ebea6 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/itemslost.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/itemslost.tt >@@ -83,7 +83,7 @@ > [% IF csv_profiles.count %] > <th class="no-sort"></th> > [% END %] >- <th class="anti-the">Title</th> >+ <th>Title</th> > <th>Author</th> > <th>Lost status</th> > <th>Lost on</th> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/orders_by_budget.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/orders_by_budget.tt >index 4f3710ab61..71ae52d44e 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/orders_by_budget.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/orders_by_budget.tt >@@ -58,7 +58,7 @@ > <th>Basket</th> > <th>Basket name</th> > <th>Basket by</th> >- <th class="anti-the">Title</th> >+ <th>Title</th> > <th>Currency</th> > <th>List price</th> > <th>RRP</th> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/reports-home.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/reports-home.tt >index 684b5362e5..9e9aac2874 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/reports-home.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/reports-home.tt >@@ -110,12 +110,12 @@ > <li><a href="/cgi-bin/koha/reports/issues_avg_stats.pl">Average loan time</a></li> > [% SET koha_version = Koha.Version %] > [% IF koha_version.development %] >- <li><a href="https://schema.koha-community.org/main" target="blank">Koha database schema</a></li> >+ <li><a href="http://schema.koha-community.org/main" target="blank">Koha database schema</a></li> > [% ELSE %] >- <li><a href="https://schema.koha-community.org/[% koha_version.major | uri %]_[% koha_version.minor | uri %]" target="blank">Koha database schema</a></li> >+ <li><a href="http://schema.koha-community.org/[% koha_version.major | uri %]_[% koha_version.minor | uri %]" target="blank">Koha database schema</a></li> > [% END %] > >- <li><a href="https://wiki.koha-community.org/wiki/SQL_Reports_Library" target="blank">Koha reports library</a></li> >+ <li><a href="http://wiki.koha-community.org/wiki/SQL_Reports_Library" target="blank">Koha reports library</a></li> > </ul> > </div> > [% IF ( Koha.Preference('Mana') == 2 ) %] >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/serials/serials-search.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/serials/serials-search.tt >index fe5eb4de85..1ad0ab6fef 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/serials/serials-search.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/serials/serials-search.tt >@@ -136,17 +136,19 @@ > [% IF closed %] > <a class="btn btn-default btn-xs dropdown-toggle" id="closedsubactions[% subscription.subscriptionid | html %]" role="button" data-bs-toggle="dropdown" href="#"> Actions </a> > <ul class="dropdown-menu" role="menu" aria-labelledby="closedsubactions[% subscription.subscriptionid | html %]"> >- [% UNLESS ( subscription.cannotedit ) %] >- <li> >- <a >- class="dropdown-item" >- href="/cgi-bin/koha/serials/serials-search.pl?subscriptionid=[% subscription.subscriptionid | uri %]&op=reopen&[% IF ( routing && CAN_user_serials_routing ) %]routing=[% subscription.routing | uri %]&[% END %]searched=1&title_filter=[% title_filter | uri %]&ISSN_filter=[% ISSN_filter | uri %]&EAN_filter=[% EAN_filter | uri %]&published_filter=[% publisher_filter | uri %]&bookseller_filter=[% bookseller_filter | uri %]&branch_filter=[% branch_filter | uri %]" >- id="reopensub" >- > >- <i class="fa-solid fa-arrow-rotate-right"></i> Reopen</a >- > >- </li> >- [% END %] >+ [% IF ( routing && CAN_user_serials_routing ) %] >+ [% UNLESS ( subscription.cannotedit ) %] >+ <li> >+ <a >+ class="dropdown-item" >+ href="/cgi-bin/koha/serials/serials-search.pl?subscriptionid=[% subscription.subscriptionid | uri %]&op=reopen&routing=[% subscription.routing | uri %]&searched=1&title_filter=[% title_filter | uri %]&ISSN_filter=[% ISSN_filter | uri %]&EAN_filter=[% EAN_filter | uri %]&published_filter=[% publisher_filter | uri %]&bookseller_filter=[% bookseller_filter | uri %]&branch_filter=[% branch_filter | uri %]" >+ id="reopensub" >+ > >+ <i class="fa-solid fa-arrow-rotate-right"></i> Reopen</a >+ > >+ </li> >+ [% END %] >+ [% END # IF ( routing && CAN_user_serials_routing ) %] > > <li> > <a class="dropdown-item" href="/cgi-bin/koha/serials/serials-collection.pl?subscriptionid=[% subscription.subscriptionid | uri %]"><i class="fa-solid fa-rectangle-list"></i> Issue history</a> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/batch_extend_due_dates.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/batch_extend_due_dates.tt >index 26787e4662..e975b76132 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/batch_extend_due_dates.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/batch_extend_due_dates.tt >@@ -272,7 +272,6 @@ > dom: "t", > order: [], > paging: false, >- pageLength: -1, > }); > > $("#extend_due_dates_form").on("submit", function (e) { >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/stage-marc-import.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/stage-marc-import.tt >index e42fde81c6..d5ff4771b5 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/stage-marc-import.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/stage-marc-import.tt >@@ -471,7 +471,7 @@ > $('#fileuploadbutton').show(); > $("#fileuploadcancel").hide(); > var filename=$('#fileToUpload').prop('files')[0].name; >- if( filename.match( new RegExp(/[^.]+\.xml$/) ) ) { >+ if( filename.match( new RegExp(/\.[^.]+xml$/) ) ) { > $('#format').val('MARCXML'); > } > $("#processfile").show(); >diff --git a/koha-tmpl/intranet-tmpl/prog/js/fetch/http-client.js b/koha-tmpl/intranet-tmpl/prog/js/fetch/http-client.js >index 93194a164b..50dc09f6ca 100644 >--- a/koha-tmpl/intranet-tmpl/prog/js/fetch/http-client.js >+++ b/koha-tmpl/intranet-tmpl/prog/js/fetch/http-client.js >@@ -1,31 +1,16 @@ >-function _ifDocumentAvailable(callback) { >- if (typeof document !== "undefined" && document.getElementById) { >- callback(); >- } >-} >- > class Dialog { > constructor(options = {}) {} > >- _appendMessage(type, message) { >- _ifDocumentAvailable(() => { >- const messagesContainer = document.getElementById("messages"); >- if (!messagesContainer) { >- return; >- } >- >- const htmlString = >- `<div class="alert alert-${type}">%s</div>`.format(message); >- messagesContainer.insertAdjacentHTML("beforeend", htmlString); >- }); >- } >- > setMessage(message) { >- this._appendMessage("info", message); >+ $("#messages").append( >+ '<div class="alert alert-info">%s</div>'.format(message) >+ ); > } > > setError(error) { >- this._appendMessage("warning", error); >+ $("#messages").append( >+ '<div class="alert alert-warning">%s</div>'.format(error) >+ ); > } > } > >@@ -37,18 +22,7 @@ class HttpClient { > "Content-Type": "application/json;charset=utf-8", > "X-Requested-With": "XMLHttpRequest", > }; >- this.csrf_token = this._getCsrfToken(options); >- } >- >- _getCsrfToken(options) { >- let token = null; >- _ifDocumentAvailable(() => { >- const metaTag = document.querySelector('meta[name="csrf-token"]'); >- if (metaTag) { >- token = metaTag.getAttribute("content"); >- } >- }); >- return token !== null ? token : options.csrfToken || null; >+ this.csrf_token = $('meta[name="csrf-token"]').attr("content"); > } > > async _fetchJSON( >diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/includes/calendar.inc b/koha-tmpl/opac-tmpl/bootstrap/en/includes/calendar.inc >index 240fa9953c..54e0e1fde9 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/en/includes/calendar.inc >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/includes/calendar.inc >@@ -96,7 +96,7 @@ > instance.clear(); > }) > .addClass("fa fa-fw fa-times") >- .attr("aria-hidden", false) >+ .attr("aria-hidden", true) > .attr("aria-label", _("Clear date")) > ) > .keydown(function (e) { >diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/includes/masthead.inc b/koha-tmpl/opac-tmpl/bootstrap/en/includes/masthead.inc >index 0a658a05e3..294963397c 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/en/includes/masthead.inc >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/includes/masthead.inc >@@ -312,7 +312,6 @@ > > [% IF ( Koha.Preference( 'OpacAddMastheadLibraryPulldown' ) == 1 && AllPublicBranches.size > 1 ) %] > <div class="col-sm col-md-3 col-lg-2 order-3 order-sm-4"> >- <label for="select_library" class="visually-hidden">Search the catalog in:</label> > <select name="limit" id="select_library" class="form-select"> > <option value="">All libraries</option> > >diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/includes/opac-bottom.inc b/koha-tmpl/opac-tmpl/bootstrap/en/includes/opac-bottom.inc >index 825846e29a..065c89c471 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/en/includes/opac-bottom.inc >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/includes/opac-bottom.inc >@@ -22,7 +22,7 @@ > </div> <!-- / #wrapper in masthead.inc --> > <!-- prettier-ignore-end --> > >- [% IF ( Koha.Preference('OPACReportProblem') && Koha.Preference('KohaAdminEmailAddress') ) || Koha.Preference( 'CookieConsent' ) || OpacKohaUrl || ( ( opaclanguagesdisplay ) && ( ! one_language_enabled ) && ( languages_loop ) && ( OpacLangSelectorMode == 'both' || OpacLangSelectorMode == 'footer') ) %] >+ [% IF ( Koha.Preference('OPACReportProblem') && Koha.Preference('KohaAdminEmailAddress') ) || Koha.Preference( 'CookieConsent' ) || OpacKohaUrl || ( ( OpacLangSelectorMode == 'both' || OpacLangSelectorMode == 'footer') ) %] > <footer id="changelanguage" class="navbar navbar-expand navbar-light bg-light noprint"> > <div class="container-fluid"> > <div class="collapse navbar-collapse"> >@@ -49,7 +49,7 @@ > </div> > [% IF OpacKohaUrl %] > <div class="navbar-nav"> >- <a id="koha_url" class="nav-link koha_url" href="https://koha-community.org"> >+ <a id="koha_url" class="nav-link koha_url" href="http://koha-community.org"> > <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"> > <path > fill="currentColor" >diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/includes/subtypes_unimarc.inc b/koha-tmpl/opac-tmpl/bootstrap/en/includes/subtypes_unimarc.inc >index e004474b10..93c52185e9 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/en/includes/subtypes_unimarc.inc >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/includes/subtypes_unimarc.inc >@@ -1,8 +1,8 @@ > <fieldset> > <legend>Coded fields</legend> > <p> >- <label for="audience">Audience</label> >- <select id="audience" name="limit" class="subtype"> >+ <label>Audience</label> >+ <select name="limit" class="subtype"> > <option value="" selected="selected">Any</option> > <option value="aud:a">juvenile, general</option> > <option value="aud:b">pre-primary (0-5)</option> >@@ -15,8 +15,8 @@ > </select> > </p> > <p> >- <label for="physical_presentation">Physical presentation</label> >- <select id="physical_presentation" name="limit" class="subtype"> >+ <label>Physical presentation</label> >+ <select name="limit" class="subtype"> > <option value="" selected="selected">Any</option> > <option value="Material-type:r">regular print</option> > <option value="Material-type:d">large print</option> >@@ -32,8 +32,8 @@ > </select> > </p> > <p> >- <label for="literary_genre">Literary genre</label> >- <select id="literary_genre" name="limit" class="subtype"> >+ <label>Literary genre</label> >+ <select name="limit" class="subtype"> > <option value="" selected="selected">Any</option> > <option value="Literature-Code:a">fiction</option> > <option value="Literature-Code:b">drama</option> >@@ -49,8 +49,8 @@ > </select> > </p> > <p> >- <label for="biography">Biography </label> >- <select id="biography" name="limit" class="subtype"> >+ <label>Biography</label> >+ <select name="limit" class="subtype"> > <option value="">Any</option> > <option value="Biography-code:y">not a biography</option> > <option value="Biography-code:a">autobiography</option> >@@ -60,8 +60,8 @@ > </select> > </p> > <p> >- <label for="illustration">Illustration</label> >- <select id="illustration" name="limit" class="subtype"> >+ <label>Illustration</label> >+ <select name="limit" class="subtype"> > <option value="">Any</option> > <option value="Illustration-Code:a">illustrations</option> > <option value="Illustration-Code:b">maps</option> >@@ -82,8 +82,8 @@ > </select> > </p> > <p> >- <label for="content">Content</label> >- <select id="content" name="limit" class="subtype"> >+ <label>Content</label> >+ <select name="limit" class="subtype"> > <option value="">Any</option> > <option value="ctype:a">bibliography</option> > <option value="ctype:b">catalogue</option> >@@ -111,8 +111,8 @@ > </select> > </p> > <p> >- <label for="video_types">Video types </label> >- <select id="video_types" name="limit" class="subtype"> >+ <label>Video types</label> >+ <select name="limit" class="subtype"> > <option value="">Any</option> > <option value="Video-mt:a">motion picture</option> > <option value="Video-mt:b">visual projection</option> >@@ -124,8 +124,8 @@ > <fieldset> > <legend>Serials</legend> > <p> >- <label for="serial_type">Serial type </label> >- <select id="serial_type" name="limit" class="subtype"> >+ <label>Serial type</label> >+ <select name="limit" class="subtype"> > <option value="">Any type</option> > <option value="Type-Of-Serial:a">Periodical</option> > <option value="Type-Of-Serial:b">Monographic series</option> >@@ -137,8 +137,8 @@ > </select> > </p> > <p> >- <label for="periodicity">Periodicity</label> >- <select id="periodicity" name="limit" class="subtype"> >+ <label>Periodicity</label> >+ <select name="limit" class="subtype"> > <option value="">Any</option> > <option value="Frequency-code:a">Daily</option> > <option value="Frequency-code:b">Semiweekly</option> >@@ -161,8 +161,8 @@ > </select> > </p> > <p> >- <label for="regularity">Regularity </label> >- <select id="regularity" name="limit" class="subtype"> >+ <label>Regularity</label> >+ <select name="limit" class="subtype"> > <option value="">Any regularity</option> > <option value="Regularity-code:a">regular</option> > <option value="Regularity-code:b">normalised irregular</option> >@@ -174,8 +174,7 @@ > > <fieldset> > <legend>Picture</legend> >- <label for="graphics-type" class="sr-only">Graphics type</label> >- <select id="graphics-type" name="limit" class="subtype"> >+ <select name="limit" class="subtype"> > <option value="">Any</option> > <option value="Graphics-type:a">collage</option> > <option value="Graphics-type:b">drawing</option> >@@ -188,8 +187,7 @@ > <option value="Graphics-type:k">technical drawing</option> > <option value="Graphics-type:z">other non-projected graphic type</option> > </select> >- <label for="graphics-support" class="sr-only">Graphics support</label> >- <select id="graphics-support" name="limit" class="subtype"> >+ <select name="limit" class="subtype"> > <option value="">Any</option> > <option value="Graphics-support:a">canvas</option> > <option value="Graphics-support:b">bristol board</option> >diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-addbybiblionumber.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-addbybiblionumber.tt >index cd0ff5f477..f0423f228d 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-addbybiblionumber.tt >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-addbybiblionumber.tt >@@ -98,7 +98,7 @@ > <legend>Add to a new list:</legend> > <label for="newvirtualshelf">List name:</label> > <input type="text" name="newvirtualshelf" id="newvirtualshelf" size="40" /> >- <label for="public">Category:</label> >+ <label for="category">Category:</label> > <select name="public" id="public"> > <option value="0">Private</option> > [% IF (OpacAllowPublicListCreation) %] >diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-browser.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-browser.tt >index a7ecba7be2..f6e6e546ac 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-browser.tt >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-browser.tt >@@ -85,7 +85,7 @@ > <!-- prettier-ignore-end --> > [% ELSE %] > <div class="warning" >- >The browser table is empty. this feature is not fully set-up. See the <a href="https://wiki.koha-community.org/wiki/Opac_browse_feature">Koha Wiki</a> for more information on what it does and how to configure >+ >The browser table is empty. this feature is not fully set-up. See the <a href="http://wiki.koha-community.org/wiki/Opac_browse_feature">Koha Wiki</a> for more information on what it does and how to configure > it.</div > > > [% END # / IF have_hierarchy %] >diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-illrequests.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-illrequests.tt >index 109e0cb480..d72022a045 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-illrequests.tt >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-illrequests.tt >@@ -207,7 +207,7 @@ > <li> > <label for="notesopac">Notes:</label> > [% IF !request.completed %] >- <textarea id="notesopac" name="notesopac" rows="5" cols="50">[% request.notesopac | html %]</textarea> >+ <textarea name="notesopac" rows="5" cols="50">[% request.notesopac | html %]</textarea> > [% ELSE %] > [% request.notesopac | html %] > [% END %] >diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-patron-consent.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-patron-consent.tt >index 7fbad0355a..41e844034a 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-patron-consent.tt >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-patron-consent.tt >@@ -57,14 +57,14 @@ > [% END %] > <fieldset> > [% IF consent.given_on %] >- <label><input type="radio" name="check_[% consent_type | html %]" value="1" checked="checked" /> Yes</label><br /> >- <label><input type="radio" name="check_[% consent_type | html %]" value="0" /> No</label> >+ <input type="radio" name="check_[% consent_type | html %]" value="1" checked="checked" /> Yes<br /> >+ <input type="radio" name="check_[% consent_type | html %]" value="0" /> No > [% ELSIF consent.refused_on %] >- <label> <input type="radio" name="check_[% consent_type | html %]" value="1" /> Yes</label><br /> >- <label><input type="radio" name="check_[% consent_type | html %]" value="0" checked="checked" /> No </label> >+ <input type="radio" name="check_[% consent_type | html %]" value="1" /> Yes<br /> >+ <input type="radio" name="check_[% consent_type | html %]" value="0" checked="checked" /> No > [% ELSE %] >- <label><input type="radio" name="check_[% consent_type | html %]" value="1" /> Yes</label><br /> >- <label><input type="radio" name="check_[% consent_type | html %]" value="0" /> No</label> >+ <input type="radio" name="check_[% consent_type | html %]" value="1" /> Yes<br /> >+ <input type="radio" name="check_[% consent_type | html %]" value="0" /> No > [% END %] > [% IF consent.given_on %] > <p class="consent_info"><strong>Your consent was registered on [% consent.given_on | html %].</strong></p> >diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-suggestions.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-suggestions.tt >index bd8775cf11..1110e7e77e 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-suggestions.tt >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-suggestions.tt >@@ -449,7 +449,7 @@ > [% END %] > <td> > <p> >- <label for="id[% suggestion.suggestionid | html %]"> >+ <label for="id[% suggestions_loo.suggestionid | html %]"> > [% IF suggestion.biblionumber %] > <strong><a href="/cgi-bin/koha/opac-detail.pl?biblionumber=[% suggestion.biblionumber | uri %]">[% suggestion.title | html %]</a></strong> > [% ELSE %] >diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-tags.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-tags.tt >index 9acf783097..961e63c745 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-tags.tt >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-tags.tt >@@ -109,7 +109,7 @@ > > <form method="get" action="opac-tags.pl" class="row"> > <div class="col-auto gx-2 ms-2 my-1"> >- <label for="limit-tag"> >+ <label> > [% IF Koha.Preference( 'opacuserlogin' ) == 1 %] > <span>Tags to show from other users:</span> > [% ELSE %] >@@ -118,7 +118,7 @@ > </label> > </div> > <div class="col-auto gx-2 my-1"> >- <input id="limit-tag" type="text" name="limit" class="form-control form-control-sm" maxlength="4" size="4" value="[% limit or '100' | html %]" /> >+ <input type="text" name="limit" class="form-control form-control-sm" maxlength="4" size="4" value="[% limit or '100' | html %]" /> > </div> > <div class="col-auto gx-2 my-1"> > <input type="submit" value="OK" class="btn btn-sm btn-primary" /> >@@ -185,7 +185,7 @@ > data-title="[% MY_TAG.title | html %]" > data-tagname="[% MY_TAG.term | html %]" > data-tagid="[% MY_TAG.tag_id | html %]" >- aria-label="[% MY_TAG.term | html %]" >+ aria-label="[% check_title | html %]" > /> > </td> > <td class="tagterm"> >diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-tags_subject.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-tags_subject.tt >index b543fcb7e5..5aa3710bc2 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-tags_subject.tt >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-tags_subject.tt >@@ -38,7 +38,7 @@ > <fieldset> > <legend>Show</legend> > <form class="form-inline" action="/cgi-bin/koha/opac-tags_subject.pl" method="get"> >- <label>up to <input type="text" name="number" value="[% number | html %]" size="4" maxlength="4" /> </label> <label>subjects <input type="submit" class="btn btn-primary" value="OK" /></label> >+ <p>up to <input type="text" name="number" value="[% number | html %]" size="4" maxlength="4" /> subjects <input type="submit" class="btn btn-primary" value="OK" /></p> > </form> > </fieldset> > >diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/sci/sci-main.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/sci/sci-main.tt >index 098313f040..1f9664fc3d 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/sci/sci-main.tt >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/sci/sci-main.tt >@@ -189,7 +189,7 @@ > </main> > <!-- / .main --> > >-[%# Help modal %] >+[% # Help modal %] > <div id="helpModal" class="modal" tabindex="-1" role="dialog" aria-labelledby="helpModalLabel" aria-hidden="true"> > <div class="modal-dialog"> > <div class="modal-content"> >@@ -222,6 +222,7 @@ > > [% INCLUDE 'opac-bottom.inc' %] > [% BLOCK jsinclude %] >+ [% Asset.js('js/timeout.js') | $raw %] > <script> > function mungeHistory() { > // prevent back button from allowing form resubmission >@@ -272,6 +273,7 @@ > $("#sci_barcodes_table").show(); > $('#sci_checkin_button').show(); > $('#sci_refresh_button').show(); >+ login_timeout(); > > // Add barcode to the array > barcodes.push(barcode); >@@ -291,31 +293,24 @@ > dofocus(); > }); > >- >- var idleTime = 0; >- $(document).ready(function () { >- //Increment the idle time counter every second >- var idleInterval = setInterval(timerIncrement, 1000); >- >- //Zero the idle timer on mouse movement. >- $(this).mousemove(function (e) { >- idleTime = 0; >- }); >- $(this).keypress(function (e) { >- idleTime = 0; >+ document.addEventListener("DOMContentLoaded",function(){ >+ if ( document.querySelector('#sci_finish_button,#sci_append_button') ){ >+ login_timeout(); >+ } >+ }); >+ function login_timeout(){ >+ //NOTE: There can only be 1 sci_login_timer at a time >+ if ( ! window.sci_login_timer ){ >+ const idleTimeout = "[% Koha.Preference('SelfCheckInTimeOut') || 120 | html %]"; >+ const home_href = "/cgi-bin/koha/sci/sci-main.pl"; >+ const sci_timer = new sc_timer({ >+ "idle_timeout": idleTimeout, >+ "redirect_url": home_href > }); >- }); >- >- function timerIncrement() { >- if ( $("#sci_finish_button").is(":visible") || $("#sci_refresh_button").is(":visible") ) { >- idleTime = idleTime + 1; >- idleTimeout = [% refresh_timeout | html %]; >- if (idleTime >= idleTimeout ) { >- location.href = '/cgi-bin/koha/sci/sci-main.pl'; >- } >- } >+ window.sci_login_timer = sci_timer; >+ sci_timer.start_timer(); > } >- >+ } > > function checkBarcodeInput() { > var inputField = document.getElementById("barcode_input"); >diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/sco/sco-main.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/sco/sco-main.tt >index 2e8d7b46c4..52227a6b42 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/sco/sco-main.tt >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/sco/sco-main.tt >@@ -55,6 +55,7 @@ > [% END %] > [% Asset.js('js/Gettext.js') | $raw %] > [% Asset.js('js/i18n.js') | $raw %] >+[% Asset.js('js/timeout.js') | $raw %] > </head> > <body id="sco_main" class="sco"> > <div id="wrapper"> >@@ -338,7 +339,7 @@ > <input type="password" id="patronpw" class="form-control" size="20" name="patronpw" autocomplete="off" /> > </div> > <div class="col-md-12"> >- <button type="submit" class="btn btn-primary">Log in</button> >+ <button id="sco_patron_login" type="submit" class="btn btn-primary">Log in</button> > </div> > </div> > <!-- /.row --> >@@ -351,7 +352,7 @@ > <input type="text" id="patronid" class="form-control focus" size="20" name="patronid" autocomplete="off" /> > </div> > <div class="col-md-12"> >- <button type="submit" class="btn btn-primary">Submit</button> >+ <button id="sco_patron_login" type="submit" class="btn btn-primary">Submit</button> > </div> > </div> > <!-- /.row --> >@@ -411,11 +412,23 @@ > history.replaceState(null, document.title, window.location.href); > } > } >- var mainTimeout; >- function sco_init() { >- mainTimeout = setTimeout(function() { >- location.href = '/cgi-bin/koha/sco/sco-main.pl?op=logout'; >- }, [% SelfCheckTimeout | html %]); >+ document.addEventListener("DOMContentLoaded",function(){ >+ if ( document.querySelector('#sco_patron_login,#logout_form') ){ >+ login_timeout(); >+ } >+ }); >+ function login_timeout(){ >+ //NOTE: There can only be 1 sco_login_timer at a time >+ if ( ! window.sco_login_timer ){ >+ const idleTimeout = "[% Koha.Preference('SelfCheckTimeout') || 120 | html %]"; >+ const home_href = "/cgi-bin/koha/sco/sco-main.pl?op=logout"; >+ const sco_timer = new sc_timer({ >+ "idle_timeout": idleTimeout, >+ "redirect_url": home_href >+ }); >+ window.sco_login_timer = sco_timer; >+ sco_timer.start_timer(); >+ } > } > function dofocus() { // named function req'd for body onload event by some FF and IE7 security models > // alert("dofocus called"); >@@ -468,7 +481,6 @@ > > $(document).ready(function() { > dofocus(); >- [% IF ( patronid ) %]sco_init();[% END %] > > var dTables = $("#loanTable, #holdst, #finestable"); > dTables.each(function(){ >@@ -500,7 +512,6 @@ > > $("#logout_form").on("click", function(e){ > e.preventDefault(e); >- clearTimeout(mainTimeout); > [% IF Koha.Preference('SelfCheckReceiptPrompt') %] > confirmModal("", _("Would you like to print a receipt?"), _("Print receipt and end session"), _("End session"), function(result) { > if ( result ){ >diff --git a/koha-tmpl/opac-tmpl/bootstrap/js/timeout.js b/koha-tmpl/opac-tmpl/bootstrap/js/timeout.js >new file mode 100644 >index 0000000000..6c508d14c0 >--- /dev/null >+++ b/koha-tmpl/opac-tmpl/bootstrap/js/timeout.js >@@ -0,0 +1,39 @@ >+class sc_timer { >+ constructor(args) { >+ const idle_timeout = args["idle_timeout"]; >+ const redirect_url = args["redirect_url"]; >+ if (idle_timeout) { >+ this.idle_timeout = idle_timeout; >+ } >+ if (redirect_url) { >+ this.redirect_url = redirect_url; >+ } >+ this.idle_time = 0; >+ } >+ >+ start_timer() { >+ const self = this; >+ //Increment the idle time counter every 1 second >+ const idle_interval = setInterval(function () { >+ self._timer_increment(); >+ }, 1000); >+ >+ document.addEventListener("mousemove", function () { >+ self.reset_timer(); >+ }); >+ document.addEventListener("keypress", function () { >+ self.reset_timer(); >+ }); >+ } >+ >+ reset_timer() { >+ this.idle_time = 0; >+ } >+ >+ _timer_increment() { >+ this.idle_time++; >+ if (this.idle_time >= this.idle_timeout) { >+ location.href = this.redirect_url; >+ } >+ } >+} >diff --git a/members/memberentry.pl b/members/memberentry.pl >index 6b39df2996..59bffba29e 100755 >--- a/members/memberentry.pl >+++ b/members/memberentry.pl >@@ -560,9 +560,6 @@ if ( ( !$nok ) and $nodouble and ( $op eq 'cud-insert' or $op eq 'cud-save' ) ) > > delete $newdata{password2}; > >- delete $newdata{guarantor_id}; >- delete $newdata{guarantor_relationship}; >- > try { > $patron->set( \%newdata )->store( { guarantors => \@guarantors } ) if scalar( keys %newdata ) > 1; > >diff --git a/misc/devel/Koha/Schema/Result/ReportsBranch.pm b/misc/devel/Koha/Schema/Result/ReportsBranch.pm >new file mode 100644 >index 0000000000..970c25eabc >--- /dev/null >+++ b/misc/devel/Koha/Schema/Result/ReportsBranch.pm >@@ -0,0 +1,85 @@ >+use utf8; >+ >+package Koha::Schema::Result::ReportsBranch; >+ >+# Created by DBIx::Class::Schema::Loader >+# DO NOT MODIFY THE FIRST PART OF THIS FILE >+ >+=head1 NAME >+ >+Koha::Schema::Result::ReportsBranch >+ >+=cut >+ >+use strict; >+use warnings; >+ >+use base 'DBIx::Class::Core'; >+ >+=head1 TABLE: C<reports_branches> >+ >+=cut >+ >+__PACKAGE__->table("reports_branches"); >+ >+=head1 ACCESSORS >+ >+=head2 report_id >+ >+ data_type: 'integer' >+ is_foreign_key: 1 >+ is_nullable: 0 >+ >+=head2 branchcode >+ >+ data_type: 'varchar' >+ is_foreign_key: 1 >+ is_nullable: 0 >+ size: 10 >+ >+=cut >+ >+__PACKAGE__->add_columns( >+ "report_id", >+ { data_type => "integer", is_foreign_key => 1, is_nullable => 0 }, >+ "branchcode", >+ { data_type => "varchar", is_foreign_key => 1, is_nullable => 0, size => 10 }, >+); >+ >+=head1 RELATIONS >+ >+=head2 branchcode >+ >+Type: belongs_to >+ >+Related object: L<Koha::Schema::Result::Branch> >+ >+=cut >+ >+__PACKAGE__->belongs_to( >+ "branchcode", >+ "Koha::Schema::Result::Branch", >+ { branchcode => "branchcode" }, >+ { is_deferrable => 1, on_delete => "CASCADE", on_update => "RESTRICT" }, >+); >+ >+=head2 report >+ >+Type: belongs_to >+ >+Related object: L<Koha::Schema::Result::SavedSql> >+ >+=cut >+ >+__PACKAGE__->belongs_to( >+ "report", >+ "Koha::Schema::Result::SavedSql", >+ { id => "report_id" }, >+ { is_deferrable => 1, on_delete => "CASCADE", on_update => "RESTRICT" }, >+); >+ >+# Created by DBIx::Class::Schema::Loader v0.07051 @ 2025-07-06 17:02:11 >+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:SJqUxMgLJHAjbX3GJlpB+A >+ >+# You can replace this text with custom code or comments, and it will be preserved on regeneration >+1; >diff --git a/misc/devel/tidy.pl b/misc/devel/tidy.pl >index f8829044ee..2ab5c20c33 100755 >--- a/misc/devel/tidy.pl >+++ b/misc/devel/tidy.pl >@@ -8,8 +8,6 @@ use File::Slurp qw( read_file write_file ); > use IPC::Cmd qw( run ); > use Parallel::ForkManager; > >-use Koha::Devel::Files; >- > my ( $perl_files, $js_files, $tt_files, $nproc, $no_write, $silent, $help ); > > our $perltidyrc = '.perltidyrc'; >@@ -36,7 +34,13 @@ pod2usage("--no-write can only be passed with a single file") if $no_write && @f > pod2usage("--perl, --js and --tt can only be passed without any other files in parameter") > if @files && ( $perl_files || $js_files || $tt_files ); > >-my $dev_files = Koha::Devel::Files->new( { context => 'tidy' } ); >+my $exceptions = { >+ pl => [qw(Koha/Schema/Result Koha/Schema.pm)], >+ js => [ >+ qw(koha-tmpl/intranet-tmpl/lib koha-tmpl/intranet-tmpl/js/Gettext.js koha-tmpl/opac-tmpl/lib Koha/ILL/Backend/) >+ ], >+ tt => [qw(Koha/ILL/Backend/ *doc-head-open.inc misc/cronjobs/rss)], >+}; > > my @original_files = @files; > if (@files) { >@@ -44,8 +48,8 @@ if (@files) { > # This is inefficient if the list of files is long but most of the time we will have only one > @files = map { > my $file = $_; >- my $filetype = $dev_files->get_filetype($file); >- my $cmd = sprintf q{git ls-files %s | grep %s}, $dev_files->build_git_exclude($filetype), $file; >+ my $filetype = get_filetype($file); >+ my $cmd = sprintf q{git ls-files %s | grep %s}, build_git_exclude($filetype), $file; > my $output = qx{$cmd}; > chomp $output; > $output ? $file : (); >@@ -65,14 +69,14 @@ if (@files) { > } > } > } else { >- push @files, $dev_files->ls_perl_files() if $perl_files; >- push @files, $dev_files->ls_js_files() if $js_files; >- push @files, $dev_files->ls_tt_files() if $tt_files; >+ push @files, get_perl_files() if $perl_files; >+ push @files, get_js_files() if $js_files; >+ push @files, get_tt_files() if $tt_files; > > unless (@files) { >- push @files, $dev_files->ls_perl_files(); >- push @files, $dev_files->ls_js_files(); >- push @files, $dev_files->ls_tt_files(); >+ push @files, get_perl_files(); >+ push @files, get_js_files(); >+ push @files, get_tt_files(); > } > } > >@@ -120,7 +124,7 @@ if (@errors) { > sub tidy { > my ($file) = @_; > >- my $filetype = $dev_files->get_filetype($file); >+ my $filetype = get_filetype($file); > > if ( $filetype eq 'pl' ) { > return tidy_perl($file); >@@ -133,6 +137,32 @@ sub tidy { > } > } > >+sub build_git_exclude { >+ my ($filetype) = @_; >+ return join( " ", map( "':(exclude)$_'", @{ $exceptions->{$filetype} } ) ); >+} >+ >+sub get_perl_files { >+ my $cmd = sprintf q{git ls-files '*.pl' '*.PL' '*.pm' '*.t' svc opac/svc %s}, build_git_exclude('pl'); >+ my @files = qx{$cmd}; >+ chomp for @files; >+ return @files; >+} >+ >+sub get_js_files { >+ my $cmd = sprintf q{git ls-files '*.js' '*.ts' '*.vue' %s}, build_git_exclude('js'); >+ my @files = qx{$cmd}; >+ chomp for @files; >+ return @files; >+} >+ >+sub get_tt_files { >+ my $cmd = sprintf q{git ls-files '*.tt' '*.inc' %s}, build_git_exclude('tt'); >+ my @files = qx{$cmd}; >+ chomp for @files; >+ return @files; >+} >+ > sub tidy_perl { > my ($file) = @_; > my $cmd = >@@ -191,6 +221,19 @@ sub tidy_tt { > return ( $success, $error_message, $full_buf, $stdout_buf, $stderr_buf ); > } > >+sub get_filetype { >+ my ($file) = @_; >+ return 'pl' if $file =~ m{^svc} || $file =~ m{^opac/svc}; >+ return 'pl' if $file =~ m{\.pl$} || $file =~ m{\.pm} || $file =~ m{\.t$}; >+ return 'pl' if $file =~ m{\.PL$}; >+ >+ return 'js' if $file =~ m{\.js$} || $file =~ m{\.ts$} || $file =~ m{\.vue$}; >+ >+ return 'tt' if $file =~ m{\.inc$} || $file =~ m{\.tt$}; >+ >+ die sprintf 'Cannot guess filetype for %s', $file; >+} >+ > sub l { > say shift unless $silent; > } >diff --git a/opac/opac-readingrecord.pl b/opac/opac-readingrecord.pl >index ffd830711c..4fe1622bc1 100755 >--- a/opac/opac-readingrecord.pl >+++ b/opac/opac-readingrecord.pl >@@ -57,7 +57,7 @@ if ( $order eq 'title' ) { > } elsif ( $order eq 'author' ) { > $template->param( orderbyauthor => 1 ); > } else { >- $order = { -desc => "date_due" }; >+ $order = "date_due desc"; > $template->param( orderbydate => 1 ); > } > >@@ -66,23 +66,23 @@ $limit //= ''; > $limit = ( $limit eq 'full' ) ? 0 : 50; > > my $checkouts = [ >- $patron->checkouts->search( >+ $patron->checkouts( > {}, > { > order_by => $order, > prefetch => { item => { biblio => 'biblioitems' } }, >- ( $limit ? ( rows => $limit ) : () ), >+ ( $limit ? ( limit => $limit ) : () ), > } > )->as_list > ]; > $limit -= scalar(@$checkouts) if $limit; > my $old_checkouts = [ >- $patron->old_checkouts->search( >+ $patron->old_checkouts( > {}, > { > order_by => $order, > prefetch => { item => { biblio => 'biblioitems' } }, >- ( $limit ? ( rows => $limit ) : () ), >+ ( $limit ? ( limit => $limit ) : () ), > } > )->as_list > ]; >diff --git a/opac/sci/sci-main.pl b/opac/sci/sci-main.pl >index 34d433a53f..d254347b5b 100755 >--- a/opac/sci/sci-main.pl >+++ b/opac/sci/sci-main.pl >@@ -102,8 +102,4 @@ if ( $op eq 'cud-check_in' ) { > $template->param( success => \@success, errors => \@errors, checkins => 1 ); > } > >-# Make sure timeout has a reasonable value >-my $timeout = C4::Context->preference('SelfCheckInTimeout') || 120; >-$template->param( refresh_timeout => $timeout ); >- > output_html_with_http_headers $cgi, $cookie, $template->output, undef, { force_no_caching => 1 }; >diff --git a/opac/sco/sco-main.pl b/opac/sco/sco-main.pl >index 9ecae7c76c..e1cc93d802 100755 >--- a/opac/sco/sco-main.pl >+++ b/opac/sco/sco-main.pl >@@ -74,13 +74,6 @@ my ( $template, $loggedinuser, $cookie ) = get_template_and_user( > } > ); > >-# Get the self checkout timeout preference, or use 120 seconds as a default >-my $selfchecktimeout = 120000; >-if ( C4::Context->preference('SelfCheckTimeout') ) { >- $selfchecktimeout = C4::Context->preference('SelfCheckTimeout') * 1000; >-} >-$template->param( SelfCheckTimeout => $selfchecktimeout ); >- > # Checks policy laid out by SCOAllowCheckin, defaults to 'on' if preference is undefined > my $allowselfcheckreturns = 1; > if ( defined C4::Context->preference('SCOAllowCheckin') ) { >diff --git a/package.json b/package.json >index 66748e8699..d16166e856 100644 >--- a/package.json >+++ b/package.json >@@ -19,6 +19,7 @@ > "bootstrap": "^5.3.3", > "css-loader": "^6.6.0", > "cypress": "^12.17.2", >+ "cypress-mysql": "^1.0.0", > "datatables.net-buttons": "^2.3.4", > "datatables.net-vue3": "^2.0.0", > "gulp": "^4.0.2", >@@ -81,7 +82,6 @@ > "globals": "^16.0.0", > "gulp-tap": "^1.0.1", > "html-webpack-plugin": "^5.5.0", >- "mysql2": "^3.14.1", > "node-sass-tilde-importer": "^1.0.2", > "postcss": "^8.4.14", > "postcss-selector-parser": "^6.0.10", >diff --git a/reports/guided_reports.pl b/reports/guided_reports.pl >index fe47501ee7..74e495245d 100755 >--- a/reports/guided_reports.pl >+++ b/reports/guided_reports.pl >@@ -42,6 +42,7 @@ use Koha::Notice::Templates; > use Koha::TemplateUtils qw( process_tt ); > use C4::ClassSource qw( GetClassSources ); > use C4::Scrubber; >+use Data::Dumper; > > =head1 NAME > >@@ -57,6 +58,9 @@ my $input = CGI->new; > my $usecache = Koha::Caches->get_instance->memcached_cache; > > my $op = $input->param('op') // ''; >+print STDERR "DEBUG op: $op\n"; >+ >+# my @branches = grep { $_ ne q{} } $input->multi_param('branches'); > my $flagsrequired; > if ( ( $op eq 'add_form' ) > || ( $op eq 'add_form_sql' ) >@@ -127,7 +131,7 @@ if ( !$op ) { > 'showsql' => 1, > 'mana_success' => scalar $input->param('mana_success'), > 'mana_id' => $report->{mana_id}, >- 'mana_comments' => $report->{comments} >+ 'mana_comments' => $report->{comments}, > ); > > } elsif ( $op eq 'edit_form' ) { >@@ -136,6 +140,7 @@ if ( !$op ) { > my $group = $report->report_group; > my $subgroup = $report->report_subgroup; > my $tables = get_tables(); >+ > $template->param( > 'sql' => $report->savedsql, > 'reportname' => $report->report_name, >@@ -148,11 +153,13 @@ if ( !$op ) { > 'editsql' => 1, > 'mana_id' => $report->{mana_id}, > 'mana_comments' => $report->{comments}, >- 'tables' => $tables >+ 'tables' => $tables, >+ 'report' => $report, > ); > > } elsif ( $op eq 'cud-update_sql' || $op eq 'cud-update_and_run_sql' ) { > my $id = $input->param('id'); >+ my $report = Koha::Reports->find($id); > my $sql = $input->param('sql'); > my $reportname = $input->param('reportname'); > my $group = $input->param('group'); >@@ -163,9 +170,20 @@ if ( !$op ) { > my $public = $input->param('public'); > my $save_anyway = $input->param('save_anyway'); > my @errors; >- my $tables = get_tables(); >- >+ my $tables = get_tables(); >+ my @branches = grep { $_ ne q{} } $input->multi_param('branches'); >+ >+ # use Data::Dumper; >+ # warn Dumper(\@branches); >+ # warn "hey"; >+ # warn "DEBUG branches: " . Dumper(\@branches); >+ # print STDERR "DEBUG branches: " . join(", ", @branches); >+ # my $libraries = $report->get_library_limits; >+ # my $stuff = $libraries ? $libraries->as_list : []; >+ # print STDERR "DEBUG stuff: " . Dumper(@branches); > # if we have the units, then we came from creating a report from SQL and thus need to handle converting units >+ # $report->store; >+ # $report->replace_library_limits( \@branches ); > if ($cache_expiry_units) { > if ( $cache_expiry_units eq "minutes" ) { > $cache_expiry *= 60; >@@ -211,6 +229,8 @@ if ( !$op ) { > 'problematic_authvals' => $problematic_authvals, > 'warn_authval_problem' => 1, > 'phase_update' => 1, >+ 'branches' => @branches, >+ 'report' => $report, > ); > > } else { >@@ -226,9 +246,14 @@ if ( !$op ) { > notes => $notes, > public => $public, > cache_expiry => $cache_expiry, >+ >+ # report => $report, > } > ); > >+ $report->store; >+ $report->replace_library_limits( \@branches ); >+ > my $editsql = 1; > if ( $op eq 'cud-update_and_run_sql' ) { > $editsql = 0; >@@ -245,7 +270,10 @@ if ( !$op ) { > 'cache_expiry' => $cache_expiry, > 'public' => $public, > 'usecache' => $usecache, >- 'tables' => $tables >+ 'tables' => $tables, >+ >+ # 'branches' => @branches, >+ 'report' => $report, > ); > logaction( "REPORTS", "MODIFY", $id, "$reportname | $sql" ) if C4::Context->preference("ReportsLog"); > } >@@ -489,6 +517,7 @@ if ( !$op ) { > my $area = $input->param('area'); > my $sql = $input->param('sql'); > my $type = $input->param('type'); >+ > $template->param( > 'save' => 1, > 'area' => $area, >@@ -514,6 +543,7 @@ if ( !$op ) { > my $public = $input->param('public'); > my $save_anyway = $input->param('save_anyway'); > my $tables = get_tables(); >+ my @branches = grep { $_ ne q{} } $input->multi_param('branches'); > > # if we have the units, then we came from creating a report from SQL and thus need to handle converting units > if ($cache_expiry_units) { >@@ -591,6 +621,9 @@ if ( !$op ) { > public => $public, > } > ); >+ my $report = Koha::Reports->find($id); >+ $report->replace_library_limits( \@branches ); >+ > logaction( "REPORTS", "ADD", $id, "$name | $sql" ) if C4::Context->preference("ReportsLog"); > $template->param( > 'save_successful' => 1, >@@ -603,7 +636,8 @@ if ( !$op ) { > 'cache_expiry' => $cache_expiry, > 'public' => $public, > 'usecache' => $usecache, >- 'tables' => $tables >+ 'tables' => $tables, >+ 'report' => $report, > ); > } > } >@@ -746,20 +780,24 @@ if ( !$op ) { > > } elsif ( $op eq 'add_form_sql' || $op eq 'duplicate' ) { > >- my ( $group, $subgroup, $sql, $reportname, $notes ); >+ my ( $group, $subgroup, $sql, $reportname, $notes, @branches, $report ); > if ( $input->param('sql') ) { > $group = $input->param('report_group'); > $subgroup = $input->param('report_subgroup'); > $sql = $input->param('sql') // ''; > $reportname = $input->param('reportname') // ''; > $notes = $input->param('notes') // ''; >+ @branches = grep { $_ ne q{} } $input->multi_param('branches'); >+ > } elsif ( my $report_id = $input->param('id') ) { >- my $report = Koha::Reports->find($report_id); >+ $report = Koha::Reports->find($report_id); > $group = $report->report_group; > $subgroup = $report->report_subgroup; > $sql = $report->savedsql // ''; > $reportname = $report->report_name // ''; > $notes = $report->notes // ''; >+ @branches = grep { $_ ne q{} } $input->multi_param('branches'); >+ > } > > my $tables = get_tables(); >@@ -775,6 +813,9 @@ if ( !$op ) { > 'usecache' => $usecache, > 'tables' => $tables, > >+ # 'branches' => \@branches, >+ 'report' => $report, >+ > ); > } > >@@ -1081,24 +1122,51 @@ if ( $op eq 'list' || $op eq 'convert' ) { > my $subgroup = $input->param('subgroup'); > $filter->{group} = $group; > $filter->{subgroup} = $subgroup; >- my $reports = get_saved_reports($filter); >- my $has_obsolete_reports; >- for my $report (@$reports) { >- $report->{results} = C4::Reports::Guided::get_results( $report->{id} ); >- if ( $report->{savedsql} =~ m|biblioitems| and $report->{savedsql} =~ m|marcxml| ) { >- $report->{seems_obsolete} = 1; >- $has_obsolete_reports++; >+ >+ my $pref_enable_filtering_reports = C4::Context->preference("EnableFilteringReports"); >+ if ( $pref_enable_filtering_reports == "1" ) { >+ my $reports_with_library_limits_results = >+ Koha::Reports->search_with_library_limits( {}, {}, C4::Context::mybranch() ); >+ my $reports_list = $reports_with_library_limits_results->unblessed; >+ my $has_obsolete_reports; >+ while ( my $report = $reports_with_library_limits_results->next ) { >+ $report->{results} = C4::Reports::Guided::get_results( $report->{id} ); >+ if ( $report->{savedsql} =~ m|biblioitems| and $report->{savedsql} =~ m|marcxml| ) { >+ $report->{seems_obsolete} = 1; >+ $has_obsolete_reports++; >+ } >+ $template->param( >+ 'manamsg' => $input->param('manamsg') || '', >+ 'saved1' => 1, >+ 'savedreports' => $reports_list, >+ 'usecache' => $usecache, >+ 'groups_with_subgroups' => groups_with_subgroups( $group, $subgroup ), >+ filters => $filter, >+ has_obsolete_reports => $has_obsolete_reports, >+ ); > } >+ } else { >+ >+ my $reports = get_saved_reports($filter); >+ my $has_obsolete_reports; >+ >+ for my $report (@$reports) { >+ $report->{results} = C4::Reports::Guided::get_results( $report->{id} ); >+ if ( $report->{savedsql} =~ m|biblioitems| and $report->{savedsql} =~ m|marcxml| ) { >+ $report->{seems_obsolete} = 1; >+ $has_obsolete_reports++; >+ } >+ } >+ $template->param( >+ 'manamsg' => $input->param('manamsg') || '', >+ 'saved1' => 1, >+ 'savedreports' => $reports, >+ 'usecache' => $usecache, >+ 'groups_with_subgroups' => groups_with_subgroups( $group, $subgroup ), >+ filters => $filter, >+ has_obsolete_reports => $has_obsolete_reports, >+ ); > } >- $template->param( >- 'manamsg' => $input->param('manamsg') || '', >- 'saved1' => 1, >- 'savedreports' => $reports, >- 'usecache' => $usecache, >- 'groups_with_subgroups' => groups_with_subgroups( $group, $subgroup ), >- filters => $filter, >- has_obsolete_reports => $has_obsolete_reports, >- ); > } > > # pass $sth, get back an array of names for the column headers >diff --git a/reports/orders_by_fund.pl b/reports/orders_by_fund.pl >index 29cb175afe..dcf833758e 100755 >--- a/reports/orders_by_fund.pl >+++ b/reports/orders_by_fund.pl >@@ -1,22 +1,22 @@ > #!/usr/bin/perl > >-# Copyright Frédérick Capovilla, 2011 - SYS-TECH >-# Copyright Ãlyse Morin, 2012 - Libéo >-# > # This file is part of Koha. > # >-# Koha is free software; you can redistribute it and/or modify it >-# under the terms of the GNU General Public License as published by >-# the Free Software Foundation; either version 3 of the License, or >-# (at your option) any later version. >+# Author : Frédérick Capovilla, 2011 - SYS-TECH >+# Modified by : Ãlyse Morin, 2012 - Libéo >+# >+# Koha is free software; you can redistribute it and/or modify it under the >+# terms of the GNU General Public License as published by the Free Software >+# Foundation; either version 3 of the License, or (at your option) any later >+# version. > # >-# Koha is distributed in the hope that it will be useful, but >-# WITHOUT ANY WARRANTY; without even the implied warranty of >-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >-# GNU General Public License for more details. >+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY >+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR >+# A PARTICULAR PURPOSE. See the GNU General Public License for more details. > # >-# You should have received a copy of the GNU General Public License >-# along with Koha; if not, see <http://www.gnu.org/licenses>. >+# You should have received a copy of the GNU General Public License along with >+# Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place, >+# Suite 330, Boston, MA 02111-1307 USA > > =head1 orders_by_budget > >diff --git a/t/Koha/I18N.t b/t/Koha/I18N.t >index 55e1425680..45a34d3a0c 100755 >--- a/t/Koha/I18N.t >+++ b/t/Koha/I18N.t >@@ -2,7 +2,7 @@ > > use Modern::Perl; > use Test::NoWarnings; >-use Test::More tests => 37; >+use Test::More tests => 36; > use Test::MockModule; > use FindBin qw($Bin); > use Encode; >@@ -61,49 +61,3 @@ my @tests = ( > foreach my $test (@tests) { > is( $test->[0], decode_utf8( $test->[1] ), $test->[1] ); > } >- >-subtest 'available_locales' => sub { >- plan tests => 6; >- >- # Test basic functionality >- my $locales = Koha::I18N::available_locales(); >- >- # Should return an arrayref >- is( ref($locales), 'ARRAY', 'available_locales returns an arrayref' ); >- >- # Should have at least the default option >- ok( scalar(@$locales) >= 1, 'At least one locale returned (default)' ); >- >- # First locale should be default >- is( $locales->[0]->{value}, 'default', 'First locale is default' ); >- is( $locales->[0]->{text}, 'Default Unicode collation', 'Default locale has correct text' ); >- >- # All locales should have value and text keys >- my $all_have_keys = 1; >- for my $locale (@$locales) { >- unless ( exists $locale->{value} && exists $locale->{text} ) { >- $all_have_keys = 0; >- last; >- } >- } >- ok( $all_have_keys, 'All locales have value and text keys' ); >- >- # Test structure for real system locales (if any) >- my $system_locales = [ grep { $_->{value} ne 'default' } @$locales ]; >- if (@$system_locales) { >- >- # Should have friendly display names for common locales >- my $has_friendly_name = 0; >- for my $locale (@$system_locales) { >- if ( $locale->{text} =~ /^[A-Z][a-z]+ \([^)]+\) - / ) { >- $has_friendly_name = 1; >- last; >- } >- } >- ok( $has_friendly_name, 'System locales have friendly display names' ) if @$system_locales; >- } else { >- >- # If no system locales, just pass this test >- ok( 1, 'No system locales found (test environment)' ); >- } >-}; >diff --git a/t/Koha/SearchEngine/Elasticsearch/Search.t b/t/Koha/SearchEngine/Elasticsearch/Search.t >index 06b1c157ed..2cb164a277 100755 >--- a/t/Koha/SearchEngine/Elasticsearch/Search.t >+++ b/t/Koha/SearchEngine/Elasticsearch/Search.t >@@ -18,110 +18,14 @@ > use Modern::Perl; > > use Test::NoWarnings; >-use Test::More tests => 5; >+use Test::More tests => 3; > use Test::MockModule; > use t::lib::Mocks; > use Encode qw( encode ); > use MIME::Base64 qw( encode_base64 ); > >-use utf8; >- > use_ok('Koha::SearchEngine::Elasticsearch::Search'); > >-subtest '_sort_facets' => sub { >- plan tests => 3; >- t::lib::Mocks::mock_preference( 'SearchEngine', 'Elasticsearch' ); >- >- my $facets = _get_facets(); >- >- my @normal_sort_facets = sort { $a->{facet_label_value} cmp $b->{facet_label_value} } @$facets; >- my @normal_expected_facets = ( >- { facet_label_value => 'Ari' }, >- { facet_label_value => 'Fairy' }, >- { facet_label_value => 'Harry' }, >- { facet_label_value => 'Mary' }, >- { facet_label_value => 'Zambidis' }, >- { facet_label_value => 'ari' }, >- { facet_label_value => 'fairy' }, >- { facet_label_value => 'harry' }, >- { facet_label_value => 'mary' }, >- { facet_label_value => 'Ãberg, Erik' }, >- { facet_label_value => 'Ãuthor' }, >- { facet_label_value => 'étienne' }, >- { facet_label_value => 'Å ostakovitÅ¡, Dmitri' }, >- ); >- >- #NOTE: stringwise/bytewise is not UTF-8 friendly >- is_deeply( \@normal_sort_facets, \@normal_expected_facets, "Perl's built-in sort is stringwise/bytewise." ); >- >- my $search = Koha::SearchEngine::Elasticsearch::Search->new( >- { index => $Koha::SearchEngine::Elasticsearch::AUTHORITIES_INDEX } ); >- >- #NOTE: The 'default' locale uses the Default Unicode Collation Element Table, which >- #is used for the locales of English (en) and French (fr). >- my $sorted_facets = $search->_sort_facets( { facets => $facets, locale => 'default' } ); >- my $expected = [ >- { facet_label_value => 'Ãberg, Erik' }, >- { facet_label_value => 'ari' }, >- { facet_label_value => 'Ari' }, >- { facet_label_value => 'Ãuthor' }, >- { facet_label_value => 'étienne' }, >- { facet_label_value => 'fairy' }, >- { facet_label_value => 'Fairy' }, >- { facet_label_value => 'harry' }, >- { facet_label_value => 'Harry' }, >- { facet_label_value => 'mary' }, >- { facet_label_value => 'Mary' }, >- { facet_label_value => 'Å ostakovitÅ¡, Dmitri' }, >- { facet_label_value => 'Zambidis' }, >- ]; >- is_deeply( $sorted_facets, $expected, "Facets sorted correctly with default locale" ); >- >- # Test system preference integration >- t::lib::Mocks::mock_preference( 'FacetSortingLocale', 'en_US.utf8' ); >- my $sorted_facets_syspref = $search->_sort_facets( { facets => $facets } ); >- >- # Should return sorted facets (exact order may vary by system locale availability) >- is( ref($sorted_facets_syspref), 'ARRAY', "System preference integration works" ); >- >- #NOTE: If "locale" is not provided to _sort_facets, it will look up the LC_COLLATE >- #for the local system. This is what allows this function to work well in production. >- #However, since LC_COLLATE could vary from system to system running these unit tests, >- #we can't test it reliably here. >-}; >- >-subtest '_sort_facets_zebra with fi_FI locale' => sub { >- plan tests => 1; >- my $locale_map = _get_locale_map(); >-SKIP: { >- skip( "fi_FI.utf8 locale not available on this system", 1 ) unless $locale_map->{"fi_FI.utf8"}; >- >- my $facets = _get_facets(); >- >- my $search = Koha::SearchEngine::Elasticsearch::Search->new( >- { index => $Koha::SearchEngine::Elasticsearch::AUTHORITIES_INDEX } ); >- >- # Test with explicit locale parameter >- my $sorted_facets_explicit = $search->_sort_facets( { facets => $facets, locale => 'fi_FI' } ); >- my $expected = [ >- { facet_label_value => 'ari' }, >- { facet_label_value => 'Ari' }, >- { facet_label_value => 'étienne' }, >- { facet_label_value => 'fairy' }, >- { facet_label_value => 'Fairy' }, >- { facet_label_value => 'harry' }, >- { facet_label_value => 'Harry' }, >- { facet_label_value => 'mary' }, >- { facet_label_value => 'Mary' }, >- { facet_label_value => 'Å ostakovitÅ¡, Dmitri' }, >- { facet_label_value => 'Zambidis' }, >- { facet_label_value => 'Ãberg, Erik' }, >- { facet_label_value => 'Ãuthor' }, >- ]; >- is_deeply( $sorted_facets_explicit, $expected, "Zebra facets sorted correctly with explicit locale" ); >- } >-}; >- > subtest 'search_auth_compat' => sub { > plan tests => 7; > >@@ -198,33 +102,4 @@ subtest 'search_auth_compat' => sub { > is( @$results[0]->{series}, 1, 'Valid main heading with ShowHeadingUse' ); > }; > >-sub _get_facets { >- my $facets = [ >- { facet_label_value => 'Mary' }, >- { facet_label_value => 'Harry' }, >- { facet_label_value => 'Fairy' }, >- { facet_label_value => 'Ari' }, >- { facet_label_value => 'mary' }, >- { facet_label_value => 'harry' }, >- { facet_label_value => 'Ãberg, Erik' }, >- { facet_label_value => 'Ãuthor' }, >- { facet_label_value => 'fairy' }, >- { facet_label_value => 'ari' }, >- { facet_label_value => 'étienne' }, >- { facet_label_value => 'Å ostakovitÅ¡, Dmitri' }, >- { facet_label_value => 'Zambidis' }, >- ]; >- return $facets; >-} >- >-sub _get_locale_map { >- my $map = {}; >- my @locales = `locale -a`; >- foreach my $locale (@locales) { >- chomp($locale); >- $map->{$locale} = 1; >- } >- return $map; >-} >- > 1; >diff --git a/t/Labels.t b/t/Labels.t >index 5facaaed78..1a5d8b53b1 100755 >--- a/t/Labels.t >+++ b/t/Labels.t >@@ -17,11 +17,11 @@ > # > # for context, see http://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=2691 > >-use Modern::Perl; >+use strict; >+use warnings; > > use C4::ClassSplitRoutine::LCC qw( split_callnumber ); >-use Test::More tests => 12; >-use Test::NoWarnings; >+use Test::More tests => 11; > > BEGIN { > use_ok( 'C4::Labels::Label', qw( _get_text_fields _check_params _guide_box ) ); >diff --git a/t/RecordProcessor.t b/t/RecordProcessor.t >index 5c22d6fe6d..c5a967788e 100755 >--- a/t/RecordProcessor.t >+++ b/t/RecordProcessor.t >@@ -215,7 +215,7 @@ subtest 'options() tests' => sub { > > subtest "'TrimFields' filter tests" => sub { > >- plan tests => 4; >+ plan tests => 2; > > # Test default values with a MARC::Record record > my $record = MARC::Record->new(); >@@ -225,8 +225,6 @@ subtest "'TrimFields' filter tests" => sub { > [ '150', ' ', ' ', a => 'Test' ], > [ '520', ' ', ' ', a => "This is\na test!\t" ], > [ '521', ' ', ' ', a => "This is a\t test!\t" ], >- [ '522', ' ', ' ', a => "This is a test!", b => " " ], >- [ '523', ' ', ' ', a => " " ], > ); > > my $p = Koha::RecordProcessor->new( { filters => ['TrimFields'] } ); >@@ -237,10 +235,4 @@ subtest "'TrimFields' filter tests" => sub { > > my $get521a = $record->subfield( '521', 'a' ); > is( $get521a, "This is a\t test!", "Trailing tabs are stripped while inner tabs are kept" ); >- >- my $get522b = $record->subfield( '522', 'b' ); >- isnt( $get522b, "", "Subfield containing spaces only removed from the field" ); >- >- my $get523 = $record->field('523'); >- is( $get523, undef, "Field with only a subfield containing spaces removed from the record" ); > }; >diff --git a/t/Test/Mock/Logger.t b/t/Test/Mock/Logger.t >index 015cdcae34..1563205f8c 100755 >--- a/t/Test/Mock/Logger.t >+++ b/t/Test/Mock/Logger.t >@@ -1,6 +1,5 @@ > use Modern::Perl; >-use Test::More tests => 11; >-use Test::NoWarnings; >+use Test::More tests => 10; > use Test::Warn; > > # Module under test >@@ -133,25 +132,16 @@ subtest 'Method chaining tests' => sub { > isa_ok( $result, 't::lib::Mocks::Logger', 'Method chaining returns the logger object' ); > }; > >+# Test diag method (output capture is complex, just verify it runs) > subtest 'Diag method test' => sub { > plan tests => 1; > > $logger->clear(); > $mocked_logger->debug('Debug message'); > >- # Capture Test::Builder diag output >- my $diag_output = ''; >- open my $fake_fh, '>', \$diag_output or die "Can't open: $!"; >- >- my $tb = Test::More->builder; >- my $original_fh = $tb->failure_output; >- $tb->failure_output($fake_fh); # Redirect diag output >- >- $logger->diag(); >- >- $tb->failure_output($original_fh); >- >- like( $diag_output, qr/debug:\n#\s*"Debug message"/xms, 'Captured diag output' ); >+ # Just make sure it doesn't throw an exception >+ eval { $logger->diag(); }; >+ is( $@, '', 'diag() method executed without errors' ); > }; > > # Test handling of empty log buffers >diff --git a/t/cypress/fixtures/sample.xml b/t/cypress/fixtures/sample.mrc >similarity index 100% >rename from t/cypress/fixtures/sample.xml >rename to t/cypress/fixtures/sample.mrc >diff --git a/t/cypress/integration/Auth/csrf.ts b/t/cypress/integration/Auth/csrf.ts >index c24b691d04..c17763090b 100644 >--- a/t/cypress/integration/Auth/csrf.ts >+++ b/t/cypress/integration/Auth/csrf.ts >@@ -5,7 +5,7 @@ const branchname = "test_branchname"; > > function cleanup() { > const sql = "DELETE FROM branches WHERE branchcode=?"; >- cy.task("query", { sql, values: [branchcode] }); >+ cy.query(sql, branchcode); > } > > describe("CSRF", () => { >@@ -32,10 +32,10 @@ describe("CSRF", () => { > .find(".alert") > .contains(/No CSRF token passed for POST/); > >- cy.task("query", { >- sql: "SELECT COUNT(*) as count FROM branches WHERE branchcode=?", >- values: [branchcode], >- }).then(result => { >+ cy.query( >+ "SELECT COUNT(*) as count FROM branches WHERE branchcode=?", >+ branchcode >+ ).then(result => { > expect(result[0].count).to.equal(0); > }); > }); >@@ -53,10 +53,10 @@ describe("CSRF", () => { > .find(".alert") > .contains(/Wrong CSRF token/); > >- cy.task("query", { >- sql: "SELECT COUNT(*) as count FROM branches WHERE branchcode=?", >- values: [branchcode], >- }).then(result => { >+ cy.query( >+ "SELECT COUNT(*) as count FROM branches WHERE branchcode=?", >+ branchcode >+ ).then(result => { > expect(result[0].count).to.equal(0); > }); > }); >@@ -89,10 +89,10 @@ describe("CSRF", () => { > // We do not want Wrong CSRF token here > cy.get(".message").should("not.exist"); > >- cy.task("query", { >- sql: "SELECT COUNT(*) as count FROM branches WHERE branchcode=?", >- values: [branchcode], >- }).then(result => { >+ cy.query( >+ "SELECT COUNT(*) as count FROM branches WHERE branchcode=?", >+ branchcode >+ ).then(result => { > expect(result[0].count).to.equal(0); > }); > }); >@@ -112,19 +112,19 @@ describe("CSRF", () => { > cy.get("select[name='libraries_length']").select("-1"); > cy.get("td").contains(branchcode); > >- cy.task("query", { >- sql: "SELECT COUNT(*) as count FROM branches WHERE branchcode=?", >- values: [branchcode], >- }).then(result => { >+ cy.query( >+ "SELECT COUNT(*) as count FROM branches WHERE branchcode=?", >+ branchcode >+ ).then(result => { > expect(result[0].count).to.equal(1); > }); > }); > > it("Delete without CSRF", () => { >- cy.task("query", { >- sql: "INSERT INTO branches(branchcode, branchname) VALUES (?, ?)", >- values: [branchcode, branchname], >- }); >+ cy.query("INSERT INTO branches(branchcode, branchname) VALUES (?, ?)", [ >+ branchcode, >+ branchname, >+ ]); > > cy.visit("/cgi-bin/koha/admin/branches.pl"); > cy.get("select[name='libraries_length']").select("-1"); >@@ -141,19 +141,19 @@ describe("CSRF", () => { > .find(".alert") > .contains(/No CSRF token passed for POST/); > >- cy.task("query", { >- sql: "SELECT COUNT(*) as count FROM branches WHERE branchcode=?", >- values: [branchcode], >- }).then(result => { >+ cy.query( >+ "SELECT COUNT(*) as count FROM branches WHERE branchcode=?", >+ branchcode >+ ).then(result => { > expect(result[0].count).to.equal(1); > }); > }); > > it("Delete", () => { >- cy.task("query", { >- sql: "INSERT INTO branches(branchcode, branchname) VALUES (?, ?)", >- values: [branchcode, branchname], >- }); >+ cy.query("INSERT INTO branches(branchcode, branchname) VALUES (?, ?)", [ >+ branchcode, >+ branchname, >+ ]); > > cy.visit("/cgi-bin/koha/admin/branches.pl"); > cy.get("select[name='libraries_length']").select("-1"); >@@ -165,10 +165,10 @@ describe("CSRF", () => { > .find(".alert") > .contains(/Library deleted successfully/); > >- cy.task("query", { >- sql: "SELECT COUNT(*) as count FROM branches WHERE branchcode=?", >- values: [branchcode], >- }).then(result => { >+ cy.query( >+ "SELECT COUNT(*) as count FROM branches WHERE branchcode=?", >+ branchcode >+ ).then(result => { > expect(result[0].count).to.equal(0); > }); > }); >diff --git a/t/cypress/integration/ERM/Agreements_spec.ts b/t/cypress/integration/ERM/Agreements_spec.ts >index 0b55448ee6..6bbcb2cdf3 100644 >--- a/t/cypress/integration/ERM/Agreements_spec.ts >+++ b/t/cypress/integration/ERM/Agreements_spec.ts >@@ -569,10 +569,9 @@ describe("Agreement CRUD operations", () => { > "X-Base-Total-Count": "1", > "X-Total-Count": "1", > }, >- }).as("get-agreements"); >+ }); > cy.intercept("GET", "/api/v1/erm/agreements/*", agreement); > cy.visit("/cgi-bin/koha/erm/agreements"); >- cy.wait("@get-agreements"); > > cy.get("#agreements_list table tbody tr:first") > .contains("Delete") >@@ -609,8 +608,14 @@ describe("Agreement CRUD operations", () => { > > // Delete from show > // Click the "name" link from the list >- cy.visit("/cgi-bin/koha/erm/agreements"); >- cy.wait("@get-agreements"); >+ cy.intercept("GET", "/api/v1/erm/agreements*", { >+ statusCode: 200, >+ body: agreements, >+ headers: { >+ "X-Base-Total-Count": "1", >+ "X-Total-Count": "1", >+ }, >+ }); > cy.intercept("GET", "/api/v1/erm/agreements/*", agreement).as( > "get-agreement" > ); >@@ -624,6 +629,7 @@ describe("Agreement CRUD operations", () => { > name_link.should("have.text", agreement.name); > name_link.click(); > cy.wait("@get-agreement"); >+ cy.wait(500); // Cypress is too fast! Vue hasn't populated the form yet! > cy.get("#agreements_show h2").contains( > "Agreement #" + agreement.agreement_id > ); >diff --git a/t/cypress/integration/ERM/DataProviders_spec.ts b/t/cypress/integration/ERM/DataProviders_spec.ts >index f3cacef726..9c2ba4ecc5 100644 >--- a/t/cypress/integration/ERM/DataProviders_spec.ts >+++ b/t/cypress/integration/ERM/DataProviders_spec.ts >@@ -636,7 +636,7 @@ describe("Data provider tab options", () => { > } > ); > >- cy.get("#files > form > fieldset > button").click(); >+ cy.get("#files > form > fieldset > input[type=submit]").click(); > > cy.get("main div[class='alert alert-info']").should( > "have.text", >diff --git a/t/cypress/integration/ERM/UsageReports_spec.ts b/t/cypress/integration/ERM/UsageReports_spec.ts >index fb237a0fb1..ddd5402299 100644 >--- a/t/cypress/integration/ERM/UsageReports_spec.ts >+++ b/t/cypress/integration/ERM/UsageReports_spec.ts >@@ -105,9 +105,7 @@ describe("Saved reports", () => { > { force: true } > ); > >- cy.get("#report_builder .default-report .action button") >- .contains("Submit") >- .click(); >+ cy.get("#report_builder .default-report .action input").click(); > > cy.url({ decode: true }).then(url => { > const urlParams = url.split("viewer?")[1].split("data=")[1]; >diff --git a/t/cypress/integration/Islands/AcquisitionsMenu_spec.ts b/t/cypress/integration/Islands/AcquisitionsMenu_spec.ts >index 121e1c9402..8d2413324d 100644 >--- a/t/cypress/integration/Islands/AcquisitionsMenu_spec.ts >+++ b/t/cypress/integration/Islands/AcquisitionsMenu_spec.ts >@@ -23,14 +23,12 @@ describe("Acquisitions menu", () => { > it("Should show/hide links based on permissions", () => { > cy.get(".sidebar_menu").should("be.visible"); > >- cy.task("query", { >- sql: "UPDATE borrowers SET flags=2052 WHERE borrowernumber=51", >- }).then(() => { >+ cy.query( >+ "UPDATE borrowers SET flags=2052 WHERE borrowernumber=51" >+ ).then(() => { > cy.reload(true); > cy.get(".sidebar_menu a").should("have.length", 8); >- cy.task("query", { >- sql: "UPDATE borrowers SET flags=1 WHERE borrowernumber=51", >- }); >+ cy.query("UPDATE borrowers SET flags=1 WHERE borrowernumber=51"); > }); > }); > it("Should correctly apply the 'current' class", () => { >diff --git a/t/cypress/integration/KohaTable/Holdings_spec.ts b/t/cypress/integration/KohaTable/Holdings_spec.ts >index 380ac9d2d8..f39e51e0e7 100644 >--- a/t/cypress/integration/KohaTable/Holdings_spec.ts >+++ b/t/cypress/integration/KohaTable/Holdings_spec.ts >@@ -42,9 +42,7 @@ describe("catalogue/detail/holdings_table with items", () => { > cy.wrap(Promise.resolve()) > .then(() => { > return queries.reduce((chain, { query, values }) => { >- return chain.then(() => >- cy.task("query", { sql: query, values }) >- ); >+ return chain.then(() => cy.query(query, values)); > }, Promise.resolve()); > }) > .then(() => { >@@ -104,19 +102,23 @@ describe("catalogue/detail/holdings_table with items", () => { > }); > }); > }); >- cy.task("query", { >- sql: "SELECT value FROM systempreferences WHERE variable='AlwaysShowHoldingsTableFilters'", >- }).then(value => { >+ cy.query( >+ "SELECT value FROM systempreferences WHERE variable='AlwaysShowHoldingsTableFilters'" >+ ).then(value => { > cy.wrap(value).as("syspref_AlwaysShowHoldingsTableFilters"); > }); > }); > >- afterEach(function () { >- cy.set_syspref( >- "AlwaysShowHoldingsTableFilters", >- this.syspref_AlwaysShowHoldingsTableFilters >- ); >- }); >+ afterEach( >+ () => >+ function () { >+ cleanup(); >+ cy.set_syspref( >+ "AlwaysShowHoldingsTableFilters", >+ this.syspref_AlwaysShowHoldingsTableFilters >+ ); >+ } >+ ); > > it("Correctly init the table", function () { > // Do not use `() => {` or this.biblio_id won't be retrieved >@@ -437,16 +439,14 @@ describe("catalogue/detail/holdings_table without items", () => { > const item_type = generated_objects["item_type"]; > const queries = [ > { >- sql: "INSERT INTO itemtypes(itemtype, description) VALUES (?, ?)", >+ query: "INSERT INTO itemtypes(itemtype, description) VALUES (?, ?)", > values: [item_type.item_type_id, item_type.description], > }, > ]; > cy.wrap(Promise.resolve()) > .then(() => { >- return queries.reduce((chain, { sql, values }) => { >- return chain.then(() => >- cy.task("query", { sql, values }) >- ); >+ return queries.reduce((chain, { query, values }) => { >+ return chain.then(() => cy.query(query, values)); > }, Promise.resolve()); > }) > .then(() => { >@@ -495,19 +495,23 @@ describe("catalogue/detail/holdings_table without items", () => { > }); > }); > }); >- cy.task("query", { >- sql: "SELECT value FROM systempreferences WHERE variable='AlwaysShowHoldingsTableFilters'", >- }).then(value => { >+ cy.query( >+ "SELECT value FROM systempreferences WHERE variable='AlwaysShowHoldingsTableFilters'" >+ ).then(value => { > cy.wrap(value).as("syspref_AlwaysShowHoldingsTableFilters"); > }); > }); > >- afterEach(function () { >- cy.set_syspref( >- "AlwaysShowHoldingsTableFilters", >- this.syspref_AlwaysShowHoldingsTableFilters >- ); >- }); >+ afterEach( >+ () => >+ function () { >+ cleanup(); >+ cy.set_syspref( >+ "AlwaysShowHoldingsTableFilters", >+ this.syspref_AlwaysShowHoldingsTableFilters >+ ); >+ } >+ ); > > it("Do not display the table", function () { > // Do not use `() => {` or this.biblio_id won't be retrieved >diff --git a/t/cypress/integration/KohaTable/KohaTable_spec.ts b/t/cypress/integration/KohaTable/KohaTable_spec.ts >index 3c0ca843fd..035404c11a 100644 >--- a/t/cypress/integration/KohaTable/KohaTable_spec.ts >+++ b/t/cypress/integration/KohaTable/KohaTable_spec.ts >@@ -333,7 +333,7 @@ describe("kohaTable (using REST API)", () => { > > cy.window().then(win => { > win.categories_map = patrons.reduce((map, p) => { >- map[p.category_id.toLowerCase()] = p.category_id; >+ map[p.category_id] = p.category_id; > return map; > }, {}); > }); >@@ -399,7 +399,7 @@ describe("kohaTable (using REST API)", () => { > > cy.window().then(win => { > win.categories_map = patrons.reduce((map, p) => { >- map[p.category_id.toLowerCase()] = p.category_id; >+ map[p.category_id] = p.category_id; > return map; > }, {}); > }); >diff --git a/t/cypress/integration/KohaTable/PatronSearch_spec.ts b/t/cypress/integration/KohaTable/PatronSearch_spec.ts >index 782cb45f4f..b706f1eb80 100644 >--- a/t/cypress/integration/KohaTable/PatronSearch_spec.ts >+++ b/t/cypress/integration/KohaTable/PatronSearch_spec.ts >@@ -9,7 +9,7 @@ const patron_attr_type = "attribute_type4TEST"; > > function cleanup() { > const sql = "DELETE FROM borrower_attribute_types WHERE code=?"; >- cy.task("query", { sql, values: [patron_attr_type] }); >+ cy.query(sql, patron_attr_type); > } > describe("ExtendedPatronAttributes", () => { > beforeEach(() => { >@@ -19,20 +19,23 @@ describe("ExtendedPatronAttributes", () => { > cy.window().then(win => { > win.localStorage.clear(); > }); >- cy.task("query", { >- sql: "SELECT value FROM systempreferences WHERE variable='ExtendedPatronAttributes'", >- }).then(value => { >+ cy.query( >+ "SELECT value FROM systempreferences WHERE variable='ExtendedPatronAttributes'" >+ ).then(value => { > cy.wrap(value).as("syspref_ExtendedPatronAttributes"); > }); > }); > >- afterEach(function () { >- cleanup(); >- cy.set_syspref( >- "ExtendedPatronAttributes", >- this.syspref_ExtendedPatronAttributes >- ); >- }); >+ afterEach( >+ () => >+ function () { >+ cleanup(); >+ cy.set_syspref( >+ "ExtendedPatronAttributes", >+ this.syspref_ExtendedPatronAttributes >+ ); >+ } >+ ); > > const table_id = "memberresultst"; > >@@ -45,9 +48,9 @@ describe("ExtendedPatronAttributes", () => { > cy.get("#search_patron_filter").type("something"); > cy.get("form.patron_search_form input[type='submit']").click(); > >- cy.task("query", { >- sql: "select count(*) as nb_searchable from borrower_attribute_types where staff_searchable=1", >- }).then(result => { >+ cy.query( >+ "select count(*) as nb_searchable from borrower_attribute_types where staff_searchable=1" >+ ).then(result => { > const has_searchable = result[0].nb_searchable; > cy.wait("@searchPatrons").then(interception => { > const q = interception.request.query.q; >@@ -55,10 +58,10 @@ describe("ExtendedPatronAttributes", () => { > }); > }); > >- cy.task("query", { >- sql: "INSERT INTO borrower_attribute_types(code, description, staff_searchable, searched_by_default) VALUES (?, 'only for tests', 1, 1)", >- values: [patron_attr_type], >- }).then(() => { >+ cy.query( >+ "INSERT INTO borrower_attribute_types(code, description, staff_searchable, searched_by_default) VALUES (?, 'only for tests', 1, 1)", >+ patron_attr_type >+ ).then(() => { > cy.visit("/cgi-bin/koha/members/members-home.pl"); > > cy.get("#search_patron_filter").type("something"); >@@ -80,9 +83,9 @@ describe("ExtendedPatronAttributes", () => { > cy.get("#search_patron_filter").type("something"); > cy.get("form.patron_search_form input[type='submit']").click(); > >- cy.task("query", { >- sql: "select count(*) as nb_searchable from borrower_attribute_types where staff_searchable=1 AND searched_by_default=1", >- }).then(result => { >+ cy.query( >+ "select count(*) as nb_searchable from borrower_attribute_types where staff_searchable=1 AND searched_by_default=1" >+ ).then(result => { > const has_searchable = result[0].nb_searchable; > cy.wait("@searchPatrons").then(interception => { > const q = interception.request.query.q; >@@ -94,10 +97,10 @@ describe("ExtendedPatronAttributes", () => { > }); > }); > >- cy.task("query", { >- sql: "INSERT INTO borrower_attribute_types(code, description, staff_searchable, searched_by_default) VALUES (?, 'only for tests', 1, 1)", >- values: [patron_attr_type], >- }).then(() => { >+ cy.query( >+ "INSERT INTO borrower_attribute_types(code, description, staff_searchable, searched_by_default) VALUES (?, 'only for tests', 1, 1)", >+ patron_attr_type >+ ).then(() => { > cy.visit("/cgi-bin/koha/members/members-home.pl"); > > cy.get("#search_patron_filter").type("something"); >diff --git a/t/cypress/integration/Tools/ManageMarcImport_spec.ts b/t/cypress/integration/Tools/ManageMarcImport_spec.ts >index e27f3cf9a1..4141a99ff2 100644 >--- a/t/cypress/integration/Tools/ManageMarcImport_spec.ts >+++ b/t/cypress/integration/Tools/ManageMarcImport_spec.ts >@@ -27,53 +27,65 @@ describe("loads the manage MARC import page", () => { > it("upload a MARC record", () => { > cy.visit("/cgi-bin/koha/tools/stage-marc-import.pl"); > >- cy.fixture("sample.xml", null).as("sample_xml"); >- cy.get("input[type=file]").selectFile("@sample_xml"); >- cy.get("#fileuploadbutton").click(); >+ cy.get('input[type="file"]').selectFile( >+ "t/cypress/fixtures/sample.mrc" >+ ); >+ cy.get('form[id="uploadfile"]').within(() => { >+ cy.get('button[id="fileuploadbutton"]').click(); >+ }); > >- cy.get("#fileuploadstatus").contains("100%"); >- cy.get("legend") >- .contains("Look for existing records in catalog?") >- .should("be.visible"); >+ //wait after file upload, it can go to quickly here >+ cy.wait(2000); > > //check default values >- cy.get("select#matcher option:selected").should("have.value", ""); >- cy.get("select#overlay_action option:selected").should( >+ cy.get('select[name="matcher"] option:selected').should( >+ "have.value", >+ "" >+ ); >+ cy.get('select[name="overlay_action"] option:selected').should( > "have.value", > "replace" > ); >- cy.get("select#nomatch_action option:selected").should( >+ cy.get('select[name="nomatch_action"] option:selected').should( > "have.value", > "create_new" > ); >- cy.get("select#item_action option:selected").should( >+ cy.get('select[name="item_action"] option:selected').should( > "have.value", > "always_add" > ); > >- cy.get('select[name="format"]').should("have.value", "MARCXML"); >+ cy.get('select[name="format"]').select("MARCXML", { force: true }); >+ cy.get("#format").should("have.value", "MARCXML"); > > //select some new options > cy.get("#matcher").select("3", { force: true }); >- cy.get("#matcher") >- .select("3", { force: true }) >- .should("have.value", "3"); >- cy.get("#overlay_action") >- .select("create_new", { force: true }) >- .should("have.value", "create_new"); >- cy.get("#nomatch_action") >- .select("ignore", { force: true }) >- .should("have.value", "ignore"); >- cy.get("#item_action") >- .select("ignore", { force: true }) >- .should("have.value", "ignore"); >+ cy.get("#overlay_action").select("create_new", { force: true }); >+ cy.get("#nomatch_action").select("ignore", { force: true }); >+ cy.get("#item_action").select("ignore", { force: true }); > >+ //remove focus >+ //cy.get('#item_action').blur(); >+ cy.screenshot("after_selection"); >+ >+ // Now verify all values >+ cy.get("#matcher").should("have.value", "3"); >+ cy.get("#overlay_action").should("have.value", "create_new"); >+ cy.get("#nomatch_action").should("have.value", "ignore"); >+ cy.get("#item_action").should("have.value", "ignore"); >+ >+ cy.screenshot("right_before_submission"); > cy.get("#mainformsubmit").click(); > > cy.get("#job_callback").should("exist"); > >+ //wait for View batch link to load with the batch ID >+ cy.wait(5000); >+ >+ cy.screenshot("after_waiting"); > cy.contains("View batch").click(); > >+ cy.wait(2000); > // Now verify all values are retained > cy.get("#new_matcher_id").should("have.value", "3"); > cy.get("#overlay_action").should("have.value", "create_new"); >diff --git a/t/cypress/integration/t/db.ts b/t/cypress/integration/t/db.ts >deleted file mode 100644 >index 5715c8870f..0000000000 >--- a/t/cypress/integration/t/db.ts >+++ /dev/null >@@ -1,15 +0,0 @@ >-describe("DB tests", () => { >- it("should be able to SELECT", () => { >- cy.task("query", { sql: "SELECT count(*) FROM borrowers" }).then( >- rows => { >- expect(typeof rows.length).to.be.equal("number"); >- } >- ); >- cy.task("query", { >- sql: "SELECT count(*) FROM borrowers WHERE `surname` = ?", >- values: ["john"], >- }).then(rows => { >- expect(typeof rows.length).to.be.equal("number"); >- }); >- }); >-}); >diff --git a/t/cypress/integration/t/mockData.ts b/t/cypress/integration/t/mockData.ts >index 33b20279c6..8c63fb75f7 100644 >--- a/t/cypress/integration/t/mockData.ts >+++ b/t/cypress/integration/t/mockData.ts >@@ -20,16 +20,6 @@ describe("Generate Random Patron", () => { > ); > }); > }); >- >- it("should not overwrite _id if passed", () => { >- const home_library_id = "LIB4TEST"; >- cy.task("buildSampleObject", { >- object: "item", >- values: { home_library_id }, >- }).then(mockItem => { >- expect(mockItem.home_library_id).to.equal(home_library_id); >- }); >- }); > }); > > describe("Generate Random Patrons", () => { >@@ -84,14 +74,4 @@ describe("Generate objects", () => { > ); > }); > }); >- >- it("should not overwrite _id if passed", () => { >- const home_library_id = "LIB4TEST"; >- cy.task("buildSampleObject", { >- object: "item", >- values: { home_library_id }, >- }).then(mockItem => { >- expect(mockItem.home_library_id).to.equal(home_library_id); >- }); >- }); > }); >diff --git a/t/cypress/plugins/db.js b/t/cypress/plugins/db.js >deleted file mode 100644 >index fb4568886c..0000000000 >--- a/t/cypress/plugins/db.js >+++ /dev/null >@@ -1,17 +0,0 @@ >-const mysql = require("mysql2/promise"); >- >-const connectionConfig = { >- host: "db", >- user: "koha_kohadev", >- password: "password", >- database: "koha_kohadev", >-}; >- >-async function query(sql, params = []) { >- const connection = await mysql.createConnection(connectionConfig); >- const [rows] = await connection.execute(sql, params); >- await connection.end(); >- return rows; >-} >- >-module.exports = { query }; >diff --git a/t/cypress/plugins/index.js b/t/cypress/plugins/index.js >index 5221471779..837e6d747c 100644 >--- a/t/cypress/plugins/index.js >+++ b/t/cypress/plugins/index.js >@@ -1,8 +1,8 @@ > const { startDevServer } = require("@cypress/webpack-dev-server"); > >-const { buildSampleObject, buildSampleObjects } = require("./mockData.js"); >+const mysql = require("cypress-mysql"); > >-const { query } = require("./db.js"); >+const { buildSampleObject, buildSampleObjects } = require("./mockData.js"); > > module.exports = (on, config) => { > on("dev-server:start", options => >@@ -11,10 +11,11 @@ module.exports = (on, config) => { > }) > ); > >+ mysql.configurePlugin(on); >+ > on("task", { > buildSampleObject, > buildSampleObjects, >- query, > }); > return config; > }; >diff --git a/t/cypress/plugins/mockData.js b/t/cypress/plugins/mockData.js >index c2025abeeb..0f9c292df8 100644 >--- a/t/cypress/plugins/mockData.js >+++ b/t/cypress/plugins/mockData.js >@@ -74,10 +74,7 @@ const generateDataFromSchema = (properties, values = {}) => { > }); > > Object.keys(ids).forEach(k => { >- if ( >- mockData.hasOwnProperty(k + "_id") && >- !values.hasOwnProperty(k + "_id") >- ) { >+ if (mockData.hasOwnProperty(k + "_id")) { > mockData[k + "_id"] = ids[k]; > } > }); >diff --git a/t/cypress/support/e2e.js b/t/cypress/support/e2e.js >index 40265d607b..e420889c3b 100644 >--- a/t/cypress/support/e2e.js >+++ b/t/cypress/support/e2e.js >@@ -1874,6 +1874,9 @@ cy.getVendor = () => { > }; > }; > >+const mysql = require("cypress-mysql"); >+mysql.addCommands(); >+ > Cypress.Commands.add("set_syspref", (variable, value) => { > cy.window().then(win => { > const client = win.APIClient.sysprefs; >diff --git a/t/db_dependent/Auth_with_shibboleth.t b/t/db_dependent/Auth_with_shibboleth.t >index b7cfdbbfb2..db6ce0b1cb 100755 >--- a/t/db_dependent/Auth_with_shibboleth.t >+++ b/t/db_dependent/Auth_with_shibboleth.t >@@ -20,10 +20,9 @@ > use Modern::Perl; > use utf8; > >-use Test::More tests => 7; >+use Test::More tests => 6; > use Test::MockModule; > use Test::Warn; >-use Test::NoWarnings; > use CGI qw(-utf8 ); > use File::Temp qw(tempdir); > >@@ -68,18 +67,17 @@ $context->mock( 'interface', sub { return $interface; } ); > # Mock Letters: GetPreparedLetter, EnqueueLetter and SendQueuedMessages > # We want to test the params > my $mocked_letters = Test::MockModule->new('C4::Letters'); >-my $sub_called = {}; > $mocked_letters->mock( > 'GetPreparedLetter', > sub { >- $sub_called->{GetPreparedLetter}++; >+ warn "GetPreparedLetter called"; > return 1; > } > ); > $mocked_letters->mock( > 'EnqueueLetter', > sub { >- $sub_called->{EnqueueLetter}++; >+ warn "EnqueueLetter called"; > > # return a 'message_id' > return 42; >@@ -89,7 +87,7 @@ $mocked_letters->mock( > 'SendQueuedMessages', > sub { > my $params = shift; >- $sub_called->{SendQueuedMessages}->{ $params->{message_id} }++; >+ warn "SendQueuedMessages called with message_id: $params->{message_id}"; > return 1; > } > ); >@@ -174,7 +172,7 @@ subtest "get_login_shib tests" => sub { > > subtest "checkpw_shib tests" => sub { > >- plan tests => 56; >+ plan tests => 54; > > # Test borrower data > my $test_borrowers = [ >@@ -253,13 +251,18 @@ subtest "checkpw_shib tests" => sub { > $ENV{'emailpro'} = 'me@myemail.com'; > $ENV{branchcode} = $library->branchcode; # needed since T::D::C does no longer hides the FK constraint > >- ( $retval, $retcard, $retuserid, $retpatron ) = checkpw_shib($shib_login); >- is( $sub_called->{GetPreparedLetter}, 1, 'GetPreparedLetter called' ); >- is( $sub_called->{EnqueueLetter}, 1, 'EnqueueLetter called' ); >- is( $sub_called->{SendQueuedMessages}->{42}, 1, 'SendQueuedMessages called with message_id: 42' ); >- is( $retval, "1", "user authenticated" ); >- is( $retuserid, "test4321", "expected userid returned" ); >- is( ref($retpatron), 'Koha::Patron', "expected Koha::Patron object returned" ); >+ warnings_are { >+ ( $retval, $retcard, $retuserid, $retpatron ) = checkpw_shib($shib_login); >+ } >+ [ >+ 'GetPreparedLetter called', >+ 'EnqueueLetter called', >+ 'SendQueuedMessages called with message_id: 42' >+ ], >+ "WELCOME notice Prepared, Enqueued and Send"; >+ is( $retval, "1", "user authenticated" ); >+ is( $retuserid, "test4321", "expected userid returned" ); >+ is( ref($retpatron), 'Koha::Patron', "expected Koha::Patron object returned" ); > $logger->debug_is( "koha borrower field to match: userid", "borrower match field debug info" ) > ->debug_is( "shibboleth attribute to match: uid", "shib match attribute debug info" )->clear(); > >diff --git a/t/db_dependent/AuthorisedValues.t b/t/db_dependent/AuthorisedValues.t >index 559cd2ec74..cf07bfc001 100755 >--- a/t/db_dependent/AuthorisedValues.t >+++ b/t/db_dependent/AuthorisedValues.t >@@ -194,8 +194,8 @@ subtest 'search_by_*_field + find_by_koha_field + get_description + authorised_v > kohafield => 'items.restricted' > } > )->store; >- Koha::MarcSubfieldStructure->new( >- { tagfield => '003', tagsubfield => '@', frameworkcode => '', authorised_value => 'CONTROL_TEST', } )->store; >+ Koha::MarcSubfieldStructure->new( { tagfield => '003', frameworkcode => '', authorised_value => 'CONTROL_TEST', } ) >+ ->store; > Koha::AuthorisedValue->new( { category => 'TEST', authorised_value => 'location_1', lib => 'location_1' } )->store; > Koha::AuthorisedValue->new( { category => 'TEST', authorised_value => 'location_2', lib => 'location_2' } )->store; > Koha::AuthorisedValue->new( { category => 'TEST', authorised_value => 'location_3', lib => 'location_3' } )->store; >diff --git a/t/db_dependent/Biblio.t b/t/db_dependent/Biblio.t >index e34c00e6da..1f08417b93 100755 >--- a/t/db_dependent/Biblio.t >+++ b/t/db_dependent/Biblio.t >@@ -17,8 +17,7 @@ > > use Modern::Perl; > >-use Test::More tests => 26; >-use Test::NoWarnings; >+use Test::More tests => 25; > use Test::MockModule; > use Test::Warn; > use List::MoreUtils qw( uniq ); >@@ -294,12 +293,11 @@ subtest "Test caching of authority types in LinkBibHeadingsToAuthorities" => sub > } > ); > my $authorities_type = Test::MockModule->new('Koha::Authority::Types'); >- my $found_auth_type = {}; > $authorities_type->mock( > 'find', > sub { > my ( $self, $params ) = @_; >- $found_auth_type->{$params}++; >+ warn "Finding auth type $params"; > return $authorities_type->original("find")->( $self, $params ); > } > ); >@@ -307,13 +305,17 @@ subtest "Test caching of authority types in LinkBibHeadingsToAuthorities" => sub > my $field1 = MARC::Field->new( 655, ' ', ' ', 'a' => 'Magical realism' ); > my $field2 = MARC::Field->new( 655, ' ', ' ', 'a' => 'Magical falsism' ); > $marc_record->append_fields( ( $field1, $field2 ) ); >- my ( $num_changed, $results ) = LinkBibHeadingsToAuthorities( $linker, $marc_record, "", undef ); >- is_deeply( $found_auth_type, { "GENRE/FORM" => 1 }, "Type fetched only once" ); >+ my ( $num_changed, $results ); >+ warning_like { ( $num_changed, $results ) = LinkBibHeadingsToAuthorities( $linker, $marc_record, "", undef ) } >+ qr/Finding auth type GENRE\/FORM/, >+ "Type fetched only once"; > my $gf_type = $cache->get_from_cache("LinkBibHeadingsToAuthorities:AuthorityType:GENRE/FORM"); > ok( $gf_type, "GENRE/FORM type is found in cache" ); > >- ( $num_changed, $results ) = LinkBibHeadingsToAuthorities( $linker, $marc_record, "", undef ); >- is_deeply( $found_auth_type, { "GENRE/FORM" => 1 }, "Type not fetched a second time" ); >+ warning_like { ( $num_changed, $results ) = LinkBibHeadingsToAuthorities( $linker, $marc_record, "", undef ) } >+ undef, >+ "Type not fetched a second time"; >+ > }; > > # Mocking variables >diff --git a/t/db_dependent/Circulation/OfflineCirculation.t b/t/db_dependent/Circulation/OfflineCirculation.t >index 8d9afffd2d..ac74899d7b 100755 >--- a/t/db_dependent/Circulation/OfflineCirculation.t >+++ b/t/db_dependent/Circulation/OfflineCirculation.t >@@ -18,7 +18,7 @@ > use Modern::Perl; > > use Test::NoWarnings; >-use Test::More tests => 4; >+use Test::More tests => 3; > use Test::MockModule; > use Test::Warn; > >@@ -85,21 +85,18 @@ subtest "Bug 34529: Offline circulation should be able to accept userid as well > } > ); > >- my ( $message, $checkout ) = ProcessOfflineIssue( >- { >- cardnumber => $borrower1->{cardnumber}, >- barcode => $item1->barcode >- } >- ); >- > is( >- $message, "Success.", >+ ProcessOfflineIssue( >+ { >+ cardnumber => $borrower1->{cardnumber}, >+ barcode => $item1->barcode >+ } >+ ), >+ "Success.", > "ProcessOfflineIssue succeeds with cardnumber" > ); >- >- ( $message, $checkout ) = ProcessOfflineIssue( { cardnumber => $borrower1->{userid}, barcode => $item2->barcode } ); > is( >- $message, >+ ProcessOfflineIssue( { cardnumber => $borrower1->{userid}, barcode => $item2->barcode } ), > "Success.", > "ProcessOfflineIssue succeeds with user id" > ); >@@ -195,48 +192,9 @@ subtest "Bug 30114 - Koha offline circulation will always cancel the next hold w > > my $op = GetOfflineOperation( $offline_rs->next->id ); > >- my ($ret) = ProcessOfflineOperation($op); >+ my $ret = ProcessOfflineOperation($op); > > is( Koha::Holds->search( { biblionumber => $biblionumber } )->count, 2, "Still found two holds for the record" ); > }; > >-subtest "Bug 32934: ProcessOfflineIssue returns checkout object for SIP no block due date" => sub { >- plan tests => 4; >- >- $branch = $builder->build( { source => 'Branch' } )->{branchcode}; >- $manager_id = $builder->build( { source => 'Borrower' } )->{borrowernumber}; >- >- my $borrower = $builder->build( >- { >- source => 'Borrower', >- value => { branchcode => $branch } >- } >- ); >- >- my $biblio = $builder->build_sample_biblio; >- my $item = $builder->build_sample_item( >- { >- biblionumber => $biblio->id, >- library => $branch, >- } >- ); >- >- my $due_date = dt_from_string->add( days => 7 )->ymd; >- >- # Test ProcessOfflineIssue returns both message and checkout object >- my ( $message, $checkout ) = ProcessOfflineIssue( >- { >- cardnumber => $borrower->{cardnumber}, >- barcode => $item->barcode, >- due_date => $due_date, >- timestamp => dt_from_string >- } >- ); >- >- is( $message, "Success.", "ProcessOfflineIssue returns success message" ); >- isa_ok( $checkout, 'Koha::Checkout', "ProcessOfflineIssue returns checkout object" ); >- is( $checkout->borrowernumber, $borrower->{borrowernumber}, "Checkout has correct borrower" ); >- is( dt_from_string( $checkout->date_due )->ymd, $due_date, "Checkout respects specified due_date" ); >-}; >- > $schema->storage->txn_rollback; >diff --git a/t/db_dependent/Circulation_holdsqueue.t b/t/db_dependent/Circulation_holdsqueue.t >index 33e2a2f791..5674fa11aa 100755 >--- a/t/db_dependent/Circulation_holdsqueue.t >+++ b/t/db_dependent/Circulation_holdsqueue.t >@@ -17,8 +17,7 @@ > > use Modern::Perl; > >-use Test::More tests => 2; >-use Test::NoWarnings; >+use Test::More tests => 1; > use Test::MockModule; > > use C4::Circulation qw( AddIssue AddReturn ); >diff --git a/t/db_dependent/Holds.t b/t/db_dependent/Holds.t >index 65b735676f..5157b1121e 100755 >--- a/t/db_dependent/Holds.t >+++ b/t/db_dependent/Holds.t >@@ -7,8 +7,7 @@ use t::lib::TestBuilder; > > use C4::Context; > >-use Test::More tests => 73; >-use Test::NoWarnings; >+use Test::More tests => 72; > use Test::Exception; > > use MARC::Record; >@@ -1654,7 +1653,7 @@ subtest 'non priority holds' => sub { > itemnumber => $item->itemnumber, > branchcode => $item->homebranch > } >- )->store->get_from_storage; >+ )->store; > > my $hid = AddReserve( > { >diff --git a/t/db_dependent/HoldsQueue/TransportCostOptimizations.t b/t/db_dependent/HoldsQueue/TransportCostOptimizations.t >index 933ab22e3f..b11b3ba073 100755 >--- a/t/db_dependent/HoldsQueue/TransportCostOptimizations.t >+++ b/t/db_dependent/HoldsQueue/TransportCostOptimizations.t >@@ -9,9 +9,7 @@ > > use Modern::Perl; > >-use Test::More tests => 120; >-use Test::NoWarnings; >-use Test::Warn; >+use Test::More tests => 117; > use Data::Dumper; > > use C4::Context; >@@ -216,32 +214,23 @@ sub test_allocation { > > $schema->txn_rollback; > } >-warning_like( >- sub { >- test_allocation( >- "trivial case", >- [], >- [], >- [], >- [], >- 0 >- ); >- }, >- qr{UseTransportCostMatrix set to yes, but matrix not populated} >+ >+test_allocation( >+ "trivial case", >+ [], >+ [], >+ [], >+ [], >+ 0 > ); > >-warning_like( >- sub { >- test_allocation( >- "unit case", >- [ [0] ], >- [1], >- [1], >- [ [ 0, 0 ] ], >- 0 >- ); >- }, >- qr{UseTransportCostMatrix set to yes, but matrix not populated} >+test_allocation( >+ "unit case", >+ [ [0] ], >+ [1], >+ [1], >+ [ [ 0, 0 ] ], >+ 0 > ); > > test_allocation( >diff --git a/t/db_dependent/Koha.t b/t/db_dependent/Koha.t >index a73738c940..986a8b354c 100755 >--- a/t/db_dependent/Koha.t >+++ b/t/db_dependent/Koha.t >@@ -11,7 +11,6 @@ use Test::Warn; > use Test::Deep; > > use t::lib::TestBuilder; >-use t::lib::Mocks; > > use C4::Context; > use Koha::Database; >@@ -34,7 +33,7 @@ my $dbh = C4::Context->dbh; > our $itype_1 = $builder->build( { source => 'Itemtype' } ); > > subtest 'Authorized Values Tests' => sub { >- plan tests => 5; >+ plan tests => 4; > > my $data = { > category => 'CATEGORY', >@@ -167,9 +166,6 @@ subtest 'Authorized Values Tests' => sub { > > warning_is { GetAuthorisedValues() } [], 'No warning when no parameter passed to GetAuthorisedValues'; > >- C4::Context->set_userenv(); >- warning_is { GetAuthorisedValues("BUG10656") } [], 'No warning when userenv is anonymous'; >- > }; > > subtest 'isbn tests' => sub { >diff --git a/t/db_dependent/Koha/Biblio.t b/t/db_dependent/Koha/Biblio.t >index f0d32ee300..446180240b 100755 >--- a/t/db_dependent/Koha/Biblio.t >+++ b/t/db_dependent/Koha/Biblio.t >@@ -1016,99 +1016,46 @@ subtest 'get_volumes_query' => sub { > }; > > subtest 'generate_marc_host_field' => sub { >- plan tests => 36; >+ plan tests => 24; > > $schema->storage->txn_begin; > >- # Set up MARC21 tests > t::lib::Mocks::mock_preference( 'marcflavour', 'MARC21' ); > >- # 1. Complete MARC21 record test >- my $record = MARC::Record->new(); >- $record->leader('00000nam a22000007a 4500'); >+ my $biblio = $builder->build_sample_biblio(); >+ my $record = $biblio->metadata->record; > $record->append_fields( >- MARC::Field->new( '001', '12345' ), >- MARC::Field->new( '003', 'NB' ), >- MARC::Field->new( '020', '', '', 'a' => '978-3-16-148410-0' ), >- MARC::Field->new( '022', '', '', 'a' => '1234-5678' ), >- MARC::Field->new( '100', '1', '', 'a' => 'Smith, John', 'e' => 'author', '9' => 'xyz', '4' => 'aut' ), >- MARC::Field->new( '245', '1', '0', 'a' => 'The Title', 'b' => 'Subtitle', 'c' => 'John Smith' ), >- MARC::Field->new( '250', '', '', 'a' => '2nd edition', 'b' => 'revised' ), >- MARC::Field->new( '260', '', '', 'a' => 'New York', 'b' => 'Publisher', 'c' => '2023' ), >- MARC::Field->new( '830', '', '', 'a' => 'Series Title', 'v' => 'vol. 2', 'x' => '2345-6789' ) >+ MARC::Field->new( '001', '1234' ), >+ MARC::Field->new( '003', 'FIRST' ), >+ MARC::Field->new( '240', '', '', a => 'A uniform title' ), >+ MARC::Field->new( '260', '', '', a => 'Publication 260' ), >+ MARC::Field->new( '250', '', '', a => 'Edition a', b => 'Edition b' ), >+ MARC::Field->new( '022', '', '', a => '0317-8471' ), > ); >- my ($biblio_id) = AddBiblio( $record, qw{} ); >- my $biblio = Koha::Biblios->find($biblio_id); >+ C4::Biblio::ModBiblio( $record, $biblio->biblionumber ); >+ $biblio = Koha::Biblios->find( $biblio->biblionumber ); > >- # Test MARC21 with UseControlNumber off >- t::lib::Mocks::mock_preference( 'UseControlNumber', 0 ); >+ t::lib::Mocks::mock_preference( 'UseControlNumber', '0' ); > my $link = $biblio->generate_marc_host_field(); > >- # Test standard MARC21 field >- is( ref($link), 'MARC::Field', 'Returns a MARC::Field object' ); >- is( $link->tag(), '773', 'Field tag is 773 for MARC21' ); >- is( $link->indicator(1), '0', 'First indicator is 0' ); >- is( $link->indicator(2), ' ', 'Second indicator is blank' ); >+ is( ref($link), 'MARC::Field', "->generate_marc_host_field returns a MARC::Field object" ); >+ is( $link->tag, '773', "MARC::Field->tag returns '773' when marcflavour is 'MARC21" ); >+ is( $link->subfield('a'), 'Some boring author', 'MARC::Field->subfield(a) returns content from 100ab' ); >+ is( $link->subfield('b'), 'Edition a Edition b', 'MARC::Field->subfield(b) returns content from 250ab' ); >+ is( $link->subfield('d'), 'Publication 260', 'MARC::Field->subfield(c) returns content from 260abc' ); >+ is( $link->subfield('s'), 'A uniform title', 'MARC::Field->subfield(s) returns content from 240a' ); >+ is( $link->subfield('t'), 'Some boring read', 'MARC::Field->subfield(s) returns content from 245ab' ); >+ is( $link->subfield('x'), '0317-8471', 'MARC::Field->subfield(s) returns content from 022a' ); >+ is( $link->subfield('z'), undef, 'MARC::Field->subfield(s) returns undef when 020a is empty' ); >+ is( $link->subfield('w'), undef, 'MARC::Field->subfield(w) returns undef when "UseControlNumber" is disabled' ); > >- # Check all subfields >- is( $link->subfield('7'), 'p1am', 'Subfield 7 correctly formed' ); >- is( $link->subfield('a'), 'Smith, John', 'Subfield a contains author from 100a' ); >- is( >- $link->subfield('t'), 'The Title Subtitle', >- 'Subfield t contains title without trailing punctuation from 245ab' >- ); >- is( $link->subfield('b'), '2nd edition revised', 'Subfield b contains edition info from 250ab' ); >- is( $link->subfield('d'), 'New York Publisher 2023', 'Subfield d contains publication info from 260abc' ); >- is( $link->subfield('k'), 'Series Title, ISSN 2345-6789 ; vol. 2', 'Subfield k contains series info from 830' ); >- is( $link->subfield('x'), '1234-5678', 'Subfield x contains ISSN from 022a' ); >- is( $link->subfield('z'), '978-3-16-148410-0', 'Subfield z contains ISBN from 020a' ); >- is( $link->subfield('w'), undef, 'Subfield w is undefined when UseControlNumber is disabled' ); >- >- # Test with UseControlNumber enabled > t::lib::Mocks::mock_preference( 'UseControlNumber', '1' ); > $link = $biblio->generate_marc_host_field(); > is( >- $link->subfield('w'), '(NB)12345', >- 'Subfield w contains control number with source when UseControlNumber is enabled' >+ $link->subfield('w'), '(FIRST)1234', >+ 'MARC::Field->subfield(w) returns content from 003 and 001 when "UseControlNumber" is enabled' > ); > >- # 245 punctuation handling tests >- # Trailing slash >- $record->field('245')->update( a => 'A title /', b => '', c => '', 'ind2' => '0' ); >- ($biblio_id) = AddBiblio( $record, qw{} ); >- $biblio = Koha::Biblios->find($biblio_id); >- $link = $biblio->generate_marc_host_field(); >- is( $link->subfield('t'), 'A title', "Trailing slash is removed from 245a" ); >- >- # Trailing period >- $record->field('245')->update( a => 'Another title.', 'ind2' => '0' ); >- ($biblio_id) = AddBiblio( $record, qw{} ); >- $biblio = Koha::Biblios->find($biblio_id); >- $link = $biblio->generate_marc_host_field(); >- is( $link->subfield('t'), 'Another title', "Trailing period is removed from 245a" ); >- >- # Offset from indicator 2 = 4 >- $record->field('245')->update( a => 'The offset title', 'ind2' => '4' ); >- ($biblio_id) = AddBiblio( $record, qw{} ); >- $biblio = Koha::Biblios->find($biblio_id); >- $link = $biblio->generate_marc_host_field(); >- is( $link->subfield('t'), 'Offset title', "Title offset applied from indicator 2" ); >- >- # Capitalization after offset >- $record->field('245')->update( a => 'the capital test', 'ind2' => '0' ); >- ($biblio_id) = AddBiblio( $record, qw{} ); >- $biblio = Koha::Biblios->find($biblio_id); >- $link = $biblio->generate_marc_host_field(); >- is( $link->subfield('t'), 'The capital test', "Title is capitalized after indicator offset" ); >- >- # 240 uniform title tests >- $record->append_fields( MARC::Field->new( '240', '1', '0', 'a' => 'Bible. English', 'l' => 'English' ) ); >- ($biblio_id) = AddBiblio( $record, qw{} ); >- $biblio = Koha::Biblios->find($biblio_id); >- $link = $biblio->generate_marc_host_field(); >- is( $link->subfield('s'), 'Bible. English', "Subfield s contains uniform title from 240a" ); >- >- # 260/264 handling tests > $record->append_fields( > MARC::Field->new( '264', '', '', a => 'Publication 264' ), > ); >@@ -1133,96 +1080,36 @@ subtest 'generate_marc_host_field' => sub { > 'MARC::Field->subfield(d) returns content from 264 with indicator 1 = 3 in preference to 264 without' > ); > >- # 2. Test MARC21 with corporate author (110) >- my $record_corporate = MARC::Record->new(); >- $record_corporate->leader('00000nam a22000007a 4500'); >- $record_corporate->append_fields( >- MARC::Field->new( '110', '2', '', 'a' => 'Corporate Author', 'e' => 'sponsor', '9' => 'xyz', '4' => 'spn' ), >- MARC::Field->new( '245', '1', '0', 'a' => 'The Title' ) >- ); >- ($biblio_id) = AddBiblio( $record_corporate, qw{} ); >- $biblio = Koha::Biblios->find($biblio_id); >- >- $link = $biblio->generate_marc_host_field(); >- is( $link->subfield('7'), 'c2am', 'Subfield 7 correctly formed for corporate author' ); >- is( $link->subfield('a'), 'Corporate Author', 'Subfield a contains corporate author' ); >- >- # 3. Test MARC21 with meeting name (111) >- my $record_meeting = MARC::Record->new(); >- $record_meeting->leader('00000nam a22000007a 4500'); >- $record_meeting->append_fields( >- MARC::Field->new( '111', '2', '', 'a' => 'Conference Name', 'j' => 'relator', '9' => 'xyz', '4' => 'spn' ), >- MARC::Field->new( '245', '1', '0', 'a' => 'The Title' ) >- ); >- ($biblio_id) = AddBiblio( $record_meeting, qw{} ); >- $biblio = Koha::Biblios->find($biblio_id); >- >- $link = $biblio->generate_marc_host_field(); >- is( $link->subfield('7'), 'm2am', 'Subfield 7 correctly formed for meeting name' ); >- >- # 4. Test MARC21 with minimal record >- my $record_minimal = MARC::Record->new(); >- $record_minimal->leader('00000nam a22000007a 4500'); >- $record_minimal->append_fields( MARC::Field->new( '245', '0', '0', 'a' => 'Title Only' ) ); >- ($biblio_id) = AddBiblio( $record_minimal, qw{} ); >- $biblio = Koha::Biblios->find($biblio_id); >- >- $link = $biblio->generate_marc_host_field(); >- is( $link->subfield('7'), 'nnam', 'Subfield 7 correctly formed with no main entry' ); >- >- # 5. Test UNIMARC >+ # UNIMARC tests > t::lib::Mocks::mock_preference( 'marcflavour', 'UNIMARC' ); >- $biblio = $builder->build_sample_biblio(); >- my $record_unimarc = MARC::Record->new(); >- $record_unimarc->append_fields( >- MARC::Field->new( '001', '54321' ), >- MARC::Field->new( '010', '', '', 'a' => '978-0-12-345678-9' ), >- MARC::Field->new( '011', '', '', 'a' => '2345-6789' ), >- MARC::Field->new( '200', '', '', 'a' => 'UNIMARC Title' ), >- MARC::Field->new( '205', '', '', 'a' => 'Third edition' ), >- MARC::Field->new( '210', '', '', 'a' => 'Paris', 'd' => '2023' ), >- MARC::Field->new( '700', '', '', 'a' => 'Doe', 'b' => 'Jane' ), >- MARC::Field->new( '856', '', '', 'u' => 'http://example.com' ) >- ); >- ($biblio_id) = AddBiblio( $record_unimarc, qw{} ); >- $biblio = Koha::Biblios->find($biblio_id); >- >- $link = $biblio->generate_marc_host_field(); > >- is( ref($link), 'MARC::Field', 'Returns a MARC::Field object for UNIMARC' ); >- is( $link->tag(), '461', 'Field tag is 461 for UNIMARC' ); >- is( $link->indicator(1), '0', 'First indicator is 0 for UNIMARC' ); >- is( $link->indicator(2), ' ', 'Second indicator is blank for UNIMARC' ); >- >- # Check UNIMARC subfields >- is( $link->subfield('a'), 'Doe Jane', 'Subfield a contains author for UNIMARC' ); >- is( $link->subfield('t'), 'UNIMARC Title', 'Subfield t contains title for UNIMARC' ); >- is( $link->subfield('c'), 'Paris', 'Subfield c contains place of publication for UNIMARC' ); >- is( $link->subfield('d'), '2023', 'Subfield d contains date of publication for UNIMARC' ); >- is( $link->subfield('0'), '54321', 'Subfield 0 contains control number for UNIMARC' ); >- >- # 6. Test UNIMARC with different author types >- my $record_unimarc_corporate = MARC::Record->new(); >- $record_unimarc_corporate->append_fields( >- MARC::Field->new( '710', '', '', 'a' => 'Corporate', 'b' => 'Department' ), >- MARC::Field->new( '200', '', '', 'a' => 'Title' ) >- ); >- C4::Biblio::ModBiblio( $record_unimarc_corporate, $biblio->biblionumber ); >- $biblio = Koha::Biblios->find( $biblio->biblionumber ); >- >- $link = $biblio->generate_marc_host_field(); >- is( $link->subfield('a'), 'Corporate Department', 'Subfield a contains corporate author for UNIMARC' ); >- >- my $record_unimarc_family = MARC::Record->new(); >- $record_unimarc_family->append_fields( >- MARC::Field->new( '720', '', '', 'a' => 'Family', 'b' => 'Name' ), >- MARC::Field->new( '200', '', '', 'a' => 'Title' ) >+ $biblio = $builder->build_sample_biblio(); >+ $record = $biblio->metadata->record; >+ $record->append_fields( >+ MARC::Field->new( '001', '1234' ), >+ MARC::Field->new( '700', '', '', a => 'A nice author' ), >+ MARC::Field->new( '210', '', '', a => 'A publication', d => 'A date' ), >+ MARC::Field->new( '205', '', '', a => "Fun things" ), >+ MARC::Field->new( '856', '', '', u => 'http://myurl.com/' ), >+ MARC::Field->new( '011', '', '', a => '0317-8471' ), >+ MARC::Field->new( '545', '', '', a => 'Invisible on OPAC' ), > ); >- C4::Biblio::ModBiblio( $record_unimarc_family, $biblio->biblionumber ); >+ C4::Biblio::ModBiblio( $record, $biblio->biblionumber ); > $biblio = Koha::Biblios->find( $biblio->biblionumber ); > > $link = $biblio->generate_marc_host_field(); >- is( $link->subfield('a'), 'Family Name', 'Subfield a contains family name for UNIMARC' ); >+ >+ is( ref($link), 'MARC::Field', "->generate_marc_host_field returns a MARC::Field object" ); >+ is( $link->tag, '461', "MARC::Field->tag returns '461' when marcflavour is 'UNIMARC" ); >+ is( $link->subfield('a'), 'A nice author', 'MARC::Field->subfield(a) returns content from 700ab' ); >+ is( $link->subfield('c'), 'A publication', 'MARC::Field->subfield(b) returns content from 210a' ); >+ is( $link->subfield('d'), 'A date', 'MARC::Field->subfield(c) returns content from 210d' ); >+ is( $link->subfield('e'), 'Fun things', 'MARC::Field->subfield(s) returns content from 205' ); >+ is( $link->subfield('t'), 'Some boring read', 'MARC::Field->subfield(s) returns content from 200a' ); >+ is( $link->subfield('u'), 'http://myurl.com/', 'MARC::Field->subfield(s) returns content from 856u' ); >+ is( $link->subfield('x'), '0317-8471', 'MARC::Field->subfield(s) returns content from 011a' ); >+ is( $link->subfield('y'), undef, 'MARC::Field->subfield(w) returns undef if 010a is empty' ); >+ is( $link->subfield('0'), '1234', 'MARC::Field->subfield(0) returns content from 001' ); > > $schema->storage->txn_rollback; > t::lib::Mocks::mock_preference( 'marcflavour', 'MARC21' ); >diff --git a/t/db_dependent/Koha/Booking.t b/t/db_dependent/Koha/Booking.t >index a63d37b120..f1fba22d66 100755 >--- a/t/db_dependent/Koha/Booking.t >+++ b/t/db_dependent/Koha/Booking.t >@@ -20,10 +20,7 @@ > use Modern::Perl; > use utf8; > >-use Test::More tests => 3; >-use Test::NoWarnings; >- >-use Test::Warn; >+use Test::More tests => 2; > > use Test::Exception; > >@@ -372,7 +369,7 @@ subtest 'store() tests' => sub { > }; > > subtest 'confirmation notice trigger' => sub { >- plan tests => 4; >+ plan tests => 2; > > # FIXME: This is a bandaid solution to prevent test failures when running > # the Koha_Main_My8 job because notices are not added at upgrade time. >@@ -415,16 +412,7 @@ subtest 'store() tests' => sub { > )->count; > > # Reuse previous booking to produce a clash >- warning_like( >- sub { >- throws_ok { >- Koha::Booking->new( $booking->unblessed )->store >- } >- 'Koha::Exceptions::Object::DuplicateID', >- 'Exception is thrown correctly'; >- }, >- qr{Duplicate entry '(.*?)' for key '(.*\.?)PRIMARY'} >- ); >+ eval { $booking = Koha::Booking->new( $booking->unblessed )->store }; > > my $post_notices_count = Koha::Notice::Messages->search( > { >@@ -624,17 +612,12 @@ subtest 'store() tests' => sub { > }; > > subtest 'status change exception' => sub { >- plan tests => 3; >+ plan tests => 2; > > $booking->discard_changes; > my $status = $booking->status; >- warning_like( >- sub { >- throws_ok { $booking->update( { status => 'blah' } ) } 'Koha::Exceptions::Object::BadValue', >- 'Throws exception when passed booking status would fail enum constraint'; >- }, >- qr{Data truncated for column 'status'} >- ); >+ throws_ok { $booking->update( { status => 'blah' } ) } 'Koha::Exceptions::Object::BadValue', >+ 'Throws exception when passed booking status would fail enum constraint'; > > # Status unchanged > $booking->discard_changes; >diff --git a/t/db_dependent/Koha/Hold.t b/t/db_dependent/Koha/Hold.t >index 55fe078227..46581eb6e0 100755 >--- a/t/db_dependent/Koha/Hold.t >+++ b/t/db_dependent/Koha/Hold.t >@@ -367,7 +367,7 @@ subtest 'fill() tests' => sub { > > t::lib::Mocks::mock_preference( 'RealTimeHoldsQueue', 1 ); > >- # Filling a hold when pref enabled should trigger a test >+ diag("Filling a hold when pref enabled should trigger a test"); > $builder->build_object( > { > class => 'Koha::Holds', >@@ -379,7 +379,7 @@ subtest 'fill() tests' => sub { > > t::lib::Mocks::mock_preference( 'RealTimeHoldsQueue', 0 ); > >- # Filling a hold when pref disabled should not trigger a test >+ diag("Filling a hold when pref disabled should not trigger a test"); > $builder->build_object( > { > class => 'Koha::Holds', >@@ -411,17 +411,16 @@ subtest 'fill() tests' => sub { > )->store; > > # Pref is off, no test triggered >- # Updating a hold location when pref disabled should not trigger a test >+ diag("Updating a hold location when pref disabled should not trigger a test"); > $hold->branchcode( $library_2->branchcode )->store; > > t::lib::Mocks::mock_preference( 'RealTimeHoldsQueue', 1 ); >- >- # Updating a hold location when pref enabled should trigger a test >+ diag("Updating a hold location when pref enabled should trigger a test"); > > # Pref is on, test triggered > $hold->branchcode( $library_1->branchcode )->store; > >- # Update with no change to pickup location should not trigger a test >+ diag("Update with no change to pickup location should not trigger a test"); > $hold->branchcode( $library_1->branchcode )->store; > > }; >diff --git a/t/db_dependent/Koha/Installer.t b/t/db_dependent/Koha/Installer.t >index f127bf0452..c9091d2bde 100755 >--- a/t/db_dependent/Koha/Installer.t >+++ b/t/db_dependent/Koha/Installer.t >@@ -18,8 +18,7 @@ > # along with Koha; if not, see <http://www.gnu.org/licenses>. > > use Modern::Perl; >-use Test::More tests => 5; >-use Test::NoWarnings; >+use Test::More tests => 4; > > use Test::MockModule; > use File::Temp qw/tempdir/; >diff --git a/t/db_dependent/Koha/Old/Hold.t b/t/db_dependent/Koha/Old/Hold.t >index 70b3368840..1204766b72 100755 >--- a/t/db_dependent/Koha/Old/Hold.t >+++ b/t/db_dependent/Koha/Old/Hold.t >@@ -17,8 +17,7 @@ > > use Modern::Perl; > >-use Test::More tests => 4; >-use Test::NoWarnings; >+use Test::More tests => 3; > use Test::Exception; > > use Koha::Database; >@@ -104,7 +103,7 @@ subtest 'biblio() tests' => sub { > my $hold_2 = $builder->build_object( > { > class => 'Koha::Old::Holds', >- value => { biblionumber => undef } >+ value => { biblionumber => '' } > } > ); > >diff --git a/t/db_dependent/Koha/Patron.t b/t/db_dependent/Koha/Patron.t >index 4f824aa782..be991cb43a 100755 >--- a/t/db_dependent/Koha/Patron.t >+++ b/t/db_dependent/Koha/Patron.t >@@ -739,8 +739,6 @@ subtest 'to_api() tests' => sub { > } > ); > >- t::lib::Mocks::mock_userenv( { patron => $consumer } ); >- > my $restricted = $patron->to_api( { user => $consumer } )->{restricted}; > ok( defined $restricted, 'restricted is defined' ); > ok( !$restricted, 'debarred is undef, restricted evaluates to false' ); >diff --git a/t/db_dependent/Koha/Patron/Modifications.t b/t/db_dependent/Koha/Patron/Modifications.t >index 147fc04dc8..f430fa452d 100755 >--- a/t/db_dependent/Koha/Patron/Modifications.t >+++ b/t/db_dependent/Koha/Patron/Modifications.t >@@ -19,8 +19,7 @@ use Modern::Perl; > > use utf8; > >-use Test::More tests => 8; >-use Test::NoWarnings; >+use Test::More tests => 7; > use Test::Exception; > > use t::lib::TestBuilder; >@@ -50,12 +49,9 @@ subtest 'new() tests' => sub { > > Koha::Patron::Modifications->search->delete; > >- my $patron = $builder->build_object( { class => 'Koha::Patrons' } ); >- > # Create new pending modification > Koha::Patron::Modification->new( > { >- borrowernumber => $patron->borrowernumber, > verification_token => '1234567890', > changed_fields => 'surname,firstname', > surname => 'Hall', >@@ -447,10 +443,9 @@ subtest 'dateofbirth tests' => sub { > { class => 'Koha::Patrons', value => { dateofbirth => '1980-01-01', surname => 'a_surname' } } ); > my $patron_modification = Koha::Patron::Modification->new( > { >- verification_token => '1234567890', >- changed_fields => 'borrowernumber,dateofbirth', >- borrowernumber => $patron->borrowernumber, >- dateofbirth => undef >+ changed_fields => 'borrowernumber,dateofbirth', >+ borrowernumber => $patron->borrowernumber, >+ dateofbirth => undef > } > )->store; > $patron_modification->approve; >@@ -464,10 +459,9 @@ subtest 'dateofbirth tests' => sub { > # Adding a dateofbirth > $patron_modification = Koha::Patron::Modification->new( > { >- verification_token => '1234567890', >- changed_fields => 'borrowernumber,dateofbirth', >- borrowernumber => $patron->borrowernumber, >- dateofbirth => '1980-02-02' >+ changed_fields => 'borrowernumber,dateofbirth', >+ borrowernumber => $patron->borrowernumber, >+ dateofbirth => '1980-02-02' > } > )->store; > $patron_modification->approve; >@@ -482,11 +476,10 @@ subtest 'dateofbirth tests' => sub { > # Modifying a dateofbirth > $patron_modification = Koha::Patron::Modification->new( > { >- verification_token => '1234567890', >- changed_fields => 'borrowernumber,dateofbirth', >- borrowernumber => $patron->borrowernumber, >- dateofbirth => '1980-03-03', >- surname => undef >+ changed_fields => 'borrowernumber,dateofbirth', >+ borrowernumber => $patron->borrowernumber, >+ dateofbirth => '1980-03-03', >+ surname => undef > } > )->store; > $patron_modification->approve; >@@ -501,11 +494,10 @@ subtest 'dateofbirth tests' => sub { > # Modifying something else > $patron_modification = Koha::Patron::Modification->new( > { >- verification_token => '1234567890', >- changed_fields => 'borrowernumber,surname', >- borrowernumber => $patron->borrowernumber, >- surname => 'another_surname', >- dateofbirth => undef >+ changed_fields => 'borrowernumber,surname', >+ borrowernumber => $patron->borrowernumber, >+ surname => 'another_surname', >+ dateofbirth => undef > } > )->store; > $patron_modification->approve; >diff --git a/t/db_dependent/Koha/Patrons.t b/t/db_dependent/Koha/Patrons.t >index 54595fecc6..ed7ad7a351 100755 >--- a/t/db_dependent/Koha/Patrons.t >+++ b/t/db_dependent/Koha/Patrons.t >@@ -2675,10 +2675,10 @@ subtest 'lock' => sub { > }; > > subtest 'anonymize' => sub { >- plan tests => 11; >+ plan tests => 10; > >- my $patron1 = $builder->build_object( { class => 'Koha::Patrons' } )->store; >- my $patron2 = $builder->build_object( { class => 'Koha::Patrons' } )->store; >+ my $patron1 = $builder->build_object( { class => 'Koha::Patrons' } ); >+ my $patron2 = $builder->build_object( { class => 'Koha::Patrons' } ); > > # First try patron with issues > my $issue = $builder->build_object( >@@ -2696,17 +2696,16 @@ subtest 'anonymize' => sub { > is( $patron1->firstname, undef, 'First name cleared' ); > isnt( $patron1->surname, $surname, 'Surname changed' ); > ok( $patron1->surname =~ /^\w{10}$/, 'Mandatory surname randomized' ); >- is( $patron1->branchcode, $branchcode, 'Branch code skipped' ); >- is( $patron1->email, undef, 'Email was mandatory, must be cleared' ); >- is( $patron1->checkprevcheckout, 'inherit', 'Enum checkprevcheckout is reset to the default value' ); >+ is( $patron1->branchcode, $branchcode, 'Branch code skipped' ); >+ is( $patron1->email, undef, 'Email was mandatory, must be cleared' ); > > # Test wrapper in Koha::Patrons >- $patron1->surname($surname)->store; # restore >+ $patron1->surname($surname)->store; # restore > my $rs = Koha::Patrons->search( { borrowernumber => [ $patron1->borrowernumber, $patron2->borrowernumber ] } ) > ->anonymize; >- $patron1->discard_changes; # refresh >+ $patron1->discard_changes; # refresh > isnt( $patron1->surname, $surname, 'Surname patron1 changed again' ); >- $patron2->discard_changes; # refresh >+ $patron2->discard_changes; # refresh > is( $patron2->firstname, undef, 'First name patron2 cleared' ); > }; > >diff --git a/t/db_dependent/Koha/Patrons/Import.t b/t/db_dependent/Koha/Patrons/Import.t >index 64e5f95a06..8949574a79 100755 >--- a/t/db_dependent/Koha/Patrons/Import.t >+++ b/t/db_dependent/Koha/Patrons/Import.t >@@ -18,8 +18,7 @@ > # along with Koha; if not, see <http://www.gnu.org/licenses>. > > use Modern::Perl; >-use Test::More tests => 181; >-use Test::NoWarnings; >+use Test::More tests => 180; > use Test::Warn; > use Test::Exception; > use Encode qw( encode_utf8 ); >diff --git a/t/db_dependent/Koha/Plugins/Patron.t b/t/db_dependent/Koha/Plugins/Patron.t >index da5382b64d..ebe4531b08 100755 >--- a/t/db_dependent/Koha/Plugins/Patron.t >+++ b/t/db_dependent/Koha/Plugins/Patron.t >@@ -16,10 +16,8 @@ > > use Modern::Perl; > >-use Test::More tests => 6; >-use Test::NoWarnings; >+use Test::More tests => 5; > use Test::Exception; >-use Test::MockModule; > > use File::Basename; > >@@ -53,10 +51,6 @@ subtest 'check_password hook tests' => sub { > my $plugins = Koha::Plugins->new; > $plugins->InstallPlugins; > >- # Mock patron_barcode_transform: we don't want to call it as it generates warnings >- my $plugin_mock = Test::MockModule->new("Koha::Plugin::Test"); >- $plugin_mock->mock( "patron_barcode_transform", sub { } ); >- > # Test Plugin enforces a 4 digit numeric pin for passwords > my $plugin = Koha::Plugin::Test->new->enable; > >diff --git a/t/db_dependent/Koha/Reports.t b/t/db_dependent/Koha/Reports.t >index 205b1df60a..9778357d87 100755 >--- a/t/db_dependent/Koha/Reports.t >+++ b/t/db_dependent/Koha/Reports.t >@@ -18,7 +18,7 @@ > use Modern::Perl; > > use Test::NoWarnings; >-use Test::More tests => 9; >+use Test::More tests => 10; > > use Koha::Report; > use Koha::Reports; >@@ -185,4 +185,40 @@ subtest '_might_add_limit' => sub { > ); > }; > >+subtest 'reports_branches are added and removed from report_branches table' => sub { >+ plan tests => 4; >+ >+ my $updated_nb_of_reports = Koha::Reports->search->count; >+ my $report = Koha::Report->new( >+ { >+ report_name => 'report_name_for_test_1', >+ savedsql => 'SELECT * FROM items WHERE itemnumber IN <<Test|list>>', >+ } >+ )->store; >+ >+ my $id = $report->id; >+ my $library1 = $builder->build_object( { class => 'Koha::Libraries' } ); >+ my $library2 = $builder->build_object( { class => 'Koha::Libraries' } ); >+ my $library3 = $builder->build_object( { class => 'Koha::Libraries' } ); >+ my @branches = ( $library1->branchcode, $library2->branchcode, $library3->branchcode ); >+ >+ $report->replace_library_limits( \@branches ); >+ >+ my @branches_loop = $report->get_library_limits->as_list; >+ is( scalar @branches_loop, 3, '3 branches added to report_branches table' ); >+ >+ $report->replace_library_limits( [ $library1->branchcode, $library2->branchcode ] ); >+ >+ @branches_loop = $report->get_library_limits->as_list; >+ is( scalar @branches_loop, 2, '1 branch removed from report_branches table' ); >+ >+ $report->delete; >+ is( Koha::Reports->search->count, $updated_nb_of_reports, 'Report deleted, count is back to original' ); >+ is( >+ $schema->resultset('ReportsBranch')->search( { report_id => $id } )->count, >+ 0, >+ 'No branches left in reports_branches table after report deletion' >+ ); >+}; >+ > $schema->storage->txn_rollback; >diff --git a/t/db_dependent/Koha/SearchEngine/Elasticsearch.t b/t/db_dependent/Koha/SearchEngine/Elasticsearch.t >index 66b267fc34..2e4b3402ec 100755 >--- a/t/db_dependent/Koha/SearchEngine/Elasticsearch.t >+++ b/t/db_dependent/Koha/SearchEngine/Elasticsearch.t >@@ -18,9 +18,7 @@ > use Modern::Perl; > use Encode; > >-use Test::More tests => 9; >-use Test::NoWarnings; >-use Test::Warn; >+use Test::More tests => 8; > use Test::Exception; > > use t::lib::Mocks; >@@ -211,7 +209,7 @@ subtest 'get_elasticsearch_mappings() tests' => sub { > > subtest 'Koha::SearchEngine::Elasticsearch::marc_records_to_documents () tests' => sub { > >- plan tests => 71; >+ plan tests => 70; > > t::lib::Mocks::mock_preference( 'marcflavour', 'MARC21' ); > t::lib::Mocks::mock_preference( 'ElasticsearchMARCFormat', 'base64ISO2709' ); >@@ -853,10 +851,7 @@ subtest 'Koha::SearchEngine::Elasticsearch::marc_records_to_documents () tests' > MARC::Field->new( '999', '', '', c => '1234567' ), > ); > >- warning_is { >- $docs = $see->marc_records_to_documents( [$marc_record_with_large_field] ); >- } >- "Warnings encountered while roundtripping a MARC record to/from USMARC. Failing over to MARCXML."; >+ $docs = $see->marc_records_to_documents( [$marc_record_with_large_field] ); > > subtest '_process_mappings() split tests' => sub { > >@@ -1230,18 +1225,21 @@ subtest 'marc_records_to_documents should set the "available" field' => sub { > # sort_fields will call this and use the actual db values unless we call it first > $see->get_elasticsearch_mappings(); > >- my $builder = t::lib::TestBuilder->new; >- my $biblio = $builder->build_sample_biblio; >- my $marc_record_1 = $biblio->metadata->record; >+ my $marc_record_1 = MARC::Record->new(); >+ $marc_record_1->leader(' cam 22 a 4500'); >+ $marc_record_1->append_fields( >+ MARC::Field->new( '245', '', '', a => 'Title' ), >+ ); >+ my ($biblionumber) = C4::Biblio::AddBiblio( $marc_record_1, '' ); > > my $docs = $see->marc_records_to_documents( [$marc_record_1] ); > is_deeply( $docs->[0]->{available}, \0, 'a biblio without items is not available' ); > >- my $item = $builder->build_sample_item( >+ my $item = Koha::Item->new( > { >- biblionumber => $biblio->biblionumber, >+ biblionumber => $biblionumber, > } >- ); >+ )->store(); > > $docs = $see->marc_records_to_documents( [$marc_record_1] ); > is_deeply( $docs->[0]->{available}, \1, 'a biblio with one item that has no particular status is available' ); >@@ -1266,11 +1264,11 @@ subtest 'marc_records_to_documents should set the "available" field' => sub { > $docs = $see->marc_records_to_documents( [$marc_record_1] ); > is_deeply( $docs->[0]->{available}, \1, 'a biblio with one item that is damaged is available' ); > >- my $item2 = $builder->build_sample_item( >+ my $item2 = Koha::Item->new( > { >- biblionumber => $biblio->biblionumber, >+ biblionumber => $biblionumber, > } >- ); >+ )->store(); > $docs = $see->marc_records_to_documents( [$marc_record_1] ); > is_deeply( > $docs->[0]->{available}, \1, >diff --git a/t/db_dependent/Koha/SearchEngine/Elasticsearch/ExportConfig.t b/t/db_dependent/Koha/SearchEngine/Elasticsearch/ExportConfig.t >index f14e253b68..9fc6f7b57c 100755 >--- a/t/db_dependent/Koha/SearchEngine/Elasticsearch/ExportConfig.t >+++ b/t/db_dependent/Koha/SearchEngine/Elasticsearch/ExportConfig.t >@@ -17,8 +17,7 @@ > > use Modern::Perl; > >-use Test::More tests => 20; >-use Test::NoWarnings; >+use Test::More tests => 19; > > use Koha::Database; > use Koha::SearchFields; >@@ -60,8 +59,7 @@ $search_field->add_to_search_marc_maps( > { > facet => 0, > suggestible => 0, >- sort => 0, >- filter => '', >+ sort => 0 > } > ); > >@@ -78,8 +76,7 @@ $search_field->add_to_search_marc_maps( > { > facet => 0, > suggestible => 0, >- sort => 0, >- filter => '', >+ sort => 0 > } > ); > >@@ -96,8 +93,7 @@ $search_field->add_to_search_marc_maps( > { > facet => 0, > suggestible => 1, >- sort => 0, >- filter => '', >+ sort => 0 > } > ); > >diff --git a/t/db_dependent/Koha/SearchEngine/Elasticsearch/Search.t b/t/db_dependent/Koha/SearchEngine/Elasticsearch/Search.t >index d5b8790abe..5e71ba5f31 100755 >--- a/t/db_dependent/Koha/SearchEngine/Elasticsearch/Search.t >+++ b/t/db_dependent/Koha/SearchEngine/Elasticsearch/Search.t >@@ -17,8 +17,7 @@ > > use Modern::Perl; > >-use Test::More tests => 15; >-use Test::NoWarnings; >+use Test::More tests => 14; > use t::lib::Mocks; > use t::lib::TestBuilder; > >diff --git a/t/db_dependent/Letters.t b/t/db_dependent/Letters.t >index 5cdf9b289d..4edf7c80f5 100755 >--- a/t/db_dependent/Letters.t >+++ b/t/db_dependent/Letters.t >@@ -19,8 +19,7 @@ > > use Modern::Perl; > use File::Basename qw(dirname); >-use Test::More tests => 105; >-use Test::NoWarnings; >+use Test::More tests => 104; > > use Test::MockModule; > use Test::Warn; >diff --git a/t/db_dependent/Overdues.t b/t/db_dependent/Overdues.t >index f17ee28d18..979f378a25 100755 >--- a/t/db_dependent/Overdues.t >+++ b/t/db_dependent/Overdues.t >@@ -1,8 +1,7 @@ > #!/usr/bin/perl; > > use Modern::Perl; >-use Test::More tests => 19; >-use Test::NoWarnings; >+use Test::More tests => 18; > use Test::Warn; > > use C4::Context; >@@ -550,9 +549,10 @@ subtest 'UpdateFine tests' => sub { > { order_by => { '-asc' => 'accountlines_id' } } > ); > is( $fines->count, 4, "New amount should be 0 so no fine added" ); >- t::lib::Mocks::mock_userenv( { patron => $patron_1 } ); >- my @r = C4::Circulation::AddReturn( $item_1->barcode, $item_1->homebranch, 1 ); >- is( $r[1]->{WasReturned}, 1, "Returning the item and forgiving fines succeeds" ); >+ ok( >+ C4::Circulation::AddReturn( $item_1->barcode, $item_1->homebranch, 1 ), >+ "Returning the item and forgiving fines succeeds" >+ ); > > t::lib::Mocks::mock_preference( 'MaxFine', 0 ); > >diff --git a/t/db_dependent/Reserves.t b/t/db_dependent/Reserves.t >index cced1feee7..a922452815 100755 >--- a/t/db_dependent/Reserves.t >+++ b/t/db_dependent/Reserves.t >@@ -17,8 +17,7 @@ > > use Modern::Perl; > >-use Test::More tests => 71; >-use Test::NoWarnings; >+use Test::More tests => 70; > use Test::MockModule; > use Test::Warn; > >@@ -414,14 +413,7 @@ is( > $which_highest->{reserve_id}, $reserve_id, > 'CheckReserves returns higher priority future reserve with sufficient lookahead' > ); >- >-{ >- # Prevent warning 'No reserves HOLD_CANCELLATION letter transported by email' >- my $mock_letters = Test::MockModule->new('C4::Letters'); >- $mock_letters->mock( 'GetPreparedLetter', sub { return } ); >- >- ModReserve( { reserve_id => $now_reserve_id, rank => 'del', cancellation_reason => 'test reserve' } ); >-} >+ModReserve( { reserve_id => $now_reserve_id, rank => 'del', cancellation_reason => 'test reserve' } ); > > # End of tests for bug 9761 (ConfirmFutureHolds) > >diff --git a/t/db_dependent/Reserves/CancelExpiredReserves.t b/t/db_dependent/Reserves/CancelExpiredReserves.t >index 2cc84788ed..b9713ebd14 100755 >--- a/t/db_dependent/Reserves/CancelExpiredReserves.t >+++ b/t/db_dependent/Reserves/CancelExpiredReserves.t >@@ -1,9 +1,7 @@ > #!/usr/bin/perl > > use Modern::Perl; >-use Test::More tests => 5; >-use Test::NoWarnings; >-use Test::MockModule; >+use Test::More tests => 4; > > use t::lib::Mocks; > use t::lib::TestBuilder; >@@ -242,13 +240,7 @@ subtest 'Test handling of cancellation reason if passed' => sub { > ); > my $reserve_id = $reserve->{reserve_id}; > my $count = Koha::Holds->search->count; >- { >- # Prevent warning 'No reserves HOLD_CANCELLATION letter transported by email' >- my $mock_letters = Test::MockModule->new('C4::Letters'); >- $mock_letters->mock( 'GetPreparedLetter', sub { return } ); >- >- CancelExpiredReserves("EXPIRED"); >- } >+ CancelExpiredReserves("EXPIRED"); > is( Koha::Holds->search->count, $count - 1, "Hold is cancelled when reason is passed" ); > my $old_reserve = Koha::Old::Holds->find($reserve_id); > is( $old_reserve->cancellation_reason, 'EXPIRED', "Hold cancellation_reason was set correctly" ); >diff --git a/t/db_dependent/SIP/Transaction.t b/t/db_dependent/SIP/Transaction.t >index b121b9c7c4..a07033def5 100755 >--- a/t/db_dependent/SIP/Transaction.t >+++ b/t/db_dependent/SIP/Transaction.t >@@ -983,7 +983,7 @@ subtest do_checkout_with_patron_blocked => sub { > }; > > subtest do_checkout_with_noblock => sub { >- plan tests => 3; >+ plan tests => 1; > > my $mockILS = Test::MockObject->new; > my $server = { ils => $mockILS }; >@@ -1033,25 +1033,6 @@ subtest do_checkout_with_noblock => sub { > $patron->checkouts->count, > 1, 'No Block checkout was performed for debarred patron' > ); >- >- # Test Bug 32934: SIP checkout with no_block_due_date should honor the specified due date >- $sip_patron = C4::SIP::ILS::Patron->new( $patron->cardnumber ); >- my $sip_item_2 = C4::SIP::ILS::Item->new( $item->barcode ); >- my $transaction = C4::SIP::ILS::Transaction::Checkout->new(); >- >- $transaction->patron($sip_patron); >- $transaction->item($sip_item_2); >- >- # Set no_block_due_date to test the fix (YYYYMMDDZZZZHHMMSS) >- my $expected_due_date = '20250115 000000'; >- my $checkout_result = $transaction->do_checkout( undef, $expected_due_date ); >- >- my $checkout_obj = $patron->checkouts->find( { itemnumber => $item->itemnumber } ); >- isnt( $checkout_obj, undef, 'Checkout object exists after no block checkout' ); >- like( >- dt_from_string( $checkout_obj->date_due )->ymd(''), qr/^20250115/, >- 'No block due date is honored in SIP checkout' >- ); > }; > > subtest do_checkout_with_holds => sub { >diff --git a/t/db_dependent/Search.t b/t/db_dependent/Search.t >index beaf6cb43a..9249bca11d 100755 >--- a/t/db_dependent/Search.t >+++ b/t/db_dependent/Search.t >@@ -170,8 +170,6 @@ $contextmodule->mock( > return q{}; > } elsif ( $pref eq 'COinSinOPACResults' ) { > return q{}; >- } elsif ( $pref eq 'FacetSortingLocale' ) { >- return 'default'; > } else { > warn > "The syspref $pref was requested but I don't know what to say; this indicates that the test requires updating" >diff --git a/t/db_dependent/Search_FacetSorting.t b/t/db_dependent/Search_FacetSorting.t >deleted file mode 100755 >index a65abc9171..0000000000 >--- a/t/db_dependent/Search_FacetSorting.t >+++ /dev/null >@@ -1,119 +0,0 @@ >-#!/usr/bin/perl >- >-# This file is part of Koha. >-# >-# Koha is free software; you can redistribute it and/or modify it >-# under the terms of the GNU General Public License as published by >-# the Free Software Foundation; either version 3 of the License, or >-# (at your option) any later version. >-# >-# Koha is distributed in the hope that it will be useful, but >-# WITHOUT ANY WARRANTY; without even the implied warranty of >-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >-# GNU General Public License for more details. >-# >-# You should have received a copy of the GNU General Public License >-# along with Koha; if not, see <http://www.gnu.org/licenses>. >- >-use Modern::Perl; >- >-use Test::NoWarnings; >-use Test::More tests => 3; >-use Test::MockModule; >-use t::lib::Mocks; >-use C4::Search; >- >-use utf8; >- >-subtest '_sort_facets_zebra with system preference' => sub { >- plan tests => 3; >- >- my $facets = _get_facets(); >- >- # Test with explicit locale parameter >- my $sorted_facets_explicit = C4::Search::_sort_facets_zebra( $facets, 'default' ); >- my $expected = [ >- { facet_label_value => 'Ãberg, Erik' }, >- { facet_label_value => 'ari' }, >- { facet_label_value => 'Ari' }, >- { facet_label_value => 'Ãuthor' }, >- { facet_label_value => 'étienne' }, >- { facet_label_value => 'fairy' }, >- { facet_label_value => 'Fairy' }, >- { facet_label_value => 'harry' }, >- { facet_label_value => 'Harry' }, >- { facet_label_value => 'mary' }, >- { facet_label_value => 'Mary' }, >- { facet_label_value => 'Å ostakovitÅ¡, Dmitri' }, >- { facet_label_value => 'Zambidis' }, >- ]; >- is_deeply( $sorted_facets_explicit, $expected, "Zebra facets sorted correctly with explicit locale" ); >- >- # Test with system preference >- t::lib::Mocks::mock_preference( 'FacetSortingLocale', 'default' ); >- my $sorted_facets_syspref = C4::Search::_sort_facets_zebra($facets); >- is_deeply( $sorted_facets_syspref, $expected, "Zebra facets sorted correctly with system preference" ); >- >- # Test fallback behavior >- t::lib::Mocks::mock_preference( 'FacetSortingLocale', '' ); >- my $sorted_facets_fallback = C4::Search::_sort_facets_zebra($facets); >- is( ref($sorted_facets_fallback), 'ARRAY', "Zebra facets sorting fallback works" ); >-}; >- >-subtest '_sort_facets_zebra with fi_FI locale' => sub { >- plan tests => 1; >- my $locale_map = _get_locale_map(); >-SKIP: { >- skip( "fi_FI.utf8 locale not available on this system", 1 ) unless $locale_map->{"fi_FI.utf8"}; >- >- my $facets = _get_facets(); >- >- # Test with explicit locale parameter >- my $sorted_facets_explicit = C4::Search::_sort_facets_zebra( $facets, 'fi_FI' ); >- my $expected = [ >- { facet_label_value => 'ari' }, >- { facet_label_value => 'Ari' }, >- { facet_label_value => 'étienne' }, >- { facet_label_value => 'fairy' }, >- { facet_label_value => 'Fairy' }, >- { facet_label_value => 'harry' }, >- { facet_label_value => 'Harry' }, >- { facet_label_value => 'mary' }, >- { facet_label_value => 'Mary' }, >- { facet_label_value => 'Å ostakovitÅ¡, Dmitri' }, >- { facet_label_value => 'Zambidis' }, >- { facet_label_value => 'Ãberg, Erik' }, >- { facet_label_value => 'Ãuthor' }, >- ]; >- is_deeply( $sorted_facets_explicit, $expected, "Zebra facets sorted correctly with explicit locale" ); >- } >-}; >- >-sub _get_facets { >- my $facets = [ >- { facet_label_value => 'Mary' }, >- { facet_label_value => 'Harry' }, >- { facet_label_value => 'Fairy' }, >- { facet_label_value => 'Ari' }, >- { facet_label_value => 'mary' }, >- { facet_label_value => 'harry' }, >- { facet_label_value => 'Ãberg, Erik' }, >- { facet_label_value => 'Ãuthor' }, >- { facet_label_value => 'fairy' }, >- { facet_label_value => 'ari' }, >- { facet_label_value => 'étienne' }, >- { facet_label_value => 'Å ostakovitÅ¡, Dmitri' }, >- { facet_label_value => 'Zambidis' }, >- ]; >- return $facets; >-} >- >-sub _get_locale_map { >- my $map = {}; >- my @locales = `locale -a`; >- foreach my $locale (@locales) { >- chomp($locale); >- $map->{$locale} = 1; >- } >- return $map; >-} >diff --git a/t/db_dependent/api/v1/biblios.t b/t/db_dependent/api/v1/biblios.t >index e337c37604..b3a457b269 100755 >--- a/t/db_dependent/api/v1/biblios.t >+++ b/t/db_dependent/api/v1/biblios.t >@@ -20,8 +20,7 @@ use Modern::Perl; > use utf8; > use Encode; > >-use Test::More tests => 16; >-use Test::NoWarnings; >+use Test::More tests => 15; > use Test::MockModule; > use Test::Mojo; > use Test::Warn; >@@ -1890,7 +1889,7 @@ subtest 'list() tests' => sub { > > subtest 'add_item() tests' => sub { > >- plan tests => 10; >+ plan tests => 8; > > $schema->storage->txn_begin; > >@@ -1940,20 +1939,17 @@ subtest 'add_item() tests' => sub { > > my $item = $builder->build_sample_item(); > >- warnings_like { >- $t->post_ok( >- "//$userid:$password@/api/v1/biblios/$biblio_id/items" => json => { >- external_id => $item->barcode, >- } >- )->status_is( 409, 'Duplicate barcode' )->json_is( "/error" => "Duplicate barcode." ); >- } >- qr{DBD::mysql::st execute failed: Duplicate entry '(.*?)' for key '(.*\.?)itembarcodeidx'}; >+ $t->post_ok( >+ "//$userid:$password@/api/v1/biblios/$biblio_id/items" => json => { >+ external_id => $item->barcode, >+ } >+ )->status_is( 409, 'Duplicate barcode' ); > > $schema->storage->txn_rollback; > }; > > subtest 'update_item() tests' => sub { >- plan tests => 9; >+ plan tests => 7; > > $schema->storage->txn_begin; > >@@ -1997,14 +1993,11 @@ subtest 'update_item() tests' => sub { > > my $other_item = $builder->build_sample_item(); > >- warnings_like { >- $t->put_ok( >- "//$userid:$password@/api/v1/biblios/$biblio_id/items/$item_id" => json => { >- external_id => $other_item->barcode, >- } >- )->status_is( 409, 'Barcode not unique' )->json_is( "/error" => "Duplicate barcode." ); >- } >- qr{DBD::mysql::st execute failed: Duplicate entry '(.*?)' for key '(.*\.?)itembarcodeidx'}; >+ $t->put_ok( >+ "//$userid:$password@/api/v1/biblios/$biblio_id/items/$item_id" => json => { >+ external_id => $other_item->barcode, >+ } >+ )->status_is( 409, 'Barcode not unique' ); > > $t->put_ok( > "//$userid:$password@/api/v1/biblios/$biblio_id/items/$item_id" => json => { >diff --git a/t/db_dependent/api/v1/holds.t b/t/db_dependent/api/v1/holds.t >index 728de95644..9f13cb3a4d 100755 >--- a/t/db_dependent/api/v1/holds.t >+++ b/t/db_dependent/api/v1/holds.t >@@ -17,8 +17,7 @@ > > use Modern::Perl; > >-use Test::More tests => 17; >-use Test::NoWarnings; >+use Test::More tests => 16; > use Test::MockModule; > use Test::Mojo; > use t::lib::TestBuilder; >@@ -200,10 +199,6 @@ subtest "Test endpoints with permission" => sub { > > plan tests => 45; > >- # Prevent warning 'No reserves HOLD_CANCELLATION letter transported by email' >- my $mock_letters = Test::MockModule->new('C4::Letters'); >- $mock_letters->mock( 'GetPreparedLetter', sub { return } ); >- > $t->get_ok("//$userid_1:$password@/api/v1/holds")->status_is(200)->json_has('/0')->json_has('/1')->json_hasnt('/2'); > > $t->get_ok("//$userid_1:$password@/api/v1/holds?priority=2")->status_is(200) >diff --git a/t/db_dependent/api/v1/two_factor_auth.t b/t/db_dependent/api/v1/two_factor_auth.t >index ddb9178e3a..1ddc0cd4b5 100755 >--- a/t/db_dependent/api/v1/two_factor_auth.t >+++ b/t/db_dependent/api/v1/two_factor_auth.t >@@ -17,8 +17,7 @@ > > use Modern::Perl; > >-use Test::More tests => 3; >-use Test::NoWarnings; >+use Test::More tests => 2; > use Test::Mojo; > use Test::MockModule; > >diff --git a/t/db_dependent/selenium/basic_workflow.t b/t/db_dependent/selenium/basic_workflow.t >index dc96e9125b..b1134aeb54 100755 >--- a/t/db_dependent/selenium/basic_workflow.t >+++ b/t/db_dependent/selenium/basic_workflow.t >@@ -32,9 +32,6 @@ > > use Modern::Perl; > >-use Test::More tests => 23; >-use Test::NoWarnings; >- > use Time::HiRes qw(gettimeofday); > use POSIX qw(strftime); > use C4::Context; >@@ -42,6 +39,7 @@ use C4::Biblio qw( AddBiblio ); > > use Koha::CirculationRules; > >+use Test::More tests => 22; > use MARC::Record; > use MARC::Field; > >@@ -328,7 +326,6 @@ sub cleanup { > sub time_diff { > my $lib = shift; > my $now = gettimeofday; >- >- #warn "CP $lib = " . sprintf( "%.2f", $now - $prev_time ) . "\n"; >+ warn "CP $lib = " . sprintf( "%.2f", $now - $prev_time ) . "\n"; > $prev_time = $now; > } >diff --git a/t/db_dependent/selenium/opac_ill_requests.t b/t/db_dependent/selenium/opac_ill_requests.t >index 20f1d49b3d..5f022dbe9b 100755 >--- a/t/db_dependent/selenium/opac_ill_requests.t >+++ b/t/db_dependent/selenium/opac_ill_requests.t >@@ -53,15 +53,14 @@ SKIP: { > 'Correctly in search results page' > ); > >- # Get the second li, the first one is "Make a purchase suggestion" > is( >- $driver->find_element('//div[@class="suggestion"]/ul/li[2]')->get_text, >+ $driver->find_element('//div[@class="suggestion"]/ul/li')->get_text, > 'Make an interlibrary loan request', > 'Placing an ILL request through the OPAC is allowed', > ); > > # Clicking on the search results page link works >- $driver->find_element('//div[@class="suggestion"]/ul/li[2]/a')->click; >+ $driver->find_element('//div[@class="suggestion"]/ul/li/a')->click; > is( > $driver->find_element('(//nav[@id="breadcrumbs"]/ol/li)[last()]')->get_text, > 'New interlibrary loan request', >@@ -95,8 +94,8 @@ SKIP: { > > is( > scalar @{$link_exists}, >- 2, >- 'Search page - Place ILL request link should be present. ' >+ 0, >+ 'Search page - Place ILL request link should be absent. ' > ); > > # Visiting the create request page directly does not work >diff --git a/t/db_dependent/selenium/regressions.t b/t/db_dependent/selenium/regressions.t >index 790cda2383..a55d9b2876 100755 >--- a/t/db_dependent/selenium/regressions.t >+++ b/t/db_dependent/selenium/regressions.t >@@ -17,13 +17,11 @@ > > use Modern::Perl; > use utf8; >-use Encode qw(encode_utf8); > > use C4::Context; > > use Test::More; > use Test::MockModule; >-use Test::NoWarnings; > > use C4::Context; > use C4::Biblio qw( AddBiblio ); >@@ -38,7 +36,7 @@ eval { require Selenium::Remote::Driver; }; > if ($@) { > plan skip_all => "Selenium::Remote::Driver is needed for selenium tests."; > } else { >- plan tests => 10; >+ plan tests => 9; > } > > my $s = t::lib::Selenium->new; >@@ -356,10 +354,7 @@ subtest 'Encoding in session variables' => sub { > is( > $driver->find_element('//span[@class="logged-in-branch-name"]')->get_text(), > $branchname, >- sprintf( >- "logged-in-branch-name set - SessionStorage=%s, branchname=%s", $SessionStorage, >- encode_utf8($branchname) >- ) >+ sprintf( "logged-in-branch-name set - SessionStorage=%s, branchname=%s", $SessionStorage, $branchname ) > ); > > $driver->find_element('//input[@id="barcode"]')->send_keys( $item->barcode ); >@@ -377,7 +372,7 @@ subtest 'Encoding in session variables' => sub { > $branchname, > sprintf( > "'Checked out from' column should contain the branchname - SessionStorage=%s, branchname=%s", >- $SessionStorage, encode_utf8($branchname) >+ $SessionStorage, $branchname > ) > ); > >diff --git a/t/dummy.t b/t/dummy.t >new file mode 100755 >index 0000000000..3eb62d4679 >--- /dev/null >+++ b/t/dummy.t >@@ -0,0 +1,4 @@ >+# Dummy test until Test::Harness or similar >+# is used by the other tests to check deps. >+use Modern::Perl; >+print "1..1\nok 1\n"; >diff --git a/xt/api.t b/xt/api.t >index 2f55b0c027..78cf588c24 100755 >--- a/xt/api.t >+++ b/xt/api.t >@@ -14,18 +14,15 @@ > > use Modern::Perl; > >-use Test::More tests => 8; >-use Test::NoWarnings; >+use Test::More tests => 6; > > use Test::Mojo; > use Data::Dumper; >-use Koha::Database; > > use FindBin(); > use IPC::Cmd qw(can_run); > use List::MoreUtils qw(any); > use File::Slurp qw(read_file); >-use YAML::XS qw(LoadFile); > > my $t = Test::Mojo->new('Koha::REST::V1'); > my $spec = $t->get_ok( '/api/v1/', 'Correctly fetched the spec' )->tx->res->json; >@@ -197,45 +194,3 @@ subtest 'POST (201) have location header' => sub { > } > } > }; >- >-subtest 'maxlength + enum' => sub { >- my $def_map = { >- >- # api def => schema >- item => 'Item', >- library => 'Branch', >- patron => 'Borrower', >- patron_category => 'Category', >- }; >- plan tests => scalar keys %$def_map; >- my $schema = Koha::Database->new->schema; >- while ( my ( $def, $dbic_src ) = each %$def_map ) { >- my @failures; >- my $definition = LoadFile("api/v1/swagger/definitions/$def.yaml"); >- my $source = $schema->source($dbic_src); >- my $object_class = Koha::Object::_get_object_class( $source->result_class ); >- eval "require $object_class"; >- my $koha_object = $object_class->new; >- my $api_mapping = $koha_object->to_api_mapping; >- my $reversed_api_mapping = >- { reverse map { defined $api_mapping->{$_} ? ( $_ => $api_mapping->{$_} ) : () } keys %$api_mapping }; >- >- while ( my ( $attr, $properties ) = each %{ $definition->{properties} } ) { >- my $db_col = $reversed_api_mapping->{$attr}; >- next unless $db_col; >- my $column_info = $koha_object->_result->column_info($db_col); >- next unless $column_info->{size}; >- >- next if ref( $column_info->{size} ) eq 'ARRAY'; # decimal # FIXME Could have a test for this as well >- >- next >- if $properties->{enum} >- ; # FIXME This is not fully correct, we might want to make sure enum is set for both DB and spec. eg. now checkprevcheckout is enum only for the api spec >- >- if ( !exists $properties->{maxLength} || $column_info->{size} != $properties->{maxLength} ) { >- push @failures, sprintf "%s.%s should have maxLength=%s in api spec", $def, $attr, $column_info->{size}; >- } >- } >- is( scalar(@failures), 0, "maxLength tests for $def" ) or diag Dumper @failures; >- } >-}; >diff --git a/xt/author/codespell.t b/xt/author/codespell.t >index e31799ca51..781d1acd97 100755 >--- a/xt/author/codespell.t >+++ b/xt/author/codespell.t >@@ -3,23 +3,24 @@ use Modern::Perl; > use Test::PerlTidy; > use Test::More; > >-use Koha::Devel::Files; >- > my $codespell_version = qx{codespell --version}; > chomp $codespell_version; > $codespell_version =~ s/-.*$//; > if ( ( $codespell_version =~ s/\.//gr ) < 220 ) { # if codespell < 2.2.0 > plan skip_all => "codespell version $codespell_version too low, need at least 2.2.0"; > } >-my $dev_files = Koha::Devel::Files->new( { context => 'codespell' } ); > my @files; >-push @files, $dev_files->ls_perl_files; >-push @files, $dev_files->ls_tt_files; >-push @files, $dev_files->ls_js_files; >+push @files, >+ qx{git ls-files '*.pl' '*.PL' '*.pm' '*.t' ':(exclude)installer/data/mysql/updatedatabase.pl' ':(exclude)installer/data/mysql/update22to30.pl' ':(exclude)installer/data/mysql/db_revs/241200035.pl' ':(exclude)misc/cronjobs/build_browser_and_cloud.pl'}; >+push @files, qx{git ls-files svc opac/svc}; # Files without extension >+push @files, qx{git ls-files '*.tt' '*.inc'}; >+push @files, >+ qx{git ls-files '*.js' '*.ts' '*.vue' ':(exclude)koha-tmpl/intranet-tmpl/lib' ':(exclude)koha-tmpl/intranet-tmpl/js/Gettext.js' ':(exclude)koha-tmpl/opac-tmpl/lib' ':(exclude)koha-tmpl/opac-tmpl/bootstrap/js/Gettext.js'}; > > plan tests => scalar @files; > > for my $file (@files) { >+ chomp $file; > my $output = qx{codespell -d --ignore-words .codespell-ignore $file}; > chomp $output; > is( $output, q{} ); >diff --git a/xt/author/pod_checker.t b/xt/author/pod_checker.t >index 53e32ddf1b..b039664083 100755 >--- a/xt/author/pod_checker.t >+++ b/xt/author/pod_checker.t >@@ -4,10 +4,11 @@ use Modern::Perl; > use Test::More; > use Test::NoWarnings; > use Pod::Checker; >-use Koha::Devel::Files; > >-my $dev_files = Koha::Devel::Files->new; >-my @files = $dev_files->ls_perl_files; >+my @files; >+push @files, qx{git ls-files '*.pl' '*.PL' '*.pm' '*.t'}; >+push @files, qx{git ls-files svc opac/svc}; # Files without extension >+chomp for @files; > > plan tests => scalar @files + 1; > >diff --git a/xt/author/podcorrectness.t b/xt/author/podcorrectness.t >index 9f73784554..c30a0df74d 100755 >--- a/xt/author/podcorrectness.t >+++ b/xt/author/podcorrectness.t >@@ -15,9 +15,9 @@ use Modern::Perl; > use Test::More; > use Test::Pod; > >-use Koha::Devel::Files; >- >-my $dev_files = Koha::Devel::Files->new; >-my @files = $dev_files->ls_perl_files; >+my @files; >+push @files, qx{git ls-files '*.pl' '*.PL' '*.pm' '*.t'}; >+push @files, qx{git ls-files svc opac/svc}; # Files without extension >+chomp for @files; > > all_pod_files_ok(@files); >diff --git a/xt/find-license-problems.t b/xt/find-license-problems.t >index 3c576b7a51..5f93516aa5 100755 >--- a/xt/find-license-problems.t >+++ b/xt/find-license-problems.t >@@ -25,32 +25,34 @@ > > use Modern::Perl; > use Test::More; >-use Test::NoWarnings; > >-my @files = map { >- chomp; >- my $name = $_; >- !( $name =~ m{^koha-tmpl/} >- || $name =~ m{\.(gif|jpg|odt|ogg|pdf|png|po|psd|svg|swf|zip)$} >- || $name =~ m{xt/find-license-problems|xt/fix-old-fsf-address|misc/translator/po2json} >- || $name =~ m[t/mock_templates/intranet-tmpl/prog] >- || !-f $name ) >- ? $_ >- : () >-} `git ls-tree -r HEAD --name-only`; # only files part of git >+use File::Spec; >+use File::Find; > >-plan tests => scalar(@files) + 1; >+my @files; >+ >+sub wanted { >+ my $name = $File::Find::name; >+ push @files, $name >+ unless $name =~ /\/(\.git|koha-tmpl|node_modules|swagger-ui)(\/.*)?$/ >+ || $name =~ /\.(gif|jpg|odt|ogg|pdf|png|po|psd|svg|swf|zip|patch)$/ >+ || $name =~ m[(xt/find-license-problems|xt/fix-old-fsf-address|misc/translator/po2json)] >+ || !-f $name; >+} >+ >+find( { wanted => \&wanted, no_chdir => 1 }, File::Spec->curdir() ); > > foreach my $name (@files) { > open( my $fh, '<', $name ) || die "cannot open file $name $!"; > my ( >- $hasgpl, $hasv3, $hasorlater, $haslinktolicense, >+ $hascopyright, $hasgpl, $hasv3, $hasorlater, $haslinktolicense, > $hasfranklinst, $is_not_us > ) = (0) x 7; > while ( my $line = <$fh> ) { >- $hasgpl = 1 if ( $line =~ /GNU General Public License/ ); >- $hasv3 = 1 if ( $line =~ /either version 3/ ); >- $hasorlater = 1 >+ $hascopyright = 1 if ( $line =~ /^(#|--)?\s*Copyright.*\d\d/ ); >+ $hasgpl = 1 if ( $line =~ /GNU General Public License/ ); >+ $hasv3 = 1 if ( $line =~ /either version 3/ ); >+ $hasorlater = 1 > if ( $line =~ /any later version/ > || $line =~ /at your option/ ); > $haslinktolicense = 1 if $line =~ m|http://www\.gnu\.org/licenses|; >@@ -58,16 +60,13 @@ foreach my $name (@files) { > $is_not_us = 1 if $line =~ m|This file is part of the Zebra server|; > } > close $fh; >- >- if ( $is_not_us || !$hasgpl ) { >- pass(); >- next; >- } >- >- ok( $hasgpl && $hasv3 && $hasorlater && $haslinktolicense && !$hasfranklinst ) >+ next unless $hascopyright; >+ next if $is_not_us; >+ is( $hasgpl && $hasv3 && $hasorlater && $haslinktolicense && !$hasfranklinst, 1 ) > or diag( > sprintf > "File %s has wrong copyright: hasgpl=%s, hasv3=%s, hasorlater=%s, haslinktolicense=%s, hasfranklinst=%s", > $name, $hasgpl, $hasv3, $hasorlater, $haslinktolicense, $hasfranklinst > ); > } >+done_testing; >diff --git a/xt/find-missing-csrf.t b/xt/find-missing-csrf.t >index 59610f9d28..c10d7ee6b1 100755 >--- a/xt/find-missing-csrf.t >+++ b/xt/find-missing-csrf.t >@@ -22,15 +22,20 @@ use Test::More tests => 2; > use File::Slurp; > use Data::Dumper; > >-use Koha::Devel::Files; >+my @files; > >-my $dev_files = Koha::Devel::Files->new; >-my @files = $dev_files->ls_tt_files; >+# OPAC >+push @files, `git ls-files 'koha-tmpl/opac-tmpl/bootstrap/en/*.tt'`; >+push @files, `git ls-files 'koha-tmpl/opac-tmpl/bootstrap/en/*.inc'`; > >+# Staff >+push @files, `git ls-files 'koha-tmpl/intranet-tmpl/prog/en/*.tt'`; >+push @files, `git ls-files 'koha-tmpl/intranet-tmpl/prog/en/*.inc'`; > ok( @files > 0, 'We should test something' ); > > my @errors; > for my $file (@files) { >+ chomp $file; > my @e = check_csrf_in_forms($file); > push @errors, sprintf "%s:%s", $file, join( ",", @e ) if @e; > } >diff --git a/xt/find-missing-filters.t b/xt/find-missing-filters.t >index 425c73921e..0aefa3707c 100755 >--- a/xt/find-missing-filters.t >+++ b/xt/find-missing-filters.t >@@ -20,15 +20,21 @@ use Test::More tests => 2; > use File::Slurp qw( read_file ); > use Data::Dumper; > use t::lib::QA::TemplateFilters; >-use Koha::Devel::Files; > >-my $dev_files = Koha::Devel::Files->new; >-my @files = $dev_files->ls_tt_files; >+my @files; > >+# OPAC >+push @files, `git ls-files 'koha-tmpl/opac-tmpl/bootstrap/en/*.tt'`; >+push @files, `git ls-files 'koha-tmpl/opac-tmpl/bootstrap/en/*.inc'`; >+ >+# Staff >+push @files, `git ls-files 'koha-tmpl/intranet-tmpl/prog/en/*.tt'`; >+push @files, `git ls-files 'koha-tmpl/intranet-tmpl/prog/en/*.inc'`; > ok( @files > 0, 'We should test something' ); > > my @errors; > for my $file (@files) { >+ chomp $file; > my $content = read_file($file); > my @e = t::lib::QA::TemplateFilters::missing_filters($content); > push @errors, { file => $file, errors => \@e } if @e; >diff --git a/xt/find-missing-op-in-forms.t b/xt/find-missing-op-in-forms.t >index 7699bfafcf..840d8b994b 100755 >--- a/xt/find-missing-op-in-forms.t >+++ b/xt/find-missing-op-in-forms.t >@@ -22,14 +22,20 @@ use Test::More tests => 2; > use File::Slurp; > use Data::Dumper; > >-use Koha::Devel::Files; >+my @files; > >-my $dev_files = Koha::Devel::Files->new; >-my @files = $dev_files->ls_tt_files; >+# OPAC >+push @files, `git ls-files 'koha-tmpl/opac-tmpl/bootstrap/en/*.tt'`; >+push @files, `git ls-files 'koha-tmpl/opac-tmpl/bootstrap/en/*.inc'`; >+ >+# Staff >+push @files, `git ls-files 'koha-tmpl/intranet-tmpl/prog/en/*.tt'`; >+push @files, `git ls-files 'koha-tmpl/intranet-tmpl/prog/en/*.inc'`; > ok( @files > 0, 'We should test something' ); > > my @errors; > for my $file (@files) { >+ chomp $file; > my @e = catch_missing_op($file); > push @errors, sprintf "%s:%s", $file, join( ",", @e ) if @e; > } >diff --git a/xt/perltidy.t b/xt/perltidy.t >index edf8a5abd3..f5b85031ab 100755 >--- a/xt/perltidy.t >+++ b/xt/perltidy.t >@@ -3,13 +3,13 @@ use Modern::Perl; > use Test::PerlTidy; > use Test::More; > >-use Koha::Devel::Files; >- >-my $dev_files = Koha::Devel::Files->new( { context => 'tidy' } ); >-my @files = $dev_files->ls_perl_files; >+my @files; >+push @files, qx{git ls-files '*.pl' '*.PL' '*.pm' '*.t' ':(exclude)Koha/Schema/Result' ':(exclude)Koha/Schema.pm'}; >+push @files, qx{git ls-files svc opac/svc}; # Files without extension > > plan tests => scalar @files; > > for my $file (@files) { >+ chomp $file; > ok( Test::PerlTidy::is_file_tidy($file) ); > } >diff --git a/xt/pl_valid.t b/xt/pl_valid.t >index ec7b8f5994..028710deb2 100755 >--- a/xt/pl_valid.t >+++ b/xt/pl_valid.t >@@ -24,10 +24,17 @@ use Pod::Checker; > use Parallel::ForkManager; > use Sys::CPU; > >-use Koha::Devel::Files; >+my @files; >+push @files, qx{git ls-files '*.pl' '*.PL' '*.pm' '*.t'}; >+push @files, qx{git ls-files svc opac/svc}; # Files without extension >+chomp for @files; > >-my $dev_files = Koha::Devel::Files->new( { context => 'valid' } ); >-my @files = $dev_files->ls_perl_files; >+my @exceptions = qw( >+ Koha/Account/Credit.pm >+ Koha/Account/Debit.pm >+ Koha/Old/Hold.pm >+ misc/translator/TmplTokenizer.pm >+); > > my $ncpu; > if ( $ENV{KOHA_PROVE_CPUS} ) { >@@ -41,6 +48,10 @@ my $pm = Parallel::ForkManager->new($ncpu); > plan tests => scalar(@files) + 1; > > for my $file (@files) { >+ if ( grep { $file eq $_ } @exceptions ) { >+ pass("$file is skipped - exception"); >+ next; >+ } > $pm->start and next; > my $output = `perl -cw '$file' 2>&1`; > chomp $output; >diff --git a/xt/single_quotes.t b/xt/single_quotes.t >index a0e7413f9b..0e84e4fc0e 100755 >--- a/xt/single_quotes.t >+++ b/xt/single_quotes.t >@@ -21,15 +21,20 @@ use Modern::Perl; > use Test::More tests => 2; > use File::Slurp qw( read_file ); > >-use Koha::Devel::Files; >+my @files; > >-my $dev_files = Koha::Devel::Files->new; >-my @files = $dev_files->ls_tt_files; >+# OPAC >+push @files, `git ls-files 'koha-tmpl/opac-tmpl/bootstrap/en/*.tt'`; >+push @files, `git ls-files 'koha-tmpl/opac-tmpl/bootstrap/en/*.inc'`; > >+# Staff >+push @files, `git ls-files 'koha-tmpl/intranet-tmpl/prog/en/*.tt'`; >+push @files, `git ls-files 'koha-tmpl/intranet-tmpl/prog/en/*.inc'`; > ok( @files > 0, 'We should test something' ); > > my @errors; > for my $file (@files) { >+ chomp $file; > my @lines = sort grep /\_\(\'/, read_file($file); > push @errors, { name => $file, lines => \@lines } if @lines; > } >diff --git a/xt/tt_tidy.t b/xt/tt_tidy.t >index 895c26be7d..c97ce7da54 100755 >--- a/xt/tt_tidy.t >+++ b/xt/tt_tidy.t >@@ -23,10 +23,7 @@ use Test::Strict; > use Parallel::ForkManager; > use Sys::CPU; > >-use Koha::Devel::Files; >- >-my $dev_files = Koha::Devel::Files->new( { context => 'tidy' } ); >-my @tt_files = $dev_files->ls_tt_files; >+my @tt_files = qx{git ls-files '*.tt' '*.inc'}; > > $Test::Strict::TEST_STRICT = 0; > >@@ -42,6 +39,7 @@ my $pm = Parallel::ForkManager->new($ncpu); > foreach my $filepath (@tt_files) { > $pm->start and next; > >+ chomp $filepath; > my $tidy = qx{perl misc/devel/tidy.pl --silent --no-write $filepath}; > my $content = read_file $filepath; > ok( $content eq $tidy, "$filepath should be kept tidy" ); >diff --git a/yarn.lock b/yarn.lock >index 5745d12e9e..6436ae5618 100755 >--- a/yarn.lock >+++ b/yarn.lock >@@ -2688,11 +2688,6 @@ aws-sign2@~0.7.0: > resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" > integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= > >-aws-ssl-profiles@^1.1.1: >- version "1.1.2" >- resolved "https://registry.yarnpkg.com/aws-ssl-profiles/-/aws-ssl-profiles-1.1.2.tgz#157dd77e9f19b1d123678e93f120e6f193022641" >- integrity sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g== >- > aws4@^1.8.0: > version "1.11.0" > resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" >@@ -3980,6 +3975,13 @@ csstype@^3.1.3: > resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" > integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== > >+cypress-mysql@^1.0.0: >+ version "1.0.0" >+ resolved "https://registry.yarnpkg.com/cypress-mysql/-/cypress-mysql-1.0.0.tgz#987dd693aa4ad6b3968c0ff24834b0ad1af00876" >+ integrity sha512-UEy/jwzKEtctyWSQbgGBPsNJH0yCGaKN/xFZsNHAdjeBGOvI1prnhrsTVnOxclPwRmESnlTmap5P52u2Vl4TjA== >+ dependencies: >+ mysql2 "^2.3.3" >+ > cypress@^12.17.2: > version "12.17.4" > resolved "https://registry.yarnpkg.com/cypress/-/cypress-12.17.4.tgz#b4dadf41673058493fa0d2362faa3da1f6ae2e6c" >@@ -4306,7 +4308,7 @@ delayed-stream@~1.0.0: > resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" > integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= > >-denque@^2.1.0: >+denque@^2.0.1: > version "2.1.0" > resolved "https://registry.yarnpkg.com/denque/-/denque-2.1.0.tgz#e93e1a6569fb5e66f16a3c2a2964617d349d6ab1" > integrity sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw== >@@ -8018,10 +8020,10 @@ log-update@^4.0.0: > slice-ansi "^4.0.0" > wrap-ansi "^6.2.0" > >-long@^5.2.1: >- version "5.3.2" >- resolved "https://registry.yarnpkg.com/long/-/long-5.3.2.tgz#1d84463095999262d7d7b7f8bfd4a8cc55167f83" >- integrity sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA== >+long@^4.0.0: >+ version "4.0.0" >+ resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" >+ integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== > > loose-envify@^1.1.0, loose-envify@^1.4.0: > version "1.4.0" >@@ -8068,11 +8070,6 @@ lru-queue@^0.1.0: > dependencies: > es5-ext "~0.10.2" > >-lru.min@^1.0.0: >- version "1.1.2" >- resolved "https://registry.yarnpkg.com/lru.min/-/lru.min-1.1.2.tgz#01ce1d72cc50c7faf8bd1f809ebf05d4331021eb" >- integrity sha512-Nv9KddBcQSlQopmBHXSsZVY5xsdlZkdH/Iey0BlcBYggMd4two7cZnKOK9vmy3nY0O5RGH99z1PCeTpPqszUYg== >- > lunr@^2.3.9: > version "2.3.9" > resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1" >@@ -8477,18 +8474,17 @@ mute-stdout@^1.0.0: > resolved "https://registry.yarnpkg.com/mute-stdout/-/mute-stdout-1.0.1.tgz#acb0300eb4de23a7ddeec014e3e96044b3472331" > integrity sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg== > >-mysql2@^3.14.1: >- version "3.14.1" >- resolved "https://registry.yarnpkg.com/mysql2/-/mysql2-3.14.1.tgz#7786160abf086fd279e0253e16e34c05b4ab3b3e" >- integrity sha512-7ytuPQJjQB8TNAYX/H2yhL+iQOnIBjAMam361R7UAL0lOVXWjtdrmoL9HYKqKoLp/8UUTRcvo1QPvK9KL7wA8w== >+mysql2@^2.3.3: >+ version "2.3.3" >+ resolved "https://registry.yarnpkg.com/mysql2/-/mysql2-2.3.3.tgz#944f3deca4b16629052ff8614fbf89d5552545a0" >+ integrity sha512-wxJUev6LgMSgACDkb/InIFxDprRa6T95+VEoR+xPvtngtccNH2dGjEB/fVZ8yg1gWv1510c9CvXuJHi5zUm0ZA== > dependencies: >- aws-ssl-profiles "^1.1.1" >- denque "^2.1.0" >+ denque "^2.0.1" > generate-function "^2.3.1" > iconv-lite "^0.6.3" >- long "^5.2.1" >- lru.min "^1.0.0" >- named-placeholders "^1.1.3" >+ long "^4.0.0" >+ lru-cache "^6.0.0" >+ named-placeholders "^1.1.2" > seq-queue "^0.0.5" > sqlstring "^2.3.2" > >@@ -8502,7 +8498,7 @@ mysql@^2.18.1: > safe-buffer "5.1.2" > sqlstring "2.3.1" > >-named-placeholders@^1.1.3: >+named-placeholders@^1.1.2: > version "1.1.3" > resolved "https://registry.yarnpkg.com/named-placeholders/-/named-placeholders-1.1.3.tgz#df595799a36654da55dda6152ba7a137ad1d9351" > integrity sha512-eLoBxg6wE/rZkJPhU/xRX1WTpkFEwDJEN96oxFrTsqBdbT5ec295Q+CoHrL9IT0DipqKhmGcaZmwOt8OON5x1w==
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 16631
:
184422
|
184508
|
184509
|
184510
|
184511
|
184512
|
184513
|
184514
|
184515
|
184516
|
184517
|
184518
|
184519
|
184520
|
184521
|
184522
|
184525
|
184526
|
184657
|
184674
|
184686
|
184687
|
184688
|
184689
|
184690
|
184691
|
184692
|
184693
|
184694
|
184695
|
184845
|
184846
|
184847
|
184848
|
184859
|
184861