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

(-)a/C4/Acquisition.pm (-7 / +5 lines)
Lines 28-33 use C4::Contract; Link Here
28
use C4::Debug;
28
use C4::Debug;
29
use C4::Templates qw(gettemplate);
29
use C4::Templates qw(gettemplate);
30
use Koha::DateUtils qw( dt_from_string output_pref );
30
use Koha::DateUtils qw( dt_from_string output_pref );
31
use Koha::Acquisition::Baskets;
31
use Koha::Acquisition::Booksellers;
32
use Koha::Acquisition::Booksellers;
32
use Koha::Acquisition::Orders;
33
use Koha::Acquisition::Orders;
33
use Koha::Biblios;
34
use Koha::Biblios;
Lines 2445-2459 sub GetHistory { Link Here
2445
        $query .= ' AND (aqorders.ordernumber IN ( ' . join (',', ('?') x @$ordernumbers ) . '))';
2446
        $query .= ' AND (aqorders.ordernumber IN ( ' . join (',', ('?') x @$ordernumbers ) . '))';
2446
        push @query_params, @$ordernumbers;
2447
        push @query_params, @$ordernumbers;
2447
    if ( @$additional_fields ) {
2448
    if ( @$additional_fields ) {
2448
        my $matching_record_ids_for_additional_fields = Koha::AdditionalField->get_matching_record_ids( {
2449
        my @baskets = Koha::Acquisition::Baskets->search_additional_fields($additional_fields);
2449
            fields => $additional_fields,
2450
2450
            tablename => 'aqbasket',
2451
        return [] unless @baskets;
2451
            exact_match => 0,
2452
        } );
2453
        return [] unless @$matching_record_ids_for_additional_fields;
2454
2452
2455
        # No parameterization because record IDs come directly from DB
2453
        # No parameterization because record IDs come directly from DB
2456
        $query .= ' AND aqbasket.basketno IN ( ' . join( ',', @$matching_record_ids_for_additional_fields ) . ' )';
2454
        $query .= ' AND aqbasket.basketno IN ( ' . join( ',', map { $_->basketno } @baskets ) . ' )';
2457
    }
2455
    }
2458
2456
2459
    if ( C4::Context->preference("IndependentBranches") ) {
2457
    if ( C4::Context->preference("IndependentBranches") ) {
(-)a/C4/Serials.pm (-26 / +25 lines)
Lines 30-36 use C4::Log; # logaction Link Here
30
use C4::Debug;
30
use C4::Debug;
31
use C4::Serials::Frequency;
31
use C4::Serials::Frequency;
32
use C4::Serials::Numberpattern;
32
use C4::Serials::Numberpattern;
33
use Koha::AdditionalField;
33
use Koha::AdditionalFieldValues;
34
use Koha::DateUtils;
34
use Koha::DateUtils;
35
use Koha::Serial;
35
use Koha::Serial;
36
use Koha::Subscriptions;
36
use Koha::Subscriptions;
Lines 275-285 sub GetSubscription { Link Here
275
    $subscription->{cannotedit} = not can_edit_subscription( $subscription );
275
    $subscription->{cannotedit} = not can_edit_subscription( $subscription );
276
276
277
    # Add additional fields to the subscription into a new key "additional_fields"
277
    # Add additional fields to the subscription into a new key "additional_fields"
278
    my $additional_field_values = Koha::AdditionalField->fetch_all_values({
278
    my %additional_field_values = map {
279
            tablename => 'subscription',
279
        $_->field->name => $_->value
280
            record_id => $subscriptionid,
280
    } Koha::Subscriptions->find($subscriptionid)->additional_field_values;
281
    });
281
    $subscription->{additional_fields} = \%additional_field_values;
282
    $subscription->{additional_fields} = $additional_field_values->{$subscriptionid};
283
282
284
    if ( my $mana_id = $subscription->{mana_id} ) {
283
    if ( my $mana_id = $subscription->{mana_id} ) {
285
        my $mana_subscription = Koha::SharedContent::get_entity_by_id(
284
        my $mana_subscription = Koha::SharedContent::get_entity_by_id(
Lines 529-540 sub SearchSubscriptions { Link Here
529
    my $additional_fields = $args->{additional_fields} // [];
528
    my $additional_fields = $args->{additional_fields} // [];
530
    my $matching_record_ids_for_additional_fields = [];
529
    my $matching_record_ids_for_additional_fields = [];
531
    if ( @$additional_fields ) {
530
    if ( @$additional_fields ) {
532
        $matching_record_ids_for_additional_fields = Koha::AdditionalField->get_matching_record_ids({
531
        my @subscriptions = Koha::Subscriptions->search_additional_fields($additional_fields);
533
                fields => $additional_fields,
532
534
                tablename => 'subscription',
533
        return () unless @subscriptions;
535
                exact_match => 0,
534
536
        });
535
        $matching_record_ids_for_additional_fields = [ map {
537
        return () unless @$matching_record_ids_for_additional_fields;
536
            $_->subscriptionid
537
        } @subscriptions ];
538
    }
538
    }
539
539
540
    my $query = q|
540
    my $query = q|
Lines 631-641 sub SearchSubscriptions { Link Here
631
        $subscription->{cannotedit} = not can_edit_subscription( $subscription );
631
        $subscription->{cannotedit} = not can_edit_subscription( $subscription );
632
        $subscription->{cannotdisplay} = not can_show_subscription( $subscription );
632
        $subscription->{cannotdisplay} = not can_show_subscription( $subscription );
633
633
634
        my $additional_field_values = Koha::AdditionalField->fetch_all_values({
634
        my %additional_field_values = map {
635
            record_id => $subscription->{subscriptionid},
635
            $_->field->name => $_->value
636
            tablename => 'subscription'
636
        } Koha::Subscriptions->find($subscription->{subscriptionid})->additional_field_values;
637
        });
637
        $subscription->{additional_fields} = \%additional_field_values;
638
        $subscription->{additional_fields} = $additional_field_values->{$subscription->{subscriptionid}};
639
    }
638
    }
640
639
641
    return @$results;
640
    return @$results;
Lines 1700-1709 sub DelSubscription { Link Here
1700
    $dbh->do("DELETE FROM subscriptionhistory WHERE subscriptionid=?", undef, $subscriptionid);
1699
    $dbh->do("DELETE FROM subscriptionhistory WHERE subscriptionid=?", undef, $subscriptionid);
1701
    $dbh->do("DELETE FROM serial WHERE subscriptionid=?", undef, $subscriptionid);
1700
    $dbh->do("DELETE FROM serial WHERE subscriptionid=?", undef, $subscriptionid);
1702
1701
1703
    my $afs = Koha::AdditionalField->all({tablename => 'subscription'});
1702
    Koha::AdditionalFieldValues->search({
1704
    foreach my $af (@$afs) {
1703
        'field.tablename' => 'subscription',
1705
        $af->delete_values({record_id => $subscriptionid});
1704
        'me.record_id' => $subscriptionid,
1706
    }
1705
    }, { join => 'field' })->delete;
1707
1706
1708
    logaction( "SERIAL", "DELETE", $subscriptionid, "" ) if C4::Context->preference("SubscriptionLog");
1707
    logaction( "SERIAL", "DELETE", $subscriptionid, "" ) if C4::Context->preference("SubscriptionLog");
1709
}
1708
}
Lines 1833-1843 sub GetLateOrMissingIssues { Link Here
1833
        }
1832
        }
1834
        $line->{"status".$line->{status}}   = 1;
1833
        $line->{"status".$line->{status}}   = 1;
1835
1834
1836
        my $additional_field_values = Koha::AdditionalField->fetch_all_values({
1835
        my $subscription = Koha::Subscriptions->find($line->{subscriptionid});
1837
            record_id => $line->{subscriptionid},
1836
        my %additional_field_values = map {
1838
            tablename => 'subscription'
1837
            $_->field->name => $_->value
1839
        });
1838
        } $subscription->additional_field_values;
1840
        %$line = ( %$line, additional_fields => $additional_field_values->{$line->{subscriptionid}} );
1839
        %$line = ( %$line, additional_fields => \%additional_field_values );
1841
1840
1842
        push @issuelist, $line;
1841
        push @issuelist, $line;
1843
    }
1842
    }
(-)a/Koha/Acquisition/Basket.pm (-1 / +1 lines)
Lines 22-28 use Modern::Perl; Link Here
22
use Koha::Database;
22
use Koha::Database;
23
use Koha::Acquisition::BasketGroups;
23
use Koha::Acquisition::BasketGroups;
24
24
25
use base qw( Koha::Object );
25
use base qw( Koha::Object Koha::Object::Mixin::AdditionalFields );
26
26
27
=head1 NAME
27
=head1 NAME
28
28
(-)a/Koha/Acquisition/Baskets.pm (-1 / +1 lines)
Lines 22-28 use Modern::Perl; Link Here
22
use Koha::Database;
22
use Koha::Database;
23
use Koha::Acquisition::Basket;
23
use Koha::Acquisition::Basket;
24
24
25
use base qw( Koha::Objects );
25
use base qw( Koha::Objects Koha::Objects::Mixin::AdditionalFields );
26
26
27
=head1 NAME
27
=head1 NAME
28
28
(-)a/Koha/AdditionalField.pm (-498 / +2 lines)
Lines 2-326 package Koha::AdditionalField; Link Here
2
2
3
use Modern::Perl;
3
use Modern::Perl;
4
4
5
use base qw(Class::Accessor);
5
use base qw(Koha::Object);
6
6
7
use C4::Context;
7
use C4::Context;
8
8
9
__PACKAGE__->mk_accessors(qw( id tablename name authorised_value_category marcfield searchable values ));
9
sub _type { 'AdditionalField' }
10
11
sub new {
12
    my ( $class, $args ) = @_;
13
14
    my $additional_field = {
15
        id => $args->{id} // q||,
16
        tablename => $args->{tablename} // q||,
17
        name => $args->{name} // q||,
18
        authorised_value_category => $args->{authorised_value_category} // q||,
19
        marcfield => $args->{marcfield} // q||,
20
        searchable => $args->{searchable} // 0,
21
        values => $args->{values} // {},
22
    };
23
24
    my $self = $class->SUPER::new( $additional_field );
25
26
    bless $self, $class;
27
    return $self;
28
}
29
30
sub fetch {
31
    my ( $self ) = @_;
32
    my $dbh = C4::Context->dbh;
33
    my $field_id = $self->id;
34
    return unless $field_id;
35
    my $data = $dbh->selectrow_hashref(
36
        q|
37
            SELECT id, tablename, name, authorised_value_category, marcfield, searchable
38
            FROM additional_fields
39
            WHERE id = ?
40
        |,
41
        {}, ( $field_id )
42
    );
43
44
    die "This additional field does not exist (id=$field_id)" unless $data;
45
    $self->{id} = $data->{id};
46
    $self->{tablename} = $data->{tablename};
47
    $self->{name} = $data->{name};
48
    $self->{authorised_value_category} = $data->{authorised_value_category};
49
    $self->{marcfield} = $data->{marcfield};
50
    $self->{searchable} = $data->{searchable};
51
    return $self;
52
}
53
54
sub update {
55
    my ( $self ) = @_;
56
57
    die "There is no id defined for this additional field. I cannot update it" unless $self->{id};
58
59
    my $dbh = C4::Context->dbh;
60
    local $dbh->{RaiseError} = 1;
61
62
    return $dbh->do(q|
63
        UPDATE additional_fields
64
        SET name = ?,
65
            authorised_value_category = ?,
66
            marcfield = ?,
67
            searchable = ?
68
        WHERE id = ?
69
    |, {}, ( $self->{name}, $self->{authorised_value_category}, $self->{marcfield}, $self->{searchable}, $self->{id} ) );
70
}
71
72
sub delete {
73
    my ( $self ) = @_;
74
    return unless $self->{id};
75
    my $dbh = C4::Context->dbh;
76
    local $dbh->{RaiseError} = 1;
77
    return $dbh->do(q|
78
        DELETE FROM additional_fields WHERE id = ?
79
    |, {}, ( $self->{id} ) );
80
}
81
82
sub insert {
83
    my ( $self ) = @_;
84
    my $dbh = C4::Context->dbh;
85
    local $dbh->{RaiseError} = 1;
86
    $dbh->do(q|
87
        INSERT INTO additional_fields
88
        ( tablename, name, authorised_value_category, marcfield, searchable )
89
        VALUES ( ?, ?, ?, ?, ? )
90
    |, {}, ( $self->{tablename}, $self->{name}, $self->{authorised_value_category}, $self->{marcfield}, $self->{searchable} ) );
91
    $self->{id} = $dbh->{mysql_insertid};
92
}
93
94
sub insert_values {
95
    my ( $self )  = @_;
96
97
    my $dbh = C4::Context->dbh;
98
    local $dbh->{RaiseError} = 1;
99
    while ( my ( $record_id, $value ) = each %{$self->{values}} ) {
100
        next unless defined $value;
101
        my $updated = $dbh->do(q|
102
            UPDATE additional_field_values
103
            SET value = ?
104
            WHERE field_id = ?
105
            AND record_id = ?
106
        |, {}, ( $value, $self->{id}, $record_id ));
107
        if ( $updated eq '0E0' ) {
108
            $dbh->do(q|
109
                INSERT INTO additional_field_values( field_id, record_id, value )
110
                VALUES( ?, ?, ?)
111
            |, {}, ( $self->{id}, $record_id, $value ));
112
        }
113
    }
114
}
115
116
sub fetch_values {
117
    my ( $self, $args ) = @_;
118
    my $record_id = $args->{record_id};
119
    my $dbh = C4::Context->dbh;
120
    my $values = $dbh->selectall_arrayref(
121
        q|
122
            SELECT *
123
            FROM additional_fields af, additional_field_values afv
124
            WHERE af.id = afv.field_id
125
                AND af.tablename = ?
126
                AND af.name = ?
127
        | . ( $record_id ? q|AND afv.record_id = ?| : '' ),
128
        {Slice => {}}, ( $self->{tablename}, $self->{name}, ($record_id ? $record_id : () ) )
129
    );
130
131
    $self->{values} = {};
132
    for my $v ( @$values ) {
133
        $self->{values}{$v->{record_id}} = $v->{value};
134
    }
135
}
136
137
sub delete_values {
138
    my ($self, $args) = @_;
139
140
    my $record_id = $args->{record_id};
141
142
    my $dbh = C4::Context->dbh;
143
144
    my @where_strs = ('field_id = ?');
145
    my @where_args = ($self->{id});
146
147
    if ($record_id) {
148
        push @where_strs, 'record_id = ?';
149
        push @where_args, $record_id;
150
    }
151
152
    my $query = q{
153
        DELETE FROM additional_field_values
154
        WHERE
155
    } . join (' AND ', @where_strs);
156
157
    $dbh->do($query, undef, @where_args);
158
}
159
160
sub all {
161
    my ( $class, $args ) = @_;
162
    die "BAD CALL: Don't use fetch_all_values as an instance method"
163
        if ref $class and UNIVERSAL::can($class,'can');
164
    my $tablename = $args->{tablename};
165
    my $searchable = $args->{searchable};
166
    my $dbh = C4::Context->dbh;
167
    my $query = q|
168
        SELECT * FROM additional_fields WHERE 1
169
    |;
170
    $query .= q| AND tablename = ?|
171
        if $tablename;
172
173
    $query .= q| AND searchable = ?|
174
        if defined $searchable;
175
176
    my $results = $dbh->selectall_arrayref(
177
        $query, {Slice => {}}, (
178
            $tablename ? $tablename : (),
179
            defined $searchable ? $searchable : ()
180
        )
181
    );
182
    my @fields;
183
    for my $r ( @$results ) {
184
        push @fields, Koha::AdditionalField->new({
185
            id => $r->{id},
186
            tablename => $r->{tablename},
187
            name => $r->{name},
188
            authorised_value_category => $r->{authorised_value_category},
189
            marcfield => $r->{marcfield},
190
            searchable => $r->{searchable},
191
        });
192
    }
193
    return \@fields;
194
195
}
196
197
sub fetch_all_values {
198
    my ( $class, $args ) = @_;
199
    die "BAD CALL: Don't use fetch_all_values as an instance method"
200
        if ref $class and UNIVERSAL::can($class,'can');
201
202
    my $record_id = $args->{record_id};
203
    my $tablename = $args->{tablename};
204
    return unless $tablename;
205
206
    my $dbh = C4::Context->dbh;
207
    my $values = $dbh->selectall_arrayref(
208
        q|
209
            SELECT afv.record_id, af.name, afv.value
210
            FROM additional_fields af, additional_field_values afv
211
            WHERE af.id = afv.field_id
212
                AND af.tablename = ?
213
        | . ( $record_id ? q| AND afv.record_id = ?| : q|| ),
214
        {Slice => {}}, ( $tablename, ($record_id ? $record_id : ()) )
215
    );
216
217
    my $r;
218
    for my $v ( @$values ) {
219
        $r->{$v->{record_id}}{$v->{name}} = $v->{value};
220
    }
221
    return $r;
222
}
223
224
sub get_matching_record_ids {
225
    my ( $class, $args ) = @_;
226
    die "BAD CALL: Don't use fetch_all_values as an instance method"
227
        if ref $class and UNIVERSAL::can($class,'can');
228
229
    my $fields = $args->{fields} // [];
230
    my $tablename = $args->{tablename};
231
    my $exact_match = $args->{exact_match} // 1;
232
    return [] unless @$fields;
233
234
    my $dbh = C4::Context->dbh;
235
    my $query = q|SELECT * FROM |;
236
    my ( @subqueries, @args );
237
    my $i = 0;
238
    for my $field ( @$fields ) {
239
        $i++;
240
        my $subquery = qq|(
241
            SELECT record_id, field$i.name AS field${i}_name
242
            FROM additional_field_values afv
243
            LEFT JOIN
244
                (
245
                    SELECT afv.id, af.name, afv.value
246
                    FROM additional_field_values afv, additional_fields af
247
                    WHERE afv.field_id = af.id
248
                    AND af.name = ?
249
                    AND af.tablename = ?
250
                    AND value LIKE ?
251
                ) AS field$i USING (id)
252
            WHERE field$i.id IS NOT NULL
253
        ) AS values$i |;
254
        $subquery .= ' USING (record_id)' if $i > 1;
255
        push @subqueries, $subquery;
256
        push @args, $field->{name}, $tablename, ( ( $exact_match or $field->{authorised_value_category} ) ? $field->{value} : "%$field->{value}%" );
257
    }
258
    $query .= join( ' LEFT JOIN ', @subqueries ) . ' WHERE 1';
259
    for my $j ( 1 .. $i ) {
260
            $query .= qq| AND field${j}_name IS NOT NULL|;
261
    }
262
    my $values = $dbh->selectall_arrayref( $query, {Slice => {}}, @args );
263
    return [
264
        map { $_->{record_id} } @$values
265
    ]
266
}
267
268
sub update_fields_from_query {
269
    my ( $class, $args ) = @_;
270
    die "BAD CALL: Don't use update_fields_from_query as an instance method"
271
        if ref $class and UNIVERSAL::can($class,'can');
272
273
    my $query = $args->{query};
274
    my $additional_fields = Koha::AdditionalField->all( { tablename => $args->{tablename} } );
275
    for my $field ( @$additional_fields ) {
276
        my $af = Koha::AdditionalField->new({ id => $field->{id} })->fetch;
277
        if ( $af->{marcfield} ) {
278
            my ( $field, $subfield ) = split /\$/, $af->{marcfield};
279
            $af->{values} = undef;
280
            if ( $args->{marc_record} and $field and $subfield ) {
281
                my $value = $args->{marc_record}->subfield( $field, $subfield );
282
                $af->{values} = {
283
                    $args->{record_id} => $value
284
                };
285
            }
286
        } else {
287
            $af->{values} = {
288
                $args->{record_id} => $query->param( 'additional_field_' . $field->{id} )
289
            } if defined $query->param( 'additional_field_' . $field->{id} );
290
        }
291
        $af->insert_values;
292
    }
293
}
294
295
sub get_filters_from_query {
296
    my ( $class, $args ) = @_;
297
    die "BAD CALL: Don't use get_filters_from_query as an instance method"
298
        if ref $class and UNIVERSAL::can($class,'can');
299
300
    my $query = $args->{query};
301
    my $additional_fields = Koha::AdditionalField->all( { tablename => $args->{tablename}, searchable => 1 } );
302
    my @additional_field_filters;
303
    for my $field ( @$additional_fields ) {
304
        my $filter_value = $query->param( 'additional_field_' . $field->{id} );
305
        if ( defined $filter_value and $filter_value ne q|| ) {
306
            push @additional_field_filters, {
307
                name => $field->{name},
308
                value => $filter_value,
309
                authorised_value_category => $field->{authorised_value_category},
310
            };
311
        }
312
    }
313
314
    return \@additional_field_filters;
315
}
316
317
sub get_filters_as_values {
318
    my ( $class, $filters ) = @_;
319
    die "BAD CALL: Don't use get_filters_as_values as an instance method"
320
        if ref $class and UNIVERSAL::can($class,'can');
321
322
    return { map { $_->{name} => $_->{value} } @$filters };
323
}
324
10
325
1;
11
1;
326
12
Lines 330-517 __END__ Link Here
330
16
331
Koha::AdditionalField
17
Koha::AdditionalField
332
18
333
=head1 SYNOPSIS
334
335
    use Koha::AdditionalField;
336
    my $af1 = Koha::AdditionalField->new({id => $id});
337
    my $af2 = Koha::AuthorisedValue->new({
338
        tablename => 'my_table',
339
        name => 'a_name',
340
        authorised_value_category => 'LOST',
341
        marcfield => '200$a',
342
        searchable => 1,
343
    });
344
    $av1->delete;
345
    $av2->{name} = 'another_name';
346
    $av2->update;
347
348
=head1 DESCRIPTION
349
350
Class for managing additional fields into Koha.
351
352
=head1 METHODS
353
354
=head2 new
355
356
Create a new Koha::AdditionalField object. This method can be called using several ways.
357
Either with the id for existing field or with different values for a new one.
358
359
=over 4
360
361
=item B<id>
362
363
    The caller just knows the id of the additional field and want to retrieve all values.
364
365
=item B<tablename, name, authorised_value_category, marcfield and searchable>
366
367
    The caller wants to create a new additional field.
368
369
=back
370
371
=head2 fetch
372
373
The information will be retrieved from the database.
374
375
=head2 update
376
377
If the AdditionalField object has been modified and the values have to be modified into the database, call this method.
378
379
=head2 delete
380
381
Remove a the record in the database using the id the object.
382
383
=head2 insert
384
385
Insert a new AdditionalField object into the database.
386
387
=head2 insert_values
388
389
Insert new values for a record.
390
391
    my $af = Koha::AdditionalField({ id => $id })->fetch;
392
    my $af->{values} = {
393
        record_id1 => 'my value',
394
        record_id2 => 'another value',
395
    };
396
    $af->insert_values;
397
398
=head2 fetch_values
399
400
Retrieve values from the database for a given record_id.
401
The record_id argument is optional.
402
403
    my $af = Koha::AdditionalField({ id => $id })->fetch;
404
    my $values = $af->fetch_values({record_id => $record_id});
405
406
    $values will be equal to something like:
407
    {
408
        record_id => {
409
            field_name1 => 'value1',
410
            field_name2 => 'value2',
411
        }
412
    }
413
414
=head2 delete_values
415
416
Delete values from the database for a given record_id.
417
The record_id argument is optional.
418
419
    my $af = Koha::AdditionalField({ id => $id })->fetch;
420
    $af->delete_values({record_id => $record_id});
421
422
=head2 all
423
424
Retrieve all additional fields in the database given some parameters.
425
Parameters are optional.
426
This method returns a list of AdditionalField objects.
427
This is a static method.
428
429
    my $fields = Koha::AdditionalField->all;
430
    or
431
    my $fields = Koha::AdditionalField->all{(tablename => 'my_table'});
432
    or
433
    my $fields = Koha::AdditionalField->all({searchable => 1});
434
435
=head2 fetch_all_values
436
437
Retrieve all values for a table name.
438
This is a static method.
439
440
    my $values = Koha::AdditionalField({ tablename => 'my_table' });
441
442
    $values will be equel to something like:
443
    {
444
        record_id1 => {
445
            field_name1 => 'value1',
446
            field_name2 => 'value2',
447
        },
448
        record_id2 => {
449
            field_name1 => 'value3',
450
            field_name2 => 'value4',
451
        }
452
453
    }
454
455
=head2 get_matching_record_ids
456
457
Retrieve all record_ids for records matching the field values given in parameter.
458
This method returns a list of ids.
459
This is a static method.
460
461
    my $fields = [
462
        {
463
            name => 'field_name',
464
            value => 'field_value',
465
        }
466
    ];
467
    my $ids = Koha::AdditionalField->get_matching_record_ids(
468
        {
469
            tablename => 'subscription',
470
            fields => $fields
471
        }
472
    );
473
474
=head2 update_fields_from_query
475
476
Updates fields based on user input (best paired with additional-fields-entry.pl) and optionally a MARC record.
477
478
This is a static method.
479
480
    Koha::AdditionalField->update_fields_from_query( {
481
        tablename => 'aqbasket',
482
        input => $input,
483
        record_id => $basketno,
484
        marc_record => GetBiblio( $biblionumber ),
485
    } );
486
487
=head2 get_filters_from_query
488
489
Extracts a list of search filters from user input, to be used with C<get_matching_record_ids> and
490
C<get_filters_as_values>.
491
492
This is a static method.
493
494
    my $filters = Koha::AdditionalField->get_filters_from_query( {
495
        tablename => 'aqbasket',
496
        input => $input,
497
    } );
498
499
=head2 get_filters_as_values
500
501
Transforms the result of C<get_filters_from_query> into a hashref of C<name> => C<value>, so
502
user-entered filters can be redisplayed.
503
504
    $template->param(
505
        additional_field_values => Koha::AdditionalField->get_filters_as_values(
506
            $filters
507
        ),
508
    );
509
510
    [% INCLUDE 'additional-field-entry.inc'
511
        values=additional_field_values
512
        available=available_additional_fields
513
    %]
514
515
=head1 AUTHOR
19
=head1 AUTHOR
516
20
517
Jonathan Druart <jonathan.druart at biblibre.com>
21
Jonathan Druart <jonathan.druart at biblibre.com>
(-)a/Koha/AdditionalFieldValue.pm (+9 lines)
Line 0 Link Here
1
package Koha::AdditionalFieldValue;
2
3
use Modern::Perl;
4
5
use base 'Koha::Object';
6
7
sub _type { 'AdditionalFieldValue' }
8
9
1;
(-)a/Koha/AdditionalFieldValues.pm (+10 lines)
Line 0 Link Here
1
package Koha::AdditionalFieldValues;
2
3
use Modern::Perl;
4
5
use base 'Koha::Objects';
6
7
sub _type { 'AdditionalFieldValue' }
8
sub object_class { 'Koha::AdditionalFieldValue' }
9
10
1;
(-)a/Koha/AdditionalFields.pm (+12 lines)
Line 0 Link Here
1
package Koha::AdditionalFields;
2
3
use Modern::Perl;
4
5
use base 'Koha::Objects';
6
7
use Koha::AdditionalField;
8
9
sub _type { 'AdditionalField' }
10
sub object_class { 'Koha::AdditionalField' }
11
12
1;
(-)a/Koha/Object/Mixin/AdditionalFields.pm (+68 lines)
Line 0 Link Here
1
package Koha::Object::Mixin::AdditionalFields;
2
3
use Modern::Perl;
4
5
=head1 NAME
6
7
Koha::Object::Mixin::AdditionalFields
8
9
=head1 SYNOPSIS
10
11
    package Koha::Foo;
12
13
    use parent qw( Koha::Object Koha::Object::Mixin::AdditionalFields );
14
15
    sub _type { 'Foo' }
16
17
18
    package main;
19
20
    use Koha::Foo;
21
22
    Koha::Foos->find($id)->set_additional_fields(...);
23
24
=head1 API
25
26
=head2 Public methods
27
28
=head3 set_additional_fields
29
30
    $foo->set_additional_fields([
31
        {
32
            id => 1,
33
            value => 'foo',
34
        },
35
        {
36
            id => 2,
37
            value => 'bar',
38
        }
39
    ]);
40
41
=cut
42
43
sub set_additional_fields {
44
    my ($self, $additional_fields) = @_;
45
46
    my $rs = Koha::Database->new->schema->resultset('AdditionalFieldValue');
47
48
    foreach my $additional_field (@$additional_fields) {
49
        my $field_value = $rs->find_or_new({
50
            field_id => $additional_field->{id},
51
            record_id => $self->id,
52
        });
53
        my $value = $additional_field->{value};
54
        if (defined $value) {
55
            $field_value->set_columns({ value => $value })->update_or_insert;
56
        } elsif ($field_value->in_storage) {
57
            $field_value->delete;
58
        }
59
    }
60
}
61
62
sub additional_field_values {
63
    my ($self) = @_;
64
65
    return $self->_result->additional_field_values;
66
}
67
68
1;
(-)a/Koha/Objects/Mixin/AdditionalFields.pm (+59 lines)
Line 0 Link Here
1
package Koha::Objects::Mixin::AdditionalFields;
2
3
use Modern::Perl;
4
5
=head1 NAME
6
7
Koha::Objects::Mixin::AdditionalFields
8
9
=head1 SYNOPSIS
10
11
    package Koha::Foos;
12
13
    use parent qw( Koha::Objects Koha::Objects::Mixin::AdditionalFields );
14
15
    sub _type { 'Foo' }
16
    sub object_class { 'Koha::Foo' }
17
18
19
    package main;
20
21
    use Koha::Foos;
22
23
    Koha::Foos->search_additional_fields(...)
24
25
=head1 API
26
27
=head2 Public methods
28
29
=head3 search_additional_fields
30
31
    my @objects = Koha::Foos->search_additional_fields([
32
        {
33
            id => 1,
34
            value => 'foo',
35
        },
36
        {
37
            id => 2,
38
            value => 'bar',
39
        }
40
    ]);
41
42
=cut
43
44
sub search_additional_fields {
45
    my ($class, $additional_fields) = @_;
46
47
    my %conditions;
48
    my $idx = 0;
49
    foreach my $additional_field (@$additional_fields) {
50
        ++$idx;
51
        my $alias = $idx > 1 ? "additional_field_values_$idx" : "additional_field_values";
52
        $conditions{"$alias.field_id"} = $additional_field->{id};
53
        $conditions{"$alias.value"} = { -like => '%' . $additional_field->{value} . '%'};
54
    }
55
56
    return $class->search(\%conditions, { join => [ ('additional_field_values') x $idx ] });
57
}
58
59
1;
(-)a/Koha/Schema/Result/Aqbasket.pm (+16 lines)
Lines 312-317 __PACKAGE__->many_to_many("borrowernumbers", "aqbasketusers", "borrowernumber"); Link Here
312
# Created by DBIx::Class::Schema::Loader v0.07042 @ 2018-02-16 17:54:53
312
# Created by DBIx::Class::Schema::Loader v0.07042 @ 2018-02-16 17:54:53
313
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:gSw/f4JmMBzEssEFRg2fAQ
313
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:gSw/f4JmMBzEssEFRg2fAQ
314
314
315
__PACKAGE__->has_many(
316
  "additional_field_values",
317
  "Koha::Schema::Result::AdditionalFieldValue",
318
  sub {
319
    my ($args) = @_;
320
321
    return {
322
        "$args->{foreign_alias}.record_id" => { -ident => "$args->{self_alias}.basketno" },
323
324
        # TODO Add column additional_field_values.tablename to avoid subquery ?
325
        "$args->{foreign_alias}.field_id" =>
326
            { -in => \'(SELECT id FROM additional_fields WHERE tablename = "aqbasket")' },
327
    };
328
  },
329
  { cascade_copy => 0, cascade_delete => 0 },
330
);
315
331
316
# You can replace this text with custom code or comments, and it will be preserved on regeneration
332
# You can replace this text with custom code or comments, and it will be preserved on regeneration
317
1;
333
1;
(-)a/Koha/Schema/Result/Subscription.pm (+16 lines)
Lines 455-460 __PACKAGE__->has_many( Link Here
455
# Created by DBIx::Class::Schema::Loader v0.07046 @ 2019-01-23 12:56:39
455
# Created by DBIx::Class::Schema::Loader v0.07046 @ 2019-01-23 12:56:39
456
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:dTb/JOO3KQ3NZGypFbRiEw
456
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:dTb/JOO3KQ3NZGypFbRiEw
457
457
458
__PACKAGE__->has_many(
459
  "additional_field_values",
460
  "Koha::Schema::Result::AdditionalFieldValue",
461
  sub {
462
    my ($args) = @_;
463
464
    return {
465
        "$args->{foreign_alias}.record_id" => { -ident => "$args->{self_alias}.subscriptionid" },
466
467
        # TODO Add column additional_field_values.tablename to avoid subquery ?
468
        "$args->{foreign_alias}.field_id" =>
469
            { -in => \'(SELECT id FROM additional_fields WHERE tablename = "subscription")' },
470
    };
471
  },
472
  { cascade_copy => 0, cascade_delete => 0 },
473
);
458
474
459
# You can replace this text with custom content, and it will be preserved on regeneration
475
# You can replace this text with custom content, and it will be preserved on regeneration
460
1;
476
1;
(-)a/Koha/Subscription.pm (-1 / +1 lines)
Lines 30-36 use Koha::Subscription::Frequencies; Link Here
30
use Koha::Subscription::Numberpatterns;
30
use Koha::Subscription::Numberpatterns;
31
use JSON;
31
use JSON;
32
32
33
use base qw(Koha::Object);
33
use base qw(Koha::Object Koha::Object::Mixin::AdditionalFields);
34
34
35
=head1 NAME
35
=head1 NAME
36
36
(-)a/Koha/Subscriptions.pm (-1 / +1 lines)
Lines 25-31 use Koha::Database; Link Here
25
25
26
use Koha::Subscription;
26
use Koha::Subscription;
27
27
28
use base qw(Koha::Objects);
28
use base qw(Koha::Objects Koha::Objects::Mixin::AdditionalFields);
29
29
30
=head1 NAME
30
=head1 NAME
31
31
(-)a/acqui/basket.pl (-6 / +6 lines)
Lines 33-38 use C4::Biblio; Link Here
33
use C4::Items;
33
use C4::Items;
34
use C4::Suggestions;
34
use C4::Suggestions;
35
use Koha::Biblios;
35
use Koha::Biblios;
36
use Koha::Acquisition::Baskets;
36
use Koha::Acquisition::Booksellers;
37
use Koha::Acquisition::Booksellers;
37
use Koha::Acquisition::Orders;
38
use Koha::Acquisition::Orders;
38
use Koha::Libraries;
39
use Koha::Libraries;
Lines 43-49 use Koha::EDI qw( create_edi_order get_edifact_ean ); Link Here
43
use Koha::CsvProfiles;
44
use Koha::CsvProfiles;
44
use Koha::Patrons;
45
use Koha::Patrons;
45
46
46
use Koha::AdditionalField;
47
use Koha::AdditionalFields;
47
48
48
=head1 NAME
49
=head1 NAME
49
50
Lines 432-442 if ( $op eq 'list' ) { Link Here
432
        has_budgets          => $has_budgets,
433
        has_budgets          => $has_budgets,
433
        duplinbatch          => $duplinbatch,
434
        duplinbatch          => $duplinbatch,
434
        csv_profiles         => [ Koha::CsvProfiles->search({ type => 'sql', used_for => 'export_basket' }) ],
435
        csv_profiles         => [ Koha::CsvProfiles->search({ type => 'sql', used_for => 'export_basket' }) ],
435
        available_additional_fields => Koha::AdditionalField->all( { tablename => 'aqbasket' } ),
436
        available_additional_fields => [ Koha::AdditionalFields->search( { tablename => 'aqbasket' } ) ],
436
        additional_field_values => Koha::AdditionalField->fetch_all_values( {
437
        additional_field_values => { map {
437
            tablename => 'aqbasket',
438
            $_->field->name => $_->value
438
            record_id => $basketno,
439
        } Koha::Acquisition::Baskets->find($basketno)->additional_field_values },
439
        } )->{$basketno},
440
    );
440
    );
441
}
441
}
442
442
(-)a/acqui/basketheader.pl (-11 / +15 lines)
Lines 54-60 use C4::Acquisition qw/GetBasket NewBasket ModBasketHeader/; Link Here
54
use C4::Contract qw/GetContracts/;
54
use C4::Contract qw/GetContracts/;
55
55
56
use Koha::Acquisition::Booksellers;
56
use Koha::Acquisition::Booksellers;
57
use Koha::AdditionalField;
57
use Koha::Acquisition::Baskets;
58
use Koha::AdditionalFields;
58
59
59
my $input = new CGI;
60
my $input = new CGI;
60
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
61
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
Lines 75-81 my $basket; Link Here
75
my $op = $input->param('op');
76
my $op = $input->param('op');
76
my $is_an_edit = $input->param('is_an_edit');
77
my $is_an_edit = $input->param('is_an_edit');
77
78
78
$template->param( available_additional_fields => scalar Koha::AdditionalField->all( { tablename => 'aqbasket' } ) );
79
$template->param( available_additional_fields => [ Koha::AdditionalFields->search( { tablename => 'aqbasket' } ) ] );
79
80
80
if ( $op eq 'add_form' ) {
81
if ( $op eq 'add_form' ) {
81
    my @contractloop;
82
    my @contractloop;
Lines 98-107 if ( $op eq 'add_form' ) { Link Here
98
        }
99
        }
99
        $template->param( is_an_edit => 1);
100
        $template->param( is_an_edit => 1);
100
        $template->param(
101
        $template->param(
101
            additional_field_values => Koha::AdditionalField->fetch_all_values( {
102
            additional_field_values => { map {
102
                tablename => 'aqbasket',
103
                $_->field->name => $_->value
103
                record_id => $basketno,
104
            } Koha::Acquisition::Baskets->find($basketno)->additional_field_values },
104
            } )->{$basketno},
105
        );
105
        );
106
    } else {
106
    } else {
107
    #new basket
107
    #new basket
Lines 170-180 if ( $op eq 'add_form' ) { Link Here
170
        );
170
        );
171
    }
171
    }
