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

(-)a/Koha/ERM/EUsage/COUNTER/5.pm (+335 lines)
Line 0 Link Here
1
package Koha::ERM::EUsage::COUNTER::5;
2
3
# Copyright 2025 Open Fifth
4
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Koha is distributed in the hope that it will be useful, but
13
# WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20
use Modern::Perl;
21
22
use base qw(Koha::ERM::EUsage::SushiCounter);
23
24
=head1 NAME
25
26
Koha::ERM::EUsage::COUNTER::5 - Koha COUNTER 5 Object class
27
28
=head1 API
29
30
=head2 Class Methods
31
32
=head3 new
33
34
    my $sushi_counter =
35
        Koha::ERM::EUsage::SushiCounter->new( { response => decode_json( $response->decoded_content ) } );
36
37
=cut
38
39
sub new {
40
    my ($class) = @_;
41
    my $self = {};
42
43
    bless( $self, $class );
44
}
45
46
=head3 _COUNTER_report_header
47
48
Return a COUNTER report header
49
https://cop5.projectcounter.org/en/5.0.2/04-reports/03-title-reports.html
50
51
=cut
52
53
sub _COUNTER_report_header {
54
    my ($self) = @_;
55
56
    my $header = $self->{sushi}->{header};
57
58
    my @metric_types_string = $self->_get_SUSHI_Name_Value( $header->{Report_Filters}, "Metric_Type" );
59
60
    my $begin_date = $self->_get_SUSHI_Name_Value( $header->{Report_Filters}, "Begin_Date" );
61
    my $end_date   = $self->_get_SUSHI_Name_Value( $header->{Report_Filters}, "End_Date" );
62
63
    return (
64
        [ Report_Name      => $header->{Report_Name}                                                            || "" ],
65
        [ Report_ID        => $header->{Report_ID}                                                              || "" ],
66
        [ Release          => $header->{Release}                                                                || "" ],
67
        [ Institution_Name => $header->{Institution_Name}                                                       || "" ],
68
        [ Institution_ID => join( "; ", map( $_->{Type} . ":" . $_->{Value}, @{ $header->{Institution_ID} } ) ) || "" ],
69
        [ Metric_Types   => join( "; ", split( /\|/, $metric_types_string[0] ) )                                || "" ],
70
        [ Report_Filters => join( "; ", map( $_->{Name} . ":" . $_->{Value}, @{ $header->{Report_Filters} } ) ) || "" ],
71
72
        #TODO: Report_Attributes may need parsing, test this with a SUSHI response that provides it
73
        [ Report_Attributes => $header->{Report_Attributes} || "" ],
74
        [
75
            Exceptions => join(
76
                "; ", map( $_->{Code} . ": " . $_->{Message} . " (" . $_->{Data} . ")", @{ $header->{Exceptions} } )
77
                )
78
                || ""
79
        ],
80
        [ Reporting_Period => "Begin_Date=" . $begin_date . "; End_Date=" . $end_date ],
81
        [ Created          => $header->{Created}    || "" ],
82
        [ Created_By       => $header->{Created_By} || "" ],
83
        [""]    #empty 13th line (COUNTER 5)
84
    );
85
}
86
87
=head3 _get_SUSHI_Name_Value
88
89
Returns "Value" of a given "Name"
90
91
=cut
92
93
sub _get_SUSHI_Name_Value {
94
    my ( $self, $item, $name ) = @_;
95
96
    my @value = map( $_->{Name} eq $name ? $_->{Value} : (), @{$item} );
97
    return $value[0];
98
}
99
100
=head3 _get_SUSHI_Type_Value
101
102
Returns "Value" of a given "Type"
103
104
=cut
105
106
sub _get_SUSHI_Type_Value {
107
    my ( $self, $item, $type ) = @_;
108
109
    my @value = map( $_->{Type} eq $type ? $_->{Value} : (), @{$item} );
110
    return $value[0];
111
}
112
113
=head3 _get_COUNTER_row_usages
114
115
Returns the total and monthly usages for a row
116
117
=cut
118
119
sub _get_COUNTER_row_usages {
120
    my ( $self, $row, $metric_type ) = @_;
121
122
    my @usage_months = $self->_get_usage_months( $self->{sushi}->{header} );
123
124
    my @usage_months_fields = ();
125
    my $count_total         = 0;
126
127
    foreach my $usage_month (@usage_months) {
128
        my $month_is_empty = 1;
129
130
        foreach my $performance ( @{ $row->{Performance} } ) {
131
            my $period             = $performance->{Period};
132
            my $period_usage_month = substr( $period->{Begin_Date}, 0, 7 );
133
134
            my $instances = $performance->{Instance};
135
            my @metric_type_count =
136
                map( $_->{Metric_Type} eq $metric_type ? $_->{Count} : (),
137
                @{$instances} );
138
139
            if ( $period_usage_month eq $usage_month && $metric_type_count[0] ) {
140
                push( @usage_months_fields, $metric_type_count[0] );
141
                $count_total += $metric_type_count[0];
142
                $month_is_empty = 0;
143
            }
144
        }
145
146
        if ($month_is_empty) {
147
            push( @usage_months_fields, 0 );
148
        }
149
    }
150
    return ( $count_total, @usage_months_fields );
151
}
152
153
=head3 get_SUSHI_metric_types
154
155
    Returns all metric types this SUSHI result has statistics for, as an array of strings.
