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 2454-2468 sub GetHistory { Link Here
2454
    }
2455
    }
2455
2456
2456
    if ( @$additional_fields ) {
2457
    if ( @$additional_fields ) {
2457
        my $matching_record_ids_for_additional_fields = Koha::AdditionalField->get_matching_record_ids( {
2458
        my @baskets = Koha::Acquisition::Baskets->search_additional_fields($additional_fields);
2458
            fields => $additional_fields,
2459
2459
            tablename => 'aqbasket',
2460
        return [] unless @baskets;
2460
            exact_match => 0,
2461
        } );
2462
        return [] unless @$matching_record_ids_for_additional_fields;
2463
2461
2464
        # No parameterization because record IDs come directly from DB
2462
        # No parameterization because record IDs come directly from DB
2465
        $query .= ' AND aqbasket.basketno IN ( ' . join( ',', @$matching_record_ids_for_additional_fields ) . ' )';
2463
        $query .= ' AND aqbasket.basketno IN ( ' . join( ',', map { $_->basketno } @baskets ) . ' )';
2466
    }
2464
    }
2467
2465
2468
    if ( C4::Context->preference("IndependentBranches") ) {
2466
    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 272-282 sub GetSubscription { Link Here
272
    $subscription->{cannotedit} = not can_edit_subscription( $subscription );
272
    $subscription->{cannotedit} = not can_edit_subscription( $subscription );
273
273
274
    # Add additional fields to the subscription into a new key "additional_fields"
274
    # Add additional fields to the subscription into a new key "additional_fields"
275
    my $additional_field_values = Koha::AdditionalField->fetch_all_values({
275
    my %additional_field_values = map {
276
            tablename => 'subscription',
276
        $_->field->name => $_->value
277
            record_id => $subscriptionid,
277
    } Koha::Subscriptions->find($subscriptionid)->additional_field_values;
278
    });
278
    $subscription->{additional_fields} = \%additional_field_values;
279
    $subscription->{additional_fields} = $additional_field_values->{$subscriptionid};
280
279
281
    return $subscription;
280
    return $subscription;
282
}
281
}
Lines 520-531 sub SearchSubscriptions { Link Here
520
    my $additional_fields = $args->{additional_fields} // [];
519
    my $additional_fields = $args->{additional_fields} // [];
521
    my $matching_record_ids_for_additional_fields = [];
520
    my $matching_record_ids_for_additional_fields = [];
522
    if ( @$additional_fields ) {
521
    if ( @$additional_fields ) {
523
        $matching_record_ids_for_additional_fields = Koha::AdditionalField->get_matching_record_ids({
522
        my @subscriptions = Koha::Subscriptions->search_additional_fields($additional_fields);
524
                fields => $additional_fields,
523
525
                tablename => 'subscription',
524
        return () unless @subscriptions;
526
                exact_match => 0,
525
527
        });
526
        $matching_record_ids_for_additional_fields = [ map {
528
        return () unless @$matching_record_ids_for_additional_fields;
527
            $_->subscriptionid
528
        } @subscriptions ];
529
    }
529
    }
530
530
531
    my $query = q|
531
    my $query = q|
Lines 622-632 sub SearchSubscriptions { Link Here
622
        $subscription->{cannotedit} = not can_edit_subscription( $subscription );
622
        $subscription->{cannotedit} = not can_edit_subscription( $subscription );
623
        $subscription->{cannotdisplay} = not can_show_subscription( $subscription );
623
        $subscription->{cannotdisplay} = not can_show_subscription( $subscription );
624
624
625
        my $additional_field_values = Koha::AdditionalField->fetch_all_values({
625
        my %additional_field_values = map {
626
            record_id => $subscription->{subscriptionid},
626
            $_->field->name => $_->value
627
            tablename => 'subscription'
627
        } Koha::Subscriptions->find($subscription->{subscriptionid})->additional_field_values;
628
        });
628
        $subscription->{additional_fields} = \%additional_field_values;
629
        $subscription->{additional_fields} = $additional_field_values->{$subscription->{subscriptionid}};
630
    }
629
    }
631
630
632
    return @$results;
631
    return @$results;
