View | Details | Raw Unified | Return to bug 36027
Collapse All | Expand All

(-)a/misc/maintenance/search_for_data_inconsistencies.pl (-187 / +240 lines)
Lines 28-49 use Koha::ItemTypes; Link Here
28
use Koha::Patrons;
28
use Koha::Patrons;
29
use C4::Biblio qw( GetMarcFromKohaField );
29
use C4::Biblio qw( GetMarcFromKohaField );
30
30
31
{
31
# %methods hash defines options and their corresponding subroutines
32
# Each numeric key represents an option, and its associated subroutine reference defines the action to be taken
33
# Option 1: CheckItemsBranch - Check for items without home or holding library
34
# Option 2: CheckItemsAuthHeader - Check for authority records with invalid authority type
35
# Option 3: CheckItemsStatus - Check for bibliographic records and items without an item type or with an invalid item type
36
# Option 4: CheckItemsFramework - Check for invalid values in fields where the framework limits to an authorized value category
37
# Option 5: CheckItemsTitle - Check for bibliographic records without a title
38
# Option 6: CheckAgeForCategory - Check for patrons with invalid age for category
39
# Option 7: CheckRelationshipsLoop - Check for relationships or dependencies between borrowers in a loop
40
41
my %methods = (
42
    1 => \&CheckItemsBranch,
43
    2 => \&CheckItemsAuthHeader,
44
    3 => \&CheckItemsStatus,
45
    4 => \&CheckItemsFramework,
46
    5 => \&CheckItemsTitle,
47
    6 => \&CheckAgeForCategory,
48
);
49
50
my @methods_to_run;
51
52
if ( @ARGV == 0 ) {
53
54
    # If no arguments are provided, add all methods to the list
55
    @methods_to_run = keys %methods;
56
}
57
else {
58
    foreach my $arg (@ARGV) {
59
        if ( $arg =~ /^(\d+)$/ ) {
60
            my $method_number = $1;
61
            if ( $method_number >= 1 && $method_number <= 7 ) {
62
                push @methods_to_run, $method_number;
63
            }
64
            else {
65
                print "Invalid method number: $method_number\n";
66
            }
67
        }
68
        else {
69
            print "Invalid argument: $arg\n";
70
        }
71
    }
72
}
73
74
foreach my $choice (@methods_to_run) {
75
    if ( $choice =~ /^\d+$/ && $choice >= 1 && $choice <= 7 ) {
76
        if ( exists $methods{$choice} ) {
77
            $methods{$choice}->();
78
        }
79
        else {
80
            print "Method $choice not found\n";
81
        }
82
    }
83
    else {
84
        print "Invalid choice: $choice\n";
85
    }
86
}
87
88
sub CheckItemsBranch {
32
    my $items = Koha::Items->search({ -or => { homebranch => undef, holdingbranch => undef }});
89
    my $items = Koha::Items->search({ -or => { homebranch => undef, holdingbranch => undef }});
33
    if ( $items->count ) { new_section("Not defined items.homebranch and/or items.holdingbranch")}
90
    if ( $items->count ) { new_section("Not defined items.homebranch and/or items.holdingbranch")}
34
    while ( my $item = $items->next ) {
91
    while ( my $item = $items->next ) {
35
        if ( not $item->homebranch and not $item->holdingbranch ) {
92
        if ( not $item->homebranch and not $item->holdingbranch ) {
36
            new_item(sprintf "Item with itemnumber=%s does not have homebranch and holdingbranch defined", $item->itemnumber);
93
            new_item(sprintf "Item with itemnumber=%s and biblionumber=%s does not have homebranch and holdingbranch defined",  $item->itemnumber, $item->biblionumber);
37
        } elsif ( not $item->homebranch ) {
94
            } elsif ( not $item->homebranch ) {
38
            new_item(sprintf "Item with itemnumber=%s does not have homebranch defined", $item->itemnumber);
95
            new_item(sprintf "Item with itemnumber=%s and biblionumber=%s does not have homebranch defined", $item->itemnumber, $item->biblionumber);
39
        } else {
96
            } else {
40
            new_item(sprintf "Item with itemnumber=%s does not have holdingbranch defined", $item->itemnumber);
97
            new_item(sprintf "Item with itemnumber=%s and biblionumber=%s does not have holdingbranch defined", $item->itemnumber, $item->biblionumber);
41
        }
98
        }
42
    }
99
    }
43
    if ( $items->count ) { new_hint("Edit these items and set valid homebranch and/or holdingbranch")}
100
    if ( $items->count ) { new_hint("Edit these items and set valid homebranch and/or holdingbranch")}
44
}
101
}
45
102
46
{
103
sub CheckItemsAuthHeader {
47
    # No join possible, FK is missing at DB level
104
    # No join possible, FK is missing at DB level
48
    my @auth_types = Koha::Authority::Types->search->get_column('authtypecode');
105
    my @auth_types = Koha::Authority::Types->search->get_column('authtypecode');
49
    my $authorities = Koha::Authorities->search({authtypecode => { 'not in' => \@auth_types } });
106
    my $authorities = Koha::Authorities->search({authtypecode => { 'not in' => \@auth_types } });
Lines 51-279 use C4::Biblio qw( GetMarcFromKohaField ); Link Here
51
    while ( my $authority = $authorities->next ) {
108
    while ( my $authority = $authorities->next ) {
52
        new_item(sprintf "Authority with authid=%s does not have a code defined (%s)", $authority->authid, $authority->authtypecode);
109
        new_item(sprintf "Authority with authid=%s does not have a code defined (%s)", $authority->authid, $authority->authtypecode);
53
    }
110
    }
54
    if ( $authorities->count ) {new_hint("Go to 'Home › Administration › Authority types' to define them")}
111
    if ( $authorities->count ) {new_hint("Go to 'Home -> Administration -> Authority types' to define them")};
55
}
112
    };