172
172
173
    Koha::AdditionalField->update_fields_from_query( {
173
    my @additional_fields;
174
        tablename => 'aqbasket',
174
    for my $field (Koha::AdditionalFields->search({ tablename => 'aqbasket' })) {
175
        record_id => $basketno,
175
        my $value = $input->param('additional_field_' . $field->id);
176
        query => $input,
176
        push @additional_fields, {
177
    } );
177
            id => $field->id,
178
            value => $value,
179
        };
180
    }
181
    Koha::Acquisition::Baskets->find($basketno)->set_additional_fields(\@additional_fields);
178
182
179
    print $input->redirect('basket.pl?basketno='.$basketno);
183
    print $input->redirect('basket.pl?basketno='.$basketno);
180
    exit 0;
184
    exit 0;
(-)a/acqui/histsearch.pl (-6 / +14 lines)
Lines 56-62 use C4::Output; Link Here
56
use C4::Acquisition;
56
use C4::Acquisition;
57
use C4::Debug;
57
use C4::Debug;
58
use C4::Koha;
58
use C4::Koha;
59
use Koha::AdditionalField;
59
use Koha::AdditionalFields;
60
use Koha::DateUtils;
60
use Koha::DateUtils;
61
61
62
my $input = new CGI;
62
my $input = new CGI;
Lines 98-109 unless ( $input->param('from') ) { Link Here
98
}
98
}
99
$filters->{from_placed_on} = output_pref( { dt => $from_placed_on, dateformat => 'iso', dateonly => 1 } ),
99
$filters->{from_placed_on} = output_pref( { dt => $from_placed_on, dateformat => 'iso', dateonly => 1 } ),
100
$filters->{to_placed_on} = output_pref( { dt => $to_placed_on, dateformat => 'iso', dateonly => 1 } ),
100
$filters->{to_placed_on} = output_pref( { dt => $to_placed_on, dateformat => 'iso', dateonly => 1 } ),
101
$filters->{additional_fields} = Koha::AdditionalField->get_filters_from_query({
101
my @additional_fields = Koha::AdditionalFields->search( { tablename => 'aqbasket', searchable => 1 } );
102
    tablename => 'aqbasket',
102
$template->param( available_additional_fields => \@additional_fields );
103
    query => $input,
103
my @additional_field_filters;
104
} );
104
foreach my $additional_field (@additional_fields) {
105
    my $value = $input->param('additional_field_' . $additional_field->id);
106
    if (defined $value and $value ne '') {
107
        push @additional_field_filters, {
108
            id => $additional_field->id,
109
            value => $value,
110
        };
111
    }
112
}
113
$filters->{additional_fields} = \@additional_field_filters;
105
114
106
$template->param( available_additional_fields => scalar Koha::AdditionalField->all( { tablename => 'aqbasket', searchable => 1 } ) );
107
115
108
my $order_loop;
116
my $order_loop;
109
# If we're supplied any value then we do a search. Otherwise we don't.
117
# If we're supplied any value then we do a search. Otherwise we don't.
(-)a/admin/additional-fields.pl (-9 / +9 lines)
Lines 22-27 use C4::Auth; Link Here
22
use C4::Koha;
22
use C4::Koha;
23
use C4::Output;
23
use C4::Output;
24
use Koha::AdditionalField;
24
use Koha::AdditionalField;
25
use Koha::AdditionalFields;
25
26
26
my $input = new CGI;
27
my $input = new CGI;
27
28
Lines 49-62 if ( $op eq 'add' ) { Link Here
49
    if ( $field_id and $name ) {
50
    if ( $field_id and $name ) {
50
        my $updated = 0;
51
        my $updated = 0;
51
        eval {
52
        eval {
52
            my $af = Koha::AdditionalField->new({
53
            my $af = Koha::AdditionalFields->find($field_id);
53
                id => $field_id,
54
            $af->set({
54
                name => $name,
55
                name => $name,
55
                authorised_value_category => $authorised_value_category,
56
                authorised_value_category => $authorised_value_category,
56
                marcfield => $marcfield,
57
                marcfield => $marcfield,
57
                searchable => $searchable,
58
                searchable => $searchable,
58
            });
59
            });
59
            $updated = $af->update;
60
            $updated = $af->store ? 1 : 0;
60
        };
61
        };
61
        push @messages, {
62
        push @messages, {
62
            code => 'update',
63
            code => 'update',
Lines 72-78 if ( $op eq 'add' ) { Link Here
72
                marcfield => $marcfield,
73
                marcfield => $marcfield,
73
                searchable => $searchable,
74
                searchable => $searchable,
74
            });
75
            });
75
            $inserted = $af->insert;
76
            $inserted = $af->store ? 1 : 0;
76
        };
77
        };