Lines 1689-1698 sub DelSubscription { Link Here
1689
    $dbh->do("DELETE FROM subscriptionhistory WHERE subscriptionid=?", undef, $subscriptionid);
1688
    $dbh->do("DELETE FROM subscriptionhistory WHERE subscriptionid=?", undef, $subscriptionid);
1690
    $dbh->do("DELETE FROM serial WHERE subscriptionid=?", undef, $subscriptionid);
1689
    $dbh->do("DELETE FROM serial WHERE subscriptionid=?", undef, $subscriptionid);
1691
1690
1692
    my $afs = Koha::AdditionalField->all({tablename => 'subscription'});
1691
    Koha::AdditionalFieldValues->search({
1693
    foreach my $af (@$afs) {
1692
        'field.tablename' => 'subscription',
1694
        $af->delete_values({record_id => $subscriptionid});
1693
        'me.record_id' => $subscriptionid,
1695
    }
1694
    }, { join => 'field' })->delete;
1696
1695
1697
    logaction( "SERIAL", "DELETE", $subscriptionid, "" ) if C4::Context->preference("SubscriptionLog");
1696
    logaction( "SERIAL", "DELETE", $subscriptionid, "" ) if C4::Context->preference("SubscriptionLog");
1698
}
1697
}
Lines 1822-1832 sub GetLateOrMissingIssues { Link Here
1822
        }
1821
        }
1823
        $line->{"status".$line->{status}}   = 1;
1822
        $line->{"status".$line->{status}}   = 1;
1824
1823
1825
        my $additional_field_values = Koha::AdditionalField->fetch_all_values({
1824
        my $subscription = Koha::Subscriptions->find($line->{subscriptionid});
1826
            record_id => $line->{subscriptionid},
1825
        my %additional_field_values = map {
1827
            tablename => 'subscription'
1826
            $_->field->name => $_->value
1828
        });
1827
        } $subscription->additional_field_values;
1829
        %$line = ( %$line, additional_fields => $additional_field_values->{$line->{subscriptionid}} );
1828
        %$line = ( %$line, additional_fields => \%additional_field_values );
1830
1829
1831
        push @issuelist, $line;
1830
        push @issuelist, $line;
1832
    }
1831
    }
(-)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 448-453 __PACKAGE__->has_many( Link Here
448
# Created by DBIx::Class::Schema::Loader v0.07042 @ 2018-02-16 17:54:54
448
# Created by DBIx::Class::Schema::Loader v0.07042 @ 2018-02-16 17:54:54
449
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:ZRLfM/4h8VMLTgW7LkUYYA
449
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:ZRLfM/4h8VMLTgW7LkUYYA
450
450
451
__PACKAGE__->has_many(
452
  "additional_field_values",
453
  "Koha::Schema::Result::AdditionalFieldValue",
454
  sub {
455
    my ($args) = @_;
456
457
    return {
458
        "$args->{foreign_alias}.record_id" => { -ident => "$args->{self_alias}.subscriptionid" },
459
460
        # TODO Add column additional_field_values.tablename to avoid subquery ?
461
        "$args->{foreign_alias}.field_id" =>
462
            { -in => \'(SELECT id FROM additional_fields WHERE tablename = "subscription")' },
463
    };
464
  },
465
  { cascade_copy => 0, cascade_delete => 0 },
466
);
451
467
452
# You can replace this text with custom content, and it will be preserved on regeneration
468
# You can replace this text with custom content, and it will be preserved on regeneration
453
1;
469
1;
(-)a/Koha/Subscription.pm (-1 / +1 lines)
Lines 25-31 use Koha::Database; Link Here
25
use Koha::Biblios;
25
use Koha::Biblios;
26
use Koha::Acquisition::Booksellers;
26
use Koha::Acquisition::Booksellers;
27
27
28
use base qw(Koha::Object);
28
use base qw(Koha::Object Koha::Object::Mixin::AdditionalFields);
29
29
30
=head1 NAME
30
=head1 NAME
31
31
(-)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::Libraries;
38
use Koha::Libraries;
38
use C4::Letters qw/SendAlerts/;
39
use C4::Letters qw/SendAlerts/;
Lines 42-48 use Koha::EDI qw( create_edi_order get_edifact_ean ); Link Here
42
use Koha::CsvProfiles;
43
use Koha::CsvProfiles;
43
use Koha::Patrons;
44
use Koha::Patrons;
44
45
45
use Koha::AdditionalField;
46
use Koha::AdditionalFields;
46
47
47
=head1 NAME
48
=head1 NAME
48
49
Lines 431-441 if ( $op eq 'list' ) { Link Here
431
        has_budgets          => $has_budgets,
432
        has_budgets          => $has_budgets,
432
        duplinbatch          => $duplinbatch,
433
        duplinbatch          => $duplinbatch,
433
        csv_profiles         => [ Koha::CsvProfiles->search({ type => 'sql', used_for => 'export_basket' }) ],
434
        csv_profiles         => [ Koha::CsvProfiles->search({ type => 'sql', used_for => 'export_basket' }) ],
434
        available_additional_fields => Koha::AdditionalField->all( { tablename => 'aqbasket' } ),
435
        available_additional_fields => [ Koha::AdditionalFields->search( { tablename => 'aqbasket' } ) ],
435
        additional_field_values => Koha::AdditionalField->fetch_all_values( {
436
        additional_field_values => { map {
436
            tablename => 'aqbasket',
437
            $_->field->name => $_->value
437
            record_id => $basketno,
438
        } Koha::Acquisition::Baskets->find($basketno)->additional_field_values },
438
        } )->{$basketno},
439
    );
439
    );