156
157
=cut
158
159
sub get_SUSHI_metric_types {
160
    my ( $self, $report_row ) = @_;
161
162
    my @metric_types = ();
163
164
    # Grab all metric_types this SUSHI result has statistics for
165
    foreach my $performance ( @{ $report_row->{Performance} } ) {
166
        my @SUSHI_metric_types =
167
            map( $_->{Metric_Type}, @{ $performance->{Instance} } );
168
169
        foreach my $sushi_metric_type (@SUSHI_metric_types) {
170
            push( @metric_types, $sushi_metric_type ) unless grep { $_ eq $sushi_metric_type } @metric_types;
171
        }
172
    }
173
174
    return @metric_types;
175
}
176
177
=head3 _COUNTER_report_body
178
179
Return the COUNTER report body as an array
180
181
=cut
182
183
sub _COUNTER_report_body {
184
    my ($self) = @_;
185
186
    my $header = $self->{sushi}->{header};
187
    my $body   = $self->{sushi}->{body};
188
189
    my @report_body = ();
190
191
    foreach my $report_row ( @{$body} ) {
192
        my @metric_types = $self->get_SUSHI_metric_types($report_row);
193
194
        # Add one report row for each metric_type we're working with
195
        foreach my $metric_type (@metric_types) {
196
            push( @report_body, $self->_COUNTER_report_row( $report_row, $metric_type ) );
197
        }
198
    }
199
200
    return @report_body;
201
}
202
203
=head3 _COUNTER_title_report_row
204
205
Return a COUNTER title for the COUNTER titles report body
206
https://cop5.projectcounter.org/en/5.0.2/04-reports/03-title-reports.html#column-headings-elements
207
208
=cut
209
210
sub _COUNTER_title_report_row {
211
    my ( $self, $title_row, $metric_type, $total_usage, $monthly_usages ) = @_;
212
213
    my $header          = $self->{sushi}->{header};
214
    my $specific_fields = $self->get_report_type_specific_fields( $header->{Report_ID} );
215
216
    return (
217
        [
218
            # Title
219
            $title_row->{Title} || "",
220
221
            # Publisher
222
            $title_row->{Publisher} || "",
223
224
            # Publisher_ID
225
            $self->_get_SUSHI_Type_Value( $title_row->{Publisher_ID}, "ISNI" ) || "",
226
227
            # Platform
228
            $title_row->{Platform} || "",
229
230
            # DOI
231
            $self->_get_SUSHI_Type_Value( $title_row->{Item_ID}, "DOI" ) || "",
232
233
            # Proprietary_ID
234
            $self->_get_SUSHI_Type_Value( $title_row->{Item_ID}, "Proprietary" ) || "",
235
236
            # ISBN
237
            grep ( /ISBN/, @{$specific_fields} )
238
            ? ( $self->_get_SUSHI_Type_Value( $title_row->{Item_ID}, "ISBN" ) || "" )
239
            : (),
240
241
            # Print_ISSN
242
            $self->_get_SUSHI_Type_Value( $title_row->{Item_ID}, "Print_ISSN" ) || "",
243
244
            # Online_ISSN
245
            $self->_get_SUSHI_Type_Value( $title_row->{Item_ID}, "Online_ISSN" ) || "",
246
247
            # URI - FIXME: What goes in URI?
248
            "",
249
250
            # YOP
251
            grep ( /YOP/, @{$specific_fields} ) ? ( $title_row->{YOP} || "" ) : (),
252
253
            # Access_Type
254
            grep ( /Access_Type/, @{$specific_fields} ) ? ( $title_row->{Access_Type} || "" ) : (),
255
256
            # Metric_Type
257
            $metric_type,
258
259
            # Report_Period_Total
260
            $total_usage,
261
262
            # Monthly usage entries
263
            @{$monthly_usages}
264
        ]
265
    );
266
}
267
268
=head3 _COUNTER_titles_report_column_headings
269
270
Return titles report column headings
271
272
=cut
273
274
sub _COUNTER_titles_report_column_headings {
275
    my ($self) = @_;
276
277
    my $header          = $self->{sushi}->{header};
278
    my @month_headings  = $self->_get_usage_months( $header, 1 );
279
    my $specific_fields = $self->get_report_type_specific_fields( $header->{Report_ID} );
280
281
    return (
282
        [
283
            "Title",
284
            "Publisher",
285
            "Publisher_ID",
286
            "Platform",
287
            "DOI",
288
            "Proprietary_ID",
289
            grep ( /ISBN/, @{$specific_fields} ) ? ("ISBN") : (),
290
            "Print_ISSN",
291
            "Online_ISSN",
292
            "URI",
293
294
            #"Data_Type", #TODO: Only if requested (?)
295
            #"Section_Type", #TODO: Only if requested (?)
296
            grep ( /YOP/,         @{$specific_fields} ) ? ("YOP")         : (),
297
            grep ( /Access_Type/, @{$specific_fields} ) ? ("Access_Type") : (),
298
299
            #"Access_Method", #TODO: Only if requested (?)
300
            "Metric_Type",
301
            "Reporting_Period_Total",
302
303
            # @month_headings in "Mmm-yyyy" format. TODO: Show unless Exclude_Monthly_Details=true
304
            @month_headings
305
        ]
306
    );
307
}
308
309
=head3 get_report_type_specific_fields
310
311
Returns the specific fields for a given report_type
312
313
=cut
314
315
sub get_report_type_specific_fields {
316
    my ( $self, $report_type ) = @_;
317
318
    my %report_type_map = (
319
        "TR_B1" => [ 'YOP', 'ISBN' ],
320
        "TR_B2" => [ 'YOP', 'ISBN' ],
321
        "TR_B3" => [ 'YOP', 'Access_Type', 'ISBN' ],
322
        "TR_J3" => ['Access_Type'],
323
        "TR_J4" => ['YOP'],
324
        "IR_A1" => [
325
            'Authors',            'Publication_Date', 'Article_Version',  'Print_ISSN', 'Online_ISSN', 'Parent_Title',
326
            'Parent_Authors',     'Parent_Article_Version', 'Parent_DOI', 'Parent_Proprietary_ID', 'Parent_Print_ISSN',
327
            'Parent_Online_ISSN', 'Parent_URI',             'Access_Type'
328
        ],
329
    );
330
331
    return $report_type_map{$report_type};
332
333
}
334
335
1;
(-)a/Koha/ERM/EUsage/COUNTER/5_1.pm (+468 lines)
Line 0 Link Here
1
package Koha::ERM::EUsage::COUNTER::5_1;
2
3
# Copyright 2025 Open Fifth
4
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Koha is distributed in the hope that it will be useful, but
13
# WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20
use Modern::Perl;
21
22
use base qw(Koha::ERM::EUsage::SushiCounter);
23
24
=head1 NAME
25
26
Koha::ERM::EUsage::COUNTER::5 - Koha COUNTER 5.1 Object class
27
28
=head1 API
29
30
=head2 Class Methods
31
32
=head3 new
33
34
    my $sushi_counter =
35
        Koha::ERM::EUsage::SushiCounter->new( { response => decode_json( $response->decoded_content ) } );
