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

(-)a/C4/Serials.pm (-11 / +108 lines)
Lines 48-53 use Koha::Subscription::Histories; Link Here
48
use Koha::Subscriptions;
48
use Koha::Subscriptions;
49
use Koha::Suggestions;
49
use Koha::Suggestions;
50
use Koha::TemplateUtils qw( process_tt );
50
use Koha::TemplateUtils qw( process_tt );
51
use List::Util qw( first );
52
use Locale::PO;
51
53
52
# Define statuses
54
# Define statuses
53
use constant {
55
use constant {
Lines 105-110 BEGIN { Link Here
105
107
106
      findSerialsByStatus
108
      findSerialsByStatus
107
109
110
      GetSeasonsTranslations
108
    );
111
    );
109
}
112
}
110
113
Lines 859-864 sub GetNextSeq { Link Here
859
        $newinnerloop1 = $subscription->{innerloop1} || 0;
862
        $newinnerloop1 = $subscription->{innerloop1} || 0;
860
        $newinnerloop2 = $subscription->{innerloop2} || 0;
863
        $newinnerloop2 = $subscription->{innerloop2} || 0;
861
        $newinnerloop3 = $subscription->{innerloop3} || 0;
864
        $newinnerloop3 = $subscription->{innerloop3} || 0;
865
        my $translations = $subscription->{translations};
862
        my %calc;
866
        my %calc;
863
        foreach(qw/X Y Z/) {
867
        foreach(qw/X Y Z/) {
864
            $calc{$_} = 1 if ($numberingmethod =~ /\{$_\}/);
868
            $calc{$_} = 1 if ($numberingmethod =~ /\{$_\}/);
Lines 897-911 sub GetNextSeq { Link Here
897
            }
901
            }
898
        }
902
        }
899
        if($calc{'X'}) {
903
        if($calc{'X'}) {
900
            my $newlastvalue1string = _numeration( $newlastvalue1, $pattern->{numbering1}, $locale );
904
            my $newlastvalue1string = _numeration( $newlastvalue1, $pattern->{numbering1}, $locale, $translations );
901
            $calculated =~ s/\{X\}/$newlastvalue1string/g;
905
            $calculated =~ s/\{X\}/$newlastvalue1string/g;
902
        }
906
        }
903
        if($calc{'Y'}) {
907
        if($calc{'Y'}) {
904
            my $newlastvalue2string = _numeration( $newlastvalue2, $pattern->{numbering2}, $locale );
908
            my $newlastvalue2string = _numeration( $newlastvalue2, $pattern->{numbering2}, $locale, $translations );
905
            $calculated =~ s/\{Y\}/$newlastvalue2string/g;
909
            $calculated =~ s/\{Y\}/$newlastvalue2string/g;
906
        }
910
        }
907
        if($calc{'Z'}) {
911
        if($calc{'Z'}) {
908
            my $newlastvalue3string = _numeration( $newlastvalue3, $pattern->{numbering3}, $locale );
912
            my $newlastvalue3string = _numeration( $newlastvalue3, $pattern->{numbering3}, $locale, $translations );
909
            $calculated =~ s/\{Z\}/$newlastvalue3string/g;
913
            $calculated =~ s/\{Z\}/$newlastvalue3string/g;
910
        }
914
        }
911
915
Lines 934-951 sub GetSeq { Link Here
934
938
935
    my $locale = $subscription->{locale};
939
    my $locale = $subscription->{locale};
936
940
941
    my $translations = $subscription->{translations};
942
937
    my $calculated = $pattern->{numberingmethod};
943
    my $calculated = $pattern->{numberingmethod};
938
944
939
    my $newlastvalue1 = $subscription->{'lastvalue1'} || 0;
945
    my $newlastvalue1 = $subscription->{'lastvalue1'} || 0;
940
    $newlastvalue1 = _numeration($newlastvalue1, $pattern->{numbering1}, $locale) if ($pattern->{numbering1}); # reset counter if needed.
946
    $newlastvalue1 = _numeration($newlastvalue1, $pattern->{numbering1}, $locale, $translations) if ($pattern->{numbering1}); # reset counter if needed.
941
    $calculated =~ s/\{X\}/$newlastvalue1/g;
947
    $calculated =~ s/\{X\}/$newlastvalue1/g;
942
948
943
    my $newlastvalue2 = $subscription->{'lastvalue2'} || 0;
949
    my $newlastvalue2 = $subscription->{'lastvalue2'} || 0;
944
    $newlastvalue2 = _numeration($newlastvalue2, $pattern->{numbering2}, $locale) if ($pattern->{numbering2}); # reset counter if needed.
950
    $newlastvalue2 = _numeration($newlastvalue2, $pattern->{numbering2}, $locale, $translations) if ($pattern->{numbering2}); # reset counter if needed.
945
    $calculated =~ s/\{Y\}/$newlastvalue2/g;
951
    $calculated =~ s/\{Y\}/$newlastvalue2/g;
946
952
947
    my $newlastvalue3 = $subscription->{'lastvalue3'} || 0;
953
    my $newlastvalue3 = $subscription->{'lastvalue3'} || 0;
948
    $newlastvalue3 = _numeration($newlastvalue3, $pattern->{numbering3}, $locale) if ($pattern->{numbering3}); # reset counter if needed.
954
    $newlastvalue3 = _numeration($newlastvalue3, $pattern->{numbering3}, $locale, $translations) if ($pattern->{numbering3}); # reset counter if needed.
949
    $calculated =~ s/\{Z\}/$newlastvalue3/g;
955
    $calculated =~ s/\{Z\}/$newlastvalue3/g;
950
    return $calculated;
956
    return $calculated;
951
}
957
}
Lines 2501-2507 num_type can take : Link Here
2501
=cut
2507
=cut
2502
2508
2503
sub _numeration {
2509
sub _numeration {
2504
    my ($value, $num_type, $locale) = @_;
2510
    my ($value, $num_type, $locale, $translations) = @_;
2505
    $value ||= 0;
2511
    $value ||= 0;
2506
    $num_type //= '';
2512
    $num_type //= '';
2507
    $locale ||= 'en';
2513
    $locale ||= 'en';
Lines 2529-2541 sub _numeration { Link Here
2529
            ? $dt->format_cldr( "LLLL" )
2535
            ? $dt->format_cldr( "LLLL" )
2530
            : $dt->strftime("%b");
2536
            : $dt->strftime("%b");
2531
    } elsif ( $num_type =~ /^season$/ ) {
2537
    } elsif ( $num_type =~ /^season$/ ) {
2532
        my @seasons= qw( Spring Summer Fall Winter );
2533
        $value = $value % 4;
2538
        $value = $value % 4;
2534
        $string = $seasons[$value];
2539
        $string = $translations->{seasons}->[$value];
2535
    } elsif ( $num_type =~ /^seasonabrv$/ ) {
2540
    } elsif ( $num_type =~ /^seasonabrv$/ ) {
2536
        my @seasonsabrv= qw( Spr Sum Fal Win );
2537
        $value = $value % 4;
2541
        $value = $value % 4;
2538
        $string = $seasonsabrv[$value];
2542
        $string = $translations->{seasonsabrv}->[$value];
2539
    } else {
2543
    } else {
2540
        $string = $value;
2544
        $string = $value;
2541
    }
2545
    }
Lines 2597-2602 sub ReopenSubscription { Link Here
2597
    $sth->execute( EXPECTED, $subscriptionid, STOPPED );
2601
    $sth->execute( EXPECTED, $subscriptionid, STOPPED );
2598
}
2602
}
2599
2603
2604
=head2 GetSeasonsTranslations
2605
2606
Provide translations for the seasons and their abbreviations for the specified locale
2607
2608
=cut
2609
2610
sub GetSeasonsTranslations {
2611
    my ( $need_seasons, $need_seasonsabrv, $subtag ) = @_;
2612
    my @seasons        = qw( Spring Summer Fall Winter );
2613
    my @seasonsabrv    = qw( Spr Sum Fal Win );
2614
    my @error_messages = qw();
2615
2616
    my @dirs = (
2617
        C4::Context->config('intranetdir') . '/misc/translator/po',
2618
        C4::Context->config('intranetdir') . '/../../misc/translator/po',
2619
    );
2620
2621
    my $dir = first { -d } @dirs;
2622
2623
    if ($dir) {
2624
        my @po_paths = glob("$dir/$subtag*staff-prog.po");
2625
        if (@po_paths) {
2626
            my $po_path     = $po_paths[0];
2627
            my $po_filename = ( $po_path =~ s/$dir\///gr );
2628
            my $po_data     = Locale::PO->load_file_ashash( $po_path, 'utf8' );
2629
2630
            if ($need_seasons) {
2631
                my $response = _translate( $po_data, @seasons );
2632
                @seasons = @{ $response->{translations} };
2633
                @error_messages =
2634
                    ( @error_messages, map { sprintf( $_, $po_filename ) } @{ $response->{error_messages} } );
2635
            }
2636
2637
            if ($need_seasonsabrv) {
2638
                my $response = _translate( $po_data, @seasonsabrv );
2639
                @seasonsabrv = @{ $response->{translations} };
2640
                @error_messages =
2641
                    ( @error_messages, map { sprintf( $_, $po_filename ) } @{ $response->{error_messages} } );
2642
            }
2643
        } else {
2644
            push(
2645
                @error_messages,
2646
                "No translation file found for $subtag. Ensure that the translation files for $subtag are installed."
2647
            );
2648
        }
2649
    } else {
2650
        push( @error_messages, "The PO directory has not been found. There is a problem in your Koha installation." );
2651
    }
2652
2653
    return { seasons => \@seasons, seasonsabrv => \@seasonsabrv, error_messages => \@error_messages };
2654
}
2655
2600
=head2 subscriptionCurrentlyOnOrder
2656
=head2 subscriptionCurrentlyOnOrder
2601
2657
2602
    $bool = subscriptionCurrentlyOnOrder( $subscriptionid );
2658
    $bool = subscriptionCurrentlyOnOrder( $subscriptionid );
Lines 2691-2696 sub _can_do_on_subscription { Link Here
2691
    return 0;
2747
    return 0;
2692
}
2748
}
2693
2749
2750
=head2 _translate
2751
2752
Provide translations for the given words based on the provided data
2753
2754
=cut
2755
2756
sub _translate {
2757
    my ( $data, @words ) = @_;
2758
2759
    my @translations   = qw();
2760
    my @error_messages = qw();
2761
2762
    for my $word (@words) {
2763
        my $regex       = qr/^"$word"$|\%s$word\%s/;
2764
        my @msgids      = grep /$regex/, keys %{$data};
2765
        my $translation = "";
2766
2767
        while ( ( $translation eq "" ) && ( my $msgid = shift(@msgids) ) ) {
2768
            next unless ( $data->{$msgid}->reference =~ /serials/ );
2769
            my $msgstr = $data->{$msgid}->msgstr;
2770
            my @ids    = split( /\%s/, $msgid );
2771
            my @strs   = split( /\%s/, $msgstr );
2772
2773
            next unless ( scalar @ids == scalar @strs );
2774
2775
            my $idx = first { $ids[$_] eq $word || $ids[$_] eq $msgid } 0 .. $#ids;
2776
            $translation = Locale::PO->dequote( $strs[$idx] ) if ( defined $idx );
2777
        }
2778
2779
        if ( $translation eq "" ) {
2780
            push( @translations,   $word );
2781
            push( @error_messages, "The translation for $word doesn't exist in the file \%s" );
2782
            next;
2783
        }
2784
2785
        push( @translations, $translation );
2786
    }
2787
2788
    return { translations => \@translations, error_messages => \@error_messages };
2789
}
2790
2694
=head2 findSerialsByStatus
2791
=head2 findSerialsByStatus
2695
2792
2696
    @serials = findSerialsByStatus($status, $subscriptionid);
2793
    @serials = findSerialsByStatus($status, $subscriptionid);
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/serials/showpredictionpattern.tt (+9 lines)
Lines 84-89 Link Here
84
  </tbody>
84
  </tbody>
85
</table>
85
</table>
86
86
87
[% IF (error_messages) %]
88
    <div class="alert alert-warning">
89
        <h4 class="alert-heading"><i class="bi-exclamation-triangle-fill"></i> Warning</h4>
90
        [% FOREACH error_message IN error_messages %]
91
            <p>[% error_message | html %]</p>
92
        [% END %]
93
    </div>
94
[% END %]
95
87
<fieldset class="action">
96
<fieldset class="action">
88
    <button class="btn btn-default btn-sm" id="hidepredictionpattern">Done</button>
97
    <button class="btn btn-default btn-sm" id="hidepredictionpattern">Done</button>
89
</fieldset>
98
</fieldset>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/serials/subscription-add.tt (-2 / +3 lines)
Lines 383-394 fieldset.rows table { clear: none; margin: 0; } Link Here
383
                                            <option value=""></option>
383
                                            <option value=""></option>
384
                                            [% FOREACH l IN locales %]
384
                                            [% FOREACH l IN locales %]
385
                                                [% IF l.language == locale %]
385
                                                [% IF l.language == locale %]
386
                                                    <option value="[% l.language | html %]" selected="selected">[% l.description | html %]</option>
386
                                                    <option value="[% l.language | html %]" data-subtag="[% l.subtag | html %]" selected="selected">[% l.description | html %]</option>
387
                                                [% ELSE %]
387
                                                [% ELSE %]
388
                                                    <option value="[% l.language | html %]">[% l.description | html %]</option>
388
                                                    <option value="[% l.language | html %]" data-subtag="[% l.subtag | html %]">[% l.description | html %]</option>
389
                                                [% END %]
389
                                                [% END %]
390
                                            [% END %]
390
                                            [% END %]
391
                                        </select>
391
                                        </select>
392
                                        <input type="hidden" id="subtag" name="subtag" value="">
392
                                        <div class="hint">If empty, English is used</div>
393
                                        <div class="hint">If empty, English is used</div>
393
                                    </li>
394
                                    </li>
394
                                    <li id="more_options">
395
                                    <li id="more_options">
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/serials/subscription-numberpatterns.tt (-2 / +12 lines)
Lines 210-219 Link Here
210
                  <select id="locale" name="locale">
210
                  <select id="locale" name="locale">
211
                      <option value=""></option>
211
                      <option value=""></option>
212
                      [% FOREACH locale IN locales %]
212
                      [% FOREACH locale IN locales %]
213
                        <option value="[% locale.language | html %]">[% locale.description | html %]</option>
213
                        <option value="[% locale.language | html %]" data-subtag="[% locale.subtag | html %]">[% locale.description | html %]</option>
214
                      [% END %]
214
                      [% END %]
215
                    </select>
215
                    </select>
216
                  <span class="hint">If empty, English is used</span>
216
                  <span class="hint">If empty, English is used</span>
217
                  <input type="hidden" id="subtag" name="subtag" value="">
217
                </li>
218
                </li>
218
              </ol>
219
              </ol>