440
}
440
}
441
441
(-)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 (-8 / +15 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 94-104 my ( $template, $loggedinuser, $cookie ) = get_template_and_user( Link Here
94
    }
94
    }
95
);
95
);
96
96
97
$template->param( available_additional_fields => scalar Koha::AdditionalField->all( { tablename => 'aqbasket', searchable => 1 } ) );
97
my @additional_fields = Koha::AdditionalFields->search( { tablename => 'aqbasket', searchable => 1 } );
98
my $additional_field_filters = Koha::AdditionalField->get_filters_from_query( {
98
$template->param( available_additional_fields => \@additional_fields );
99
    tablename => 'aqbasket',
99
my @additional_field_filters;
100
    query => $input,
100
foreach my $additional_field (@additional_fields) {
101
} );
101
    my $value = $input->param('additional_field_' . $additional_field->id);
102
    if (defined $value and $value ne '') {
103
        push @additional_field_filters, {
104
            id => $additional_field->id,
105
            value => $value,
106
        };
107
    }
108
}
102
109
103
my $order_loop;
110
my $order_loop;
104
# If we're supplied any value then we do a search. Otherwise we don't.
111
# If we're supplied any value then we do a search. Otherwise we don't.
Lines 119-125 if ($do_search) { Link Here
119
        ordernumber => $ordernumber,
126
        ordernumber => $ordernumber,
120
        search_children_too => $search_children_too,
127
        search_children_too => $search_children_too,
121
        created_by => \@created_by,
128
        created_by => \@created_by,
122
        additional_fields => $additional_field_filters,
129
        additional_fields => \@additional_field_filters,
123
    );
130
    );
124
}
131
}
125
132
Lines 152-158 $template->param( Link Here
152
    budget_id               => $budget,
159
    budget_id               => $budget,
153
    bp_loop                 => $bp_loop,
160
    bp_loop                 => $bp_loop,
154
    search_done             => $do_search,
161
    search_done             => $do_search,
155
    additional_field_filters => Koha::AdditionalField->get_filters_as_values( $additional_field_filters ),
162
    additional_field_filters => { map { $_->{id} => $_->{value} } @additional_field_filters },
156
    debug                   => $debug || $input->param('debug') || 0,
163
    debug                   => $debug || $input->param('debug') || 0,
157
    uc(C4::Context->preference("marcflavour")) => 1
164
    uc(C4::Context->preference("marcflavour")) => 1
158
);
165
);
(-)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 360-366 Link Here
360
                      <select id="additional_field_[% field.id | html %]" name="additional_field_[% field.id | html %]">
360
                      <select id="additional_field_[% field.id | html %]" name="additional_field_[% field.id | html %]">
361
                        <option value="">All</option>
361
                        <option value="">All</option>
362
                        [% FOREACH av IN AuthorisedValues.GetAuthValueDropbox(field.authorised_value_category) %]
362
                        [% FOREACH av IN AuthorisedValues.GetAuthValueDropbox(field.authorised_value_category) %]
363
                          [% IF av.authorised_value == additional_field_filters.${field.name} %]
363
                          [% IF av.authorised_value == additional_field_filters.${field.id} %]
364
                            <option value="[% av.authorised_value | html %]" selected="selected">[% av.lib | html %]</option>
364
                            <option value="[% av.authorised_value | html %]" selected="selected">[% av.lib | html %]</option>
365
                          [% ELSE %]
365
                          [% ELSE %]
366
                            <option value="[% av.authorised_value | html %]">[% av.lib | html %]</option>
366
                            <option value="[% av.authorised_value | html %]">[% av.lib | html %]</option>
Lines 368-374 Link Here
368
                        [% END %]
368
                        [% END %]
369
                      </select>
369
                      </select>
370
                    [% ELSE %]
370
                    [% ELSE %]
371
                      <input id="additional_field_[% field.id | html %]" type="text" value="[% additional_field_filters.${field.name} | html %]" name="additional_field_[% field.id | html %]" />
371
                      <input id="additional_field_[% field.id | html %]" type="text" value="[% additional_field_filters.${field.id} | html %]" name="additional_field_[% field.id | html %]" />
372
                    [% END %]
372
                    [% END %]
373
                  </li>
373
                  </li>
374
                [% END %]