36
37
=cut
38
39
sub new {
40
    my ($class) = @_;
41
    my $self = {};
42
43
    bless( $self, $class );
44
}
45
46
=head3 _COUNTER_report_header
47
48
Return a COUNTER report header
49
https://cop5.projectcounter.org/en/5.1/04-reports/03-title-reports.html
50
51
=cut
52
53
sub _COUNTER_report_header {
54
    my ($self) = @_;
55
56
    my $header = $self->{sushi}->{header};
57
58
    my $metric_types       = $self->_get_SUSHI_Name_Value( $header->{Report_Filters}, "Metric_Type" );
59
    my @metric_types_array = split( /\|/, $metric_types );
60
    $metric_types = join( "; ", @metric_types_array ) if @metric_types_array;
61
62
    my $begin_date = $self->_get_SUSHI_Name_Value( $header->{Report_Filters}, "Begin_Date" );
63
    my $end_date   = $self->_get_SUSHI_Name_Value( $header->{Report_Filters}, "End_Date" );
64
65
    return (
66
        [ Report_Name      => $header->{Report_Name}                                              || "" ],
67
        [ Report_ID        => $header->{Report_ID}                                                || "" ],
68
        [ Release          => $header->{Release}                                                  || "" ],
69
        [ Institution_Name => $header->{Institution_Name}                                         || "" ],
70
        [ Institution_ID   => $self->get_mapped_SUSHI_values( 'Type', $header->{Institution_ID} ) || "" ],
71
        [ Metric_Types     => $metric_types                                                       || "" ],
72
        [ Report_Filters   => $self->get_mapped_SUSHI_values( 'Name', $header->{Report_Filters} ) || "" ],
73
74
        #TODO: Report_Attributes may need parsing, test this with a SUSHI response that provides it
75
        [ Report_Attributes => $header->{Report_Attributes} || "" ],
76
        [
77
            Exceptions => join(
78
                "; ", map( $_->{Code} . ": " . $_->{Message} . " (" . $_->{Data} . ")", @{ $header->{Exceptions} } )
79
                )
80
                || ""
81
        ],
82
        [ Reporting_Period => "Begin_Date=" . $begin_date . "; End_Date=" . $end_date ],
83
        [ Created          => $header->{Created}         || "" ],
84
        [ Created_By       => $header->{Created_By}      || "" ],
85
        [ Registry_Record  => $header->{Registry_Record} || "" ],
86
        [""]    #empty 14th line (COUNTER 5.1)
87
    );
88
}
89
90
=head3 get_counter51_value
91
92
    Given a SUSHI response, get the value for the given key in the correct format for the COUNTER report
93
    https://counter5.cambridge.org/r51/sushi-docs/
94
95
=cut
96
97
sub get_counter51_value {
98
    my ( $self, $item, $key ) = @_;
99
    my $counter_51_value = $item->{$key};
100
    if ( ref($counter_51_value) eq 'ARRAY' ) {
101
        return join( "; ", @$counter_51_value );
102
    } else {
103
        return $counter_51_value;
104
    }
105
}
106
107
=head3 _get_SUSHI_Name_Value
108
109
    Given a SUSHI response, get the value for the given key in the correct format for the COUNTER report
110
    https://counter5.cambridge.org/r51/sushi-docs/
111
112
    It will return a string of the form "Name:Value;Name:Value;..."
113
    If the value is an array with a single element, just the value will be returned.
114
    If the value is an array with multiple elements, they will be joined with "|"
115
116
=cut
117
118
sub get_mapped_SUSHI_values {
119
    my ( $self, $key, $sushi_type_value ) = @_;
120
121
    return join(
122
        "; ",
123
        map {
124
            $_ . ":"
125
                . (
126
                ref $sushi_type_value->{$_} eq 'ARRAY'
127
                    && scalar( @{ $sushi_type_value->{$_} } ) == 1 ? $sushi_type_value->{$_}[0]
128
                : ( ref $sushi_type_value->{$_} eq 'ARRAY' && scalar( @{ $sushi_type_value->{$_} } ) > 1 )
129
                ? join( "|", @{ $sushi_type_value->{$_} } )
130
                : $sushi_type_value->{$_}
131
                )
132
        } keys %{$sushi_type_value}
133
    );
134
}
135
136
=head3 _get_SUSHI_Name_Value
137
138
Returns "Value" of a given "Name"
139
140
=cut
141
142
sub _get_SUSHI_Name_Value {
143
    my ( $self, $item, $name ) = @_;
144
145
    return $self->get_counter51_value( $item, $name );
146
}
147
148
=head3 _get_SUSHI_Type_Value
149
150
Returns "Value" of a given "Type"
151
152
=cut
153
154
sub _get_SUSHI_Type_Value {
155
    my ( $self, $item, $type ) = @_;
156
157
    return $self->get_counter51_value( $item, $type );
158
}
159
160
=head3 _get_COUNTER_row_usages
161
162
Returns the total and monthly usages for a row
163
164
=cut
165
166
sub _get_COUNTER_row_usages {
167
    my ( $self, $row, $metric_type, $access_type ) = @_;
168
169
    my @usage_months = $self->_get_usage_months( $self->{sushi}->{header} );
170
171
    my @usage_months_fields = ();
172
    my $count_total         = 0;
173
174
    foreach my $usage_month (@usage_months) {
175
        my $month_is_empty = 1;
176
177
        my $usage_to_add;
178
        if ($access_type) {
179
            my @access_type_performances =
180
                grep { $_->{Access_Type} eq $access_type } @{ $row->{Attribute_Performance} };
181
            $usage_to_add = $access_type_performances[0]->{Performance}->{$metric_type}->{$usage_month};
182
        } else {
183
            $usage_to_add = $row->{Attribute_Performance}->[0]->{Performance}->{$metric_type}->{$usage_month};
184
        }
185
        if ( defined $usage_to_add ) {
186
            $count_total += $usage_to_add;
187
            $month_is_empty = 0;
188
            push( @usage_months_fields, $usage_to_add );
189
        }
190
191
        if ($month_is_empty) {
192
            push( @usage_months_fields, 0 );
193
        }
194
    }
195
196
    return ( $count_total, @usage_months_fields );
197
}
198
199
=head3 get_SUSHI_metric_types
200
201
    Given a SUSHI report row, return a sorted list of all the metric types