219
              <table>
220
              <table>
Lines 334-339 Link Here
334
    [% INCLUDE 'calendar.inc' %]
335
    [% INCLUDE 'calendar.inc' %]
335
    [% INCLUDE 'datatables.inc' %]
336
    [% INCLUDE 'datatables.inc' %]
336
    <script>
337
    <script>
338
        function setSubtag () {
339
            $("#subtag").val($("#locale").find(':selected').data('subtag'));
340
        }
341
337
        function confirmDelete() {
342
        function confirmDelete() {
338
            return confirm(_("Are you sure you want to delete this numbering pattern?"));
343
            return confirm(_("Are you sure you want to delete this numbering pattern?"));
339
        }
344
        }
Lines 367-373 Link Here
367
                    'lastvalue1', 'lastvalue2', 'lastvalue3', 'add1', 'add2', 'add3',
372
                    'lastvalue1', 'lastvalue2', 'lastvalue3', 'add1', 'add2', 'add3',
368
                    'every1', 'every2', 'every3', 'innerloop1', 'innerloop2', 'innerloop3',
373
                    'every1', 'every2', 'every3', 'innerloop1', 'innerloop2', 'innerloop3',
369
                    'setto1', 'setto2', 'setto3', 'numbering1', 'numbering2', 'numbering3',
374
                    'setto1', 'setto2', 'setto3', 'numbering1', 'numbering2', 'numbering3',
370
                    'whenmorethan1', 'whenmorethan2', 'whenmorethan3', 'locale'
375
                    'whenmorethan1', 'whenmorethan2', 'whenmorethan3', 'locale', 'subtag'
371
                ];
376
                ];
372
                for(i in ajaxParams) {
377
                for(i in ajaxParams) {
373
                    var param = ajaxParams[i];
378
                    var param = ajaxParams[i];
Lines 410-415 Link Here
410
            $("#test_pattern").on("click",function(){
415
            $("#test_pattern").on("click",function(){
411
                 testPattern();
416
                 testPattern();
412
            });
417
            });
418
            $("#locale").on("change", function() {
419
                setSubtag();
420
            });
421
422
            setSubtag();
413
        });
423
        });
414
    </script>
424
    </script>
415
[% END %]
425
[% END %]
(-)a/koha-tmpl/intranet-tmpl/prog/js/subscription-add.js (-1 / +10 lines)
Lines 329-335 function testPredictionPattern() { Link Here
329
        'lastvalue1', 'lastvalue2', 'lastvalue3', 'add1', 'add2', 'add3',
329
        'lastvalue1', 'lastvalue2', 'lastvalue3', 'add1', 'add2', 'add3',
330
        'every1', 'every2', 'every3', 'innerloop1', 'innerloop2', 'innerloop3',
330
        'every1', 'every2', 'every3', 'innerloop1', 'innerloop2', 'innerloop3',
331
        'setto1', 'setto2', 'setto3', 'numbering1', 'numbering2', 'numbering3',
331
        'setto1', 'setto2', 'setto3', 'numbering1', 'numbering2', 'numbering3',
332
        'whenmorethan1', 'whenmorethan2', 'whenmorethan3', 'locale',
332
        'whenmorethan1', 'whenmorethan2', 'whenmorethan3', 'locale', 'subtag',
333
        'sfdescription', 'unitsperissue', 'issuesperunit', 'unit'
333
        'sfdescription', 'unitsperissue', 'issuesperunit', 'unit'
334
    ];
334
    ];