77
        push @messages, {
78
        push @messages, {
78
            code => 'insert',
79
            code => 'insert',
Lines 90-98 if ( $op eq 'add' ) { Link Here
90
if ( $op eq 'delete' ) {
91
if ( $op eq 'delete' ) {
91
    my $deleted = 0;
92
    my $deleted = 0;
92
    eval {
93
    eval {
93
        my $af = Koha::AdditionalField->new( { id => $field_id } );
94
        my $af = Koha::AdditionalFields->find($field_id);
94
        $deleted = $af->delete;
95
        $deleted = $af->delete;
95
        $deleted = 0 if $deleted eq '0E0';
96
    };
96
    };
97
    push @messages, {
97
    push @messages, {
98
        code => 'delete',
98
        code => 'delete',
Lines 104-113 if ( $op eq 'delete' ) { Link Here
104
if ( $op eq 'add_form' ) {
104
if ( $op eq 'add_form' ) {
105
    my $field;
105
    my $field;
106
    if ( $field_id ) {
106
    if ( $field_id ) {
107
        $field = Koha::AdditionalField->new( { id => $field_id } )->fetch;
107
        $field = Koha::AdditionalFields->find($field_id);
108
    }
108
    }
109
109
110
    $tablename = $field->{tablename} if $field;
110
    $tablename = $field->tablename if $field;
111
111
112
    $template->param(
112
    $template->param(
113
        field => $field,
113
        field => $field,
Lines 115-121 if ( $op eq 'add_form' ) { Link Here
115
}
115
}
116
116
117
if ( $op eq 'list' ) {
117
if ( $op eq 'list' ) {
118
    my $fields = Koha::AdditionalField->all( { tablename => $tablename } );
118
    my $fields = Koha::AdditionalFields->search( { tablename => $tablename } );
119
    $template->param( fields => $fields );
119
    $template->param( fields => $fields );
120
}
120
}
121
121
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/additional-fields-entry.inc (-3 / +3 lines)
Lines 11-17 Link Here
11
                    <select name="additional_field_[% field.id %]" id="additional_field_[% field.id %]">
11
                    <select name="additional_field_[% field.id %]" id="additional_field_[% field.id %]">
12
                        <option value="">All</option>
12
                        <option value="">All</option>
13
                        [% FOREACH av IN AuthorisedValues.GetAuthValueDropbox( field.authorised_value_category ) %]
13
                        [% FOREACH av IN AuthorisedValues.GetAuthValueDropbox( field.authorised_value_category ) %]
14
                            [% IF av.authorised_value == values.${field.name} %]
14
                            [% IF av.authorised_value == values.${field.id} %]
15
                                <option value="[% av.authorised_value %]" selected="selected">[% av.lib %]</option>
15
                                <option value="[% av.authorised_value %]" selected="selected">[% av.lib %]</option>
16
                            [% ELSE %]
16
                            [% ELSE %]
17
                                <option value="[% av.authorised_value %]">[% av.lib %]</option>
17
                                <option value="[% av.authorised_value %]">[% av.lib %]</option>
Lines 20-29 Link Here
20
                    </select> (Authorised values for [% field.authorised_value_category %])
20
                    </select> (Authorised values for [% field.authorised_value_category %])
21
                [% ELSE %]
21
                [% ELSE %]
22
                    [% IF field.marcfield %]
22
                    [% IF field.marcfield %]
23
                        <input type="text" value="[% values.${field.name} %]" id="additional_field_[% field.id %]" name="additional_field_[% field.id %]" readonly="readonly" />
23
                        <input type="text" value="[% values.${field.id} %]" id="additional_field_[% field.id %]" name="additional_field_[% field.id %]" readonly="readonly" />
24
                        This value will be filled with the [% field.marcfield %] subfield of the selected biblio.
24
                        This value will be filled with the [% field.marcfield %] subfield of the selected biblio.
25
                    [% ELSE %]
25
                    [% ELSE %]
26
                        <input type="text" value="[% values.${field.name} %]" id="additional_field_[% field.id %]" name="additional_field_[% field.id %]" />
26
                        <input type="text" value="[% values.${field.id} %]" id="additional_field_[% field.id %]" name="additional_field_[% field.id %]" />
27
                    [% END %]
27
                    [% END %]
28
                [% END %]
28
                [% END %]
29
            </li>
29
            </li>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/additional-fields.tt (-7 / +16 lines)
Lines 12-17 Link Here
12
[% Asset.css('css/datatables.css') %]
12
[% Asset.css('css/datatables.css') %]
13
</head>
13
</head>
14
14
15
[% marcfield_tables = ['subscription'] %]
16
[% show_marcfield = marcfield_tables.grep('^' _ tablename _ '$').size ? 1 : 0 %]
17
15
<body id="ser_add_fields" class="ser">
18
<body id="ser_add_fields" class="ser">
16
    [% INCLUDE 'header.inc' %]
19
    [% INCLUDE 'header.inc' %]
17
    [% INCLUDE 'cat-search.inc' %]
20
    [% INCLUDE 'cat-search.inc' %]
Lines 77-83 Link Here
77
                    <tr>
80
                    <tr>
78
                        <th>Name</th>
81
                        <th>Name</th>
79
                        <th>Authorised value category</th>
82
                        <th>Authorised value category</th>
80
                        <th>MARC field</th>
83
                        [% IF show_marcfield %]
84
                            <th>MARC field</th>
85
                        [% END %]
81
                        <th>Searchable</th>
86
                        <th>Searchable</th>
82
                        <th>Actions</th>
87
                        <th>Actions</th>
83
                    </tr>
88
                    </tr>
Lines 87-99 Link Here
87
                        <tr>
92
                        <tr>
88
                            <td>[% field.name %]</td>
93
                            <td>[% field.name %]</td>
89
                            <td>[% field.authorised_value_category %]</td>
94
                            <td>[% field.authorised_value_category %]</td>
90
                            <td>[% field.marcfield %]</td>
95
                            [% IF show_marcfield %]
96
                                <td>[% field.marcfield %]</td>
97
                            [% END %]
91
                            <td>
98
                            <td>
92
                                [% IF field.searchable %]Yes[% ELSE %]No[% END %]
99
                                [% IF field.searchable %]Yes[% ELSE %]No[% END %]
93
                            </td>
100
                            </td>
94
                            <td class="actions">
101
                            <td class="actions">
95
                                <a class="btn btn-default btn-xs" href="?op=add_form&amp;field_id=[% field.id %]"><i class="fa fa-pencil"></i> Edit</a>
102
                                <a class="btn btn-default btn-xs" href="?op=add_form&amp;field_id=[% field.id %]"><i class="fa fa-pencil"></i> Edit</a>
96
                                <a class="confirmdelete btn btn-default btn-xs" href="?op=delete&amp;field_id=[% field.id %]"><i class="fa fa-trash"></i> Delete</a>
103
                                <a class="confirmdelete btn btn-default btn-xs" href="?op=delete&amp;field_id=[% field.id %]&amp;tablename=[% tablename %]"><i class="fa fa-trash"></i> Delete</a>
97
                            </td>
104
                            </td>
98
                        </tr>
105
                        </tr>
99
                    [% END %]
106
                    [% END %]
Lines 127-136 Link Here
127
                            %]
134
                            %]
128
                        </select>
135
                        </select>
129
                    </li>
136
                    </li>
130
                    <li>
137
                    [% IF show_marcfield %]
131
                        <label for="marcfield">MARC field: </label>
138
                        <li>
132
                        <input type="text" name="marcfield" id="marcfield" value="[% field.marcfield %]" />
139
                            <label for="marcfield">MARC field: </label>
133
                    </li>
140
                            <input type="text" name="marcfield" id="marcfield" value="[% field.marcfield %]" />
141
                        </li>
142
                    [% END %]
134
                    <li>
143
                    <li>
135
                        <label for="searchable">Searchable: </label>
144
                        <label for="searchable">Searchable: </label>
136
                        [% IF field.searchable %]
145
                        [% IF field.searchable %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/serials/serials-search.tt (-2 / +2 lines)
Lines 376-382 Link Here
376
                      <select id="additional_field_[% field.id | html %]" name="additional_field_[% field.id | html %]">
376
                      <select id="additional_field_[% field.id | html %]" name="additional_field_[% field.id | html %]">
377
                        <option value="">All</option>
377
                        <option value="">All</option>
378
                        [% FOREACH av IN AuthorisedValues.GetAuthValueDropbox(field.authorised_value_category) %]
378
                        [% FOREACH av IN AuthorisedValues.GetAuthValueDropbox(field.authorised_value_category) %]
379
                          [% IF av.authorised_value == additional_field_filters.${field.name} %]
379
                          [% IF av.authorised_value == additional_field_filters.${field.id} %]
380
                            <option value="[% av.authorised_value | html %]" selected="selected">[% av.lib | html %]</option>
380
                            <option value="[% av.authorised_value | html %]" selected="selected">[% av.lib | html %]</option>
381
                          [% ELSE %]
381
                          [% ELSE %]
382
                            <option value="[% av.authorised_value | html %]">[% av.lib | html %]</option>
382
                            <option value="[% av.authorised_value | html %]">[% av.lib | html %]</option>
Lines 384-390 Link Here
384
                        [% END %]
384
                        [% END %]
385
                      </select>
385
                      </select>
386
                    [% ELSE %]
386
                    [% ELSE %]
387
                      <input id="additional_field_[% field.id | html %]" type="text" value="[% additional_field_filters.${field.name} | html %]" name="additional_field_[% field.id | html %]" />
387
                      <input id="additional_field_[% field.id | html %]" type="text" value="[% additional_field_filters.${field.id} | html %]" name="additional_field_[% field.id | html %]" />
388
                    [% END %]
388
                    [% END %]
389
                  </li>
389
                  </li>
390
                [% END %]
390
                [% END %]
(-)a/serials/claims.pl (-8 / +2 lines)
Lines 27-33 use C4::Context; Link Here
27
use C4::Letters;
27
use C4::Letters;
28
use C4::Koha qw( GetAuthorisedValues );
28
use C4::Koha qw( GetAuthorisedValues );
29
29
30
use Koha::AdditionalField;
30
use Koha::AdditionalFields;
31
use Koha::CsvProfiles;
31
use Koha::CsvProfiles;
32
32
33
my $input = CGI->new;
33
my $input = CGI->new;
Lines 57-69 for my $s (@{$supplierlist} ) { Link Here
57
    }
57
    }
58
}
58
}
59
59
60
my $additional_fields = Koha::AdditionalField->all( { tablename => 'subscription', searchable => 1 } );
60
my $additional_fields = Koha::AdditionalFields->search( { tablename => 'subscription', searchable => 1 } );
61
for my $field ( @$additional_fields ) {
62
    if ( $field->{authorised_value_category} ) {
63
        $field->{authorised_value_choices} = GetAuthorisedValues( $field->{authorised_value_category} );
64
    }
65
}
66
67
61
68
my @serialnums=$input->multi_param('serialid');
62
my @serialnums=$input->multi_param('serialid');
69
if (@serialnums) { # i.e. they have been flagged to generate claims
63
if (@serialnums) { # i.e. they have been flagged to generate claims
(-)a/serials/serials-search.pl (-9 / +15 lines)
Lines 35-41 use C4::Context; Link Here
35
use C4::Koha qw( GetAuthorisedValues );
35
use C4::Koha qw( GetAuthorisedValues );
36
use C4::Output;
36
use C4::Output;
37
use C4::Serials;
37
use C4::Serials;
38
use Koha::AdditionalField;
38
use Koha::AdditionalFields;
39
39
40
use Koha::DateUtils;
40
use Koha::DateUtils;
41
use Koha::SharedContent;
41
use Koha::SharedContent;
Lines 79-89 if ( $op and $op eq "close" ) { Link Here
79
}
79
}
80
80
81
81
82
my $additional_fields = Koha::AdditionalField->all( { tablename => 'subscription', searchable => 1 } );
82
my @additional_fields = Koha::AdditionalFields->search( { tablename => 'subscription', searchable => 1 } );
83
my $additional_field_filters = Koha::AdditionalField->get_filters_from_query( {
83
my @additional_field_filters;
84
    tablename => 'subscription',
84
for my $field ( @additional_fields ) {
85
    query => $query,
85
    my $value = $query->param( 'additional_field_' . $field->id );
86
} );
86
    if ( defined $value and $value ne '' ) {
87
        push @additional_field_filters, {
88
            id => $field->id,
89
            value => $value,
90
        };
91
    }
92
}
87
93
88
my $expiration_date_dt = $expiration_date ? dt_from_string( $expiration_date ) : undef;
94
my $expiration_date_dt = $expiration_date ? dt_from_string( $expiration_date ) : undef;
89
my @subscriptions;
95
my @subscriptions;
Lines 110-116 if ($searched){ Link Here
110
            publisher    => $publisher,
116
            publisher    => $publisher,
111
            bookseller   => $bookseller,
117
            bookseller   => $bookseller,
112
            branch       => $branch,
118
            branch       => $branch,
113
            additional_fields => $additional_field_filters,
119
            additional_fields => \@additional_field_filters,
114
            location     => $location,
120
            location     => $location,
115
            expiration_date => $expiration_date_dt,
121
            expiration_date => $expiration_date_dt,
116
        });
122
        });
Lines 188-195 else Link Here
188
        branches_loop => \@branches_loop,
194
        branches_loop => \@branches_loop,
189
        done_searched => $searched,
195
        done_searched => $searched,
190
        routing       => $routing,
196
        routing       => $routing,
191
        additional_field_filters => Koha::AdditionalField->get_filters_as_values( $additional_field_filters ),
197
        additional_field_filters => { map { $_->{id} => $_->{value} } @additional_field_filters },
192
        additional_fields_for_subscription => $additional_fields,
198
        additional_fields_for_subscription => \@additional_fields,
193
        marcflavour   => (uc(C4::Context->preference("marcflavour"))),
199
        marcflavour   => (uc(C4::Context->preference("marcflavour"))),
194
        mana => $mana
200
        mana => $mana
195
    );
201
    );
(-)a/serials/subscription-add.pl (-14 / +34 lines)
Lines 29-35 use C4::Serials; Link Here
29
use C4::Serials::Frequency;
29
use C4::Serials::Frequency;
30
use C4::Serials::Numberpattern;
30
use C4::Serials::Numberpattern;
31
use C4::Letters;
31
use C4::Letters;
32
use Koha::AdditionalField;
32
use Koha::AdditionalFields;
33
use Koha::Biblios;
33
use Koha::Biblios;
34
use Koha::DateUtils;
34
use Koha::DateUtils;
35
use Koha::ItemTypes;
35
use Koha::ItemTypes;
Lines 144-150 $template->param( Link Here
144
    locations_loop=>$locations_loop,
144
    locations_loop=>$locations_loop,
145
);
145
);
146
146
147
$template->param( additional_fields_for_subscription => scalar Koha::AdditionalField->all( { tablename => 'subscription' } ) );
147
$template->param( additional_fields_for_subscription => [ Koha::AdditionalFields->search( { tablename => 'subscription' } ) ] );
148
148
149
my $typeloop = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search_with_localization->unblessed } };
149
my $typeloop = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search_with_localization->unblessed } };
150
150
Lines 370-381 sub redirect_add_subscription { Link Here
370
        $template->param( mana_msg => $result->{msg} );
370
        $template->param( mana_msg => $result->{msg} );
371
    }