56
113
    
57
{
114
    sub CheckItemsStatus {
58
    if ( C4::Context->preference('item-level_itypes') ) {
115
        if ( C4::Context->preference('item-level_itypes') ) {
59
        my $items_without_itype = Koha::Items->search( { -or => [itype => undef,itype => ''] } );
116
            my $items_without_itype = Koha::Items->search( { -or => [itype => undef,itype => ''] } );
60
        if ( $items_without_itype->count ) {
117
            if ( $items_without_itype->count ) {
61
            new_section("Items do not have itype defined");
118
                new_section("Items do not have itype defined");
62
            while ( my $item = $items_without_itype->next ) {
119
                while ( my $item = $items_without_itype->next ) {
63
                if (defined $item->biblioitem->itemtype && $item->biblioitem->itemtype ne '' ) {
120
                    if (defined $item->biblioitem->itemtype && $item->biblioitem->itemtype ne '' ) {
64
                    new_item(
121
                        new_item(
65
                        sprintf "Item with itemnumber=%s does not have a itype value, biblio's item type will be used (%s)",
122
                        sprintf "Item with itemnumber=%s and biblionumber = %s does not have a itype value, biblio's item type will be used (%s)",
66
                        $item->itemnumber, $item->biblioitem->itemtype
123
                        $item->itemnumber, $item->biblioitem->biblionumber, $item->biblioitem->itemtype
67
                    );
124
                        );
68
                } else {
125
                        } else {
69
                    new_item(
126
                        new_item(
70
                        sprintf "Item with itemnumber=%s does not have a itype value, additionally no item type defined for biblionumber=%s",
127
                        sprintf "Item with itemnumber=%s and biblionumber = %s does not have a itype value, additionally no item type defined for biblionumber=%s",
71
                        $item->itemnumber, $item->biblioitem->biblionumber
128
                        $item->itemnumber, $item->biblioitem->biblionumber, $item->biblioitem->biblionumber
72
                    );
129
                        );
73
               }
130
                    }
131
                }
132
                new_hint("The system preference item-level_itypes expects item types to be defined at item level");
74
            }
133
            }
75
            new_hint("The system preference item-level_itypes expects item types to be defined at item level");
134
        }else{
76
        }
135
            my $biblioitems_without_itemtype = Koha::Biblioitems->search( { itemtype => undef } );
77
    }
136
            if ( $biblioitems_without_itemtype->count ) {
78
    else {
137
                new_section("Biblioitems do not have itemtype defined");
79
        my $biblioitems_without_itemtype = Koha::Biblioitems->search( { itemtype => undef } );
138
                while ( my $biblioitem = $biblioitems_without_itemtype->next ) {
80
        if ( $biblioitems_without_itemtype->count ) {
139
                    new_item(
81
            new_section("Biblioitems do not have itemtype defined");
82
            while ( my $biblioitem = $biblioitems_without_itemtype->next ) {
83
                new_item(
84
                    sprintf "Biblioitem with biblioitemnumber=%s does not have a itemtype value",
140
                    sprintf "Biblioitem with biblioitemnumber=%s does not have a itemtype value",
85
                    $biblioitem->biblioitemnumber
141
                    $biblioitem->biblioitemnumber
86
                );
142
                    );
143
                }
144
                new_hint("The system preference item-level_itypes expects item types to be defined at biblio level");
87
            }
145
            }
88
            new_hint("The system preference item-level_itypes expects item types to be defined at biblio level");
89
        }
146
        }
90
    }
147
        
91
148
        my @itemtypes = Koha::ItemTypes->search->get_column('itemtype');
92
    my @itemtypes = Koha::ItemTypes->search->get_column('itemtype');
149
        if ( C4::Context->preference('item-level_itypes') ) {
93
    if ( C4::Context->preference('item-level_itypes') ) {
150
            my $items_with_invalid_itype = Koha::Items->search( { -and => [itype => { not_in => \@itemtypes }, itype => { '!=' => '' }] } );
94
        my $items_with_invalid_itype = Koha::Items->search( { -and => [itype => { not_in => \@itemtypes }, itype => { '!=' => '' }] } );
151
            if ( $items_with_invalid_itype->count ) {
95
        if ( $items_with_invalid_itype->count ) {
152
                new_section("Items have invalid itype defined");
96
            new_section("Items have invalid itype defined");
153
                while ( my $item = $items_with_invalid_itype->next ) {
97
            while ( my $item = $items_with_invalid_itype->next ) {
154
                    new_item(
98
                new_item(
99
                    sprintf "Item with itemnumber=%s, biblionumber=%s does not have a valid itype value (%s)",
155
                    sprintf "Item with itemnumber=%s, biblionumber=%s does not have a valid itype value (%s)",
100
                    $item->itemnumber, $item->biblionumber, $item->itype
156
                    $item->itemnumber, $item->biblionumber, $item->itype
101
                );
157
                    );
158
                }
159
                new_hint("The items must have a itype value that is defined in the item types of Koha (Home › Administration › Item types administration)");
102
            }
160
            }
103
            new_hint("The items must have a itype value that is defined in the item types of Koha (Home › Administration › Item types administration)");
161
        }else{
104
        }
162
            my $biblioitems_with_invalid_itemtype = Koha::Biblioitems->search(
105
    }
106
    else {
107
        my $biblioitems_with_invalid_itemtype = Koha::Biblioitems->search(
108
            { itemtype => { not_in => \@itemtypes } }
163
            { itemtype => { not_in => \@itemtypes } }
109
        );
164
            );
110
        if ( $biblioitems_with_invalid_itemtype->count ) {
165
            if ( $biblioitems_with_invalid_itemtype->count ) {
111
            new_section("Biblioitems do not have itemtype defined");
166
                new_section("Biblioitems do not have itemtype defined");
112
            while ( my $biblioitem = $biblioitems_with_invalid_itemtype->next ) {
167
                while ( my $biblioitem = $biblioitems_with_invalid_itemtype->next ) {
113
                new_item(
168
                    new_item(
114
                    sprintf "Biblioitem with biblioitemnumber=%s does not have a valid itemtype value",
169
                    sprintf "Biblioitem with biblioitemnumber=%s does not have a valid itemtype value",
115
                    $biblioitem->biblioitemnumber
170
                    $biblioitem->biblioitemnumber
116
                );
171
                    );
172
                }
173
                new_hint("The biblioitems must have a itemtype value that is defined in the item types of Koha (Home › Administration › Item types administration)");
117
            }
174
            }
118
            new_hint("The biblioitems must have a itemtype value that is defined in the item types of Koha (Home › Administration › Item types administration)");
119
        }
120
    }
121
122
    my ( @decoding_errors, @ids_not_in_marc );
123
    my $biblios = Koha::Biblios->search;
124
    my ( $biblio_tag,     $biblio_subfield )     = C4::Biblio::GetMarcFromKohaField( "biblio.biblionumber" );
125
    my ( $biblioitem_tag, $biblioitem_subfield ) = C4::Biblio::GetMarcFromKohaField( "biblioitems.biblioitemnumber" );
126
    while ( my $biblio = $biblios->next ) {
127
        my $record = eval{$biblio->metadata->record;};
128
        if ($@) {
129
            push @decoding_errors, $@;
130
            next;
131
        }
132
        my ( $biblionumber, $biblioitemnumber );
133
        if ( $biblio_tag < 10 ) {
134
            my $biblio_control_field = $record->field($biblio_tag);
135
            $biblionumber = $biblio_control_field->data if $biblio_control_field;
136
        } else {
137
            $biblionumber = $record->subfield( $biblio_tag, $biblio_subfield );
138
        }
175
        }
139
        if ( $biblioitem_tag < 10 ) {
176
        
140
            my $biblioitem_control_field = $record->field($biblioitem_tag);
177
        my ( @decoding_errors, @ids_not_in_marc );
141
            $biblioitemnumber = $biblioitem_control_field->data if $biblioitem_control_field;
178
        my $biblios = Koha::Biblios->search;
142
        } else {
179
        my ( $biblio_tag,     $biblio_subfield )     = C4::Biblio::GetMarcFromKohaField( "biblio.biblionumber" );
143
            $biblioitemnumber = $record->subfield( $biblioitem_tag, $biblioitem_subfield );
180
        my ( $biblioitem_tag, $biblioitem_subfield ) = C4::Biblio::GetMarcFromKohaField( "biblioitems.biblioitemnumber" );
144
        }
181
        while ( my $biblio = $biblios->next ) {
145
        if ( $biblionumber != $biblio->biblionumber ) {
182
            my $record = eval{$biblio->metadata->record;};
146
            push @ids_not_in_marc,
183
            if ($@) {
147
              {
184
                push @decoding_errors, $@;
185
                next;
186
            }
187
            my ( $biblionumber, $biblioitemnumber );
188
            if ( $biblio_tag < 10 ) {
189
                my $biblio_control_field = $record->field($biblio_tag);
190
                $biblionumber = $biblio_control_field->data if $biblio_control_field;
191
                } else {
192
                $biblionumber = $record->subfield( $biblio_tag, $biblio_subfield );
193
            }
194
            if ( $biblioitem_tag < 10 ) {
195
                my $biblioitem_control_field = $record->field($biblioitem_tag);
196
                $biblioitemnumber = $biblioitem_control_field->data if $biblioitem_control_field;
197
                } else {
198
                $biblioitemnumber = $record->subfield( $biblioitem_tag, $biblioitem_subfield );
199
            }
200
            if ( $biblionumber != $biblio->biblionumber ) {
201
                push @ids_not_in_marc,
202
                {
148
                biblionumber         => $biblio->biblionumber,
203
                biblionumber         => $biblio->biblionumber,
149
                biblionumber_in_marc => $biblionumber,
204
                biblionumber_in_marc => $biblionumber,
150
              };
205
                };
151
        }
206
            }
152
        if ( $biblioitemnumber != $biblio->biblioitem->biblioitemnumber ) {
207
            if ( $biblioitemnumber != $biblio->biblioitem->biblioitemnumber ) {
153
            push @ids_not_in_marc,
208
                push @ids_not_in_marc,
154
            {
209
                {
155
                biblionumber     => $biblio->biblionumber,
210
                biblionumber     => $biblio->biblionumber,
156
                biblioitemnumber => $biblio->biblioitem->biblioitemnumber,
211
                biblioitemnumber => $biblio->biblioitem->biblioitemnumber,
157
                biblioitemnumber_in_marc => $biblionumber,
212
                biblioitemnumber_in_marc => $biblionumber,
158
            };
213
                };
214
            }
159
        }
215
        }
160
    }
216
        if ( @decoding_errors ) {
161
    if ( @decoding_errors ) {
217
            new_section("Bibliographic records have invalid MARCXML");
162
        new_section("Bibliographic records have invalid MARCXML");
218
            new_item($_) for @decoding_errors;
163
        new_item($_) for @decoding_errors;
219
            new_hint("The bibliographic records must have a valid MARCXML or you will face encoding issues or wrong displays");
164
        new_hint("The bibliographic records must have a valid MARCXML or you will face encoding issues or wrong displays");
220
        }
165
    }
221
        if (@ids_not_in_marc) {
166
    if (@ids_not_in_marc) {
222
            new_section("Bibliographic records have MARCXML without biblionumber or biblioitemnumber");
167
        new_section("Bibliographic records have MARCXML without biblionumber or biblioitemnumber");
223
            for my $id (@ids_not_in_marc) {
168
        for my $id (@ids_not_in_marc) {
224
                if ( exists $id->{biblioitemnumber} ) {
169
            if ( exists $id->{biblioitemnumber} ) {
225
                    new_item(
170
                new_item(
171
                    sprintf(q{Biblionumber %s has biblioitemnumber '%s' but should be '%s' in %s$%s},
226
                    sprintf(q{Biblionumber %s has biblioitemnumber '%s' but should be '%s' in %s$%s},
172
                        $id->{biblionumber},
227
                    $id->{biblionumber},
173
                        $id->{biblioitemnumber},
228
                    $id->{biblioitemnumber},
174
                        $id->{biblioitemnumber_in_marc},
229
                    $id->{biblioitemnumber_in_marc},
175
                        $biblioitem_tag,
230
                    $biblioitem_tag,
176
                        $biblioitem_subfield,
231
                    $biblioitem_subfield,
177
                    )
232
                    )
178
                );
233
                    );
179
            }
234
                }else{
180
            else {
235
                    new_item(
181
                new_item(
182
                    sprintf(q{Biblionumber %s has '%s' in %s$%s},
236
                    sprintf(q{Biblionumber %s has '%s' in %s$%s},
183
                        $id->{biblionumber},
237
                    $id->{biblionumber},
184
                        $id->{biblionumber_in_marc},
238
                    $id->{biblionumber_in_marc},
185
                        $biblio_tag,
239
                    $biblio_tag,
186
                        $biblio_subfield,
240
                    $biblio_subfield,
187
                    )
241
                    )
188
                );
242
                    );
243
                }
189
            }
244
            }
245
            new_hint("The bibliographic records must have the biblionumber and biblioitemnumber in MARCXML");
190
        }
246
        }
191
        new_hint("The bibliographic records must have the biblionumber and biblioitemnumber in MARCXML");
192
    }
247
    }
193
}
194
195
{
196
    my @framework_codes = Koha::BiblioFrameworks->search()->get_column('frameworkcode');
197
    push @framework_codes,""; # The default is not stored in frameworks, we need to force it
198
248
199
    my $invalid_av_per_framework = {};
249
    sub CheckItemsFramework {
200
    foreach my $frameworkcode ( @framework_codes ) {
250
        my @framework_codes = Koha::BiblioFrameworks->search()->get_column('frameworkcode');
201
        # We are only checking fields that are mapped to DB fields
251
        push @framework_codes,""; # The default is not stored in frameworks, we need to force it
202
        my $msss = Koha::MarcSubfieldStructures->search({
252
        
253
        my $invalid_av_per_framework = {};
254
        foreach my $frameworkcode ( @framework_codes ) {
255
            # We are only checking fields that are mapped to DB fields
256
            my $msss = Koha::MarcSubfieldStructures->search({
203
            frameworkcode => $frameworkcode,
257
            frameworkcode => $frameworkcode,
204
            authorised_value => {
258
            authorised_value => {
205
                '!=' => [ -and => ( undef, '' ) ]
259
            '!=' => [ -and => ( undef, '' ) ]
206
            },
260
            },
207
            kohafield => {
261
            kohafield => {
208
                '!=' => [ -and => ( undef, '' ) ]
262
            '!=' => [ -and => ( undef, '' ) ]
209
            }
263
        }
210
        });
264
        });
211
        while ( my $mss = $msss->next ) {
265
        while ( my $mss = $msss->next ) {
212
            my $kohafield = $mss->kohafield;
266
            my $kohafield = $mss->kohafield;
213
            my $av = $mss->authorised_value;
267
            my $av = $mss->authorised_value;
214
            next if grep {$_ eq $av} qw( branches itemtypes cn_source ); # internal categories
268
            next if grep {$_ eq $av} qw( branches itemtypes cn_source ); # internal categories
215
269
            
216
            my $avs = Koha::AuthorisedValues->search_by_koha_field(
270
            my $avs = Koha::AuthorisedValues->search_by_koha_field(
217
                {
271
            {
218
                    frameworkcode => $frameworkcode,
272
            frameworkcode => $frameworkcode,
219
                    kohafield     => $kohafield,
273
            kohafield     => $kohafield,
220
                }
274
        }
221
            );
275
        );
222
            my $tmp_kohafield = $kohafield;
276
        my $tmp_kohafield = $kohafield;
223
            if ( $tmp_kohafield =~ /^biblioitems/ ) {
277
        if ( $tmp_kohafield =~ /^biblioitems/ ) {
224
                $tmp_kohafield =~ s|biblioitems|biblioitem|;
278
            $tmp_kohafield =~ s|biblioitems|biblioitem|;
225
            } else {
279
            } else {
226
                $tmp_kohafield =~ s|items|me|;
280
            $tmp_kohafield =~ s|items|me|;
227
            }
281
        }
228
            # replace items.attr with me.attr
282
        # replace items.attr with me.attr
229
283
        
230
            # We are only checking biblios with items
284
        # We are only checking biblios with items
231
            my $items = Koha::Items->search(
285
        my $items = Koha::Items->search(
232
                {
286
        {
233
                    $tmp_kohafield =>
287
        $tmp_kohafield =>
234
                      {
288
        {
235
                          -not_in => [ $avs->get_column('authorised_value'), '' ],
289
        -not_in => [ $avs->get_column('authorised_value'), '' ],
236
                          '!='    => undef,
290
        '!='    => undef,
237
                      },
291
        },
238
                    'biblio.frameworkcode' => $frameworkcode
292
        'biblio.frameworkcode' => $frameworkcode
239
                },
293
        },
240
                { join => [ 'biblioitem', 'biblio' ] }
294
        { join => [ 'biblioitem', 'biblio' ] }
241
            );
295
        );
242
            if ( $items->count ) {
296
        if ( $items->count ) {
243
                $invalid_av_per_framework->{ $frameworkcode }->{$av} =
297
            $invalid_av_per_framework->{ $frameworkcode }->{$av} =
244
                  { items => $items, kohafield => $kohafield };
298
            { items => $items, kohafield => $kohafield };
245
            }
246
        }
299
        }
247
    }
300
    }
248
    if (%$invalid_av_per_framework) {
301
}
249
        new_section('Wrong values linked to authorised values');
302
if (%$invalid_av_per_framework) {
250
        for my $frameworkcode ( keys %$invalid_av_per_framework ) {
303
    new_section('Wrong values linked to authorised values');
251
            while ( my ( $av_category, $v ) = each %{$invalid_av_per_framework->{$frameworkcode}} ) {
304
    for my $frameworkcode ( keys %$invalid_av_per_framework ) {
252
                my $items     = $v->{items};
305
        while ( my ( $av_category, $v ) = each %{$invalid_av_per_framework->{$frameworkcode}} ) {
253
                my $kohafield = $v->{kohafield};
306
            my $items     = $v->{items};
254
                my ( $table, $column ) = split '\.', $kohafield;
307
            my $kohafield = $v->{kohafield};
255
                my $output;
308
            my ( $table, $column ) = split '\.', $kohafield;
256
                while ( my $i = $items->next ) {
309
            my $output;
257
                    my $value = $table eq 'items'
310
            while ( my $i = $items->next ) {
258
                        ? $i->$column
311
                my $value = $table eq 'items'
259
                        : $table eq 'biblio'
312
                ? $i->$column
260
                        ? $i->biblio->$column
313
                : $table eq 'biblio'
261
                        : $i->biblioitem->$column;
314
                ? $i->biblio->$column
262
                    $output .= " {" . $i->itemnumber . " => " . $value . "}\n";
315
                : $i->biblioitem->$column;
263
                }
316
                $output .= " {" . $i->itemnumber . " and " . $i->biblioitem->biblionumber. " => " . $value . "}\n";
264
                new_item(
265
                    sprintf(
266
                        "The Framework *%s* is using the authorised value's category *%s*, "
267
                        . "but the following %s do not have a value defined ({itemnumber => value }):\n%s",
268
                        $frameworkcode, $av_category, $kohafield, $output
269
                    )
270
                );
271
            }
317
            }
318
            new_item(
319
            sprintf(
320
            "The Framework *%s* is using the authorised value's category *%s*, "
321
            . "but the following %s do not have a value defined ({itemnumber and biblionumber => value }):\n%s",
322
            $frameworkcode, $av_category, $kohafield, $output
323
            )
324
            );
272
        }
325
        }
273
    }
326
    }
274
}
327
}
328
}
275
329
276
{
330
sub CheckItemsTitle {
277
    my $biblios = Koha::Biblios->search({
331
    my $biblios = Koha::Biblios->search({
278
        -or => [
332
        -or => [
279
            title => '',
333
            title => '',
Lines 292-298 use C4::Biblio qw( GetMarcFromKohaField ); Link Here
292
    }
346
    }
293
}
347
}
294
348
295
{
349
sub CheckAgeForCategory {
296
    my $aging_patrons = Koha::Patrons->search(
350
    my $aging_patrons = Koha::Patrons->search(
297
        {
351
        {
298
            -not => {
352
            -not => {
299
- 

Return to bug 36027