335
    for(i in ajaxParams) {
335
    for(i in ajaxParams) {
Lines 543-548 function mana_comment_close(){ Link Here
543
    $("#new_mana_comment").hide();
543
    $("#new_mana_comment").hide();
544
}
544
}
545
545
546
function setSubtag () {
547
    $("#subtag").val($("#locale").find(':selected').data('subtag'));
548
}
549
546
function showPredictionPatternTest( data ){
550
function showPredictionPatternTest( data ){
547
    $("#displayexample").html(data).show();
551
    $("#displayexample").html(data).show();
548
    $("#page_2 > div").attr("class","col-xs-6");
552
    $("#page_2 > div").attr("class","col-xs-6");
Lines 744-747 $(document).ready(function() { Link Here
744
        $(".use_items").css('display', display).find("select").val("")
748
        $(".use_items").css('display', display).find("select").val("")
745
    });
749
    });
746
750
751
    $("#locale").on("change", function() {
752
        setSubtag();
753
    });
754
755
    setSubtag();
747
});
756
});
(-)a/serials/showpredictionpattern.pl (-1 / +10 lines)
Lines 34-40 use CGI qw ( -utf8 ); Link Here
34
use Date::Calc qw( Add_Delta_Days Add_Delta_YM Day_of_Week Delta_Days );
34
use Date::Calc qw( Add_Delta_Days Add_Delta_YM Day_of_Week Delta_Days );
35
use C4::Auth qw( get_template_and_user );
35
use C4::Auth qw( get_template_and_user );
36
use C4::Output qw( output_html_with_http_headers );
36
use C4::Output qw( output_html_with_http_headers );
37
use C4::Serials qw( GetSubscription GetFictiveIssueNumber GetSeq GetSubscriptionIrregularities GetNextDate GetNextSeq );
37
use C4::Serials qw( GetSubscription GetFictiveIssueNumber GetSeq GetSubscriptionIrregularities GetNextDate GetNextSeq GetSeasonsTranslations );
38
use C4::Serials::Frequency;
38
use C4::Serials::Frequency;
39
use Koha::DateUtils qw( dt_from_string );
39
use Koha::DateUtils qw( dt_from_string );
40
40
Lines 97-102 $enddate = dt_from_string($enddate)->ymd if $enddate; Link Here
97
$nextacquidate = $nextacquidate ? dt_from_string($nextacquidate)->ymd : $firstacquidate;
97
$nextacquidate = $nextacquidate ? dt_from_string($nextacquidate)->ymd : $firstacquidate;
98
my $date = $nextacquidate;
98
my $date = $nextacquidate;
99
99
100
my $need_seasons     = grep { $_ =~ /^season$/ } %pattern;
101
my $need_seasonsabrv = grep { $_ =~ /^seasonabrv$/ } %pattern;
102
my $subtag           = scalar $input->param('subtag');
103
104
my $translations;
105
$translations = GetSeasonsTranslations( $need_seasons, $need_seasonsabrv, $subtag ) if ( $need_seasons || $need_seasonsabrv );
106
100
my %subscription = (
107
my %subscription = (
101
    locale      => scalar $input->param('locale') // '',
108
    locale      => scalar $input->param('locale') // '',
102
    lastvalue1      => scalar $input->param('lastvalue1') // '',
109
    lastvalue1      => scalar $input->param('lastvalue1') // '',
Lines 108-113 my %subscription = ( Link Here
108
    irregularity    => '',
115
    irregularity    => '',
109
    countissuesperunit  => 1,
116
    countissuesperunit  => 1,
110
    firstacquidate  => $firstacquidate,
117
    firstacquidate  => $firstacquidate,
118
    translations    => $translations,
111
);
119
);
112
120
113
my $issuenumber;
121
my $issuenumber;
Lines 178-183 while( $i < 1000 ) { Link Here
178
186
179
$template->param(
187
$template->param(
180
    predictions_loop => \@predictions_loop,
188
    predictions_loop => \@predictions_loop,
189
    error_messages   => \@{ $translations->{error_messages} },
181
);
190
);
182
191
183
if ( $frequency->{unit} and not $custompattern ) {
192
if ( $frequency->{unit} and not $custompattern ) {
(-)a/serials/showpredictionpattern.pl.tdy (+218 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
# Copyright 2011-2013 Biblibre SARL
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Koha is distributed in the hope that it will be useful, but
13
# WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20
=head1 NAME
21
22
showpredictionpattern.pl
23
24
=head1 DESCRIPTION
25
26
This script calculate numbering of serials based on numbering pattern, and
27
publication date, based on frequency and first publication date.
28
29
=cut
30
31
use Modern::Perl;
32
33
use CGI qw ( -utf8 );
34
use Date::Calc qw( Add_Delta_Days Add_Delta_YM Day_of_Week Delta_Days );
35
use C4::Auth qw( get_template_and_user );
36
use C4::Output qw( output_html_with_http_headers );
37
use C4::Serials
38
    qw( GetSubscription GetFictiveIssueNumber GetSeq GetSubscriptionIrregularities GetNextDate GetNextSeq GetSeasonsTranslations );
39
use C4::Serials::Frequency;
40
use Koha::DateUtils qw( dt_from_string );
41
42
my $input = CGI->new;
43
my ( $template, $loggedinuser, $cookie, $flags ) = get_template_and_user(
44
    {
45
        template_name => 'serials/showpredictionpattern.tt',
46
        query         => $input,
47
        type          => 'intranet',
48
        flagsrequired => { 'serials' => '*' },
49
    }
50
);
51
52
my $subscriptionid = $input->param('subscriptionid');
53
my $frequencyid    = $input->param('frequency');
54
my $firstacquidate = $input->param('firstacquidate');
55
my $nextacquidate  = $input->param('nextacquidate');
56
my $enddate        = $input->param('to');
57
my $subtype        = $input->param('subtype');
58
my $sublength      = $input->param('sublength');
59
my $custompattern  = $input->param('custompattern');
60
61
my $frequency;
62
if ( $frequencyid eq 'mana' ) {
63
    $frequency = {
64
        'id'            => undef,
65
        'displayorder'  => undef,
66
        'description'   => scalar $input->param('sfdescription') // '',
67
        'unitsperissue' => scalar $input->param('unitsperissue') // '',
68
        'issuesperunit' => scalar $input->param('issuesperunit') // '',
69
        'unit'          => scalar $input->param('unit')          // ''
70
    };
71
} else {
72
    $frequency = GetSubscriptionFrequency($frequencyid);
73
}
74
75
my %pattern = (
76
    numberingmethod => scalar $input->param('numberingmethod') // '',
77
    numbering1      => scalar $input->param('numbering1')      // '',
78
    numbering2      => scalar $input->param('numbering2')      // '',
79
    numbering3      => scalar $input->param('numbering3')      // '',
80
    add1            => scalar $input->param('add1')            // '',
81
    add2            => scalar $input->param('add2')            // '',
82
    add3            => scalar $input->param('add3')            // '',
83
    whenmorethan1   => scalar $input->param('whenmorethan1')   // '',
84
    whenmorethan2   => scalar $input->param('whenmorethan2')   // '',
85
    whenmorethan3   => scalar $input->param('whenmorethan3')   // '',
86
    setto1          => scalar $input->param('setto1')          // '',
87
    setto2          => scalar $input->param('setto2')          // '',
88
    setto3          => scalar $input->param('setto3')          // '',
89
    every1          => scalar $input->param('every1')          // '',
90
    every2          => scalar $input->param('every2')          // '',
91
    every3          => scalar $input->param('every3')          // '',
92
);
93
94
$firstacquidate = $firstacquidate ? dt_from_string($firstacquidate)->ymd : dt_from_string->ymd;
95
96
$enddate = dt_from_string($enddate)->ymd if $enddate;
97
98
$nextacquidate = $nextacquidate ? dt_from_string($nextacquidate)->ymd : $firstacquidate;
99
my $date = $nextacquidate;
100
101
my $need_seasons     = grep { $_ =~ /^season$/ } %pattern;
102
my $need_seasonsabrv = grep { $_ =~ /^seasonabrv$/ } %pattern;
103
my $subtag           = scalar $input->param('subtag');
104
105
my $translations;
106
$translations = GetSeasonsTranslations( $need_seasons, $need_seasonsabrv, $subtag )
107
    if ( $need_seasons || $need_seasonsabrv );
108
109
my %subscription = (
110
    locale             => scalar $input->param('locale')     // '',
111
    lastvalue1         => scalar $input->param('lastvalue1') // '',
112
    lastvalue2         => scalar $input->param('lastvalue2') // '',
113
    lastvalue3         => scalar $input->param('lastvalue3') // '',
114
    innerloop1         => scalar $input->param('innerloop1') // '',
115
    innerloop2         => scalar $input->param('innerloop2') // '',
116
    innerloop3         => scalar $input->param('innerloop3') // '',
117
    irregularity       => '',
118
    countissuesperunit => 1,
119
    firstacquidate     => $firstacquidate,
120
    translations       => $translations,
121
);
122
123
my $issuenumber;
124
if ( defined $subscriptionid ) {
125
    ($issuenumber) = C4::Serials::GetFictiveIssueNumber( \%subscription, $date, $frequency );
126
} else {
127
    $issuenumber = 1;
128
}
129
130
my @predictions_loop;
131
my ($calculated) = GetSeq( \%subscription, \%pattern );
132
push @predictions_loop, {
133
    number          => $calculated,
134
    publicationdate => $date,
135
    issuenumber     => $issuenumber,
136
    dow             => Day_of_Week( split /-/, $date ),
137
};
138
my @irreg = ();
139
if ( defined $subscriptionid ) {
140
    @irreg = C4::Serials::GetSubscriptionIrregularities($subscriptionid);
141
    while ( @irreg && $issuenumber > $irreg[0] ) {
142
        shift @irreg;
143
    }
144
    if ( @irreg && $issuenumber == $irreg[0] ) {
145
        $predictions_loop[0]->{'not_published'} = 1;
146
        shift @irreg;
147
    }
148
}
149
150
my $i = 1;
151
while ( $i < 1000 ) {
152
    my %line;
153
154
    if ( defined $date ) {
155
        $date = GetNextDate( \%subscription, $date, $frequency );
156
    }
157
    if ( defined $date ) {
158
        $line{'publicationdate'} = $date;
159
        $line{'dow'}             = Day_of_Week( split /-/, $date );
160
    }
161
162
    # Check if we don't have exceed end date
163
    if ($sublength) {
164
        if ( $subtype eq "issues" && $i >= $sublength ) {
165
            last;
166
        } elsif ( $subtype eq "weeks"
167
            && $date
168
            && Delta_Days( split( /-/, $date ), Add_Delta_Days( split( /-/, $firstacquidate ), 7 * $sublength - 1 ) ) <
169
            0 )
170
        {
171
            last;
172
        } elsif ( $subtype eq "months"
173
            && $date
174
            && ( Delta_Days( split( /-/, $date ), Add_Delta_YM( split( /-/, $firstacquidate ), 0, $sublength ) ) - 1 )
175
            < 0 )
176
        {
177
            last;
178
        }
179
    }
180
    if ( $enddate && $date && Delta_Days( split( /-/, $date ), split( /-/, $enddate ) ) <= 0 ) {
181
        last;
182
    }
183
184
    (
185
        $calculated, $subscription{'lastvalue1'}, $subscription{'lastvalue2'}, $subscription{'lastvalue3'},
186
        $subscription{'innerloop1'}, $subscription{'innerloop2'}, $subscription{'innerloop3'}
187
    ) = GetNextSeq( \%subscription, \%pattern, $frequency );
188
    $issuenumber++;
189
    $line{'number'}      = $calculated;
190
    $line{'issuenumber'} = $issuenumber;
191
    if ( @irreg && $issuenumber == $irreg[0] ) {
192
        $line{'not_published'} = 1;
193
        shift @irreg;
194
    }
195
    push @predictions_loop, \%line;
196
197
    $i++;
198
}
199
200
$template->param(
201
    predictions_loop => \@predictions_loop,
202
    error_messages   => \@{ $translations->{error_messages} },
203
);
204
205
if ( $frequency->{unit} and not $custompattern ) {
206
    $template->param( ask_for_irregularities => 1 );
207
    if ( $frequency->{unit} eq 'day' and $frequency->{unitsperissue} == 1 ) {
208
        $template->param( daily_options => 1 );
209
    }
210
}
211
212
if (   ( $date && $enddate && $date ne $enddate )
213
    or ( $subtype eq 'issues' && $i < $sublength ) )
214
{
215
    $template->param( not_consistent_end_date => 1 );
216
}
217
218
output_html_with_http_headers $input, $cookie, $template->output;
(-)a/serials/subscription-add.pl (+1 lines)
Lines 225-230 if ($op eq 'cud-addsubscription') { Link Here
225
    my $languages = [ map {
225
    my $languages = [ map {
226
        {
226
        {
227
            language => $_->{iso639_2_code},
227
            language => $_->{iso639_2_code},
228
            subtag      => $_->{subtag},
228
            description => $_->{language_description} || $_->{language}
229
            description => $_->{language_description} || $_->{language}
229
        }
230
        }
230
    } @{ C4::Languages::getAllLanguages() } ];
231
    } @{ C4::Languages::getAllLanguages() } ];
(-)a/serials/subscription-add.pl.tdy (+527 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
# This file is part of Koha.
4
#
5
# Koha is free software; you can redistribute it and/or modify it
6
# under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 3 of the License, or
8
# (at your option) any later version.
9
#
10
# Koha is distributed in the hope that it will be useful, but
11
# WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
14
#
15
# You should have received a copy of the GNU General Public License
16
# along with Koha; if not, see <http://www.gnu.org/licenses>.
17
18
use Modern::Perl;
19
20
use CGI qw ( -utf8 );
21
use Date::Calc qw( Add_Delta_Days Add_Delta_YM );
22
use C4::Koha qw( GetAuthorisedValues );
23
use C4::Auth qw( get_template_and_user );
24
use C4::Output qw( output_and_exit output_html_with_http_headers );
25
use C4::Context;
26
use C4::Serials
27
    qw( GetSubscription GetNextExpected GetSerials GetSubscriptionLength NewSubscription ModNextExpected ModSubscription );
28
use C4::Serials::Frequency;
29
use C4::Serials::Numberpattern;
30
use C4::Letters qw( GetLetters );
31
use Koha::AdditionalFields;
32
use Koha::Biblios;
33
use Koha::DateUtils qw( output_pref );
34
use Koha::ItemTypes;
35
use Carp qw( carp );
36
37
use Koha::Subscription::Numberpattern;
38
use Koha::Subscription::Frequency;
39
use Koha::SharedContent;
40
41
our $query = CGI->new;
42
my $op  = $query->param('op') || '';
43
my $dbh = C4::Context->dbh;
44
my $sub_length;
45
46
# Permission needed if it is a modification : edit_subscription
47
# Permission needed otherwise (nothing or dup) : create_subscription
48
my $permission = ( $op eq 'modify' || $op eq 'cud-modsubscription' ) ? "edit_subscription" : "create_subscription";
49
50
our ( $template, $loggedinuser, $cookie ) = get_template_and_user(
51
    {
52
        template_name => "serials/subscription-add.tt",
53
        query         => $query,
54
        type          => "intranet",
55
        flagsrequired => { serials => $permission },
56
    }
57
);
58
59
my $sub_on;
60
61
my $subs;
62
our $firstissuedate;
63
64
my $mana_url = C4::Context->config('mana_config');
65
$template->param( 'mana_url' => $mana_url );
66
my $subscriptionid = $query->param('subscriptionid');
67
68
if ( $op eq 'modify' || $op eq 'dup' || $op eq 'cud-modsubscription' ) {
69
70
    $subs = GetSubscription($subscriptionid);
71
72
    output_and_exit( $query, $cookie, $template, 'unknown_subscription' )
73
        unless $subs;
74
75
    ## FIXME : Check rights to edit if mod. Could/Should display an error message.
76
    if ( $subs->{'cannotedit'} && $op eq 'modify' ) {
77
        carp "Attempt to modify subscription $subscriptionid by " . C4::Context->userenv->{'id'} . " not allowed";
78
        print $query->redirect("/cgi-bin/koha/serials/subscription-detail.pl?subscriptionid=$subscriptionid");
79
    }
80
    $firstissuedate = $subs->{firstacquidate} || '';    # in iso format.
81
    if ( !defined $subs->{letter} ) {
82
        $subs->{letter} = q{};
83
    }
84
    my $nextexpected = GetNextExpected($subscriptionid);
85
    $nextexpected->{'isfirstissue'} = $nextexpected->{planneddate} eq $firstissuedate;
86
    $subs->{nextacquidate}          = $nextexpected->{planneddate} if ( $op eq 'modify' );
87
    unless ( $op eq 'cud-modsubscription' ) {
88
        foreach my $length_unit (qw(numberlength weeklength monthlength)) {
89
            if ( $subs->{$length_unit} ) {
90
                $sub_length = $subs->{$length_unit};
91
                $sub_on     = $length_unit;
92
                last;
93
            }
94
        }
95
96
        $template->param( %{$subs} );
97
        $template->param(
98
            $op               => 1,
99
            "subtype_$sub_on" => 1,
100
            sublength         => $sub_length,
101
            history           => ( $op eq 'modify' ),
102
            firstacquiyear    => substr( $firstissuedate, 0, 4 ),
103
        );
104
105
        if ( $op eq 'modify' ) {
106
            my ($serials_number) = GetSerials($subscriptionid);
107
            if ( $serials_number > 1 ) {
108
                $template->param( more_than_one_serial => 1 );
109
            }
110
        }
111
    }
112
113
    if ( $op eq 'dup' ) {
114
        my $dont_copy_fields = C4::Context->preference('SubscriptionDuplicateDroppedInput');
115
        my @fields_id        = map { fieldid => $_ }, split '\|', $dont_copy_fields;
116
        $template->param( dont_export_field_loop => \@fields_id );
117
    }
118
119
    my $letters = get_letter_loop( $subs->{letter} );
120
    $template->param( letterloop => $letters );
121
122
}
123
124
my $locations_loop = GetAuthorisedValues("LOC");
125
my $ccodes_loop    = GetAuthorisedValues("CCODE");
126
127
$template->param(
128
    branchcode     => $subs->{branchcode},
129
    locations_loop => $locations_loop,
130
    ccodes_loop    => $ccodes_loop
131
);
132
133
my @additional_fields = Koha::AdditionalFields->search( { tablename => 'subscription' } )->as_list;
134
my %additional_field_values;
135
if ($subscriptionid) {
136
    my $subscription = Koha::Subscriptions->find($subscriptionid);
137
    foreach my $value ( $subscription->additional_field_values->as_list ) {
138
        $additional_field_values{ $value->field_id } = $value->value;
139
    }
140
}
141
142
$template->param(
143
    additional_fields       => \@additional_fields,
144
    additional_field_values => \%additional_field_values,
145
);
146
147
my $typeloop = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search_with_localization->unblessed } };
148
149
# FIXME We should use the translated_description for item types
150
my @typearg =
151
    map {
152
    {
153
        code     => $_, value => $typeloop->{$_}{'description'},
154
        selected => ( ( $subs->{itemtype} and $_ eq $subs->{itemtype} ) ? "selected=\"selected\"" : "" ),
155
    }
156
    } sort keys %{$typeloop};
157
my @previoustypearg =
158
    map {
159
    {
160
        code => $_, value => $typeloop->{$_}{'description'}, selected =>
161
            ( ( $subs->{previousitemtype} and $_ eq $subs->{previousitemtype} ) ? "selected=\"selected\"" : "" ),
162
    }
163
    } sort keys %{$typeloop};
164
165
$template->param(
166
    typeloop         => \@typearg,
167
    previoustypeloop => \@previoustypearg,
168
    locations_loop   => $locations_loop,
169
);
170
171
# prepare template variables common to all $op conditions:
172
$template->param( 'makePreviousSerialAvailable' => 1 ) if ( C4::Context->preference('makePreviousSerialAvailable') );
173
174
if ( $op !~ /^mod/ ) {
175
    my $letters = get_letter_loop();
176
    $template->param( letterloop => $letters );
177
}
178
179
if ( $op eq 'cud-addsubscription' ) {
180
    redirect_add_subscription();
181
} elsif ( $op eq 'cud-modsubscription' ) {
182
    redirect_mod_subscription();
183
} else {
184
185
    $template->param(
186
        subtypes => [qw( numberlength weeklength monthlength )],
187
        subtype  => $sub_on,
188
    );
189
190
    if ( $op ne 'cud-modsubscription' && $op ne 'dup' && $op ne 'modify' ) {
191
        my $letters = get_letter_loop();
192
        $template->param( letterloop => $letters );
193
    }
194
195
    my $new_biblionumber = $query->param('biblionumber_for_new_subscription');
196
    if ( defined $new_biblionumber ) {
197
        my $biblio = Koha::Biblios->find($new_biblionumber);
198
        if ( defined $biblio ) {
199
            $template->param( bibnum      => $new_biblionumber );
200
            $template->param( bibliotitle => $biblio->title );
201
        }
202
    }
203
204
    $template->param( ( uc( C4::Context->preference("marcflavour") ) ) => 1 );
205
206
    my @frequencies = GetSubscriptionFrequencies;
207
    my @frqloop;
208
    foreach my $freq (@frequencies) {
209
        my $selected = 0;
210
        $selected = 1 if ( $subs->{periodicity} and $freq->{id} eq $subs->{periodicity} );
211
        my $row = {
212
            id       => $freq->{'id'},
213
            selected => $selected,
214
            label    => $freq->{'description'},
215
        };
216
        push @frqloop, $row;
217
    }
218
    $template->param( frequencies => \@frqloop );
219
220
    my @numpatterns = GetSubscriptionNumberpatterns;
221
    my @numberpatternloop;
222
    foreach my $numpattern (@numpatterns) {
223
        my $selected = 0;
224
        $selected = 1 if ( $subs->{numberpattern} and $numpattern->{id} eq $subs->{numberpattern} );
225
        my $row = {
226
            id       => $numpattern->{'id'},
227
            selected => $selected,
228
            label    => $numpattern->{'label'},
229
        };
230
        push @numberpatternloop, $row;
231
    }
232
    $template->param( numberpatterns => \@numberpatternloop );
233
234
    my $languages = [
235
        map {
236
            {
237
                language    => $_->{iso639_2_code},
238
                subtag      => $_->{subtag},
239
                description => $_->{language_description} || $_->{language}
240
            }
241
        } @{ C4::Languages::getAllLanguages() }
242
    ];
243
244
    $template->param( locales => $languages );
245
246
    my @bookseller_ids = Koha::Acquisition::Booksellers->search->get_column('id');
247
    $template->param( bookseller_ids => \@bookseller_ids );
248
249
    output_html_with_http_headers $query, $cookie, $template->output;
250
}
251
252
sub get_letter_loop {
253
    my ($selected_lettercode) = @_;
254
    $selected_lettercode //= '';
255
    my $letters = GetLetters( { module => 'serial' } );
256
    return [
257
        map {
258
            {
259
                value      => $_->{code},
260
                lettername => $_->{name},
261
                ( $_->{code} eq $selected_lettercode ? ( selected => 1 ) : () ),
262
            }
263
        } @$letters
264
    ];
265
}
266
267
sub _guess_enddate {
268
    my ( $startdate_iso, $frequencyid, $numberlength, $weeklength, $monthlength ) = @_;
269
    my ( $year, $month, $day );
270
    my $enddate;
271
    if ( $numberlength != 0 ) {
272
        my $frequency = GetSubscriptionFrequency($frequencyid);
273
        if ( $frequency->{'unit'} eq 'day' ) {
274
            ( $year, $month, $day ) = Add_Delta_Days(
275
                split( /-/, $startdate_iso ),
276
                $numberlength * $frequency->{'unitsperissue'} / $frequency->{'issuesperunit'}
277
            );
278
        } elsif ( $frequency->{'unit'} eq 'week' ) {
279
            ( $year, $month, $day ) = Add_Delta_Days(
280
                split( /-/, $startdate_iso ),
281
                $numberlength * 7 * $frequency->{'unitsperissue'} / $frequency->{'issuesperunit'}
282
            );
283
        } elsif ( $frequency->{'unit'} eq 'month' ) {
284
            ( $year, $month, $day ) = Add_Delta_YM(
285
                split( /-/, $startdate_iso ), 0,
286
                $numberlength * $frequency->{'unitsperissue'} / $frequency->{'issuesperunit'}
287
            );
288
        } elsif ( $frequency->{'unit'} eq 'year' ) {
289
            ( $year, $month, $day ) = Add_Delta_YM(
290
                split( /-/, $startdate_iso ),
291
                $numberlength * $frequency->{'unitsperissue'} / $frequency->{'issuesperunit'}, 0
292
            );
293
        }
294
    } elsif ( $weeklength != 0 ) {
295
        ( $year, $month, $day ) = Add_Delta_Days( split( /-/, $startdate_iso ), $weeklength * 7 );
296
    } elsif ( $monthlength != 0 ) {
297
        ( $year, $month, $day ) = Add_Delta_YM( split( /-/, $startdate_iso ), 0, $monthlength );
298
    }
299
    if ( defined $year ) {
300
        $enddate = sprintf( "%04d-%02d-%02d", $year, $month, $day );
301
    } else {
302
        undef $enddate;
303
    }
304
    return $enddate;
305
}
306
307
sub redirect_add_subscription {
308
    my $periodicity = $query->param('frequency');
309
    if ( $periodicity eq 'mana' ) {
310
        my $subscription_freq = Koha::Subscription::Frequency->new()->set(
311
            {
312
                description   => $query->param('sfdescription'),
313
                unit          => $query->param('unit'),
314
                unitsperissue => $query->param('unitsperissue'),
315
                issuesperunit => $query->param('issuesperunit'),
316
            }
317
        )->store();
318
        $periodicity = $subscription_freq->id;
319
    }
320
    my $numberpattern = Koha::Subscription::Numberpatterns->new_or_existing( { $query->Vars } );
321
322
    my $auser          = $query->param('user');
323
    my $branchcode     = $query->param('branchcode');
324
    my $aqbooksellerid = $query->param('aqbooksellerid');
325
    my $cost           = $query->param('cost');
326
    my $aqbudgetid     = $query->param('aqbudgetid');
327
    my @irregularity   = $query->multi_param('irregularity');
328
    my $locale         = $query->param('locale');
329
    my $graceperiod    = $query->param('graceperiod') || 0;
330
331
    my $subtype   = $query->param('subtype');
332
    my $sublength = $query->param('sublength');
333
    my ( $numberlength, $weeklength, $monthlength ) = GetSubscriptionLength( $subtype, $sublength );
334
    my $add1                  = $query->param('add1');
335
    my $lastvalue1            = $query->param('lastvalue1');
336
    my $innerloop1            = $query->param('innerloop1');
337
    my $innerloop2            = $query->param('innerloop2');
338
    my $lastvalue2            = $query->param('lastvalue2');
339
    my $lastvalue3            = $query->param('lastvalue3');
340
    my $innerloop3            = $query->param('innerloop3');
341
    my $status                = 1;
342
    my $biblionumber          = $query->param('biblionumber');
343
    my $callnumber            = $query->param('callnumber');
344
    my $notes                 = $query->param('notes');
345
    my $internalnotes         = $query->param('internalnotes');
346
    my $letter                = $query->param('letter');
347
    my $manualhistory         = $query->param('manualhist') ? 1 : 0;
348
    my $serialsadditems       = $query->param('serialsadditems');
349
    my $staffdisplaycount     = $query->param('staffdisplaycount');
350
    my $opacdisplaycount      = $query->param('opacdisplaycount');
351
    my $location              = $query->param('location');
352
    my $itemtype              = $query->param('itemtype');
353
    my $previousitemtype      = $query->param('previousitemtype');
354
    my $skip_serialseq        = $query->param('skip_serialseq');
355
    my $ccode                 = $query->param('ccode');
356
    my $published_on_template = $query->param('published_on_template');
357
358
    my $mana_id;
359
    if ( $query->param('mana_id') ne "" ) {
360
        $mana_id = $query->param('mana_id');
361
        Koha::SharedContent::increment_entity_value( "subscription", $mana_id, "nbofusers" );
362
    }
363
364
    my $startdate = output_pref( { str => scalar $query->param('startdate'), dateonly => 1, dateformat => 'iso' } );
365
    my $enddate   = output_pref( { str => scalar $query->param('enddate'),   dateonly => 1, dateformat => 'iso' } );
366
    my $firstacquidate =
367
        output_pref( { str => scalar $query->param('firstacquidate'), dateonly => 1, dateformat => 'iso' } );
368
369
    if ( !defined $enddate || $enddate eq '' ) {
370
        if ( $subtype eq "issues" ) {
371
            $enddate = _guess_enddate( $firstacquidate, $periodicity, $numberlength, $weeklength, $monthlength );
372
        } else {
373
            $enddate = _guess_enddate( $startdate, $periodicity, $numberlength, $weeklength, $monthlength );
374
        }
375
    }
376
    my $subscriptionid = NewSubscription(
377
        $auser,                     $branchcode,       $aqbooksellerid, $cost, $aqbudgetid, $biblionumber,
378
        $startdate,                 $periodicity,      $numberlength,   $weeklength,
379
        $monthlength,               $lastvalue1,       $innerloop1,     $lastvalue2, $innerloop2,
380
        $lastvalue3,                $innerloop3,       $status,         $notes, $letter, $firstacquidate,
381
        join( ";", @irregularity ), $numberpattern,    $locale,         $callnumber,
382
        $manualhistory,             $internalnotes,    $serialsadditems,
383
        $staffdisplaycount,         $opacdisplaycount, $graceperiod, $location, $enddate,
384
        $skip_serialseq,            $itemtype,         $previousitemtype, $mana_id, $ccode, $published_on_template
385
    );
386
    if (    ( C4::Context->preference('Mana') == 1 )
387
        and ( grep { $_ eq "subscription" } split( /,/, C4::Context->preference('AutoShareWithMana') ) ) )
388
    {
389
        my $result = Koha::SharedContent::send_entity(
390
            $query->param('mana_language') || '', $loggedinuser, $subscriptionid,
391
            'subscription'
392
        );
393
        $template->param( mana_msg => $result->{msg} );
394
    }
395
396
    my @additional_fields;
397
    my $biblio              = Koha::Biblios->find($biblionumber);
398
    my $subscription_fields = Koha::AdditionalFields->search( { tablename => 'subscription' } );
399
    while ( my $field = $subscription_fields->next ) {
400
        my $value = $query->param( 'additional_field_' . $field->id );
401
        push @additional_fields, {
402
            id    => $field->id,
403
            value => $value,
404
        };
405
    }
406
    Koha::Subscriptions->find($subscriptionid)->set_additional_fields( \@additional_fields );
407
408
    print $query->redirect("/cgi-bin/koha/serials/subscription-detail.pl?subscriptionid=$subscriptionid");
409
    return;
410
}
411
412
sub redirect_mod_subscription {
413
    my $subscriptionid = $query->param('subscriptionid');
414
    my @irregularity   = $query->multi_param('irregularity');
415
    my $auser          = $query->param('user');
416
    my $librarian => scalar $query->param('librarian'),
417
        my $branchcode = $query->param('branchcode');
418
    my $cost           = $query->param('cost');
419
    my $aqbooksellerid = $query->param('aqbooksellerid');
420
    my $biblionumber   = $query->param('biblionumber');
421
    my $aqbudgetid     = $query->param('aqbudgetid');
422
423
    my $startdate = output_pref( { str => scalar $query->param('startdate'), dateonly => 1, dateformat => 'iso' } );
424
    my $enddate   = output_pref( { str => scalar $query->param('enddate'),   dateonly => 1, dateformat => 'iso' } );
425
    my $firstacquidate =
426
        output_pref( { str => scalar $query->param('firstacquidate'), dateonly => 1, dateformat => 'iso' } );
427
428
    my $nextacquidate = $query->param('nextacquidate');
429
    $nextacquidate =
430
        $nextacquidate
431
        ? output_pref( { str => $nextacquidate, dateonly => 1, dateformat => 'iso' } )
432
        : $firstacquidate;
433
434
    my $periodicity = $query->param('frequency');
435
    if ( $periodicity eq 'mana' ) {
436
        my $subscription_freq = Koha::Subscription::Frequency->new()->set(
437
            {
438
                description   => $query->param('sfdescription'),
439
                unit          => $query->param('unit'),
440
                unitsperissue => $query->param('unitsperissue'),
441
                issuesperunit => $query->param('issuesperunit'),
442
            }
443
        )->store();
444
        $periodicity = $subscription_freq->id;
445
    }
446
    my $numberpattern = Koha::Subscription::Numberpatterns->new_or_existing( { $query->Vars } );
447
448
    my $subtype   = $query->param('subtype');
449
    my $sublength = $query->param('sublength');
450
    my ( $numberlength, $weeklength, $monthlength ) = GetSubscriptionLength( $subtype, $sublength );
451
    my $locale                = $query->param('locale');
452
    my $lastvalue1            = $query->param('lastvalue1');
453
    my $innerloop1            = $query->param('innerloop1');
454
    my $lastvalue2            = $query->param('lastvalue2');
455
    my $innerloop2            = $query->param('innerloop2');
456
    my $lastvalue3            = $query->param('lastvalue3');
457
    my $innerloop3            = $query->param('innerloop3');
458
    my $status                = 1;
459
    my $callnumber            = $query->param('callnumber');
460
    my $notes                 = $query->param('notes');
461
    my $internalnotes         = $query->param('internalnotes');
462
    my $letter                = $query->param('letter');
463
    my $manualhistory         = $query->param('manualhist') ? 1 : 0;
464
    my $serialsadditems       = $query->param('serialsadditems');
465
    my $staffdisplaycount     = $query->param('staffdisplaycount');
466
    my $opacdisplaycount      = $query->param('opacdisplaycount');
467
    my $graceperiod           = $query->param('graceperiod') || 0;
468
    my $location              = $query->param('location');
469
    my $itemtype              = $query->param('itemtype');
470
    my $previousitemtype      = $query->param('previousitemtype');
471
    my $skip_serialseq        = $query->param('skip_serialseq');
472
    my $ccode                 = $query->param('ccode');
473
    my $published_on_template = $query->param('published_on_template');
474
475
    my $mana_id;
476
    if ( $query->param('mana_id') ne "" ) {
477
        $mana_id = $query->param('mana_id');
478
        Koha::SharedContent::increment_entity_value( "subscription", $mana_id, "nbofusers" );
479
    } else {
480
        $mana_id = undef;
481
    }
482
483
    # Guess end date
484
    if ( !defined $enddate || $enddate eq '' ) {
485
        if ( $subtype eq "issues" ) {
486
            $enddate = _guess_enddate( $nextacquidate, $periodicity, $numberlength, $weeklength, $monthlength );
487
        } else {
488
            $enddate = _guess_enddate( $startdate, $periodicity, $numberlength, $weeklength, $monthlength );
489
        }
490
    }
491
492
    my $nextexpected = GetNextExpected($subscriptionid);
493
494
    #  If it's  a mod, we need to check the current 'expected' issue, and mod it in the serials table if necessary.
495
    if ( $nextexpected->{planneddate} && $nextacquidate ne $nextexpected->{planneddate} ) {
496
        ModNextExpected( $subscriptionid, $nextacquidate );
497
498
        # if we have not received any issues yet, then we also must change the firstacquidate for the subs.
499
        $firstissuedate = $nextacquidate if ( $nextexpected->{isfirstissue} );
500
    }
501
502
    ModSubscription(
503
        $auser,            $branchcode,     $aqbooksellerid, $cost, $aqbudgetid, $startdate,
504
        $periodicity,      $firstacquidate, join( ";", @irregularity ),
505
        $numberpattern,    $locale,         $numberlength,     $weeklength, $monthlength, $lastvalue1,
506
        $innerloop1,       $lastvalue2,     $innerloop2,       $lastvalue3, $innerloop3,
507
        $status,           $biblionumber,   $callnumber,       $notes,      $letter,
508
        $manualhistory,    $internalnotes,  $serialsadditems,  $staffdisplaycount,
509
        $opacdisplaycount, $graceperiod,    $location,         $enddate, $subscriptionid,
510
        $skip_serialseq,   $itemtype,       $previousitemtype, $mana_id, $ccode, $published_on_template
511
    );
512
513
    my @additional_fields;
514
    my $biblio              = Koha::Biblios->find($biblionumber);
515
    my $subscription_fields = Koha::AdditionalFields->search( { tablename => 'subscription' } );
516
    while ( my $field = $subscription_fields->next ) {
517
        my $value = $query->param( 'additional_field_' . $field->id );
518
        push @additional_fields, {
519
            id    => $field->id,
520
            value => $value,
521
        };
522
    }
523
    Koha::Subscriptions->find($subscriptionid)->set_additional_fields( \@additional_fields );
524
525
    print $query->redirect("/cgi-bin/koha/serials/subscription-detail.pl?subscriptionid=$subscriptionid");
526
    return;
527
}
(-)a/serials/subscription-numberpatterns.pl (+1 lines)
Lines 116-121 if($op && ($op eq 'new' || $op eq 'modify')) { Link Here
116
    my $languages = [ map {
116
    my $languages = [ map {
117
        {
117
        {
118
            language => $_->{iso639_2_code},
118
            language => $_->{iso639_2_code},
119
            subtag      => $_->{subtag},
119
            description => $_->{language_description} || $_->{language}
120
            description => $_->{language_description} || $_->{language}
120
        }
121
        }
121
    } @{ C4::Languages::getAllLanguages() } ];
122
    } @{ C4::Languages::getAllLanguages() } ];
(-)a/serials/subscription-numberpatterns.pl.tdy (+164 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
# Copyright 2011-2013 Biblibre SARL
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Koha is distributed in the hope that it will be useful, but
13
# WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20
=head1 NAME
21
22
subscription-numberpatterns.pl
23
24
=head1 DESCRIPTION
25
26
Manage numbering patterns
27
28
=cut
29
30
use Modern::Perl;
31
use CGI qw ( -utf8 );
32
33
use C4::Auth qw( get_template_and_user );
34
use C4::Output qw( output_html_with_http_headers );
35
use C4::Serials::Numberpattern qw(
36
    AddSubscriptionNumberpattern
37
    DelSubscriptionNumberpattern
38
    GetSubscriptionNumberpattern
39
    GetSubscriptionNumberpatternByName
40
    GetSubscriptionNumberpatterns
41
    GetSubscriptionsWithNumberpattern
42
    ModSubscriptionNumberpattern
43
);
44
use C4::Serials::Frequency qw( GetSubscriptionFrequencies );
45
46
my @NUMBERPATTERN_FIELDS = qw/
47
    label description numberingmethod displayorder
48
    label1 label2 label3 add1 add2 add3 every1 every2 every3
49
    setto1 setto2 setto3 whenmorethan1 whenmorethan2 whenmorethan3
50
    numbering1 numbering2 numbering3 /;
51
52
my $input = CGI->new;
53
my ( $template, $loggedinuser, $cookie, $flags ) = get_template_and_user(
54
    {
55
        template_name => 'serials/subscription-numberpatterns.tt',
56
        query         => $input,
57
        type          => 'intranet',
58
        flagsrequired => { 'serials' => "*" }
59
    }
60
);
61
62
my $op = $input->param('op');
63
64
if ( $op && $op eq 'cud-savenew' ) {
65
    my $label = $input->param('label');
66
    my $numberpattern;
67
    foreach (@NUMBERPATTERN_FIELDS) {
68
        $numberpattern->{$_} = $input->param($_);
69
        if ( defined $numberpattern->{$_} and $numberpattern->{$_} eq '' ) {
70
            $numberpattern->{$_} = undef;
71
        }
72
    }
73
    my $numberpattern2 = GetSubscriptionNumberpatternByName($label);
74
75
    if ( !defined $numberpattern2 ) {
76
        AddSubscriptionNumberpattern($numberpattern);
77
    } else {
78
        $op = 'new';
79
        $template->param( error_existing_numberpattern => 1 );
80
        $template->param(%$numberpattern);
81
    }
82
} elsif ( $op && $op eq 'cud-savemod' ) {
83
    my $id            = $input->param('id');
84
    my $label         = $input->param('label');
85
    my $numberpattern = GetSubscriptionNumberpattern($id);
86
    my $mod_ok        = 1;
87
    if ( $numberpattern->{'label'} ne $label ) {
88
        my $numberpattern2 = GetSubscriptionNumberpatternByName($label);
89
        if ( defined $numberpattern2 && $id != $numberpattern2->{'id'} ) {
90
            $mod_ok = 0;
91
        }
92
    }
93
    if ($mod_ok) {
94
        foreach (@NUMBERPATTERN_FIELDS) {
95
            $numberpattern->{$_} = $input->param($_) || undef;
96
            if ( defined $numberpattern->{$_} and $numberpattern->{$_} eq '' ) {
97
                $numberpattern->{$_} = undef;
98
            }
99
        }
100
        ModSubscriptionNumberpattern($numberpattern);
101
    } else {
102
        $op = 'cud-modify';
103
        $template->param( error_existing_numberpattern => 1 );
104
    }
105
}
106
107
if ( $op && ( $op eq 'new' || $op eq 'modify' ) ) {
108
    if ( $op eq 'modify' ) {
109
        my $id = $input->param('id');
110
        if ( defined $id ) {
111
            my $numberpattern = GetSubscriptionNumberpattern($id);
112
            $template->param(%$numberpattern);
113
        } else {
114
            $op = 'new';
115
        }
116
    }
117
    my @frequencies = GetSubscriptionFrequencies();
118
    my $languages   = [
119
        map {
120
            {
121
                language    => $_->{iso639_2_code},
122
                subtag      => $_->{subtag},
123
                description => $_->{language_description} || $_->{language}
124
            }
125
        } @{ C4::Languages::getAllLanguages() }
126
    ];
127
128
    $template->param(
129
        $op              => 1,
130
        frequencies_loop => \@frequencies,
131
        locales          => $languages,
132
    );
133
    output_html_with_http_headers $input, $cookie, $template->output;
134
    exit;
135
}
136
137
if ( $op && $op eq 'cud-del' ) {
138
    my $id = $input->param('id');
139
    if ($id) {
140
        my $confirm = $input->param('confirm');
141
        if ($confirm) {
142
            DelSubscriptionNumberpattern($id);
143
        } else {
144
            my @subs = GetSubscriptionsWithNumberpattern($id);
145
            if (@subs) {
146
                $template->param(
147
                    id            => $id,
148
                    still_used    => 1,
149
                    subscriptions => \@subs
150
                );
151
            } else {
152
                DelSubscriptionNumberpattern($id);
153
            }
154
        }
155
    }
156
}
157
158
my @numberpatterns_loop = GetSubscriptionNumberpatterns();
159
160
$template->param(
161
    numberpatterns_loop => \@numberpatterns_loop,
162
);
163
164
output_html_with_http_headers $input, $cookie, $template->output;
(-)a/t/db_dependent/Serials.t (-5 / +77 lines)
Lines 5-26 Link Here
5
5
6
use Modern::Perl;
6
use Modern::Perl;
7
7
8
use C4::Serials qw( updateClaim NewSubscription GetSubscription GetSubscriptionHistoryFromSubscriptionId SearchSubscriptions ModSubscription GetExpirationDate GetSerials GetSerialInformation NewIssue AddItem2Serial DelSubscription GetFullSubscription PrepareSerialsData GetSubscriptionsFromBiblionumber ModSubscriptionHistory GetSerials2 GetLatestSerials GetNextSeq GetSeq CountSubscriptionFromBiblionumber ModSerialStatus findSerialsByStatus HasSubscriptionStrictlyExpired HasSubscriptionExpired GetLateOrMissingIssues check_routing addroutingmember GetNextDate );
8
use C4::Serials qw( updateClaim NewSubscription GetSubscription GetSubscriptionHistoryFromSubscriptionId SearchSubscriptions ModSubscription GetExpirationDate GetSerials GetSerialInformation NewIssue AddItem2Serial DelSubscription GetFullSubscription PrepareSerialsData GetSubscriptionsFromBiblionumber ModSubscriptionHistory GetSerials2 GetLatestSerials GetNextSeq GetSeq CountSubscriptionFromBiblionumber ModSerialStatus findSerialsByStatus HasSubscriptionStrictlyExpired HasSubscriptionExpired GetLateOrMissingIssues check_routing addroutingmember GetNextDate GetSeasonsTranslations );
9
use C4::Serials::Frequency;
9
use C4::Serials::Frequency;
10
use C4::Serials::Numberpattern;
10
use C4::Serials::Numberpattern;
11
use C4::Biblio qw( AddBiblio GetMarcFromKohaField );
11
use C4::Biblio qw( AddBiblio GetMarcFromKohaField );
12
use C4::Budgets qw( AddBudgetPeriod AddBudget );
12
use C4::Budgets qw( AddBudgetPeriod AddBudget );
13
use C4::Context;
13
use C4::Items qw( AddItemFromMarc );
14
use C4::Items qw( AddItemFromMarc );
15
use Encode qw( encode );
16
use File::Temp;
14
use Koha::Database;
17
use Koha::Database;
15
use Koha::DateUtils qw( dt_from_string output_pref );
18
use Koha::DateUtils qw( dt_from_string output_pref );
16
use Koha::Acquisition::Booksellers;
19
use Koha::Acquisition::Booksellers;
17
use t::lib::Mocks;
20
use t::lib::Mocks;
18
use t::lib::TestBuilder;
21
use t::lib::TestBuilder;
19
use Test::MockModule;
22
use Test::More tests => 55;
20
use Test::More tests => 54;
21
23
22
BEGIN {
24
BEGIN {
23
    use_ok('C4::Serials', qw( updateClaim NewSubscription GetSubscription GetSubscriptionHistoryFromSubscriptionId SearchSubscriptions ModSubscription GetExpirationDate GetSerials GetSerialInformation NewIssue AddItem2Serial DelSubscription GetFullSubscription PrepareSerialsData GetSubscriptionsFromBiblionumber ModSubscriptionHistory GetSerials2 GetLatestSerials GetNextSeq GetSeq CountSubscriptionFromBiblionumber ModSerialStatus findSerialsByStatus HasSubscriptionStrictlyExpired HasSubscriptionExpired GetLateOrMissingIssues check_routing addroutingmember GetNextDate ));
25
    use_ok('C4::Serials', qw( updateClaim NewSubscription GetSubscription GetSubscriptionHistoryFromSubscriptionId SearchSubscriptions ModSubscription GetExpirationDate GetSerials GetSerialInformation NewIssue AddItem2Serial DelSubscription GetFullSubscription PrepareSerialsData GetSubscriptionsFromBiblionumber ModSubscriptionHistory GetSerials2 GetLatestSerials GetNextSeq GetSeq CountSubscriptionFromBiblionumber ModSerialStatus findSerialsByStatus HasSubscriptionStrictlyExpired HasSubscriptionExpired GetLateOrMissingIssues check_routing addroutingmember GetNextDate GetSeasonsTranslations ));
24
}
26
}
25
27
26
# Auth required for cataloguing plugins
28
# Auth required for cataloguing plugins
Lines 554-560 subtest "NewSubscription|ModSubscription" => sub { Link Here
554
556
555
subtest "_numeration" => sub {
557
subtest "_numeration" => sub {
556
558
557
    plan tests => 6;
559
    plan tests => 8;
558
560
559
    my $s = C4::Serials::_numeration(0, 'monthname', 'cat');
561
    my $s = C4::Serials::_numeration(0, 'monthname', 'cat');
560
    is( $s, "gener" );
562
    is( $s, "gener" );
Lines 569-572 subtest "_numeration" => sub { Link Here
569
    like( $s, qr{^ene\.?} );
571
    like( $s, qr{^ene\.?} );
570
    $s = C4::Serials::_numeration(0, 'monthabrv', 'fr');
572
    $s = C4::Serials::_numeration(0, 'monthabrv', 'fr');
571
    is( $s, "janv." );
573
    is( $s, "janv." );
574
575
    my $translations = {
576
        seasons     => [ 'Spring', 'Summer', 'Fall', 'Winter' ],
577
        seasonsabrv => [ 'Spr', 'Sum', 'Fal', 'Win' ],
578
    };
579
580
    $s = C4::Serials::_numeration( 0, 'season', 'en', $translations );
581
    is( $s, "Spring" );
582
    $s = C4::Serials::_numeration( 0, 'seasonabrv', 'en', $translations );
583
    is( $s, "Spr" );
584
};
585
586
subtest "GetSeasonsTranslations" => sub {
587
588
    plan tests => 8;
589
590
    my @seasons     = qw( Printemps Été Automne Hiver );
591
    my @seasonsabrv = qw( Pri Été Aut Hiv );
592
593
    my $dir      = C4::Context->config('intranetdir') . '/misc/translator/po/';
594
    my $fh       = File::Temp->new( DIR => $dir, SUFFIX => '-staff-prog.po' );
595
    my $filename = $fh->filename;
596
597
    my $txt = '
598
#: koha-tmpl/intranet-tmpl/prog/en/modules/serials/subscription-detail.tt:530
599
#, c-format
600
msgid "Spring"
601
msgstr "Printemps"
602
603
#: koha-tmpl/intranet-tmpl/prog/en/modules/serials/subscription-detail.tt:530
604
#, c-format
605
msgid "Summer"
606
msgstr "Été"
607
608
#: koha-tmpl/intranet-tmpl/prog/en/modules/serials/subscription-detail.tt:530
609
#, c-format
610
msgid "Fall"
611
msgstr "Automne"
612
613
#: koha-tmpl/intranet-tmpl/prog/en/modules/serials/subscription-detail.tt:530
614
#, c-format
615
msgid "Winter"
616
msgstr "Hiver"
617
618
#: koha-tmpl/intranet-tmpl/prog/en/modules/admin/searchengine/elasticsearch/mappings.tt:208
619
#: koha-tmpl/intranet-tmpl/prog/en/modules/admin/searchengine/elasticsearch/mappings.tt:210
620
#, c-format
621
msgid "Sum"
622
msgstr "Total"
623
624
#: koha-tmpl/intranet-tmpl/prog/en/modules/serials/serials-collection.tt:248
625
#: koha-tmpl/intranet-tmpl/prog/en/modules/serials/showpredictionpattern.tt:43
626
#, c-format
627
msgid ""
628
"%s %sSpring%s %s %sSummer%s %s %sFall%s %s %sWinter%s %s %sSpr%s %s %sSum%s "
629
"%s %sFal%s %s %sWin%s %s %s %s "
630
msgstr ""
631
"%s %sPrintemps%s %s %sÉté%s %s %sAutomne%s %s %sHiver%s %s %sPri%s %s %sÉté"
632
"%s %s %sAut%s %s %sHiv%s %s %s %s "
633
    ';
634
635
    print $fh encode( 'utf-8', $txt );
636
    close($fh);
637
638
    my $translations = GetSeasonsTranslations( 1, 1, $filename =~ s/($dir|-staff-prog.po)//gr );
639
640
    for my $idx ( 0 .. $#{ $translations->{seasons} } ) {
641
        is( $translations->{seasons}->[$idx],     $seasons[$idx] );
642
        is( $translations->{seasonsabrv}->[$idx], $seasonsabrv[$idx] );
643
    }
572
};
644
};
(-)a/t/db_dependent/Serials.t.tdy (+738 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
#
3
# This Koha test module is a stub!
4
# Add more tests here!!!
5
6
use Modern::Perl;
7
8
use C4::Serials
9
    qw( updateClaim NewSubscription GetSubscription GetSubscriptionHistoryFromSubscriptionId SearchSubscriptions ModSubscription GetExpirationDate GetSerials GetSerialInformation NewIssue AddItem2Serial DelSubscription GetFullSubscription PrepareSerialsData GetSubscriptionsFromBiblionumber ModSubscriptionHistory GetSerials2 GetLatestSerials GetNextSeq GetSeq CountSubscriptionFromBiblionumber ModSerialStatus findSerialsByStatus HasSubscriptionStrictlyExpired HasSubscriptionExpired GetLateOrMissingIssues check_routing addroutingmember GetNextDate GetSeasonsTranslations );
10
use C4::Serials::Frequency;
11
use C4::Serials::Numberpattern;
12
use C4::Biblio qw( AddBiblio GetMarcFromKohaField );
13
use C4::Budgets qw( AddBudgetPeriod AddBudget );
14
use C4::Context;
15
use C4::Items qw( AddItemFromMarc );
16
use Encode qw( encode );
17
use File::Temp;
18
use Koha::Database;
19
use Koha::DateUtils qw( dt_from_string output_pref );
20
use Koha::Acquisition::Booksellers;
21
use t::lib::Mocks;
22
use t::lib::TestBuilder;
23
use Test::More tests => 55;
24
25
BEGIN {
26
    use_ok(
27
        'C4::Serials',
28
        qw( updateClaim NewSubscription GetSubscription GetSubscriptionHistoryFromSubscriptionId SearchSubscriptions ModSubscription GetExpirationDate GetSerials GetSerialInformation NewIssue AddItem2Serial DelSubscription GetFullSubscription PrepareSerialsData GetSubscriptionsFromBiblionumber ModSubscriptionHistory GetSerials2 GetLatestSerials GetNextSeq GetSeq CountSubscriptionFromBiblionumber ModSerialStatus findSerialsByStatus HasSubscriptionStrictlyExpired HasSubscriptionExpired GetLateOrMissingIssues check_routing addroutingmember GetNextDate GetSeasonsTranslations )
29
    );
30
}
31
32
# Auth required for cataloguing plugins
33
my $mAuth = Test::MockModule->new('C4::Auth');
34
$mAuth->mock( 'check_cookie_auth', sub { return ('ok') } );
35
36
my $schema = Koha::Database->new->schema;
37
$schema->storage->txn_begin;
38
my $dbh = C4::Context->dbh;
39
40
$dbh->do('DELETE FROM subscription');
41
42
my $builder = t::lib::TestBuilder->new();
43
44
# This could/should be used for all untested methods
45
my @methods = ('updateClaim');
46
can_ok( 'C4::Serials', @methods );
47
48
$dbh->do(
49
    q|UPDATE marc_subfield_structure SET value_builder="callnumber.pl" where kohafield="items.itemcallnumber" and frameworkcode=''|
50
);
51
52
my $bookseller = Koha::Acquisition::Bookseller->new(
53
    {
54
        name     => "my vendor",
55
        address1 => "bookseller's address",
56
        phone    => "0123456",
57
        active   => 1
58
    }
59
);
60
61
my ( $biblionumber, $biblioitemnumber ) = AddBiblio( MARC::Record->new, '' );
62
63
my $bpid = AddBudgetPeriod(
64
    {
65
        budget_period_startdate   => '2015-01-01',
66
        budget_period_enddate     => '2015-12-31',
67
        budget_period_description => "budget desc"
68
    }
69
);
70
71
my $budget_id = AddBudget(
72
    {
73
        budget_code      => "ABCD",
74
        budget_amount    => "123.132",
75
        budget_name      => "Périodiques",
76
        budget_notes     => "This is a note",
77
        budget_period_id => $bpid
78
    }
79
);
80
81
my $frequency_id = AddSubscriptionFrequency( { description => "Test frequency 1" } );
82
my $pattern_id   = AddSubscriptionNumberpattern(
83
    {
84
        label           => 'Test numberpattern 1',
85
        description     => 'Description for numberpattern 1',
86
        numberingmethod => '{X}',
87
        label1          => q{},
88
        add1            => 1,
89
        every1          => 1,
90
        every1          => 1,
91
        numbering1      => 1,
92
        whenmorethan1   => 1,
93
    }
94
);
95
96
my $notes          = "a\nnote\non\nseveral\nlines";
97
my $internalnotes  = 'intnotes';
98
my $ccode          = 'FIC';
99
my $subscriptionid = NewSubscription(
100
    undef,
101
    "",
102
    undef,
103
    undef,
104
    $budget_id,
105
    $biblionumber,
106
    '2013-01-01',
107
    $frequency_id,
108
    undef,
109
    undef,
110
    undef,
111
    undef,
112
    undef,
113
    undef,
114
    undef,
115
    undef,
116
    undef,
117
    1,
118
    $notes,
119
    undef,
120
    '2013-01-01',
121
    undef,
122
    $pattern_id,
123
    undef,
124
    undef,
125
    0,
126
    $internalnotes,
127
    0,
128
    undef,
129
    undef,
130
    0,
131
    undef,
132
    '2013-12-31', 0,
133
    undef,
134
    undef,
135
    undef,
136
    $ccode
137
);
138
139
NewSubscription(
140
    undef,
141
    "",
142
    undef,
143
    undef,
144
    $budget_id,
145
    $biblionumber,
146
    '2013-01-02',
147
    $frequency_id,
148
    undef,
149
    undef,
150
    undef,
151
    undef,
152
    undef,
153
    undef,
154
    undef,
155
    undef,
156
    undef,
157
    1,
158
    $notes,
159
    undef,
160
    '2013-01-02',
161
    undef,
162
    $pattern_id,
163
    undef,
164
    undef,
165
    0,
166
    $internalnotes,
167
    0,
168
    undef,
169
    undef,
170
    0,
171
    undef,
172
    '2013-12-31',
173
    0,
174
    undef,
175
    undef,
176
    undef,
177
    $ccode
178
);
179
180
my $subscriptioninformation = GetSubscription($subscriptionid);
181
182
is( $subscriptioninformation->{notes},         $notes,         'NewSubscription should set notes' );
183
is( $subscriptioninformation->{internalnotes}, $internalnotes, 'NewSubscription should set internalnotes' );
184
is( $subscriptioninformation->{ccode},         $ccode,         'NewSubscription should set ccode' );
185
186
my $subscription_history = C4::Serials::GetSubscriptionHistoryFromSubscriptionId($subscriptionid);
187
is( $subscription_history->{opacnote}, undef, 'NewSubscription should not set subscriptionhistory opacnotes' );
188
is(
189
    $subscription_history->{librariannote}, undef,
190
    'NewSubscription should not set subscriptionhistory librariannotes'
191
);
192
193
my @subscriptions = SearchSubscriptions( { string => $subscriptioninformation->{bibliotitle}, orderby => 'title' } );
194
isa_ok( \@subscriptions, 'ARRAY' );
195
196
@subscriptions = SearchSubscriptions( { issn => $subscriptioninformation->{issn}, orderby => 'title' } );
197
isa_ok( \@subscriptions, 'ARRAY' );
198
199
@subscriptions = SearchSubscriptions( { ean => $subscriptioninformation->{ean}, orderby => 'title' } );
200
isa_ok( \@subscriptions, 'ARRAY' );
201
202
@subscriptions = SearchSubscriptions( { biblionumber => $subscriptioninformation->{bibnum}, orderby => 'title' } );
203
isa_ok( \@subscriptions, 'ARRAY' );
204
205
@subscriptions = SearchSubscriptions( {} );
206
is(
207
    @subscriptions,
208
    2,
209
    'SearchSubscriptions returned the expected number of subscriptions when results_limit is not set'
210
);
211
212
@subscriptions = SearchSubscriptions( {}, { results_limit => 1 } );
213
is(
214
    @subscriptions,
215
    1,
216
    'SearchSubscriptions returned only one subscription when results_limit is set to "1"'
217
);
218
219
my $frequency = GetSubscriptionFrequency( $subscriptioninformation->{periodicity} );
220
my $old_frequency;
221
if ( not $frequency->{unit} ) {
222
    $old_frequency                              = $frequency->{id};
223
    $frequency->{unit}                          = "month";
224
    $frequency->{unitsperissue}                 = 1;
225
    $frequency->{issuesperunit}                 = 1;
226
    $frequency->{description}                   = "Frequency created by t/db_dependant/Serials.t";
227
    $subscriptioninformation->{periodicity}     = AddSubscriptionFrequency($frequency);
228
    $subscriptioninformation->{serialsadditems} = 1;
229
    $subscriptioninformation->{ccode}           = 'NFIC';
230
231
    ModSubscription(
232
        @$subscriptioninformation{
233
            qw(
234
                librarian branchcode aqbooksellerid cost aqbudgetid startdate
235
                periodicity firstacquidate irregularity numberpattern locale
236
                numberlength weeklength monthlength lastvalue1 innerloop1 lastvalue2
237
                innerloop2 lastvalue3 innerloop3 status biblionumber callnumber notes
238
                letter manualhistory internalnotes serialsadditems staffdisplaycount
239
                opacdisplaycount graceperiod location enddate subscriptionid
240
                skip_serialseq itemtype previousitemtype mana_id ccode
241
            )
242
        }
243
    );
244
}
245
my $expirationdate = GetExpirationDate($subscriptionid);
246
ok( $expirationdate, "expiration date is not NULL" );
247
248
# Check ModSubscription has updated the ccode
249
my $subscriptioninformation2 = GetSubscription($subscriptionid);
250
is( $subscriptioninformation2->{ccode}, 'NFIC', 'ModSubscription should update ccode' );
251
252
ok( C4::Serials::GetSubscriptionHistoryFromSubscriptionId($subscriptionid), 'test getting history from sub-scription' );
253
254
my ( $serials_count, @serials ) = GetSerials($subscriptionid);
255
ok( $serials_count > 0, 'Subscription has at least one serial' );
256
my $serial = $serials[0];
257
258
isa_ok( C4::Serials::GetSerialInformation( $serial->{serialid} ), 'HASH', 'test getting Serial Information' );
259
260
subtest 'Values should not be erased on editing' => sub {
261
262
    plan tests => 1;
263
264
    my $biblio       = $builder->build_sample_biblio();
265
    my $biblionumber = $biblio->biblionumber;
266
    my ( $icn_tag, $icn_sf ) = GetMarcFromKohaField('items.itemcallnumber');
267
    my ( $it_tag, $it_sf )   = GetMarcFromKohaField('items.itype');
268
269
    my $itemtype       = $builder->build( { source => 'Itemtype' } )->{itemtype};
270
    my $itemcallnumber = 'XXXmy itemcallnumberXXX';
271
272
    my $item_record = MARC::Record->new;
273
274
    $item_record->append_fields(
275
        MARC::Field->new( '080', '', '', "a" => "default" ),
276
        MARC::Field->new(
277
            $icn_tag, '', '',
278
            $icn_sf => $itemcallnumber,
279
            $it_sf  => $itemtype
280
        )
281
    );
282
    my ( undef, undef, $itemnumber ) = C4::Items::AddItemFromMarc( $item_record, $biblionumber );
283
    my $serialid = C4::Serials::NewIssue(
284
        "serialseq", $subscriptionid, $biblionumber,
285
        1, undef, undef, "publisheddatetext", "notes", "routingnotes"
286
    );
287
    C4::Serials::AddItem2Serial( $serialid, $itemnumber );
288
    my $serial_info = C4::Serials::GetSerialInformation($serialid);
289
    my ($itemcallnumber_info) =
290
        grep { $_->{kohafield} eq 'items.itemcallnumber' } @{ $serial_info->{items}[0]->{iteminformation} };
291
    like( $itemcallnumber_info->{marc_value}, qr|value="$itemcallnumber"| );
292
};
293
294
# Delete created frequency
295
if ($old_frequency) {
296
    my $freq_to_delete = $subscriptioninformation->{periodicity};
297
    $subscriptioninformation->{periodicity} = $old_frequency;
298
299
    ModSubscription(
300
        @$subscriptioninformation{
301
            qw(
302
                librarian branchcode aqbooksellerid cost aqbudgetid startdate
303
                periodicity firstacquidate irregularity numberpattern locale
304
                numberlength weeklength monthlength lastvalue1 innerloop1 lastvalue2
305
                innerloop2 lastvalue3 innerloop3 status biblionumber callnumber notes
306
                letter manualhistory internalnotes serialsadditems staffdisplaycount
307
                opacdisplaycount graceperiod location enddate subscriptionid
308
                skip_serialseq
309
            )
310
        }
311
    );
312
313
    DelSubscriptionFrequency($freq_to_delete);
314
}
315
316
# Test calling subs without parameters
317
is( C4::Serials::AddItem2Serial(),      undef, 'test adding item to serial' );
318
is( C4::Serials::GetFullSubscription(), undef, 'test getting full subscription' );
319
is( C4::Serials::PrepareSerialsData(),  undef, 'test preparing serial data' );
320
321
subtest 'GetSubscriptionsFromBiblionumber' => sub {
322
    plan tests => 4;
323
324
    is(
325
        C4::Serials::GetSubscriptionsFromBiblionumber(),
326
        undef, 'test getting subscriptions form biblio number'
327
    );
328
329
    my $subscriptions = C4::Serials::GetSubscriptionsFromBiblionumber($biblionumber);
330
    ModSubscriptionHistory(
331
        $subscriptions->[0]->{subscriptionid},
332
        undef, undef, $notes, $notes, $notes
333
    );
334
335
    $subscriptions = C4::Serials::GetSubscriptionsFromBiblionumber($biblionumber);
336
    is(
337
        $subscriptions->[0]->{opacnote}, $notes,
338
        'GetSubscriptionsFromBiblionumber should have returned the opacnote as it is in DB, ie. without br tags'
339
    );
340
    is(
341
        $subscriptions->[0]->{recievedlist}, $notes,
342
        'GetSubscriptionsFromBiblionumber should have returned recievedlist as it is in DB, ie. without br tags'
343
    );
344
    is(
345
        $subscriptions->[0]->{missinglist}, $notes,
346
        'GetSubscriptionsFromBiblionumber should have returned missinglist as it is in DB, ie. without br tags'
347
    );
348
};
349
350
is( C4::Serials::GetSerials(),  undef, 'test getting serials when you enter nothing' );
351
is( C4::Serials::GetSerials2(), undef, 'test getting serials when you enter nothing' );
352
353
is( C4::Serials::GetLatestSerials(), undef, 'test getting lastest serials' );
354
355
is( C4::Serials::GetNextSeq(), undef, 'test getting next seq when you enter nothing' );
356
357
is( C4::Serials::GetSeq(), undef, 'test getting seq when you enter nothing' );
358
359
is( C4::Serials::CountSubscriptionFromBiblionumber(), undef, 'test counting subscription when nothing is entered' );
360
361
is( C4::Serials::ModSubscriptionHistory(), undef, 'test modding subscription history' );
362
363
is( C4::Serials::ModSerialStatus(), undef, 'test modding serials' );
364
365
is( C4::Serials::findSerialsByStatus(), 0, 'test finding serial by status with no parameters' );
366
367
is( C4::Serials::NewIssue(), undef, 'test getting 0 when nothing is entered' );
368
369
is( C4::Serials::HasSubscriptionStrictlyExpired(), undef, 'test if the subscriptions has expired' );
370
is( C4::Serials::HasSubscriptionExpired(),         undef, 'test if the subscriptions has expired' );
371
372
is( C4::Serials::GetLateOrMissingIssues(), undef, 'test getting last or missing issues' );
373
374
subtest 'test_updateClaim' => sub {
375
    plan tests => 11;
376
377
    my $today = output_pref( { dt => dt_from_string, dateonly => 1 } );
378
379
    # Given ... nothing much
380
    # When ... Then ...
381
    my $result_0 = C4::Serials::updateClaim(undef);
382
    is( $result_0, undef, 'Got the expected undef from update claim with nothin' );
383
384
    # Given ... 3 serial. 2 of them updated.
385
    my $claimdate_1   = dt_from_string('2001-01-13');    # arbitrary date some time in the past.
386
    my $claim_count_1 = 5;
387
    my $biblio        = $builder->build_sample_biblio;
388
    my $serial1       = $builder->build_object(
389
        {
390
            class => 'Koha::Serials',
391
            value => {
392
                serialseq      => 'serialseq',
393
                subscriptionid => $subscriptionid,
394
                status         => 3,
395
                biblionumber   => $biblio->biblionumber,
396
                claimdate      => $claimdate_1,
397
                claims_count   => $claim_count_1,
398
            }
399
        }
400
    );
401
    my $serial2 = $builder->build_object(
402
        {
403
            class => 'Koha::Serials',
404
            value => {
405
                serialseq      => 'serialseq',
406
                subscriptionid => $subscriptionid,
407
                status         => 3,
408
                biblionumber   => $biblio->biblionumber,
409
                claimdate      => $claimdate_1,
410
                claims_count   => $claim_count_1,
411
            }
412
        }
413
    );
414
    my $serial3 = $builder->build_object(
415
        {
416
            class => 'Koha::Serials',
417
            value => {
418
                serialseq      => 'serialseq',
419
                subscriptionid => $subscriptionid,
420
                status         => 3,
421
                biblionumber   => $biblio->biblionumber,
422
                claimdate      => $claimdate_1,
423
                claims_count   => $claim_count_1,
424
            }
425
        }
426
    );
427
428
    # When ...
429
    my $result_1 = C4::Serials::updateClaim( [ $serial1->serialid, $serial2->serialid ] );
430
431
    # Then ...
432
    is( $result_1, 2, 'Got the expected 2 from update claim with 2 serial ids' );
433
434
    my @late_or_missing_issues_1_0 = C4::Serials::GetLateOrMissingIssues( undef, $serial1->serialid );
435
    is(
436
        output_pref( { str => $late_or_missing_issues_1_0[0]->{claimdate}, dateonly => 1 } ), $today,
437
        'Got the expected first different claim date from update claim'
438
    );
439
    is(
440
        $late_or_missing_issues_1_0[0]->{claims_count}, $claim_count_1 + 1,
441
        'Got the expected first claim count from update claim'
442
    );
443
    is( $late_or_missing_issues_1_0[0]->{status}, 7, 'Got the expected first claim status from update claim' );
444
445
    my @late_or_missing_issues_1_1 = C4::Serials::GetLateOrMissingIssues( undef, $serial2->serialid );
446
    is(
447
        output_pref( { str => $late_or_missing_issues_1_1[0]->{claimdate}, dateonly => 1 } ), $today,
448
        'Got the expected second different claim date from update claim'
449
    );
450
    is(
451
        $late_or_missing_issues_1_1[0]->{claims_count}, $claim_count_1 + 1,
452
        'Got the expected second claim count from update claim'
453
    );
454
    is( $late_or_missing_issues_1_1[0]->{status}, 7, 'Got the expected second claim status from update claim' );
455
456
    my @late_or_missing_issues_1_2 = C4::Serials::GetLateOrMissingIssues( undef, $serial3->serialid );
457
    is(
458
        output_pref( { str => $late_or_missing_issues_1_2[0]->{claimdate}, dateonly => 1 } ),
459
        output_pref( { dt  => $claimdate_1,                                dateonly => 1 } ),
460
        'Got the expected unchanged claim date from update claim'
461
    );
462
    is(
463
        $late_or_missing_issues_1_2[0]->{claims_count}, $claim_count_1,
464
        'Got the expected unchanged claim count from update claim'
465
    );
466
    is( $late_or_missing_issues_1_2[0]->{status}, 3, 'Got the expected unchanged claim status from update claim' );
467
};
468
469
is( C4::Serials::check_routing(),                undef, 'test checking route' );
470
is( C4::Serials::check_routing($subscriptionid), 0,     'There should not have any routing list for the subscription' );
471
472
# TODO really test this check_routing subroutine
473
474
is( C4::Serials::addroutingmember(), undef, 'test adding route member' );
475
476
# Unit tests for statuses management (Bug 11689)
477
$subscriptionid = NewSubscription(
478
    undef,        "",            undef, undef,          $budget_id, $biblionumber,
479
    '2013-01-01', $frequency_id, undef, undef,          undef,
480
    undef,        undef,         undef, undef,          undef, undef,
481
    1,            $notes,        undef, '2013-01-01',   undef, $pattern_id,
482
    undef,        undef,         0,     $internalnotes, 0,
483
    undef,        undef,         0,     undef,          '2013-12-31', 0
484
);
485
my $total_issues;
486
( $total_issues, @serials ) = C4::Serials::GetSerials($subscriptionid);
487
is( $total_issues, 1, "NewSubscription created a first serial" );
488
is( @serials,      1, "GetSerials returns the serial" );
489
my $subscription = C4::Serials::GetSubscription($subscriptionid);
490
my $pattern      = C4::Serials::Numberpattern::GetSubscriptionNumberpattern( $subscription->{numberpattern} );
491
( $total_issues, @serials ) = C4::Serials::GetSerials($subscriptionid);
492
my $publisheddate = output_pref( { dt => dt_from_string, dateformat => 'iso', dateonly => 1 } );
493
( $total_issues, @serials ) = C4::Serials::GetSerials($subscriptionid);
494
$frequency = C4::Serials::Frequency::GetSubscriptionFrequency( $subscription->{periodicity} );
495
my $nextpublisheddate = C4::Serials::GetNextDate( $subscription, $publisheddate, $frequency, 1 );
496
my @statuses          = qw( 2 2 3 3 3 3 3 4 4 41 42 43 44 5 );
497
498
# Add 14 serials
499
my $counter = 0;
500
for my $status (@statuses) {
501
    my $serialseq = "No." . $counter;
502
    my ($expected_serial) = GetSerials2( $subscriptionid, [1] );
503
    C4::Serials::ModSerialStatus(
504
        $expected_serial->{serialid}, $serialseq, $publisheddate, $publisheddate,
505
        $publisheddate, $statuses[$counter], 'an useless note'
506
    );
507
    $counter++;
508
}
509
510
# Here we have 15 serials with statuses : 2*2 + 5*3 + 2*4 + 1*41 + 1*42 + 1*43 + 1*44 + 1*5 + 1*1
511
my @serialsByStatus = C4::Serials::findSerialsByStatus( 2, $subscriptionid );
512
is( @serialsByStatus, 2, "findSerialsByStatus returns all serials with chosen status" );
513
( $total_issues, @serials ) = C4::Serials::GetSerials($subscriptionid);
514
is( $total_issues, @statuses + 1, "GetSerials returns total_issues" );
515
my @arrived_missing = map {
516
    my $status = $_->{status};
517
    ( grep { /^$status$/ } qw( 2 4 41 42 43 44 5 ) ) ? $_ : ()
518
} @serials;
519
my @others = map {
520
    my $status = $_->{status};
521
    ( grep { /^$status$/ } qw( 2 4 41 42 43 44 5 ) ) ? () : $_
522
} @serials;
523
is( @arrived_missing, 5, "GetSerials returns 5 arrived/missing by default" );
524
is( @others,          6, "GetSerials returns all serials not arrived and not missing" );
525
526
( $total_issues, @serials ) = C4::Serials::GetSerials( $subscriptionid, 10 );
527
is( $total_issues, @statuses + 1, "GetSerials returns total_issues" );
528
@arrived_missing = map {
529
    my $status = $_->{status};
530
    ( grep { /^$status$/ } qw( 2 4 41 42 43 44 5 ) ) ? $_ : ()
531
} @serials;
532
@others = map {
533
    my $status = $_->{status};
534
    ( grep { /^$status$/ } qw( 2 4 41 42 43 44 5 ) ) ? () : $_
535
} @serials;
536
is( @arrived_missing, 9, "GetSerials returns all arrived/missing if count given" );
537
is( @others,          6, "GetSerials returns all serials not arrived and not missing if count given" );
538
539
$subscription = C4::Serials::GetSubscription($subscriptionid);    # Retrieve the updated subscription
540
541
my @serialseqs;
542
for my $am (@arrived_missing) {
543
    if ( grep { /^$am->{status}$/ } qw( 4 41 42 43 44 ) ) {
544
        push @serialseqs, $am->{serialseq};
545
    } elsif ( grep { /^$am->{status}$/ } qw( 5 ) ) {
546
        push @serialseqs, 'not issued ' . $am->{serialseq};
547
    }
548
}
549
is(
550
    $subscription->{missinglist}, join( '; ', @serialseqs ),
551
    "subscription missinglist is updated after ModSerialStatus"
552
);
553
554
subtest "Do not generate an expected if one already exists" => sub {
555
    plan tests => 2;
556
    my ($expected_serial) = GetSerials2( $subscriptionid, [1] );
557
558
    #Find serialid for serial with status Expected
559
    my $serialexpected = ( C4::Serials::findSerialsByStatus( 1, $subscriptionid ) )[0];
560
561
    #delete serial with status Expected
562
    C4::Serials::ModSerialStatus(
563
        $serialexpected->{serialid}, $serialexpected->{serialseq}, $publisheddate,
564
        $publisheddate, $publisheddate, '1', 'an useless note'
565
    );
566
    @serialsByStatus = C4::Serials::findSerialsByStatus( 1, $subscriptionid );
567
    is( @serialsByStatus, 1, "ModSerialStatus delete corectly serial expected and create another if not exist" );
568
569
    # add 1 serial with status=Expected 1
570
    C4::Serials::ModSerialStatus(
571
        $expected_serial->{serialid}, 'NO.20', $publisheddate, $publisheddate,
572
        $publisheddate, '1', 'an useless note'
573
    );
574
575
    #Now we have two serials it have status expected
576
    #put status delete for last serial
577
    C4::Serials::ModSerialStatus(
578
        $serialexpected->{serialid}, $serialexpected->{serialseq}, $publisheddate,
579
        $publisheddate, $publisheddate, '1', 'an useless note'
580
    );
581
582
    #try if create or not another serial with status is expected
583
    @serialsByStatus = C4::Serials::findSerialsByStatus( 1, $subscriptionid );
584
    is( @serialsByStatus, 1, "ModSerialStatus delete corectly serial expected and not create another if exists" );
585
};
586
587
subtest "PreserveSerialNotes preference" => sub {
588
    plan tests => 2;
589
    my ($expected_serial) = GetSerials2( $subscriptionid, [1] );
590
591
    t::lib::Mocks::mock_preference( 'PreserveSerialNotes', 1 );
592
593
    C4::Serials::ModSerialStatus(
594
        $expected_serial->{serialid}, 'NO.20', $publisheddate, $publisheddate,
595
        $publisheddate, '1', 'an useless note'
596
    );
597
    @serialsByStatus = C4::Serials::findSerialsByStatus( 1, $subscriptionid );
598
    is( $serialsByStatus[0]->{note}, $expected_serial->{note}, "note passed through if supposed to" );
599
600
    t::lib::Mocks::mock_preference( 'PreserveSerialNotes', 0 );
601
    $expected_serial = $serialsByStatus[0];
602
    C4::Serials::ModSerialStatus(
603
        $expected_serial->{serialid}, 'NO.20', $publisheddate, $publisheddate,
604
        $publisheddate, '1', 'an useless note'
605
    );
606
    is( $serialsByStatus[0]->{note}, $expected_serial->{note}, "note not passed through if not supposed to" );
607
608
};
609
610
subtest "NewSubscription|ModSubscription" => sub {
611
    plan tests => 4;
612
    my $subscriptionid = NewSubscription(
613
        "",           "",            "", "",             $budget_id, $biblionumber,
614
        '2013-01-01', $frequency_id, "", "",             "",
615
        "",           "",            "", "",             "", "",
616
        1,            $notes,        "", '2013-01-01',   "", $pattern_id,
617
        "",           "",            0,  $internalnotes, 0,
618
        "",           "",            0,  "",             '2013-12-31', 0
619
    );
620
    ok( $subscriptionid, "Sending empty string instead of undef to reflect use of the interface" );
621
622
    my $subscription = Koha::Subscriptions->find($subscriptionid);
623
    my $serials      = Koha::Serials->search( { subscriptionid => $subscriptionid } );
624
    is( $serials->count, 1, "NewSubscription created a first serial" );
625
626
    my $biblio_2          = $builder->build_sample_biblio;
627
    my $subscription_info = $subscription->unblessed;
628
    $subscription_info->{biblionumber} = $biblio_2->biblionumber;
629
    ModSubscription(
630
        @$subscription_info{
631
            qw(
632
                librarian branchcode aqbooksellerid cost aqbudgetid startdate
633
                periodicity firstacquidate irregularity numberpattern locale
634
                numberlength weeklength monthlength lastvalue1 innerloop1 lastvalue2
635
                innerloop2 lastvalue3 innerloop3 status biblionumber callnumber notes
636
                letter manualhistory internalnotes serialsadditems staffdisplaycount
637
                opacdisplaycount graceperiod location enddate subscriptionid
638
                skip_serialseq
639
            )
640
        }
641
    );
642
643
    $serials = Koha::Serials->search( { subscriptionid => $subscriptionid } );
644
    is( $serials->count, 1, "Still only one serial" );
645
    is(
646
        $serials->next->biblionumber, $biblio_2->biblionumber,
647
        'ModSubscription should have updated serial.biblionumber'
648
    );
649
};
650
651
subtest "_numeration" => sub {
652
653
    plan tests => 8;
654
655
    my $s = C4::Serials::_numeration( 0, 'monthname', 'cat' );
656
    is( $s, "gener" );
657
    $s = C4::Serials::_numeration( 0, 'monthname', 'es' );
658
    is( $s, "enero" );
659
    $s = C4::Serials::_numeration( 0, 'monthname', 'fr' );
660
    is( $s, "janvier" );
661
662
    $s = C4::Serials::_numeration( 0, 'monthabrv', 'cat' );
663
    is( $s, "de gen." );
664
    $s = C4::Serials::_numeration( 0, 'monthabrv', 'es' );
665
    like( $s, qr{^ene\.?} );
666
    $s = C4::Serials::_numeration( 0, 'monthabrv', 'fr' );
667
    is( $s, "janv." );
668
669
    my $translations = {
670
        seasons     => [ 'Spring', 'Summer', 'Fall', 'Winter' ],
671
        seasonsabrv => [ 'Spr',    'Sum',    'Fal',  'Win' ],
672
    };
673
674
    $s = C4::Serials::_numeration( 0, 'season', 'en', $translations );
675
    is( $s, "Spring" );
676
    $s = C4::Serials::_numeration( 0, 'seasonabrv', 'en', $translations );
677
    is( $s, "Spr" );
678
};
679
680
subtest "GetSeasonsTranslations" => sub {
681
682
    plan tests => 8;
683
684
    my @seasons     = qw( Printemps Été Automne Hiver );
685
    my @seasonsabrv = qw( Pri Été Aut Hiv );
686
687
    my $dir      = C4::Context->config('intranetdir') . '/misc/translator/po/';
688
    my $fh       = File::Temp->new( DIR => $dir, SUFFIX => '-staff-prog.po' );
689
    my $filename = $fh->filename;
690
691
    my $txt = '
692
#: koha-tmpl/intranet-tmpl/prog/en/modules/serials/subscription-detail.tt:530
693
#, c-format
694
msgid "Spring"
695
msgstr "Printemps"
696
697
#: koha-tmpl/intranet-tmpl/prog/en/modules/serials/subscription-detail.tt:530
698
#, c-format
699
msgid "Summer"
700
msgstr "Été"
701
702
#: koha-tmpl/intranet-tmpl/prog/en/modules/serials/subscription-detail.tt:530
703
#, c-format
704
msgid "Fall"
705
msgstr "Automne"
706
707
#: koha-tmpl/intranet-tmpl/prog/en/modules/serials/subscription-detail.tt:530
708
#, c-format
709
msgid "Winter"
710
msgstr "Hiver"
711
712
#: koha-tmpl/intranet-tmpl/prog/en/modules/admin/searchengine/elasticsearch/mappings.tt:208
713
#: koha-tmpl/intranet-tmpl/prog/en/modules/admin/searchengine/elasticsearch/mappings.tt:210
714
#, c-format
715
msgid "Sum"
716
msgstr "Total"
717
718
#: koha-tmpl/intranet-tmpl/prog/en/modules/serials/serials-collection.tt:248
719
#: koha-tmpl/intranet-tmpl/prog/en/modules/serials/showpredictionpattern.tt:43
720
#, c-format
721
msgid ""
722
"%s %sSpring%s %s %sSummer%s %s %sFall%s %s %sWinter%s %s %sSpr%s %s %sSum%s "
723
"%s %sFal%s %s %sWin%s %s %s %s "
724
msgstr ""
725
"%s %sPrintemps%s %s %sÉté%s %s %sAutomne%s %s %sHiver%s %s %sPri%s %s %sÉté"
726
"%s %s %sAut%s %s %sHiv%s %s %s %s "
727
    ';
728
729
    print $fh encode( 'utf-8', $txt );
730
    close($fh);
731
732
    my $translations = GetSeasonsTranslations( 1, 1, $filename =~ s/($dir|-staff-prog.po)//gr );
733
734
    for my $idx ( 0 .. $#{ $translations->{seasons} } ) {
735
        is( $translations->{seasons}->[$idx],     $seasons[$idx] );
736
        is( $translations->{seasonsabrv}->[$idx], $seasonsabrv[$idx] );
737
    }
738
};
(-)a/t/db_dependent/Serials/GetNextSeq.t (+1 lines)
Lines 143-148 $subscription = { Link Here
143
    irregularity => '3;4;6',
143
    irregularity => '3;4;6',
144
    countissuesperunit => 1,
144
    countissuesperunit => 1,
145
    locale => 'C',
145
    locale => 'C',
146
    translations => { seasons => [ 'Spring', 'Summer', 'Fall', 'Winter' ] },
146
};
147
};
147
$pattern = {
148
$pattern = {
148
             add1 =>  1,          add2 =>  0,          add3 =>  0,
149
             add1 =>  1,          add2 =>  0,          add3 =>  0,
(-)a/t/db_dependent/Serials/GetNextSeq.t.tdy (-1 / +279 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/perl
2
3
use C4::Context;
4
use Test::More tests => 32;
5
use Modern::Perl;
6
use Koha::Database;
7
8
my $schema = Koha::Database->new->schema;
9
$schema->storage->txn_begin;
10
11
use C4::Serials::Frequency;
12
use C4::Serials qw( GetNextDate GetNextSeq );
13
14
my $frequency = {
15
    description   => "One issue per day",
16
    unit          => 'day',
17
    issuesperunit => 1,
18
    unitsperissue => 1,
19
};
20
my $id = AddSubscriptionFrequency($frequency);
21
22
# TEST CASE 1 - 1 variable, from 1 to 4
23
my $pattern = {
24
    add1            => 1, add2          => 0, add3          => 0,
25
    every1          => 1, every2        => 0, every3        => 0,
26
    whenmorethan1   => 4, whenmorethan2 => 0, whenmorethan3 => 0,
27
    setto1          => 1, setto2        => 0, setto3        => 0,
28
    numberingmethod => 'X: {X}',
29
    numbering1      => '',
30
    numbering2      => '',
31
    numbering3      => '',
32
};
33
34
my $subscription = {
35
    periodicity        => $id,
36
    firstacquidate     => '1970-01-01',
37
    lastvalue1         => 1, lastvalue2 => 1, lastvalue3 => 1,
38
    innerloop1         => 0, innerloop2 => 0, innerloop3 => 0,
39
    skip_serialseq     => 1,
40
    irregularity       => '3;5',
41
    countissuesperunit => 1,
42
    locale             => 'en',
43
};
44
my $publisheddate = $subscription->{firstacquidate};
45
46
my $seq = _next_seq( $subscription, $pattern, $frequency, $publisheddate );
47
is( $seq, 'X: 2' );
48
$publisheddate = GetNextDate( $subscription, $publisheddate, $frequency );
49
$seq           = _next_seq( $subscription, $pattern, $frequency, $publisheddate );
50
is( $seq, 'X: 4' );
51
$publisheddate = GetNextDate( $subscription, $publisheddate, $frequency );
52
$seq           = _next_seq( $subscription, $pattern, $frequency, $publisheddate );
53
is( $seq, 'X: 2' );
54
$publisheddate = GetNextDate( $subscription, $publisheddate, $frequency );
55
$seq           = _next_seq( $subscription, $pattern, $frequency, $publisheddate );
56
is( $seq, 'X: 3' );
57
58
# TEST CASE 2 - 1 variable, use 'dayname' numbering, from 1 to 7
59
$subscription = {
60
    periodicity        => $id,
61
    firstacquidate     => '1970-01-01',
62
    lastvalue1         => 1, lastvalue2 => 1, lastvalue3 => 1,
63
    innerloop1         => 0, innerloop2 => 0, innerloop3 => 0,
64
    skip_serialseq     => 1,
65
    irregularity       => '3;4;6',
66
    countissuesperunit => 1,
67
    locale             => 'C',
68
};
69
$pattern = {
70
    add1            => 1, add2          => 0, add3          => 0,
71
    every1          => 1, every2        => 0, every3        => 0,
72
    whenmorethan1   => 7, whenmorethan2 => 0, whenmorethan3 => 0,
73
    setto1          => 1, setto2        => 0, setto3        => 0,
74
    numberingmethod => 'X: {X}',
75
    numbering1      => 'dayname',
76
    numbering2      => '',
77
    numbering3      => '',
78
};
79
80
$publisheddate = $subscription->{firstacquidate};
81
82
$seq = _next_seq( $subscription, $pattern, $frequency, $publisheddate );
83
is( $seq, 'X: Tuesday' );
84
$publisheddate = GetNextDate( $subscription, $publisheddate, $frequency );
85
$seq           = _next_seq( $subscription, $pattern, $frequency, $publisheddate );
86
is( $seq, 'X: Friday' );
87
$publisheddate = GetNextDate( $subscription, $publisheddate, $frequency );
88
$seq           = _next_seq( $subscription, $pattern, $frequency, $publisheddate );
89
is( $seq, 'X: Sunday' );
90
$publisheddate = GetNextDate( $subscription, $publisheddate, $frequency );
91
$seq           = _next_seq( $subscription, $pattern, $frequency, $publisheddate );
92
is( $seq, 'X: Monday' );
93
$publisheddate = GetNextDate( $subscription, $publisheddate, $frequency );
94
$seq           = _next_seq( $subscription, $pattern, $frequency, $publisheddate );
95
is( $seq, 'X: Tuesday' );
96
97
# TEST CASE 3 - 1 variable, use 'monthname' numbering, from 0 to 11 by step of 2
98
$subscription = {
99
    periodicity        => $id,
100
    firstacquidate     => '1970-01-01',
101
    lastvalue1         => 0, lastvalue2 => 1, lastvalue3 => 1,
102
    innerloop1         => 0, innerloop2 => 0, innerloop3 => 0,
103
    skip_serialseq     => 1,
104
    irregularity       => '3;4;6',
105
    countissuesperunit => 1,
106
    locale             => 'C',
107
};
108
$pattern = {
109
    add1            => 2,  add2          => 0, add3          => 0,
110
    every1          => 1,  every2        => 0, every3        => 0,
111
    whenmorethan1   => 11, whenmorethan2 => 0, whenmorethan3 => 0,
112
    setto1          => 0,  setto2        => 0, setto3        => 0,
113
    numberingmethod => 'X: {X}',
114
    numbering1      => 'monthname',
115
    numbering2      => '',
116
    numbering3      => '',
117
};
118
119
$publisheddate = $subscription->{firstacquidate};
120
121
$seq = _next_seq( $subscription, $pattern, $frequency, $publisheddate );
122
is( $seq, 'X: March' );
123
$publisheddate = GetNextDate( $subscription, $publisheddate, $frequency );
124
$seq           = _next_seq( $subscription, $pattern, $frequency, $publisheddate );
125
is( $seq, 'X: September' );
126
$publisheddate = GetNextDate( $subscription, $publisheddate, $frequency );
127
$seq           = _next_seq( $subscription, $pattern, $frequency, $publisheddate );
128
is( $seq, 'X: January' );
129
$publisheddate = GetNextDate( $subscription, $publisheddate, $frequency );
130
$seq           = _next_seq( $subscription, $pattern, $frequency, $publisheddate );
131
is( $seq, 'X: March' );
132
$publisheddate = GetNextDate( $subscription, $publisheddate, $frequency );
133
$seq           = _next_seq( $subscription, $pattern, $frequency, $publisheddate );
134
is( $seq, 'X: May' );
135
136
# TEST CASE 4 - 1 variable, use 'season' numbering, from 0 to 3
137
$subscription = {
138
    periodicity        => $id,
139
    firstacquidate     => '1970-01-01',
140
    lastvalue1         => 0, lastvalue2 => 1, lastvalue3 => 1,
141
    innerloop1         => 0, innerloop2 => 0, innerloop3 => 0,
142
    skip_serialseq     => 1,
143
    irregularity       => '3;4;6',
144
    countissuesperunit => 1,
145
    locale             => 'C',
146
    translations       => { seasons => [ 'Spring', 'Summer', 'Fall', 'Winter' ] },
147
};
148
$pattern = {
149
    add1            => 1, add2          => 0, add3          => 0,
150
    every1          => 1, every2        => 0, every3        => 0,
151
    whenmorethan1   => 3, whenmorethan2 => 0, whenmorethan3 => 0,
152
    setto1          => 0, setto2        => 0, setto3        => 0,
153
    numberingmethod => 'X: {X}',
154
    numbering1      => 'season',
155
    numbering2      => '',
156
    numbering3      => '',
157
};
158
159
$publisheddate = $subscription->{firstacquidate};
160
161
$seq = _next_seq( $subscription, $pattern, $frequency, $publisheddate );
162
is( $seq, 'X: Summer' );
163
$publisheddate = GetNextDate( $subscription, $publisheddate, $frequency );
164
$seq           = _next_seq( $subscription, $pattern, $frequency, $publisheddate );
165
is( $seq, 'X: Spring' );
166
$publisheddate = GetNextDate( $subscription, $publisheddate, $frequency );
167
$seq           = _next_seq( $subscription, $pattern, $frequency, $publisheddate );
168
is( $seq, 'X: Fall' );
169
$publisheddate = GetNextDate( $subscription, $publisheddate, $frequency );
170
$seq           = _next_seq( $subscription, $pattern, $frequency, $publisheddate );
171
is( $seq, 'X: Winter' );
172
$publisheddate = GetNextDate( $subscription, $publisheddate, $frequency );
173
$seq           = _next_seq( $subscription, $pattern, $frequency, $publisheddate );
174
is( $seq, 'X: Spring' );
175
176
# TEST CASE 5 - 2 variables, from 1 to 12, and from 1 to 4
177
$subscription = {
178
    periodicity        => $id,
179
    firstacquidate     => '1970-01-01',
180
    lastvalue1         => 1, lastvalue2 => 1, lastvalue3 => 1,
181
    innerloop1         => 0, innerloop2 => 0, innerloop3 => 0,
182
    skip_serialseq     => 1,
183
    irregularity       => '3;4;6',
184
    countissuesperunit => 1,
185
    locale             => 'C',
186
};
187
$pattern = {
188
    add1            => 1, add2          => 1,  add3          => 0,
189
    every1          => 1, every2        => 4,  every3        => 0,
190
    whenmorethan1   => 4, whenmorethan2 => 12, whenmorethan3 => 0,
191
    setto1          => 1, setto2        => 1,  setto3        => 0,
192
    numberingmethod => 'Y: {Y}, X: {X}',
193
    numbering1      => '',
194
    numbering2      => '',
195
    numbering3      => '',
196
};
197
198
$publisheddate = $subscription->{firstacquidate};
199
200
$seq = _next_seq( $subscription, $pattern, $frequency, $publisheddate );
201
is( $seq, 'Y: 1, X: 2' );
202
$publisheddate = GetNextDate( $subscription, $publisheddate, $frequency );
203
$seq           = _next_seq( $subscription, $pattern, $frequency, $publisheddate );
204
is( $seq, 'Y: 2, X: 1' );
205
$publisheddate = GetNextDate( $subscription, $publisheddate, $frequency );
206
$seq           = _next_seq( $subscription, $pattern, $frequency, $publisheddate );
207
is( $seq, 'Y: 2, X: 3' );
208
$publisheddate = GetNextDate( $subscription, $publisheddate, $frequency );
209
$seq           = _next_seq( $subscription, $pattern, $frequency, $publisheddate );
210
is( $seq, 'Y: 2, X: 4' );
211
$publisheddate = GetNextDate( $subscription, $publisheddate, $frequency );
212
$seq           = _next_seq( $subscription, $pattern, $frequency, $publisheddate );
213
is( $seq, 'Y: 3, X: 1' );
214
215
# TEST CASE 6 - 3 variables, from 1 to 12, from 1 to 8, and from 1 to 4
216
$subscription = {
217
    periodicity        => $id,
218
    firstacquidate     => '1970-01-01',
219
    lastvalue1         => 1, lastvalue2 => 1, lastvalue3 => 1,
220
    innerloop1         => 0, innerloop2 => 0, innerloop3 => 0,
221
    skip_serialseq     => 1,
222
    irregularity       => '3;4;6;110',
223
    countissuesperunit => 1,
224
    locale             => 'C',
225
};
226
$pattern = {
227
    add1            => 1, add2          => 1, add3          => 1,
228
    every1          => 1, every2        => 4, every3        => 32,
229
    whenmorethan1   => 4, whenmorethan2 => 8, whenmorethan3 => 12,
230
    setto1          => 1, setto2        => 1, setto3        => 1,
231
    numberingmethod => 'Z: {Z}, Y: {Y}, X: {X}',
232
    numbering1      => '',
233
    numbering2      => '',
234
    numbering3      => '',
235
};
236
237
$publisheddate = $subscription->{firstacquidate};
238
239
$seq = _next_seq( $subscription, $pattern, $frequency, $publisheddate );
240
is( $seq, 'Z: 1, Y: 1, X: 2' );
241
$publisheddate = GetNextDate( $subscription, $publisheddate, $frequency );
242
$seq           = _next_seq( $subscription, $pattern, $frequency, $publisheddate );
243
is( $seq, 'Z: 1, Y: 2, X: 1' );
244
$publisheddate = GetNextDate( $subscription, $publisheddate, $frequency );
245
$seq           = _next_seq( $subscription, $pattern, $frequency, $publisheddate );
246
is( $seq, 'Z: 1, Y: 2, X: 3' );
247
$publisheddate = GetNextDate( $subscription, $publisheddate, $frequency );
248
$seq           = _next_seq( $subscription, $pattern, $frequency, $publisheddate );
249
is( $seq, 'Z: 1, Y: 2, X: 4' );
250
251
for ( 1 .. 100 ) {
252
    $publisheddate = GetNextDate( $subscription, $publisheddate, $frequency );
253
    $seq           = _next_seq( $subscription, $pattern, $frequency, $publisheddate );
254
}
255
$publisheddate = GetNextDate( $subscription, $publisheddate, $frequency );
256
$seq           = _next_seq( $subscription, $pattern, $frequency, $publisheddate );
257
is( $seq, 'Z: 4, Y: 4, X: 1' );
258
259
# 110th is here
260
$publisheddate = GetNextDate( $subscription, $publisheddate, $frequency );
261
$seq           = _next_seq( $subscription, $pattern, $frequency, $publisheddate );
262
is( $seq, 'Z: 4, Y: 4, X: 3' );
263
$publisheddate = GetNextDate( $subscription, $publisheddate, $frequency );
264
$seq           = _next_seq( $subscription, $pattern, $frequency, $publisheddate );
265
is( $seq, 'Z: 4, Y: 4, X: 4' );
266
$publisheddate = GetNextDate( $subscription, $publisheddate, $frequency );
267
$seq           = _next_seq( $subscription, $pattern, $frequency, $publisheddate );
268
is( $seq, 'Z: 4, Y: 5, X: 1' );
269
270
sub _next_seq {
271
    my ( $subscription, $pattern, $frequency, $publisheddate ) = @_;
272
    my $seq;
273
    (
274
        $seq,                        $subscription->{lastvalue1}, $subscription->{lastvalue2},
275
        $subscription->{lastvalue3}, $subscription->{innerloop1},
276
        $subscription->{innerloop2}, $subscription->{innerloop3}
277
    ) = GetNextSeq( $subscription, $pattern, $frequency, $publisheddate );
278
    return $seq;
279
}

Return to bug 35590