371
    }
372
372
373
    Koha::AdditionalField->update_fields_from_query( {
373
    my @additional_fields;
374
        tablename => 'subscription',
374
    my $record = GetMarcBiblio({ biblionumber => $biblionumber, embed_items => 1 });
375
        record_id => $subscriptionid,
375
    for my $field (Koha::AdditionalFields->search({ tablename => 'subscription' })) {
376
        query => $query,
376
        my $value = $query->param('additional_field_' . $field->id);
377
        marc_record => GetMarcBiblio({ biblionumber => $biblionumber, embed_items => 1 })
377
        if ($field->marcfield) {
378
    } );
378
            my ($field, $subfield) = split /\$/, $field->marcfield;
379
            if ( $record and $field and $subfield ) {
380
                $value = $record->subfield( $field, $subfield );
381
            }
382
        }
383
        push @additional_fields, {
384
            id => $field->id,
385
            value => $value,
386
        };
387
    }
388
    Koha::Subscriptions->find($subscriptionid)->set_additional_fields(\@additional_fields);
379
389
380
    print $query->redirect("/cgi-bin/koha/serials/subscription-detail.pl?subscriptionid=$subscriptionid");
390
    print $query->redirect("/cgi-bin/koha/serials/subscription-detail.pl?subscriptionid=$subscriptionid");