202
203
=cut
204
205
sub get_SUSHI_metric_types {
206
    my ( $self, $report_row ) = @_;
207
208
    my @metric_types = ();
209
    @metric_types = keys %{ $report_row->{Attribute_Performance}->[0]->{Performance} };
210
    @metric_types = sort @metric_types;
211
    return @metric_types;
212
}
213
214
=head3 _COUNTER_report_body
215
216
Return the COUNTER report body as an array
217
218
=cut
219
220
sub _COUNTER_report_body {
221
    my ($self) = @_;
222
223
    my $header = $self->{sushi}->{header};
224
    my $body   = $self->{sushi}->{body};
225
226
    my @report_body = ();
227
228
    foreach my $report_row ( @{$body} ) {
229
        my @metric_types = $self->get_SUSHI_metric_types($report_row);
230
231
        my $specific_fields = $self->get_report_type_specific_fields( $header->{Report_ID} );
232
        my $use_access_type = grep ( /Access_Type/, @{$specific_fields} ) ? 1 : 0;
233
        my $use_yop         = grep ( /YOP/,         @{$specific_fields} ) ? 1 : 0;
234
        my $use_data_type   = grep ( /Data_Type/,   @{$specific_fields} ) ? 1 : 0;
235
236
        if ($use_data_type) {
237
            my %data_types = map { $_->{Data_Type} => 1 } @{ $report_row->{Attribute_Performance} };
238
            my @data_types = sort keys %data_types;
239
240
            foreach my $data_type (@data_types) {
241
242
                if ($use_yop) {
243
                    my %yops = map  { $_->{YOP} => 1 } @{ $report_row->{Attribute_Performance} };
244
                    my @yops = sort { $b <=> $a } keys %yops;
245
                    foreach my $yop (@yops) {
246
247
                        if ($use_access_type) {
248
                            my @access_types = map { $_->{"Access_Type"} } @{ $report_row->{Attribute_Performance} };
249
                            foreach my $access_type (@access_types) {
250
251
                                # Add one report row for each metric_type we're working with
252
                                foreach my $metric_type (@metric_types) {
253
                                    push(
254
                                        @report_body,
255
                                        $self->_COUNTER_report_row(
256
                                            $report_row, $metric_type, $access_type, $yop,
257
                                            $data_type
258
                                        )
259
                                    );
260
                                }
261
                            }
262
                        } else {
263
264
                            # Add one report row for each metric_type we're working with
265
                            foreach my $metric_type (@metric_types) {
266
                                push(
267
                                    @report_body,
268
                                    $self->_COUNTER_report_row( $report_row, $metric_type, undef, $yop, $data_type )
269
                                );
270
                            }
271
                        }
272
                    }
273
                } else {
274
275
                    # Add one report row for each metric_type we're working with
276
                    foreach my $metric_type (@metric_types) {
277
                        push(
278
                            @report_body,
279
                            $self->_COUNTER_report_row( $report_row, $metric_type, undef, undef, $data_type )
280
                        );
281
                    }
282
                }
283
            }
284
        } elsif ($use_yop) {
285
            my %yops = map  { $_->{YOP} => 1 } @{ $report_row->{Attribute_Performance} };
286
            my @yops = sort { $b <=> $a } keys %yops;
287
            foreach my $yop (@yops) {
288
289
                if ($use_access_type) {
290
                    my @access_types = map { $_->{"Access_Type"} } @{ $report_row->{Attribute_Performance} };
291
                    foreach my $access_type (@access_types) {
292
293
                        # Add one report row for each metric_type we're working with
294
                        foreach my $metric_type (@metric_types) {
295
                            push(
296
                                @report_body,
297
                                $self->_COUNTER_report_row( $report_row, $metric_type, $access_type, $yop )
298
                            );
299
                        }
300
                    }
301
                } else {
302
303
                    # Add one report row for each metric_type we're working with
304
                    foreach my $metric_type (@metric_types) {
305
                        push( @report_body, $self->_COUNTER_report_row( $report_row, $metric_type, undef, $yop ) );
306
                    }
307
                }
308
            }
309
310
        } elsif ($use_access_type) {
311
            my @access_types = map { $_->{"Access_Type"} } @{ $report_row->{Attribute_Performance} };
312
            foreach my $access_type (@access_types) {
313
314
                # Add one report row for each metric_type we're working with
315
                foreach my $metric_type (@metric_types) {
316
                    push( @report_body, $self->_COUNTER_report_row( $report_row, $metric_type, $access_type ) );
317
                }
318
            }
319
        } else {
320
            foreach my $metric_type (@metric_types) {
321
                push( @report_body, $self->_COUNTER_report_row( $report_row, $metric_type ) );
322
            }
323
        }
324
325
    }
326
327
    return @report_body;
328
}
329
330
=head3 _COUNTER_title_report_row
331
332
Return a COUNTER title for the COUNTER titles report body
333
https://cop5.countermetrics.org/en/5.1.0.1/04-reports/03-title-reports.html#column-headings-elements
334
335
=cut
336
337
sub _COUNTER_title_report_row {
338
    my ( $self, $title_row, $metric_type, $total_usage, $monthly_usages, $access_type, $yop, $data_type ) = @_;
339
340
    my $header             = $self->{sushi}->{header};
341
    my $specific_fields    = $self->get_report_type_specific_fields( $header->{Report_ID} );
342
    my $access_type_to_use = $access_type ? $access_type : ( $title_row->{Access_Type} || "" );
343
    my $yop_to_use         = $yop         ? $yop         : ( $title_row->{YOP}         || "" );
344
    my $data_type_to_use   = $data_type   ? $data_type   : ( $title_row->{Data_Type}   || "" );
345
346
    return (
347
        [
348
            # Title
349
            $title_row->{Title} || "",
350
351
            # Publisher
352
            $title_row->{Publisher} || "",
353
354
            # Publisher_ID
355
            $self->_get_SUSHI_Type_Value( $title_row->{Publisher_ID}, "ISNI" ) || "",
356
357
            # Platform
358
            $title_row->{Platform} || "",
359
360
            # DOI
361
            $self->_get_SUSHI_Type_Value( $title_row->{Item_ID}, "DOI" ) || "",
362
363
            # Proprietary_ID
364
            $self->_get_SUSHI_Type_Value( $title_row->{Item_ID}, "Proprietary" ) || "",
365
366
            # ISBN
367
            grep ( /ISBN/, @{$specific_fields} )
368
            ? ( $self->_get_SUSHI_Type_Value( $title_row->{Item_ID}, "ISBN" ) || "" )
369
            : (),
370
371
            # Print_ISSN
372
            $self->_get_SUSHI_Type_Value( $title_row->{Item_ID}, "Print_ISSN" ) || "",
373
374
            # Online_ISSN
375
            $self->_get_SUSHI_Type_Value( $title_row->{Item_ID}, "Online_ISSN" ) || "",
376
377
            # URI - FIXME: What goes in URI?
378
            "",
379
380
            # Data_Type
381
            grep ( /Data_Type/, @{$specific_fields} ) ? $data_type_to_use : (),
382
383
            # YOP
384
            grep ( /YOP/, @{$specific_fields} ) ? $yop_to_use : (),
385
386
            # Access_Type
387
            grep ( /Access_Type/, @{$specific_fields} ) ? $access_type_to_use : (),
388
389
            # Metric_Type
390
            $metric_type,
391
392
            # Report_Period_Total
393
            $total_usage,
394
395
            # Monthly usage entries
396
            @{$monthly_usages}
397
        ]
398
    );
399
}
400
401
=head3 _COUNTER_titles_report_column_headings
402
403
Return titles report column headings
404
405
=cut
406
407
sub _COUNTER_titles_report_column_headings {
408
    my ($self) = @_;
409
410
    my $header          = $self->{sushi}->{header};
411
    my @month_headings  = $self->_get_usage_months( $header, 1 );
412
    my $specific_fields = $self->get_report_type_specific_fields( $header->{Report_ID} );
413
414
    return (
415
        [
416
            "Title",
417
            "Publisher",
418
            "Publisher_ID",
419
            "Platform",
420
            "DOI",
421
            "Proprietary_ID",
422
            grep ( /ISBN/, @{$specific_fields} ) ? ("ISBN") : (),
423
            "Print_ISSN",
424
            "Online_ISSN",
425
            "URI",
426
            grep ( /Data_Type/, @{$specific_fields} ) ? ("Data_Type") : (),
427
428
            #"Section_Type", #TODO: Only if requested (?)
429
            grep ( /YOP/,         @{$specific_fields} ) ? ("YOP")         : (),
430
            grep ( /Access_Type/, @{$specific_fields} ) ? ("Access_Type") : (),
431
432
            #"Access_Method", #TODO: Only if requested (?)
433
            "Metric_Type",
434
            "Reporting_Period_Total",
435
436
            # @month_headings in "Mmm-yyyy" format. TODO: Show unless Exclude_Monthly_Details=true
437
            @month_headings
438
        ]
439
    );
440
}
441
442
=head3 get_report_type_specific_fields
443
444
Returns the specific fields for a given report_type
445
446
=cut
447
448
sub get_report_type_specific_fields {
449
    my ( $self, $report_type ) = @_;
450
451
    my %report_type_map = (
452
        "TR_B1" => [ 'YOP', 'Data_Type', 'ISBN' ],
453
        "TR_B2" => [ 'YOP', 'Data_Type', 'ISBN' ],
454
        "TR_B3" => [ 'YOP', 'Data_Type', 'Access_Type', 'ISBN' ],
455
        "TR_J3" => ['Access_Type'],
456
        "TR_J4" => ['YOP'],
457
        "IR_A1" => [
458
            'Authors',            'Publication_Date', 'Article_Version',  'Print_ISSN', 'Online_ISSN', 'Parent_Title',
459
            'Parent_Authors',     'Parent_Article_Version', 'Parent_DOI', 'Parent_Proprietary_ID', 'Parent_Print_ISSN',
460
            'Parent_Online_ISSN', 'Parent_URI',             'Access_Type'
461
        ],
462
    );
463
464
    return $report_type_map{$report_type};
465
466
}
467
468
1;
(-)a/Koha/ERM/EUsage/CounterFile.pm (-15 / +47 lines)
Lines 85-90 Receive background_job_callbacks to be able to update job progress Link Here
85
sub store {
85
sub store {
86
    my ( $self, $background_job_callbacks ) = @_;
86
    my ( $self, $background_job_callbacks ) = @_;
87
87
88
    # DOCS:
89
    # COUNTER 5 CSV examples:
90
    # https://cop5.countermetrics.org/en/5.0.3/appendices/h-sample-counter-master-reports-and-standard-views.html
91
    # COUNTER 5.1 CSV examples:
92
    # https://cop5.projectcounter.org/en/5.1/appendices/g-sample-counter-reports-and-standard-views.html
93
88
    $self->_set_report_type_from_file;
94
    $self->_set_report_type_from_file;
89
95
90
    my $result = $self->SUPER::store;
96
    my $result = $self->SUPER::store;
Lines 227-233 sub _add_monthly_usage_entries { Link Here
227
233
228
    my $usage_data_provider = $self->get_usage_data_provider;
234
    my $usage_data_provider = $self->get_usage_data_provider;
229
    my $usage_object_info   = $self->_get_usage_object_id_hash($usage_object);
235
    my $usage_object_info   = $self->_get_usage_object_id_hash($usage_object);
230
    my $specific_fields     = Koha::ERM::EUsage::SushiCounter->get_report_type_specific_fields( $self->type );
236
    my $specific_fields     = Koha::ERM::EUsage::SushiCounter->get_report_type_specific_fields_by_release(
237
        $self->type,
238
        $self->get_COUNTER_report_release->{header_value}
239
    );
231
240
232
    $usage_object->monthly_usages(
241
    $usage_object->monthly_usages(
233
        [
242
        [
Lines 262-268 sub _add_yearly_usage_entries { Link Here
262
271
263
    my $usage_data_provider = $self->get_usage_data_provider;
272
    my $usage_data_provider = $self->get_usage_data_provider;
264
    my $usage_object_info   = $self->_get_usage_object_id_hash($usage_object);
273
    my $usage_object_info   = $self->_get_usage_object_id_hash($usage_object);
265
    my $specific_fields     = Koha::ERM::EUsage::SushiCounter->get_report_type_specific_fields( $self->type );
274
    my $specific_fields     = Koha::ERM::EUsage::SushiCounter->get_report_type_specific_fields_by_release(
275
        $self->type,
276
        $self->get_COUNTER_report_release->{header_value}
277
    );
266
278
267
    while ( my ( $year, $usage ) = each( %{$yearly_usages} ) ) {
279
    while ( my ( $year, $usage ) = each( %{$yearly_usages} ) ) {
268
280
Lines 303-323 A I <Koha::Exceptions::ERM::EUsage::CounterFile> exception is thrown Link Here
303
sub validate {
315
sub validate {
304
    my ($self) = @_;
316
    my ($self) = @_;
305
317
306
    open my $fh, "<", \$self->file_content or die;
318
    my $release = $self->get_COUNTER_report_release;
307
    my $csv = Text::CSV_XS->new( { binary => 1, always_quote => 1, eol => $/, decode_utf8 => 1, formula => 'empty' } );
308
309
    $csv->column_names(qw( header_key header_value ));
310
    my @header_rows = $csv->getline_hr_all( $fh, 0, 12 );
311
    my @header      = $header_rows[0];
312
313
    my @release_row =
314
        map( $_->{header_key} eq 'Release' ? $_ : (), @{ $header[0] } );
315
    my $release = $release_row[0];
316
319
317
    # TODO: Validate that there is an empty row between header and body
320
    # TODO: Validate that there is an empty row between header and body
318
321
319
    Koha::Exceptions::ERM::EUsage::CounterFile::UnsupportedRelease->throw
322
    Koha::Exceptions::ERM::EUsage::CounterFile::UnsupportedRelease->throw
320
        if $release && $release->{header_value} != 5;
323
        if $release && ( $release->{header_value} != 5 && $release->{header_value} ne '5.1' );
321
324
322
}
325
}
323
326
Lines 344-349 sub _set_report_type_from_file { Link Here
344
    $self->type( $report->{header_value} );
347
    $self->type( $report->{header_value} );
345
}
348
}
346
349
350
=head3 get_COUNTER_report_release
351
352
Retrieves the COUNTER report release for the given file_content
353
354
=cut
355
356
sub get_COUNTER_report_release {
357
    my ($self) = @_;
358
359
    open my $fh, "<", \$self->file_content or die;
360
    my $csv = Text::CSV_XS->new( { binary => 1, always_quote => 1, eol => $/, decode_utf8 => 1, formula => 'empty' } );
361
362
    $csv->column_names(qw( header_key header_value ));
363
    my @header_rows = $csv->getline_hr_all( $fh, 0, 12 );
364
    my @header      = $header_rows[0];
365
366
    my @release_row =
367
        map( $_->{header_key} eq 'Release' ? $_ : (), @{ $header[0] } );
368
    return $release_row[0];
369
}
370
347
=head3 _get_rows_from_COUNTER_file
371
=head3 _get_rows_from_COUNTER_file
348
372
349
Returns array of rows from COUNTER file
373
Returns array of rows from COUNTER file
Lines 356-362 sub _get_rows_from_COUNTER_file { Link Here
356
    open my $fh, "<", \$self->file_content or die;
380
    open my $fh, "<", \$self->file_content or die;
357
    my $csv = Text::CSV_XS->new( { binary => 1, always_quote => 1, eol => $/, decode_utf8 => 1, formula => 'empty' } );
381
    my $csv = Text::CSV_XS->new( { binary => 1, always_quote => 1, eol => $/, decode_utf8 => 1, formula => 'empty' } );
358
382
359
    my $header_columns = $csv->getline_all( $fh, 13, 1 );
383
    my $release = $self->get_COUNTER_report_release;
384
    $release = $release->{header_value};
385
386
    my $header_rows = $release eq '5.1' ? 14 : 13;
387
388
    my $header_columns = $csv->getline_all( $fh, $header_rows, 1 );
360
    $csv->column_names( @{$header_columns}[0] );
389
    $csv->column_names( @{$header_columns}[0] );
361
390
362
    # Get all rows from 14th onward
391
    # Get all rows from 14th onward
Lines 588-594 sub _add_usage_object_entry { Link Here
588
    my ( $self, $row ) = @_;
617
    my ( $self, $row ) = @_;
589
618
590
    my $usage_data_provider = $self->get_usage_data_provider;
619
    my $usage_data_provider = $self->get_usage_data_provider;
591
    my $specific_fields     = Koha::ERM::EUsage::SushiCounter->get_report_type_specific_fields( $self->type );
620
    my $specific_fields     = Koha::ERM::EUsage::SushiCounter->get_report_type_specific_fields_by_release(
621
        $self->type,
622
        $self->get_COUNTER_report_release->{header_value}
623
    );
592
624
593
    if ( $self->type =~ /PR/i ) {
625
    if ( $self->type =~ /PR/i ) {
594
        my $new_usage_platform = Koha::ERM::EUsage::UsagePlatform->new(
626
        my $new_usage_platform = Koha::ERM::EUsage::UsagePlatform->new(
(-)a/Koha/ERM/EUsage/SushiCounter.pm (-280 / +35 lines)
Lines 41-55 Koha::ERM::EUsage::SushiCounter - Koha SushiCounter Object class Link Here
41
sub new {
41
sub new {
42
    my ( $class, $params ) = @_;
42
    my ( $class, $params ) = @_;
43
43
44
    my $self = $class->SUPER::new;
44
    my $counter_release;
45
    $self->{sushi} = {
45
    if ( $params->{response}->{Report_Header}->{Release} eq "5" ) {
46
        require Koha::ERM::EUsage::COUNTER::5;
47
        $counter_release = Koha::ERM::EUsage::COUNTER::5->new;
48
    } elsif ( $params->{response}->{Report_Header}->{Release} eq "5.1" ) {
49
        require Koha::ERM::EUsage::COUNTER::5_1;
50
        $counter_release = Koha::ERM::EUsage::COUNTER::5_1->new;
51
    } else {
52
53
        #TODO: Throw an exception stating release not found / not supported!
54
    }
55
56
    $counter_release->{sushi} = {
46
        header => $params->{response}->{Report_Header},
57
        header => $params->{response}->{Report_Header},
47
        body   => $params->{response}->{Report_Items}
58
        body   => $params->{response}->{Report_Items}
48
    };
59
    };
49
60
50
    #TODO: Handle empty $self->{sushi}->{body} here!
61
    #TODO: Handle empty $self->{sushi}->{body} here!
51
62
52
    return $self;
63
    return $counter_release;
53
}
64
}
54
65
55
=head3 get_COUNTER_from_SUSHI
66
=head3 get_COUNTER_from_SUSHI
Lines 92-138 sub _build_COUNTER_report_file { Link Here
92
103
93
}
104
}
94
105
95
=head3 _COUNTER_report_header
96
97
Return a COUNTER report header
98
https://cop5.projectcounter.org/en/5.0.2/04-reports/03-title-reports.html
99
100
=cut
101
102
sub _COUNTER_report_header {
103
    my ($self) = @_;
104
105
    my $header = $self->{sushi}->{header};
106
107
    my @metric_types_string = $self->_get_SUSHI_Name_Value( $header->{Report_Filters}, "Metric_Type" );
108
109
    my $begin_date = $self->_get_SUSHI_Name_Value( $header->{Report_Filters}, "Begin_Date" );
110
    my $end_date   = $self->_get_SUSHI_Name_Value( $header->{Report_Filters}, "End_Date" );
111
112
    return (
113
        [ Report_Name      => $header->{Report_Name}                                                            || "" ],
114
        [ Report_ID        => $header->{Report_ID}                                                              || "" ],
115
        [ Release          => $header->{Release}                                                                || "" ],
116
        [ Institution_Name => $header->{Institution_Name}                                                       || "" ],
117
        [ Institution_ID => join( "; ", map( $_->{Type} . ":" . $_->{Value}, @{ $header->{Institution_ID} } ) ) || "" ],
118
        [ Metric_Types   => join( "; ", split( /\|/, $metric_types_string[0] ) )                                || "" ],
119
        [ Report_Filters => join( "; ", map( $_->{Name} . ":" . $_->{Value}, @{ $header->{Report_Filters} } ) ) || "" ],
120
121
        #TODO: Report_Attributes may need parsing, test this with a SUSHI response that provides it
122
        [ Report_Attributes => $header->{Report_Attributes} || "" ],
123
        [
124
            Exceptions => join(
125
                "; ", map( $_->{Code} . ": " . $_->{Message} . " (" . $_->{Data} . ")", @{ $header->{Exceptions} } )
126
                )
127
                || ""
128
        ],
129
        [ Reporting_Period => "Begin_Date=" . $begin_date . "; End_Date=" . $end_date ],
130
        [ Created          => $header->{Created}    || "" ],
131
        [ Created_By       => $header->{Created_By} || "" ],
132
        [""]    #empty 13th line (COUNTER 5)
133
    );
134
}
135
136
=head3 _COUNTER_item_report_row
106
=head3 _COUNTER_item_report_row
137
107
138
Return a COUNTER item for the COUNTER items report body
108
Return a COUNTER item for the COUNTER items report body
Lines 274-344 sub _COUNTER_platform_report_row { Link Here
274
    );
244
    );
275
}
245
}
276
246
277
=head3 _COUNTER_title_report_row
278
279
Return a COUNTER title for the COUNTER titles report body
280
https://cop5.projectcounter.org/en/5.0.2/04-reports/03-title-reports.html#column-headings-elements
281
282
=cut
283
284
sub _COUNTER_title_report_row {
285
    my ( $self, $title_row, $metric_type, $total_usage, $monthly_usages ) = @_;
286
287
    my $header          = $self->{sushi}->{header};
288
    my $specific_fields = $self->get_report_type_specific_fields( $header->{Report_ID} );
289
290
    return (
291
        [
292
            # Title
293
            $title_row->{Title} || "",
294
295
            # Publisher
296
            $title_row->{Publisher} || "",
297
298
            # Publisher_ID
299
            $self->_get_SUSHI_Type_Value( $title_row->{Publisher_ID}, "ISNI" ) || "",
300
301
            # Platform
302
            $title_row->{Platform} || "",
303
304
            # DOI
305
            $self->_get_SUSHI_Type_Value( $title_row->{Item_ID}, "DOI" ) || "",
306
307
            # Proprietary_ID
308
            $self->_get_SUSHI_Type_Value( $title_row->{Item_ID}, "Proprietary" ) || "",
309
310
            # ISBN
311
            grep ( /ISBN/, @{$specific_fields} )
312
            ? ( $self->_get_SUSHI_Type_Value( $title_row->{Item_ID}, "ISBN" ) || "" )
313
            : (),
314
315
            # Print_ISSN
316
            $self->_get_SUSHI_Type_Value( $title_row->{Item_ID}, "Print_ISSN" ) || "",
317
318
            # Online_ISSN
319
            $self->_get_SUSHI_Type_Value( $title_row->{Item_ID}, "Online_ISSN" ) || "",
320
321
            # URI - FIXME: What goes in URI?
322
            "",
323
324
            # YOP
325
            grep ( /YOP/, @{$specific_fields} ) ? ( $title_row->{YOP} || "" ) : (),
326
327
            # Access_Type
328
            grep ( /Access_Type/, @{$specific_fields} ) ? ( $title_row->{Access_Type} || "" ) : (),
329
330
            # Metric_Type
331
            $metric_type,
332
333
            # Report_Period_Total
334
            $total_usage,
335
336
            # Monthly usage entries
337
            @{$monthly_usages}
338
        ]
339
    );
340
}
341
342
=head3 _COUNTER_report_row
247
=head3 _COUNTER_report_row
343
248
344
Return a COUNTER row for the COUNTER report body
249
Return a COUNTER row for the COUNTER report body
Lines 346-356 Return a COUNTER row for the COUNTER report body Link Here
346
=cut
251
=cut
347
252
348
sub _COUNTER_report_row {
253
sub _COUNTER_report_row {
349
    my ( $self, $report_row, $metric_type ) = @_;
254
    my ( $self, $report_row, $metric_type, $access_type, $yop, $data_type ) = @_;
350
255
351
    my $header = $self->{sushi}->{header};
256
    my $header = $self->{sushi}->{header};
352
257
353
    my ( $total_usage, @monthly_usages ) = $self->_get_COUNTER_row_usages( $report_row, $metric_type );
258
    my ( $total_usage, @monthly_usages ) = $self->_get_COUNTER_row_usages( $report_row, $metric_type, $access_type );
354
259
355
    if ( $header->{Report_ID} =~ /PR/i ) {
260
    if ( $header->{Report_ID} =~ /PR/i ) {
356
        return $self->_COUNTER_platform_report_row(
261
        return $self->_COUNTER_platform_report_row(
Lines 360-474 sub _COUNTER_report_row { Link Here
360
    } elsif ( $header->{Report_ID} =~ /DR/i ) {
265
    } elsif ( $header->{Report_ID} =~ /DR/i ) {
361
        return $self->_COUNTER_database_report_row( $report_row, $metric_type, $total_usage, \@monthly_usages );
266
        return $self->_COUNTER_database_report_row( $report_row, $metric_type, $total_usage, \@monthly_usages );
362
    } elsif ( $header->{Report_ID} =~ /IR/i ) {
267
    } elsif ( $header->{Report_ID} =~ /IR/i ) {
268
269
        #TODO: Send $access_type to _COUNTER_item_report_row like we're doing with _COUNTER_title_report_row
363
        return $self->_COUNTER_item_report_row( $report_row, $metric_type, $total_usage, \@monthly_usages );
270
        return $self->_COUNTER_item_report_row( $report_row, $metric_type, $total_usage, \@monthly_usages );
364
    } elsif ( $header->{Report_ID} =~ /TR/i ) {
271
    } elsif ( $header->{Report_ID} =~ /TR/i ) {
365
        return $self->_COUNTER_title_report_row( $report_row, $metric_type, $total_usage, \@monthly_usages );
272
        return $self->_COUNTER_title_report_row(
366
    }
273
            $report_row,  $metric_type, $total_usage, \@monthly_usages,
367
}
274
            $access_type, $yop,         $data_type
368
275
        );
369
=head3 _get_COUNTER_row_usages
370
371
Returns the total and monthly usages for a row
372
373
=cut
374
375
sub _get_COUNTER_row_usages {
376
    my ( $self, $row, $metric_type ) = @_;
377
378
    my @usage_months = $self->_get_usage_months( $self->{sushi}->{header} );
379
380
    my @usage_months_fields = ();
381
    my $count_total         = 0;
382
383
    foreach my $usage_month (@usage_months) {
384
        my $month_is_empty = 1;
385
386
        foreach my $performance ( @{ $row->{Performance} } ) {
387
            my $period             = $performance->{Period};
388
            my $period_usage_month = substr( $period->{Begin_Date}, 0, 7 );
389
390
            my $instances = $performance->{Instance};
391
            my @metric_type_count =
392
                map( $_->{Metric_Type} eq $metric_type ? $_->{Count} : (),
393
                @{$instances} );
394
395
            if ( $period_usage_month eq $usage_month && $metric_type_count[0] ) {
396
                push( @usage_months_fields, $metric_type_count[0] );
397
                $count_total += $metric_type_count[0];
398
                $month_is_empty = 0;
399
            }
400
        }
401
402
        if ($month_is_empty) {
403
            push( @usage_months_fields, 0 );
404
        }
405
    }
406
    return ( $count_total, @usage_months_fields );
407
}
408
409
=head3 _COUNTER_report_body
410
411
Return the COUNTER report body as an array
412
413
=cut
414
415
sub _COUNTER_report_body {
416
    my ($self) = @_;
417
418
    my $header = $self->{sushi}->{header};
419
    my $body   = $self->{sushi}->{body};
420
421
    my @report_body = ();
422
423
    foreach my $report_row ( @{$body} ) {
424
425
        my @metric_types = ();
426
427
        # Grab all metric_types this SUSHI result has statistics for
428
        foreach my $performance ( @{ $report_row->{Performance} } ) {
429
            my @SUSHI_metric_types =
430
                map( $_->{Metric_Type}, @{ $performance->{Instance} } );
431
432
            foreach my $sushi_metric_type (@SUSHI_metric_types) {
433
                push( @metric_types, $sushi_metric_type ) unless grep { $_ eq $sushi_metric_type } @metric_types;
434
            }
435
        }
436
437
        # Add one report row for each metric_type we're working with
438
        foreach my $metric_type (@metric_types) {
439
            push( @report_body, $self->_COUNTER_report_row( $report_row, $metric_type ) );
440
        }
441
    }
276
    }
442
443
    return @report_body;
444
}
445
446
=head3 _get_SUSHI_Name_Value
447
448
Returns "Value" of a given "Name"
449
450
=cut
451
452
sub _get_SUSHI_Name_Value {
453
    my ( $self, $item, $name ) = @_;
454
455
    my @value = map( $_->{Name} eq $name ? $_->{Value} : (), @{$item} );
456
457
    return $value[0];
458
}
459
460
=head3 _get_SUSHI_Type_Value
461
462
Returns "Value" of a given "Type"
463
464
=cut
465
466
sub _get_SUSHI_Type_Value {
467
    my ( $self, $item, $type ) = @_;
468
469
    my @value = map( $_->{Type} eq $type ? $_->{Value} : (), @{$item} );
470
471
    return $value[0];
472
}
277
}
473
278
474
=head3 _COUNTER_report_column_headings
279
=head3 _COUNTER_report_column_headings
Lines 617-661 sub _COUNTER_platforms_report_column_headings { Link Here
617
    );
422
    );
618
}
423
}
619
424
620
=head3 _COUNTER_titles_report_column_headings
425
=head3 get_report_type_specific_fields_by_release
621
426
622
Return titles report column headings
427
Returns the specific fields for a given report_type
623
428
624
=cut
429
=cut
625
430
626
sub _COUNTER_titles_report_column_headings {
431
sub get_report_type_specific_fields_by_release {
627
    my ($self) = @_;
432
    my ( $self, $report_type, $counter_release ) = @_;
628
629
    my $header          = $self->{sushi}->{header};
630
    my @month_headings  = $self->_get_usage_months( $header, 1 );
631
    my $specific_fields = $self->get_report_type_specific_fields( $header->{Report_ID} );
632
633
    return (
634
        [
635
            "Title",
636
            "Publisher",
637
            "Publisher_ID",
638
            "Platform",
639
            "DOI",
640
            "Proprietary_ID",
641
            grep ( /ISBN/, @{$specific_fields} ) ? ("ISBN") : (),
642
            "Print_ISSN",
643
            "Online_ISSN",
644
            "URI",
645
646
            #"Data_Type", #TODO: Only if requested (?)
647
            #"Section_Type", #TODO: Only if requested (?)
648
            grep ( /YOP/,         @{$specific_fields} ) ? ("YOP")         : (),
649
            grep ( /Access_Type/, @{$specific_fields} ) ? ("Access_Type") : (),
650
433
651
            #"Access_Method", #TODO: Only if requested (?)
434
    if ( $counter_release eq "5" ) {
652
            "Metric_Type",
435
        require Koha::ERM::EUsage::COUNTER::5;
653
            "Reporting_Period_Total",
436
        return Koha::ERM::EUsage::COUNTER::5->get_report_type_specific_fields($report_type);
654
437
    } elsif ( $counter_release eq "5.1" ) {
655
            # @month_headings in "Mmm-yyyy" format. TODO: Show unless Exclude_Monthly_Details=true
438
        require Koha::ERM::EUsage::COUNTER::5_1;
656
            @month_headings
439
        return Koha::ERM::EUsage::COUNTER::5_1->get_report_type_specific_fields($report_type);
657
        ]
440
    }
658
    );
659
}
441
}
660
442
661
=head3 _get_usage_months
443
=head3 _get_usage_months
Lines 672-682 sub _get_usage_months { Link Here
672
        "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
454
        "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
673
    );
455
    );
674
456
675
    my @begin_date  = map( $_->{Name} eq "Begin_Date" ? $_->{Value} : (), @{ $header->{Report_Filters} } );
457
    my @begin_date  = $self->_get_SUSHI_Name_Value( $header->{Report_Filters}, 'Begin_Date' );
676
    my $begin_month = substr( $begin_date[0], 5, 2 );
458
    my $begin_month = substr( $begin_date[0], 5, 2 );
677
    my $begin_year  = substr( $begin_date[0], 0, 4 );
459
    my $begin_year  = substr( $begin_date[0], 0, 4 );
678
460
679
    my @end_date  = map( $_->{Name} eq "End_Date" ? $_->{Value} : (), @{ $header->{Report_Filters} } );
461
    my @end_date  = $self->_get_SUSHI_Name_Value( $header->{Report_Filters}, 'End_Date' );
680
    my $end_month = substr( $end_date[0], 5, 2 );
462
    my $end_month = substr( $end_date[0], 5, 2 );
681
    my $end_year  = substr( $end_date[0], 0, 4 );
463
    my $end_year  = substr( $end_date[0], 0, 4 );
682
464
Lines 699-730 sub _get_usage_months { Link Here
699
    return @month_headings;
481
    return @month_headings;
700
}
482
}
701
483
702
=head3 get_report_type_specific_fields
703
704
Returns the specific fields for a given report_type
705
706
=cut
707
708
sub get_report_type_specific_fields {
709
    my ( $self, $report_type ) = @_;
710
711
    my %report_type_map = (
712
        "TR_B1" => [ 'YOP', 'ISBN' ],
713
        "TR_B2" => [ 'YOP', 'ISBN' ],
714
        "TR_B3" => [ 'YOP', 'Access_Type', 'ISBN' ],
715
        "TR_J3" => ['Access_Type'],
716
        "TR_J4" => ['YOP'],
717
        "IR_A1" => [
718
            'Authors',            'Publication_Date', 'Article_Version',  'Print_ISSN', 'Online_ISSN', 'Parent_Title',
719
            'Parent_Authors',     'Parent_Article_Version', 'Parent_DOI', 'Parent_Proprietary_ID', 'Parent_Print_ISSN',
720
            'Parent_Online_ISSN', 'Parent_URI',             'Access_Type'
721
        ],
722
    );
723
724
    return $report_type_map{$report_type};
725
726
}
727
728
=head3 _type
484
=head3 _type
729
485
730
=cut
486
=cut
731
- 

Return to bug 39345