374
                [% 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
41
Lines 77-87 if ( $op and $op eq "close" ) { Link Here
77
}
77
}
78
78
79
79
80
my $additional_fields = Koha::AdditionalField->all( { tablename => 'subscription', searchable => 1 } );
80
my @additional_fields = Koha::AdditionalFields->search( { tablename => 'subscription', searchable => 1 } );
81
my $additional_field_filters = Koha::AdditionalField->get_filters_from_query( {
81
my @additional_field_filters;
82
    tablename => 'subscription',
82
for my $field ( @additional_fields ) {
83
    query => $query,
83
    my $value = $query->param( 'additional_field_' . $field->id );
84
} );
84
    if ( defined $value and $value ne '' ) {
85
        push @additional_field_filters, {
86
            id => $field->id,
87
            value => $value,
88
        };
89
    }
90
}
85
91
86
my $expiration_date_dt = $expiration_date ? dt_from_string( $expiration_date ) : undef;
92
my $expiration_date_dt = $expiration_date ? dt_from_string( $expiration_date ) : undef;
87
my @subscriptions;
93
my @subscriptions;
Lines 96-102 if ($searched){ Link Here
96
            publisher    => $publisher,
102
            publisher    => $publisher,
97
            bookseller   => $bookseller,
103
            bookseller   => $bookseller,
98
            branch       => $branch,
104
            branch       => $branch,
99
            additional_fields => $additional_field_filters,
105
            additional_fields => \@additional_field_filters,
100
            location     => $location,
106
            location     => $location,
101
            expiration_date => $expiration_date_dt,
107
            expiration_date => $expiration_date_dt,
102
        }
108
        }
Lines 136-143 $template->param( Link Here
136
    expiration_date_filter => $expiration_date_dt,
142
    expiration_date_filter => $expiration_date_dt,
137
    done_searched => $searched,
143
    done_searched => $searched,
138
    routing       => $routing,
144
    routing       => $routing,
139
    additional_field_filters => Koha::AdditionalField->get_filters_as_values( $additional_field_filters ),
145
    additional_field_filters => { map { $_->{id} => $_->{value} } @additional_field_filters },
140
    additional_fields_for_subscription => $additional_fields,
146
    additional_fields_for_subscription => \@additional_fields,
141
    marcflavour   => (uc(C4::Context->preference("marcflavour")))
147
    marcflavour   => (uc(C4::Context->preference("marcflavour")))
142
);
148
);
143
149
(-)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 134-140 $template->param( Link Here
134
    locations_loop=>$locations_loop,
134
    locations_loop=>$locations_loop,
135
);
135
);
136
136
137
$template->param( additional_fields_for_subscription => scalar Koha::AdditionalField->all( { tablename => 'subscription' } ) );
137
$template->param( additional_fields_for_subscription => [ Koha::AdditionalFields->search( { tablename => 'subscription' } ) ] );
138
138
139
my $typeloop = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search_with_localization->unblessed } };
139
my $typeloop = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search_with_localization->unblessed } };
140
140
Lines 339-350 sub redirect_add_subscription { Link Here
339
        $skip_serialseq, $itemtype, $previousitemtype
339
        $skip_serialseq, $itemtype, $previousitemtype
340
    );
340
    );
341
341
342
    Koha::AdditionalField->update_fields_from_query( {
342
    my @additional_fields;
343
        tablename => 'subscription',
343
    my $record = GetMarcBiblio({ biblionumber => $biblionumber, embed_items => 1 });
344
        record_id => $subscriptionid,
344
    for my $field (Koha::AdditionalFields->search({ tablename => 'subscription' })) {
345
        query => $query,
345
        my $value = $query->param('additional_field_' . $field->id);
346
        marc_record => GetMarcBiblio({ biblionumber => $biblionumber, embed_items => 1 })
346
        if ($field->marcfield) {
347
    } );
347
            my ($field, $subfield) = split /\$/, $field->marcfield;
348
            if ( $record and $field and $subfield ) {
349
                $value = $record->subfield( $field, $subfield );
350
            }
351
        }
352
        push @additional_fields, {
353
            id => $field->id,
354
            value => $value,
355
        };
356
    }
357
    Koha::Subscriptions->find($subscriptionid)->set_additional_fields(\@additional_fields);
348
358
349
    print $query->redirect("/cgi-bin/koha/serials/subscription-detail.pl?subscriptionid=$subscriptionid");
359
    print $query->redirect("/cgi-bin/koha/serials/subscription-detail.pl?subscriptionid=$subscriptionid");
350
    return;
360
    return;
Lines 427-438 sub redirect_mod_subscription { Link Here
427
        $skip_serialseq, $itemtype, $previousitemtype
437
        $skip_serialseq, $itemtype, $previousitemtype
428
    );
438
    );