381
    return;
391
    return;
Lines 478-489 sub redirect_mod_subscription { Link Here
478
        $skip_serialseq, $itemtype, $previousitemtype, $mana_id
488
        $skip_serialseq, $itemtype, $previousitemtype, $mana_id
479
    );
489
    );
480
490
481
    Koha::AdditionalField->update_fields_from_query( {
491
    my @additional_fields;
482
        tablename => 'subscription',
492
    my $record = GetMarcBiblio({ biblionumber => $biblionumber, embed_items => 1 });
483
        record_id => $subscriptionid,
493
    for my $field (Koha::AdditionalFields->search({ tablename => 'subscription' })) {
484
        query => $query,
494
        my $value = $query->param('additional_field_' . $field->id);
485
        marc_record => GetMarcBiblio({ biblionumber => $biblionumber, embed_items => 1 })
495
        if ($field->marcfield) {
486
    } );
496
            my ($field, $subfield) = split /\$/, $field->marcfield;
497
            if ( $record and $field and $subfield ) {
498
                $value = $record->subfield( $field, $subfield );
499
            }
500
        }
501
        push @additional_fields, {
502
            id => $field->id,
503
            value => $value,
504
        };
505
    }
506
    Koha::Subscriptions->find($subscriptionid)->set_additional_fields(\@additional_fields);