429
439
430
    Koha::AdditionalField->update_fields_from_query( {
440
    my @additional_fields;
431
        tablename => 'subscription',
441
    my $record = GetMarcBiblio({ biblionumber => $biblionumber, embed_items => 1 });
432
        record_id => $subscriptionid,
442
    for my $field (Koha::AdditionalFields->search({ tablename => 'subscription' })) {
433
        query => $query,
443
        my $value = $query->param('additional_field_' . $field->id);
434
        marc_record => GetMarcBiblio({ biblionumber => $biblionumber, embed_items => 1 })
444
        if ($field->marcfield) {
435
    } );
445
            my ($field, $subfield) = split /\$/, $field->marcfield;
446
            if ( $record and $field and $subfield ) {
447
                $value = $record->subfield( $field, $subfield );
448
            }
449
        }
450
        push @additional_fields, {
451
            id => $field->id,
452
            value => $value,
453
        };
454
    }
455
    Koha::Subscriptions->find($subscriptionid)->set_additional_fields(\@additional_fields);
436
456
437
    print $query->redirect("/cgi-bin/koha/serials/subscription-detail.pl?subscriptionid=$subscriptionid");
457
    print $query->redirect("/cgi-bin/koha/serials/subscription-detail.pl?subscriptionid=$subscriptionid");
438
    return;
458
    return;
(-)a/serials/subscription-batchedit.pl (-16 / +15 lines)
Lines 23-31 use CGI qw( -utf8 ); Link Here
23
23
24
use C4::Auth;
24
use C4::Auth;
25
use C4::Output;
25
use C4::Output;
26
use C4::Serials;
26
use Koha::Subscriptions;
27
use Koha::Subscriptions;
27
use Koha::Acquisition::Booksellers;
28
use Koha::Acquisition::Booksellers;
28
use Koha::AdditionalField;
29
use Koha::AdditionalFields;
29
use Koha::DateUtils;
30
use Koha::DateUtils;
30
31
31
my $cgi = new CGI;
32
my $cgi = new CGI;
Lines 47-53 foreach my $subscriptionid (@subscriptionids) { Link Here
47
    push @subscriptions, $subscription if $subscription;
48
    push @subscriptions, $subscription if $subscription;
48
}
49
}
49
50
50
my $additional_fields = Koha::AdditionalField->all({tablename => 'subscription'});
51
my @additional_fields = Koha::AdditionalFields->search({tablename => 'subscription'});
51
52
52
my $batchedit = $cgi->param('batchedit');
53
my $batchedit = $cgi->param('batchedit');
53
if ($batchedit) {
54
if ($batchedit) {
Lines 63-71 if ($batchedit) { Link Here
63
    );
64
    );
64
65
65
    my $field_values = {};
66
    my $field_values = {};
66
    foreach my $field (@$additional_fields) {
67
    foreach my $field (@additional_fields) {
67
        my $value = $cgi->param('field_' . $field->{id});
68
        my $value = $cgi->param('field_' . $field->id);
68
        $field_values->{$field->{id}} = $value;
69
        $field_values->{$field->id} = $value;
69
    }
70
    }
70
71
71
    foreach my $subscription (@subscriptions) {
72
    foreach my $subscription (@subscriptions) {
Lines 76-98 if ($batchedit) { Link Here
76
            }
77
            }
77
        }
78
        }
78
79
79
        foreach my $field (@$additional_fields) {
80
        my @additional_field_values;
80
            my $value = $field_values->{$field->{id}};
81
        foreach my $field (@additional_fields) {
82
            my $value = $field_values->{$field->id};
81
            if (defined $value and $value ne '') {
83
            if (defined $value and $value ne '') {
82
                $field->{values} //= {};
84
                push @additional_field_values, {
83
                $field->{values}->{$subscription->subscriptionid} = $value;
85
                    id => $field->id,
86
                    value => $value,
87
                };
84
            }
88
            }
85
        }
89
        }
90
        $subscription->set_additional_fields(\@additional_field_values);
86
91
87
        $subscription->store;
92
        $subscription->store;
88
    }
93
    }
89
94
90
    foreach my $field (@$additional_fields) {
91
        if (defined $field->{values}) {
92
            $field->insert_values();
93
        }
94
    }
95
96
    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';
97
    print $cgi->redirect($redirect_url);
96
    print $cgi->redirect($redirect_url);
98
    exit;
97
    exit;