487
507
488
    print $query->redirect("/cgi-bin/koha/serials/subscription-detail.pl?subscriptionid=$subscriptionid");
508
    print $query->redirect("/cgi-bin/koha/serials/subscription-detail.pl?subscriptionid=$subscriptionid");
489
    return;
509
    return;
(-)a/serials/subscription-batchedit.pl (-16 / +14 lines)
Lines 26-32 use C4::Output; Link Here
26
use C4::Serials;
26
use C4::Serials;
27
use Koha::Subscriptions;
27
use Koha::Subscriptions;
28
use Koha::Acquisition::Booksellers;
28
use Koha::Acquisition::Booksellers;
29
use Koha::AdditionalField;
29
use Koha::AdditionalFields;
30
use Koha::DateUtils;
30
use Koha::DateUtils;
31
31
32
my $cgi = new CGI;
32
my $cgi = new CGI;
Lines 48-54 foreach my $subscriptionid (@subscriptionids) { Link Here
48
    push @subscriptions, $subscription if $subscription;
48
    push @subscriptions, $subscription if $subscription;
49
}
49
}
50
50
51
my $additional_fields = Koha::AdditionalField->all({tablename => 'subscription'});
51
my @additional_fields = Koha::AdditionalFields->search({tablename => 'subscription'});
52
52
53
my $batchedit = $cgi->param('batchedit');
53
my $batchedit = $cgi->param('batchedit');
54
if ($batchedit) {
54
if ($batchedit) {
Lines 64-72 if ($batchedit) { Link Here
64
    );
64
    );
65
65
66
    my $field_values = {};
66
    my $field_values = {};
67
    foreach my $field (@$additional_fields) {
67
    foreach my $field (@additional_fields) {
68
        my $value = $cgi->param('field_' . $field->{id});
68
        my $value = $cgi->param('field_' . $field->id);
69
        $field_values->{$field->{id}} = $value;
69
        $field_values->{$field->id} = $value;
70
    }
70
    }
71
71
72
    foreach my $subscription (@subscriptions) {
72
    foreach my $subscription (@subscriptions) {
Lines 77-99 if ($batchedit) { Link Here
77
            }
77
            }
78
        }
78
        }
79
79
80
        foreach my $field (@$additional_fields) {
80
        my @additional_field_values;
81
            my $value = $field_values->{$field->{id}};
81
        foreach my $field (@additional_fields) {
82
            my $value = $field_values->{$field->id};
82
            if (defined $value and $value ne '') {
83
            if (defined $value and $value ne '') {
83
                $field->{values} //= {};
84
                push @additional_field_values, {
84
                $field->{values}->{$subscription->subscriptionid} = $value;
85
                    id => $field->id,
86
                    value => $value,
87
                };
85
            }
88
            }
86
        }
89
        }
90
        $subscription->set_additional_fields(\@additional_field_values);
87
91
88
        $subscription->store;
92
        $subscription->store;
89
    }
93
    }
90
94
91
    foreach my $field (@$additional_fields) {
92
        if (defined $field->{values}) {
93
            $field->insert_values();
94
        }
95
    }
96
97
    my $redirect_url = $cgi->param('referrer') // '/cgi-bin/koha/serials/serials-home.pl';
95
    my $redirect_url = $cgi->param('referrer') // '/cgi-bin/koha/serials/serials-home.pl';
98
    print $cgi->redirect($redirect_url);
96
    print $cgi->redirect($redirect_url);
99
    exit;
97
    exit;
Lines 102-108 if ($batchedit) { Link Here
102
$template->param(
100
$template->param(
103
    subscriptions => \@subscriptions,
101
    subscriptions => \@subscriptions,
104
    booksellers => [ Koha::Acquisition::Booksellers->search() ],
102
    booksellers => [ Koha::Acquisition::Booksellers->search() ],
105
    additional_fields => $additional_fields,
103
    additional_fields => \@additional_fields,
106
    referrer => scalar $cgi->param('referrer'),
104
    referrer => scalar $cgi->param('referrer'),
107
);
105
);
108
106
(-)a/serials/subscription-detail.pl (-6 / +2 lines)
Lines 26-31 use C4::Output; Link Here
26
use C4::Context;
26
use C4::Context;
27
use C4::Search qw/enabled_staff_search_views/;
27
use C4::Search qw/enabled_staff_search_views/;
28
28
29
use Koha::AdditionalFields;
29
use Koha::AuthorisedValues;
30
use Koha::AuthorisedValues;
30
use Koha::DateUtils;
31
use Koha::DateUtils;
31
use Koha::Acquisition::Bookseller;
32
use Koha::Acquisition::Bookseller;
Lines 128-139 my $numberpattern = C4::Serials::Numberpattern::GetSubscriptionNumberpattern($su Link Here
128
129
129
my $default_bib_view = get_default_view();
130
my $default_bib_view = get_default_view();
130
131
131
my $additional_fields = Koha::AdditionalField->all( { tablename => 'subscription' } );
132
my $additional_fields = Koha::AdditionalFields->search( { tablename => 'subscription' } );
132
for my $field ( @$additional_fields ) {
133
    if ( $field->{authorised_value_category} ) {
134
        $field->{authorised_value_choices} = GetAuthorisedValues( $field->{authorised_value_category} );
135
    }
136
}
137
$template->param( additional_fields_for_subscription => $additional_fields );
133
$template->param( additional_fields_for_subscription => $additional_fields );
138
134
139
# FIXME Do we want to hide canceled orders?
135
# FIXME Do we want to hide canceled orders?
(-)a/t/db_dependent/AdditionalField.t (-293 lines)
Lines 1-293 Link Here
1
#!/usr/bin/perl
2
3
use Modern::Perl;
4
use Test::More tests => 40;
5
6
use C4::Context;
7
use Koha::AdditionalField;
8
use Koha::Database;
9
10
my $schema = Koha::Database->new->schema;
11
$schema->storage->txn_begin;
12
my $dbh = C4::Context->dbh;
13
14
$dbh->do( q|DELETE FROM additional_fields| );
15
$dbh->do( q|DELETE FROM additional_field_values| );
16
17
my $afs = Koha::AdditionalField->all;
18
is( scalar( @$afs ), 0, "all: there is no additional field" );
19
20
my $af1_name = q|af1|;
21
my $af1 = Koha::AdditionalField->new({
22
    tablename => 'subscription',
23
    name => $af1_name,
24
    authorised_values_category => '',
25
    marcfield => '',
26
    searchable => 1,
27
});
28
is ( $af1->name, $af1_name, "new: name value is kept" );
29
30
$af1->insert;
31
like ( $af1->id, qr|^\d+$|, "new: populate id value" );
32
33
my $af2_name = q|af2|;
34
my $af2_marcfield = q|200$a|;
35
my $af2_searchable = 1;
36
my $af2_tablename = q|subscription|;
37
my $af2_avc = q|LOST|;
38
my $af2 = Koha::AdditionalField->new({
39
    tablename => $af2_tablename,
40
    name => $af2_name,
41
    authorised_value_category => $af2_avc,
42
    marcfield => $af2_marcfield,
43
    searchable => $af2_searchable,
44
});
45
$af2->insert;
46
my $af2_id = $af2->id;
47
$af2 = Koha::AdditionalField->new({ id => $af2_id })->fetch;
48
is( ref($af2) , q|Koha::AdditionalField|, "fetch: return an object" );
49
is( $af2->id, $af2_id, "fetch: id for af2" );
50
is( $af2->tablename, $af2_tablename, "fetch: tablename for af2" );
51
is( $af2->name, $af2_name, "fetch: name for af2" );
52
is( $af2->authorised_value_category, $af2_avc, "fetch: authorised_value_category for af2" );
53
is( $af2->marcfield, $af2_marcfield, "fetch: marcfield for af2" );
54
is( $af2->searchable, $af2_searchable, "fetch: searchable for af2" );
55
56
my $af3 = Koha::AdditionalField->new({
57
    tablename => 'a_table',
58
    name => q|af3|,
59
    authorised_value_category => '',
60
    marcfield => '',
61
    searchable => 1,
62
});
63
$af3->insert;
64
65
my $af_common = Koha::AdditionalField->new({
66
    tablename => 'subscription',
67
    name => q|common|,
68
    authorised_value_category => '',
69
    marcfield => '',
70
    searchable => 1,
71
});
72
$af_common->insert;
73
74
# update
75
$af3->{tablename} = q|another_table|;
76
$af3->{name} = q|af3_mod|;
77
$af3->{authorised_value_category} = q|LOST|;
78
$af3->{marcfield} = q|200$a|;
79
$af3->{searchable} = 0;
80
my $updated = $af3->update;
81
$af3 = Koha::AdditionalField->new({ id => $af3->id })->fetch;
82
is( $updated, 1, "update: return number of affected rows" );
83
is( $af3->tablename, q|a_table|, "update: tablename is *not* updated, there is no sense to copy a field to another table" );
84
is( $af3->name, q|af3_mod|, "update: name" );
85
is( $af3->authorised_value_category, q|LOST|, "update: authorised_value_category" );
86
is( $af3->marcfield, q|200$a|, "update: marcfield" );
87
is( $af3->searchable, q|0|, "update: searchable" );
88
89
# fetch all
90
$afs = Koha::AdditionalField->all;
91
is( scalar( @$afs ), 4, "all: got 4 additional fields" );
92
$afs = Koha::AdditionalField->all({tablename => 'subscription'});
93
is( scalar( @$afs ), 3, "all: got 3 additional fields for the subscription table" );
94
$afs = Koha::AdditionalField->all({searchable => 1});
95
is( scalar( @$afs ), 3, "all: got 3 searchable additional fields" );
96
$af3->delete;
97
$afs = Koha::AdditionalField->all;
98
is( scalar( @$afs ), 3, "all: got 3 additional fields after deleting one" );
99
100
101
# Testing additional field values
102
103
## Creating 2 subscriptions
104
use C4::Acquisition;
105
use C4::Biblio;
106
use C4::Budgets;
107
use C4::Serials;
108
use C4::Serials::Frequency;
109
use C4::Serials::Numberpattern;
110
111
my ($biblionumber, $biblioitemnumber) = AddBiblio(MARC::Record->new, '');
112
my $budgetid;
113
my $bpid = AddBudgetPeriod({
114
    budget_period_startdate => '2015-01-01',
115
    budget_period_enddate   => '2016-01-01',
116
});
117
118
my $budget_id = AddBudget({
119
    budget_code        => "ABCD",
120
    budget_amount      => "123.132",
121
    budget_name        => "Périodiques",
122
    budget_notes       => "This is a note",
123
    budget_period_id   => $bpid
124
});
125
126
my $frequency_id = AddSubscriptionFrequency({ description => "Test frequency 1" });
127
my $pattern_id = AddSubscriptionNumberpattern({
128
    label => 'Test numberpattern 1',
129
    description => 'Description for numberpattern 1',
130
    numberingmethod => '{X}'
131
});
132
133
my $subscriptionid1 = NewSubscription(
134
    undef,      "",     undef, undef, $budget_id, $biblionumber,
135
    '2013-01-01', $frequency_id, undef, undef,  undef,
136
    undef,      undef,  undef, undef, undef, undef,
137
    1,          "notes",undef, '2013-01-01', undef, $pattern_id,
138
    undef,       undef,  0,    "intnotes",  0,
139
    undef, undef, 0,          undef,         '2013-01-01', 0
140
);
141
142
my $subscriptionid2 = NewSubscription(
143
    undef,      "",     undef, undef, $budget_id, $biblionumber,
144
    '2013-01-01', $frequency_id, undef, undef,  undef,
145
    undef,      undef,  undef, undef, undef, undef,
146
    1,          "notes",undef, '2013-01-01', undef, $pattern_id,
147
    undef,       undef,  0,    "intnotes",  0,
148
    undef, undef, 0,          undef,         '2013-01-01', 0
149
);
150
151
# insert
152
my $af1_values = {
153
    $subscriptionid1 => "value_for_af1_$subscriptionid1",
154
    $subscriptionid2 => "value_for_af1_$subscriptionid2",
155
};
156
$af1->{values} = $af1_values;
157
$af1->insert_values;
158
159
my $af2_values = {
160
    $subscriptionid1 => "old_value_for_af2_$subscriptionid1",
161
    $subscriptionid2 => "old_value_for_af2_$subscriptionid2",
162
};
163
$af2->{values} = $af2_values;
164
$af2->insert_values;
165
my $new_af2_values = {
166
    $subscriptionid1 => "value_for_af2_$subscriptionid1",
167
    $subscriptionid2 => "value_for_af2_$subscriptionid2",
168
};
169
$af2->{values} = $new_af2_values;
170
$af2->insert_values; # Insert should replace old values
171
172
my $common_values = {
173
    $subscriptionid1 => 'common_value',
174
    $subscriptionid2 => 'common_value',
175
};
176
177
$af_common->{values} = $common_values;
178
$af_common->insert_values;
179
180
# fetch_values
181
$af1 = Koha::AdditionalField->new({ id => $af1->id })->fetch;
182
$af2 = Koha::AdditionalField->new({ id => $af2->id })->fetch;
183
184
$af1->fetch_values;
185
is_deeply ( $af1->values, {$subscriptionid1 => qq|value_for_af1_$subscriptionid1|, $subscriptionid2 => qq|value_for_af1_$subscriptionid2| }, "fetch_values: without argument, returns 2 records" );
186
$af1->fetch_values({ record_id => $subscriptionid1 });
187
is_deeply ( $af1->values, {$subscriptionid1 => qq|value_for_af1_$subscriptionid1|}, "fetch_values: values for af1 and subscription1" );
188
$af2->fetch_values({ record_id => $subscriptionid2 });
189
is_deeply ( $af2->values, {$subscriptionid2 => qq|value_for_af2_$subscriptionid2|}, "fetch_values: values for af2 and subscription2" );
190
191
# fetch_all_values
192
eval{
193
    $af1->fetch_all_values;
194
};
195
like ( $@, qr|^BAD CALL|, 'fetch_all_values: fail if called with a blessed object' );
196
197
my $fetched_values = Koha::AdditionalField->fetch_all_values({ tablename => 'subscription' });
198
my $expected_values = {
199
    $subscriptionid1 => {
200
        $af1_name => qq|value_for_af1_$subscriptionid1|,
201
        $af2_name => qq|value_for_af2_$subscriptionid1|,
202
        'common' => q|common_value|,
203
    },
204
    $subscriptionid2 => {
205
        $af1_name => qq|value_for_af1_$subscriptionid2|,
206
        $af2_name => qq|value_for_af2_$subscriptionid2|,
207
        'common' => q|common_value|,
208
    }
209
};
210
is_deeply ( $fetched_values, $expected_values, "fetch_all_values: values for table subscription" );
211
212
my $expected_values_1 = {
213
    $subscriptionid1 => {
214
        $af1_name => qq|value_for_af1_$subscriptionid1|,
215
        $af2_name => qq|value_for_af2_$subscriptionid1|,
216
        common => q|common_value|,
217
    }
218
};
219
my $fetched_values_1 = Koha::AdditionalField->fetch_all_values({ tablename => 'subscription', record_id => $subscriptionid1 });
220
is_deeply ( $fetched_values_1, $expected_values_1, "fetch_all_values: values for subscription1" );
221
222
# get_matching_record_ids
223
eval{
224
    $af1->get_matching_record_ids;
225
};
226
like ( $@, qr|^BAD CALL|, 'get_matching_record_ids: fail if called with a blessed object' );
227
228
my $matching_record_ids = Koha::AdditionalField->get_matching_record_ids;
229
is_deeply ( $matching_record_ids, [], "get_matching_record_ids: return [] if no argument given" );
230
$matching_record_ids = Koha::AdditionalField->get_matching_record_ids({ tablename => 'subscription' });
231
is_deeply ( $matching_record_ids, [], "get_matching_record_ids: return [] if no field given" );
232
233
my $fields = [
234
    {
235
        name => $af1_name,
236
        value => qq|value_for_af1_$subscriptionid1|
237
    }
238
];
239
$matching_record_ids = Koha::AdditionalField->get_matching_record_ids({ tablename => 'subscription', fields => $fields });
240
is_deeply ( $matching_record_ids, [ $subscriptionid1 ], "get_matching_record_ids: field $af1_name: value_for_af1_$subscriptionid1 matches subscription1" );
241
242
$fields = [
243
    {
244
        name => $af1_name,
245
        value => qq|value_for_af1_$subscriptionid1|
246
    },
247
    {
248
        name => $af2_name,
249
        value => qq|value_for_af2_$subscriptionid1|,
250
    }
251
];
252
$matching_record_ids = Koha::AdditionalField->get_matching_record_ids({ tablename => 'subscription', fields => $fields });
253
is_deeply ( $matching_record_ids, [ $subscriptionid1 ], "get_matching_record_ids: fields $af1_name:value_for_af1_$subscriptionid1 and $af2_name:value_for_af2_$subscriptionid1 match subscription1" );
254
255
$fields = [
256
    {
257
        name => 'common',
258
        value => q|common_value|,
259
    }
260
];
261
$matching_record_ids = Koha::AdditionalField->get_matching_record_ids({ tablename => 'subscription', fields => $fields });
262
my $exists = grep /$subscriptionid1/, @$matching_record_ids;
263
is ( $exists, 1, "get_matching_record_ids: field common: common_value matches subscription1" );
264
$exists = grep /$subscriptionid2/, @$matching_record_ids;
265
is ( $exists, 1, "get_matching_record_ids: field common: common_value matches subscription2 too" );
266
$exists = grep /not_existent_id/, @$matching_record_ids;
267
is ( $exists, 0, "get_matching_record_ids: field common: common_value does not inexistent id" );
268
269
$fields = [
270
    {
271
        name => 'common',
272
        value => q|common|,
273
    }
274
];
275
$matching_record_ids = Koha::AdditionalField->get_matching_record_ids({ tablename => 'subscription', fields => $fields, exact_match => 0 });
276
$exists = grep /$subscriptionid1/, @$matching_record_ids;
277
is ( $exists, 1, "get_matching_record_ids: field common: common% matches subscription1" );
278
$exists = grep /$subscriptionid2/, @$matching_record_ids;
279
is ( $exists, 1, "get_matching_record_ids: field common: common% matches subscription2 too" );
280
$exists = grep /not_existent_id/, @$matching_record_ids;
281
is ( $exists, 0, "get_matching_record_ids: field common: common% does not inexistent id" );
282
283
# delete_values
284
$af1 = Koha::AdditionalField->new({ id => $af1->id })->fetch;
285
286
$af1->fetch_values;
287
is_deeply ( $af1->values, {$subscriptionid1 => qq|value_for_af1_$subscriptionid1|, $subscriptionid2 => qq|value_for_af1_$subscriptionid2| }, "fetch_values: without argument, returns 2 records" );
288
$af1->delete_values({record_id => $subscriptionid1});
289
$af1->fetch_values;
290
is_deeply ( $af1->values, {$subscriptionid2 => qq|value_for_af1_$subscriptionid2|}, "fetch_values: values for af2 and subscription2" );
291
$af1->delete_values;
292
$af1->fetch_values;
293
is_deeply ( $af1->values, {}, "fetch_values: no values" );
(-)a/t/db_dependent/Koha/Objects/Mixin/AdditionalFields.t (-1 / +126 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/env perl
2
3
use Modern::Perl;
4
5
use Test::More tests => 10;
6
7
use Koha::Acquisition::Baskets; # Koha::Acquisition::Baskets uses the mixin
8
use Koha::AdditionalFields;
9
use Koha::AdditionalField;
10
use Koha::AdditionalFieldValue;
11
use Koha::Database;
12
13
use t::lib::TestBuilder;
14
15
my $storage = Koha::Database->new->schema->storage;
16
$storage->txn_begin;
17
18
my $builder = t::lib::TestBuilder->new;
19
my $basket1 = $builder->build_object({
20
    class => 'Koha::Acquisition::Baskets',
21
});
22
my $basket2 = $builder->build_object({
23
    class => 'Koha::Acquisition::Baskets',
24
});
25
26
my $foo = Koha::AdditionalField->new({
27
    tablename => 'aqbasket',
28
    name => 'basket_foo',
29
})->store;
30
my $bar = Koha::AdditionalField->new({
31
    tablename => 'aqbasket',
32
    name => 'basket_bar',
33
})->store;
34
35
Koha::AdditionalFieldValue->new({
36
    field_id => $foo->id,
37
    record_id => $basket1->basketno,
38
    value => 'foo value for basket1',
39
})->store;
40
Koha::AdditionalFieldValue->new({
41
    field_id => $bar->id,
42
    record_id => $basket1->basketno,
43
    value => 'bar value for basket1',
44
})->store;
45
Koha::AdditionalFieldValue->new({
46
    field_id => $foo->id,
47
    record_id => $basket2->basketno,
48
    value => 'foo value for basket2',
49
})->store;
50
Koha::AdditionalFieldValue->new({
51
    field_id => $bar->id,
52
    record_id => $basket2->basketno,
53
    value => 'bar value for basket2',
54
})->store;
55
56
my @baskets = Koha::Acquisition::Baskets->search_additional_fields([
57
    {
58
        id => $foo->id,
59
        value => 'foo value for basket1',
60
    },
61
]);
62
63
is(scalar @baskets, 1, 'search returns only one result');
64
is($baskets[0]->basketno, $basket1->basketno, 'result is basket1');
65
66
@baskets = Koha::Acquisition::Baskets->search_additional_fields([
67
    {
68
        id => $foo->id,
69
        value => 'foo value for basket2',
70
    },
71
]);
72
73
is(scalar @baskets, 1, 'search returns only one result');
74
is($baskets[0]->basketno, $basket2->basketno, 'result is basket2');
75
76
@baskets = Koha::Acquisition::Baskets->search_additional_fields([
77
    {
78
        id => $foo->id,
79
        value => 'foo value for basket1',
80
    },
81
    {
82
        id => $bar->id,
83
        value => 'bar value for basket1',
84
    },
85
]);
86
87
is(scalar @baskets, 1, 'search returns only one result');
88
is($baskets[0]->basketno, $basket1->basketno, 'result is basket1');
89
90
@baskets = Koha::Acquisition::Baskets->search_additional_fields([
91
    {
92
        id => $foo->id,
93
        value => 'foo value for basket1',
94
    },
95
    {
96
        id => $bar->id,
97
        value => 'bar value for basket2',
98
    },
99
]);
100
101
is(scalar @baskets, 0, 'search returns no result');
102
103
@baskets = Koha::Acquisition::Baskets->search_additional_fields([
104
    {
105
        id => $foo->id,
106
        value => 'foo',
107
    },
108
]);
109
110
is(scalar @baskets, 2, 'search returns two results');
111
112
@baskets = Koha::Acquisition::Baskets->search_additional_fields([
113
    {
114
        id => $foo->id,
115
        value => 'foo',
116
    },
117
    {
118
        id => $foo->id,
119
        value => 'basket1',
120
    },
121
]);
122
123
is(scalar @baskets, 1, 'search returns only one result');
124
is($baskets[0]->basketno, $basket1->basketno, 'result is basket1');
125
126
$storage->txn_rollback;

Return to bug 15774