Lines 101-107 if ($batchedit) { Link Here
101
$template->param(
100
$template->param(
102
    subscriptions => \@subscriptions,
101
    subscriptions => \@subscriptions,
103
    booksellers => [ Koha::Acquisition::Booksellers->search() ],
102
    booksellers => [ Koha::Acquisition::Booksellers->search() ],
104
    additional_fields => $additional_fields,
103
    additional_fields => \@additional_fields,
105
    referrer => scalar $cgi->param('referrer'),
104
    referrer => scalar $cgi->param('referrer'),
106
);
105
);
107
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 116-127 my $numberpattern = C4::Serials::Numberpattern::GetSubscriptionNumberpattern($su Link Here
116
117
117
my $default_bib_view = get_default_view();
118
my $default_bib_view = get_default_view();
118
119
119
my $additional_fields = Koha::AdditionalField->all( { tablename => 'subscription' } );
120
my $additional_fields = Koha::AdditionalFields->search( { tablename => 'subscription' } );
120
for my $field ( @$additional_fields ) {
121
    if ( $field->{authorised_value_category} ) {
122
        $field->{authorised_value_choices} = GetAuthorisedValues( $field->{authorised_value_category} );
123
    }
124
}
125
$template->param( additional_fields_for_subscription => $additional_fields );
121
$template->param( additional_fields_for_subscription => $additional_fields );
126
122
127
# FIXME Do we want to hide canceled orders?
123
# FIXME Do we want to hide canceled orders?
(-)a/t/db_dependent/AdditionalField.t (-295 lines)
Lines 1-295 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
9
my $dbh = C4::Context->dbh;
10
$dbh->{AutoCommit} = 0;
11
$dbh->{RaiseError} = 1;
12
13
$dbh->do( q|DELETE FROM additional_fields| );
14
$dbh->do( q|DELETE FROM additional_field_values| );
15
16
my $afs = Koha::AdditionalField->all;
17
is( scalar( @$afs ), 0, "all: there is no additional field" );
18
19
my $af1_name = q|af1|;
20
my $af1 = Koha::AdditionalField->new({
21
    tablename => 'subscription',
22
    name => $af1_name,
23
    authorised_values_category => '',
24
    marcfield => '',
25
    searchable => 1,
26
});
27
is ( $af1->name, $af1_name, "new: name value is kept" );
28
29
$af1->insert;
30
like ( $af1->id, qr|^\d+$|, "new: populate id value" );
31
32
my $af2_name = q|af2|;
33
my $af2_marcfield = q|200$a|;
34
my $af2_searchable = 1;
35
my $af2_tablename = q|subscription|;
36
my $af2_avc = q|LOST|;
37
my $af2 = Koha::AdditionalField->new({
38
    tablename => $af2_tablename,
39
    name => $af2_name,
40
    authorised_value_category => $af2_avc,
41
    marcfield => $af2_marcfield,
42
    searchable => $af2_searchable,
43
});
44
$af2->insert;
45
my $af2_id = $af2->id;
46
$af2 = Koha::AdditionalField->new({ id => $af2_id })->fetch;
47
is( ref($af2) , q|Koha::AdditionalField|, "fetch: return an object" );
48
is( $af2->id, $af2_id, "fetch: id for af2" );
49
is( $af2->tablename, $af2_tablename, "fetch: tablename for af2" );
50
is( $af2->name, $af2_name, "fetch: name for af2" );
51
is( $af2->authorised_value_category, $af2_avc, "fetch: authorised_value_category for af2" );
52
is( $af2->marcfield, $af2_marcfield, "fetch: marcfield for af2" );
53
is( $af2->searchable, $af2_searchable, "fetch: searchable for af2" );
54
55
my $af3 = Koha::AdditionalField->new({
56
    tablename => 'a_table',
57
    name => q|af3|,
58
    authorised_value_category => '',
59
    marcfield => '',
60
    searchable => 1,
61
});
62
$af3->insert;
63
64
my $af_common = Koha::AdditionalField->new({
65
    tablename => 'subscription',
66
    name => q|common|,
67
    authorised_value_category => '',
68
    marcfield => '',
69
    searchable => 1,
70
});
71
$af_common->insert;
72
73
# update
74
$af3->{tablename} = q|another_table|;
75
$af3->{name} = q|af3_mod|;
76
$af3->{authorised_value_category} = q|LOST|;
77
$af3->{marcfield} = q|200$a|;
78
$af3->{searchable} = 0;
79
my $updated = $af3->update;
80
$af3 = Koha::AdditionalField->new({ id => $af3->id })->fetch;
81
is( $updated, 1, "update: return number of affected rows" );
82
is( $af3->tablename, q|a_table|, "update: tablename is *not* updated, there is no sense to copy a field to another table" );
83
is( $af3->name, q|af3_mod|, "update: name" );
84
is( $af3->authorised_value_category, q|LOST|, "update: authorised_value_category" );
85
is( $af3->marcfield, q|200$a|, "update: marcfield" );
86
is( $af3->searchable, q|0|, "update: searchable" );
87
88
# fetch all
89
$afs = Koha::AdditionalField->all;
90
is( scalar( @$afs ), 4, "all: got 4 additional fields" );
91
$afs = Koha::AdditionalField->all({tablename => 'subscription'});
92
is( scalar( @$afs ), 3, "all: got 3 additional fields for the subscription table" );
93
$afs = Koha::AdditionalField->all({searchable => 1});
94
is( scalar( @$afs ), 3, "all: got 3 searchable additional fields" );
95
$af3->delete;
96
$afs = Koha::AdditionalField->all;
97
is( scalar( @$afs ), 3, "all: got 3 additional fields after deleting one" );
98
99
100
# Testing additional field values
101
102
## Creating 2 subscriptions
103
use C4::Acquisition;
104
use C4::Biblio;
105
use C4::Budgets;
106
use C4::Serials;
107
use C4::Serials::Frequency;
108
use C4::Serials::Numberpattern;
109
110
my ($biblionumber, $biblioitemnumber) = AddBiblio(MARC::Record->new, '');
111
my $budgetid;
112
my $bpid = AddBudgetPeriod({
113
    budget_period_startdate => '2015-01-01',
114
    budget_period_enddate   => '2016-01-01',
115
});
116
117
my $budget_id = AddBudget({
118
    budget_code        => "ABCD",
119
    budget_amount      => "123.132",
120
    budget_name        => "Périodiques",
121
    budget_notes       => "This is a note",
122
    budget_period_id   => $bpid
123
});
124
125
my $frequency_id = AddSubscriptionFrequency({ description => "Test frequency 1" });
126
my $pattern_id = AddSubscriptionNumberpattern({
127
    label => 'Test numberpattern 1',
128
    description => 'Description for numberpattern 1',
129
    numberingmethod => '{X}'
130
});
131
132
my $subscriptionid1 = NewSubscription(
133
    undef,      "",     undef, undef, $budget_id, $biblionumber,
134
    '2013-01-01', $frequency_id, undef, undef,  undef,
135
    undef,      undef,  undef, undef, undef, undef,
136
    1,          "notes",undef, '2013-01-01', undef, $pattern_id,
137
    undef,       undef,  0,    "intnotes",  0,
138
    undef, undef, 0,          undef,         '2013-01-01', 0
139
);
140
141
my $subscriptionid2 = NewSubscription(
142
    undef,      "",     undef, undef, $budget_id, $biblionumber,
143
    '2013-01-01', $frequency_id, undef, undef,  undef,
144
    undef,      undef,  undef, undef, undef, undef,
145
    1,          "notes",undef, '2013-01-01', undef, $pattern_id,
146
    undef,       undef,  0,    "intnotes",  0,
147
    undef, undef, 0,          undef,         '2013-01-01', 0
148
);
149
150
# insert
151
my $af1_values = {
152
    $subscriptionid1 => "value_for_af1_$subscriptionid1",
153
    $subscriptionid2 => "value_for_af1_$subscriptionid2",
154
};
155
$af1->{values} = $af1_values;
156
$af1->insert_values;
157
158
my $af2_values = {
159
    $subscriptionid1 => "old_value_for_af2_$subscriptionid1",
160
    $subscriptionid2 => "old_value_for_af2_$subscriptionid2",
161
};
162
$af2->{values} = $af2_values;
163
$af2->insert_values;
164
my $new_af2_values = {
165
    $subscriptionid1 => "value_for_af2_$subscriptionid1",
166
    $subscriptionid2 => "value_for_af2_$subscriptionid2",
167
};
168
$af2->{values} = $new_af2_values;
169
$af2->insert_values; # Insert should replace old values
170
171
my $common_values = {
172
    $subscriptionid1 => 'common_value',
173
    $subscriptionid2 => 'common_value',
174
};
175
176
$af_common->{values} = $common_values;
177
$af_common->insert_values;
178
179
# fetch_values
180
$af1 = Koha::AdditionalField->new({ id => $af1->id })->fetch;
181
$af2 = Koha::AdditionalField->new({ id => $af2->id })->fetch;
182
183
$af1->fetch_values;
184
is_deeply ( $af1->values, {$subscriptionid1 => qq|value_for_af1_$subscriptionid1|, $subscriptionid2 => qq|value_for_af1_$subscriptionid2| }, "fetch_values: without argument, returns 2 records" );
185
$af1->fetch_values({ record_id => $subscriptionid1 });
186
is_deeply ( $af1->values, {$subscriptionid1 => qq|value_for_af1_$subscriptionid1|}, "fetch_values: values for af1 and subscription1" );
187
$af2->fetch_values({ record_id => $subscriptionid2 });
188
is_deeply ( $af2->values, {$subscriptionid2 => qq|value_for_af2_$subscriptionid2|}, "fetch_values: values for af2 and subscription2" );
189
190
# fetch_all_values
191
eval{
192
    $af1->fetch_all_values;
193
};
194
like ( $@, qr|^BAD CALL|, 'fetch_all_values: fail if called with a blessed object' );
195
196
my $fetched_values = Koha::AdditionalField->fetch_all_values({ tablename => 'subscription' });
197
my $expected_values = {
198
    $subscriptionid1 => {
199
        $af1_name => qq|value_for_af1_$subscriptionid1|,
200
        $af2_name => qq|value_for_af2_$subscriptionid1|,
201
        'common' => q|common_value|,
202
    },
203
    $subscriptionid2 => {
204
        $af1_name => qq|value_for_af1_$subscriptionid2|,
205
        $af2_name => qq|value_for_af2_$subscriptionid2|,
206
        'common' => q|common_value|,
207
    }
208
};
209
is_deeply ( $fetched_values, $expected_values, "fetch_all_values: values for table subscription" );
210
211
my $expected_values_1 = {
212
    $subscriptionid1 => {
213
        $af1_name => qq|value_for_af1_$subscriptionid1|,
214
        $af2_name => qq|value_for_af2_$subscriptionid1|,
215
        common => q|common_value|,
216
    }
217
};
218
my $fetched_values_1 = Koha::AdditionalField->fetch_all_values({ tablename => 'subscription', record_id => $subscriptionid1 });
219
is_deeply ( $fetched_values_1, $expected_values_1, "fetch_all_values: values for subscription1" );
220
221
# get_matching_record_ids
222
eval{
223
    $af1->get_matching_record_ids;
224
};
225
like ( $@, qr|^BAD CALL|, 'get_matching_record_ids: fail if called with a blessed object' );
226
227
my $matching_record_ids = Koha::AdditionalField->get_matching_record_ids;
228
is_deeply ( $matching_record_ids, [], "get_matching_record_ids: return [] if no argument given" );
229
$matching_record_ids = Koha::AdditionalField->get_matching_record_ids({ tablename => 'subscription' });
230
is_deeply ( $matching_record_ids, [], "get_matching_record_ids: return [] if no field given" );
231
232
my $fields = [
233
    {
234
        name => $af1_name,
235
        value => qq|value_for_af1_$subscriptionid1|
236
    }
237
];
238
$matching_record_ids = Koha::AdditionalField->get_matching_record_ids({ tablename => 'subscription', fields => $fields });
239
is_deeply ( $matching_record_ids, [ $subscriptionid1 ], "get_matching_record_ids: field $af1_name: value_for_af1_$subscriptionid1 matches subscription1" );
240
241
$fields = [
242
    {
243
        name => $af1_name,
244
        value => qq|value_for_af1_$subscriptionid1|
245
    },
246
    {
247
        name => $af2_name,
248
        value => qq|value_for_af2_$subscriptionid1|,
249
    }
250
];
251
$matching_record_ids = Koha::AdditionalField->get_matching_record_ids({ tablename => 'subscription', fields => $fields });
252
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" );
253
254
$fields = [
255
    {
256
        name => 'common',
257
        value => q|common_value|,
258
    }
259
];
260
$matching_record_ids = Koha::AdditionalField->get_matching_record_ids({ tablename => 'subscription', fields => $fields });
261
my $exists = grep /$subscriptionid1/, @$matching_record_ids;
262
is ( $exists, 1, "get_matching_record_ids: field common: common_value matches subscription1" );
263
$exists = grep /$subscriptionid2/, @$matching_record_ids;
264
is ( $exists, 1, "get_matching_record_ids: field common: common_value matches subscription2 too" );
265
$exists = grep /not_existent_id/, @$matching_record_ids;
266
is ( $exists, 0, "get_matching_record_ids: field common: common_value does not inexistent id" );
267
268
$fields = [
269
    {
270
        name => 'common',
271
        value => q|common|,
272
    }
273
];
274
$matching_record_ids = Koha::AdditionalField->get_matching_record_ids({ tablename => 'subscription', fields => $fields, exact_match => 0 });
275
$exists = grep /$subscriptionid1/, @$matching_record_ids;
276
is ( $exists, 1, "get_matching_record_ids: field common: common% matches subscription1" );
277
$exists = grep /$subscriptionid2/, @$matching_record_ids;
278
is ( $exists, 1, "get_matching_record_ids: field common: common% matches subscription2 too" );
279
$exists = grep /not_existent_id/, @$matching_record_ids;
280
is ( $exists, 0, "get_matching_record_ids: field common: common% does not inexistent id" );
281
282
# delete_values
283
$af1 = Koha::AdditionalField->new({ id => $af1->id })->fetch;
284
285
$af1->fetch_values;
286
is_deeply ( $af1->values, {$subscriptionid1 => qq|value_for_af1_$subscriptionid1|, $subscriptionid2 => qq|value_for_af1_$subscriptionid2| }, "fetch_values: without argument, returns 2 records" );
287
$af1->delete_values({record_id => $subscriptionid1});
288
$af1->fetch_values;
289
is_deeply ( $af1->values, {$subscriptionid2 => qq|value_for_af1_$subscriptionid2|}, "fetch_values: values for af2 and subscription2" );
290
$af1->delete_values;
291
$af1->fetch_values;
292
is_deeply ( $af1->values, {}, "fetch_values: no values" );
293
294
295
$dbh->rollback;
(-)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