Bug 12495 - Include streetnumber in hold alert address
[koha_fer] / C4 / Serials.pm
index 86f3c0b..bcb37e3 100644 (file)
@@ -20,9 +20,12 @@ package C4::Serials;
 
 use Modern::Perl;
 
+use C4::Auth qw(haspermission);
+use C4::Context;
 use C4::Dates qw(format_date format_date_in_iso);
+use DateTime;
 use Date::Calc qw(:all);
-use POSIX qw(strftime setlocale LC_TIME);
+use POSIX qw(strftime);
 use C4::Biblio;
 use C4::Log;    # logaction
 use C4::Debug;
@@ -100,7 +103,7 @@ sub GetSuppliersWithLateIssues {
     WHERE id > 0
         AND (
             (planneddate < now() AND serial.status=1)
-            OR serial.STATUS = 3 OR serial.STATUS = 4
+            OR serial.STATUS IN (3, 4, 41, 42, 43, 44)
         )
         AND subscription.closed = 0
     ORDER BY name|;
@@ -228,15 +231,7 @@ sub GetSerialInformation {
     my ($serialid) = @_;
     my $dbh        = C4::Context->dbh;
     my $query      = qq|
-        SELECT serial.*, serial.notes as sernotes, serial.status as serstatus,subscription.*,subscription.subscriptionid as subsid |;
-    if (   C4::Context->preference('IndependentBranches')
-        && C4::Context->userenv
-        && C4::Context->userenv->{'flags'} != 1
-        && C4::Context->userenv->{'branch'} ) {
-        $query .= "
-      , ((subscription.branchcode <>\"" . C4::Context->userenv->{'branch'} . "\") and subscription.branchcode <>\"\" and subscription.branchcode IS NOT NULL) as cannotedit ";
-    }
-    $query .= qq|             
+        SELECT serial.*, serial.notes as sernotes, serial.status as serstatus,subscription.*,subscription.subscriptionid as subsid
         FROM   serial LEFT JOIN subscription ON subscription.subscriptionid=serial.subscriptionid
         WHERE  serialid = ?
     |;
@@ -275,6 +270,7 @@ sub GetSerialInformation {
     $data->{ "status" . $data->{'serstatus'} } = 1;
     $data->{'subscriptionexpired'} = HasSubscriptionExpired( $data->{'subscriptionid'} ) && $data->{'status'} == 1;
     $data->{'abouttoexpire'} = abouttoexpire( $data->{'subscriptionid'} );
+    $data->{cannotedit} = not can_edit_subscription( $data );
     return $data;
 }
 
@@ -339,15 +335,7 @@ sub GetSubscription {
                 subscriptionhistory.*,
                 aqbooksellers.name AS aqbooksellername,
                 biblio.title AS bibliotitle,
-                subscription.biblionumber as bibnum);
-    if (   C4::Context->preference('IndependentBranches')
-        && C4::Context->userenv
-        && C4::Context->userenv->{'flags'} != 1
-        && C4::Context->userenv->{'branch'} ) {
-        $query .= "
-      , ((subscription.branchcode <>\"" . C4::Context->userenv->{'branch'} . "\") and subscription.branchcode <>\"\" and subscription.branchcode IS NOT NULL) as cannotedit ";
-    }
-    $query .= qq(             
+                subscription.biblionumber as bibnum
        FROM subscription
        LEFT JOIN subscriptionhistory ON subscription.subscriptionid=subscriptionhistory.subscriptionid
        LEFT JOIN aqbooksellers ON subscription.aqbooksellerid=aqbooksellers.id
@@ -355,16 +343,12 @@ sub GetSubscription {
        WHERE subscription.subscriptionid = ?
     );
 
-    #     if (C4::Context->preference('IndependentBranches') &&
-    #         C4::Context->userenv &&
-    #         C4::Context->userenv->{'flags'} != 1){
-    # #       $debug and warn "flags: ".C4::Context->userenv->{'flags'};
-    #       $query.=" AND subscription.branchcode IN ('".C4::Context->userenv->{'branch'}."',\"\")";
-    #     }
     $debug and warn "query : $query\nsubsid :$subscriptionid";
     my $sth = $dbh->prepare($query);
     $sth->execute($subscriptionid);
-    return $sth->fetchrow_hashref;
+    my $subscription = $sth->fetchrow_hashref;
+    $subscription->{cannotedit} = not can_edit_subscription( $subscription );
+    return $subscription;
 }
 
 =head2 GetFullSubscription
@@ -391,15 +375,7 @@ sub GetFullSubscription {
             aqbooksellers.name as aqbooksellername,
             biblio.title as bibliotitle,
             subscription.branchcode AS branchcode,
-            subscription.subscriptionid AS subscriptionid |;
-    if (   C4::Context->preference('IndependentBranches')
-        && C4::Context->userenv
-        && C4::Context->userenv->{'flags'} != 1
-        && C4::Context->userenv->{'branch'} ) {
-        $query .= "
-      , ((subscription.branchcode <>\"" . C4::Context->userenv->{'branch'} . "\") and subscription.branchcode <>\"\" and subscription.branchcode IS NOT NULL) as cannotedit ";
-    }
-    $query .= qq|
+            subscription.subscriptionid AS subscriptionid
   FROM      serial 
   LEFT JOIN subscription ON 
           (serial.subscriptionid=subscription.subscriptionid )
@@ -413,7 +389,11 @@ sub GetFullSubscription {
     $debug and warn "GetFullSubscription query: $query";
     my $sth = $dbh->prepare($query);
     $sth->execute($subscriptionid);
-    return $sth->fetchall_arrayref( {} );
+    my $subscriptions = $sth->fetchall_arrayref( {} );
+    for my $subscription ( @$subscriptions ) {
+        $subscription->{cannotedit} = not can_edit_subscription( $subscription );
+    }
+    return $subscriptions;
 }
 
 =head2 PrepareSerialsData
@@ -440,13 +420,15 @@ sub PrepareSerialsData {
 
     foreach my $subs (@{$lines}) {
         for my $datefield ( qw(publisheddate planneddate) ) {
-            # handle both undef and undef returned as 0000-00-00
-            if (!defined $subs->{$datefield} or $subs->{$datefield}=~m/^00/) {
-                $subs->{$datefield} = 'XXX';
+            # handle 0000-00-00 dates
+            if (defined $subs->{$datefield} and $subs->{$datefield} =~ m/^00/) {
+                $subs->{$datefield} = undef;
             }
         }
         $subs->{ "status" . $subs->{'status'} } = 1;
-        $subs->{"checked"}                      = $subs->{'status'} =~ /1|3|4|7/;
+        if ( grep { $_ == $subs->{status} } qw( 1 3 4 41 42 43 44 7 ) ) {
+            $subs->{"checked"} = 1;
+        }
 
         if ( $subs->{'year'} && $subs->{'year'} ne "" ) {
             $year = $subs->{'year'};
@@ -514,13 +496,6 @@ sub GetSubscriptionsFromBiblionumber {
         $subs->{ "periodicity" . $subs->{periodicity} }     = 1;
         $subs->{ "numberpattern" . $subs->{numberpattern} } = 1;
         $subs->{ "status" . $subs->{'status'} }             = 1;
-        $subs->{'cannotedit'} =
-          (      C4::Context->preference('IndependentBranches')
-              && C4::Context->userenv
-              && C4::Context->userenv->{flags} % 2 != 1
-              && C4::Context->userenv->{branch}
-              && $subs->{branchcode}
-              && ( C4::Context->userenv->{branch} ne $subs->{branchcode} ) );
 
         if ( $subs->{enddate} eq '0000-00-00' ) {
             $subs->{enddate} = '';
@@ -529,6 +504,7 @@ sub GetSubscriptionsFromBiblionumber {
         }
         $subs->{'abouttoexpire'}       = abouttoexpire( $subs->{'subscriptionid'} );
         $subs->{'subscriptionexpired'} = HasSubscriptionExpired( $subs->{'subscriptionid'} );
+        $subs->{cannotedit} = not can_edit_subscription( $subs );
         push @res, $subs;
     }
     return \@res;
@@ -554,16 +530,7 @@ sub GetFullSubscriptionsFromBiblionumber {
             year(IF(serial.publisheddate="00-00-0000",serial.planneddate,serial.publisheddate)) as year,
             biblio.title as bibliotitle,
             subscription.branchcode AS branchcode,
-            subscription.subscriptionid AS subscriptionid|;
-    if (   C4::Context->preference('IndependentBranches')
-        && C4::Context->userenv
-        && C4::Context->userenv->{'flags'} != 1
-        && C4::Context->userenv->{'branch'} ) {
-        $query .= "
-      , ((subscription.branchcode <>\"" . C4::Context->userenv->{'branch'} . "\") and subscription.branchcode <>\"\" and subscription.branchcode IS NOT NULL) as cannotedit ";
-    }
-
-    $query .= qq|      
+            subscription.subscriptionid AS subscriptionid
   FROM      serial 
   LEFT JOIN subscription ON 
           (serial.subscriptionid=subscription.subscriptionid)
@@ -576,7 +543,11 @@ sub GetFullSubscriptionsFromBiblionumber {
           |;
     my $sth = $dbh->prepare($query);
     $sth->execute($biblionumber);
-    return $sth->fetchall_arrayref( {} );
+    my $subscriptions = $sth->fetchall_arrayref( {} );
+    for my $subscription ( @$subscriptions ) {
+        $subscription->{cannotedit} = not can_edit_subscription( $subscription );
+    }
+    return $subscriptions;
 }
 
 =head2 GetSubscriptions
@@ -651,30 +622,36 @@ sub GetSubscriptions {
     $debug and warn "GetSubscriptions query: $sql params : ", join( " ", @bind_params );
     $sth = $dbh->prepare($sql);
     $sth->execute(@bind_params);
-    my @results;
-
-    while ( my $line = $sth->fetchrow_hashref ) {
-        $line->{'cannotedit'} =
-          (      C4::Context->preference('IndependentBranches')
-              && C4::Context->userenv
-              && C4::Context->userenv->{flags} % 2 != 1
-              && C4::Context->userenv->{branch}
-              && $line->{branchcode}
-              && ( C4::Context->userenv->{branch} ne $line->{branchcode} ) );
-        push @results, $line;
-    }
-    return @results;
+    my $subscriptions = $sth->fetchall_arrayref( {} );
+    for my $subscription ( @$subscriptions ) {
+        $subscription->{cannotedit} = not can_edit_subscription( $subscription );
+    }
+    return @$subscriptions;
 }
 
 =head2 SearchSubscriptions
 
-@results = SearchSubscriptions($args);
-$args is a hashref. Its keys can be contained: title, issn, ean, publisher, bookseller and branchcode
+  @results = SearchSubscriptions($args);
 
-this function gets all subscriptions which have title like $title, ISSN like $issn, EAN like $ean, publisher like $publisher, bookseller like $bookseller AND branchcode eq $branch.
+This function returns a list of hashrefs, one for each subscription
+that meets the conditions specified by the $args hashref.
 
-return:
-a table of hashref. Each hash containt the subscription.
+The valid search fields are:
+
+  biblionumber
+  title
+  issn
+  ean
+  callnumber
+  location
+  publisher
+  bookseller
+  branch
+  expiration_date
+  closed
+
+The expiration_date search field is special; it specifies the maximum
+subscription expiration date.
 
 =cut
 
@@ -722,6 +699,10 @@ sub SearchSubscriptions {
         push @where_strs, "biblioitems.ean LIKE ?";
         push @where_args, "%$args->{ean}%";
     }
+    if ( $args->{callnumber} ) {
+        push @where_strs, "subscription.callnumber LIKE ?";
+        push @where_args, "%$args->{callnumber}%";
+    }
     if( $args->{publisher} ){
         push @where_strs, "biblioitems.publishercode LIKE ?";
         push @where_args, "%$args->{publisher}%";
@@ -734,6 +715,14 @@ sub SearchSubscriptions {
         push @where_strs, "subscription.branchcode = ?";
         push @where_args, "$args->{branch}";
     }
+    if ( $args->{location} ) {
+        push @where_strs, "subscription.location = ?";
+        push @where_args, "$args->{location}";
+    }
+    if ( $args->{expiration_date} ) {
+        push @where_strs, "subscription.enddate <= ?";
+        push @where_args, "$args->{expiration_date}";
+    }
     if( defined $args->{closed} ){
         push @where_strs, "subscription.closed = ?";
         push @where_args, "$args->{closed}";
@@ -748,6 +737,11 @@ sub SearchSubscriptions {
     my $results = $sth->fetchall_arrayref( {} );
     $sth->finish;
 
+    for my $subscription ( @$results ) {
+        $subscription->{cannotedit} = not can_edit_subscription( $subscription );
+        $subscription->{cannotdisplay} = not can_show_subscription( $subscription );
+    }
+
     return @$results;
 }
 
@@ -776,7 +770,7 @@ sub GetSerials {
     my @serials;
     my $query = "SELECT serialid,serialseq, status, publisheddate, planneddate,notes, routingnotes
                         FROM   serial
-                        WHERE  subscriptionid = ? AND status NOT IN (2,4,5) 
+                        WHERE  subscriptionid = ? AND status NOT IN (2, 4, 41, 42, 43, 44, 5)
                         ORDER BY IF(publisheddate<>'0000-00-00',publisheddate,planneddate) DESC";
     my $sth = $dbh->prepare($query);
     $sth->execute($subscriptionid);
@@ -797,7 +791,7 @@ sub GetSerials {
     $query = "SELECT   serialid,serialseq, status, planneddate, publisheddate,notes, routingnotes
        FROM     serial
        WHERE    subscriptionid = ?
-       AND      (status in (2,4,5))
+       AND      (status in (2, 4, 41, 42, 43, 44, 5))
        ORDER BY IF(publisheddate<>'0000-00-00',publisheddate,planneddate) DESC
       ";
     $sth = $dbh->prepare($query);
@@ -853,7 +847,7 @@ sub GetSerials2 {
         $line->{ "status" . $line->{status} } = 1; # fills a "statusX" value, used for template status select list
         # Format dates for display
         for my $datefield ( qw( planneddate publisheddate ) ) {
-            if ($line->{$datefield} =~m/^00/) {
+            if (!defined($line->{$datefield}) || $line->{$datefield} =~m/^00/) {
                 $line->{$datefield} = q{};
             }
             else {
@@ -885,7 +879,7 @@ sub GetLatestSerials {
     my $strsth = "SELECT   serialid,serialseq, status, planneddate, publisheddate, notes
                         FROM     serial
                         WHERE    subscriptionid = ?
-                        AND      (status =2 or status=4)
+                        AND      status IN (2, 4, 41, 42, 43, 44)
                         ORDER BY publisheddate DESC LIMIT 0,$limit
                 ";
     my $sth = $dbh->prepare($strsth);
@@ -1163,50 +1157,6 @@ sub ModSubscriptionHistory {
     return $sth->rows;
 }
 
-# Update missinglist field, used by ModSerialStatus
-sub _update_missinglist {
-    my $subscriptionid = shift;
-
-    my $dbh = C4::Context->dbh;
-    my @missingserials = GetSerials2($subscriptionid, "4,5");
-    my $missinglist;
-    foreach (@missingserials) {
-        if($_->{'status'} == 4) {
-            $missinglist .= $_->{'serialseq'} . "; ";
-        } elsif($_->{'status'} == 5) {
-            $missinglist .= "not issued " . $_->{'serialseq'} . "; ";
-        }
-    }
-    $missinglist =~ s/; $//;
-    my $query = qq{
-        UPDATE subscriptionhistory
-        SET missinglist = ?
-        WHERE subscriptionid = ?
-    };
-    my $sth = $dbh->prepare($query);
-    $sth->execute($missinglist, $subscriptionid);
-}
-
-# Update recievedlist field, used by ModSerialStatus
-sub _update_receivedlist {
-    my $subscriptionid = shift;
-
-    my $dbh = C4::Context->dbh;
-    my @receivedserials = GetSerials2($subscriptionid, "2");
-    my $receivedlist;
-    foreach (@receivedserials) {
-        $receivedlist .= $_->{'serialseq'} . "; ";
-    }
-    $receivedlist =~ s/; $//;
-    my $query = qq{
-        UPDATE subscriptionhistory
-        SET recievedlist = ?
-        WHERE subscriptionid = ?
-    };
-    my $sth = $dbh->prepare($query);
-    $sth->execute($receivedlist, $subscriptionid);
-}
-
 =head2 ModSerialStatus
 
 ModSerialStatus($serialid,$serialseq, $planneddate,$publisheddate,$status,$notes)
@@ -1239,10 +1189,6 @@ sub ModSerialStatus {
         DelIssue( { 'serialid' => $serialid, 'subscriptionid' => $subscriptionid, 'serialseq' => $serialseq } );
     } else {
 
-        unless ($frequency->{'unit'}) {
-            if ( not $planneddate or $planneddate eq '0000-00-00' ) { $planneddate = C4::Dates->new()->output('iso') };
-            if ( not $publisheddate or $publisheddate eq '0000-00-00' ) { $publisheddate = C4::Dates->new()->output('iso') };
-        }
         my $query = 'UPDATE serial SET serialseq=?,publisheddate=?,planneddate=?,status=?,notes=? WHERE  serialid = ?';
         $sth = $dbh->prepare($query);
         $sth->execute( $serialseq, $publisheddate, $planneddate, $status, $notes, $serialid );
@@ -1251,14 +1197,32 @@ sub ModSerialStatus {
         $sth->execute($subscriptionid);
         my $val = $sth->fetchrow_hashref;
         unless ( $val->{manualhistory} ) {
+            $query = "SELECT missinglist,recievedlist FROM subscriptionhistory WHERE  subscriptionid=?";
+            $sth   = $dbh->prepare($query);
+            $sth->execute($subscriptionid);
+            my ( $missinglist, $recievedlist ) = $sth->fetchrow;
+
             if ( $status == 2 || ($oldstatus == 2 && $status != 2) ) {
-                  _update_receivedlist($subscriptionid);
+                $recievedlist .= "; $serialseq"
+                    if ($recievedlist !~ /(^|;)\s*$serialseq(?=;|$)/);
             }
-            if($status == 4 || $status == 5
-              || ($oldstatus == 4 && $status != 4)
-              || ($oldstatus == 5 && $status != 5)) {
-                _update_missinglist($subscriptionid);
+
+            # in case serial has been previously marked as missing
+            if (grep /$status/, (1,2,3,7)) {
+                $missinglist=~ s/(^|;)\s*$serialseq(?=;|$)//g;
             }
+
+            my @missing_statuses = qw( 4 41 42 43 44 );
+            $missinglist .= "; $serialseq"
+                if ( ( grep { $_ == $status } @missing_statuses ) && ( $missinglist !~/(^|;)\s*$serialseq(?=;|$)/ ) );
+            $missinglist .= "; not issued $serialseq"
+                if ( $status == 5 && $missinglist !~ /(^|;)\s*$serialseq(?=;|$)/ );
+
+            $query = "UPDATE subscriptionhistory SET recievedlist=?, missinglist=? WHERE  subscriptionid=?";
+            $sth   = $dbh->prepare($query);
+            $recievedlist =~ s/^; //;
+            $missinglist  =~ s/^; //;
+            $sth->execute( $recievedlist, $missinglist, $subscriptionid );
         }
     }
 
@@ -1462,7 +1426,7 @@ $subscriptionid = &NewSubscription($auser,branchcode,$aqbooksellerid,$cost,$aqbu
     $startdate,$periodicity,$numberlength,$weeklength,$monthlength,
     $lastvalue1,$innerloop1,$lastvalue2,$innerloop2,$lastvalue3,$innerloop3,
     $status, $notes, $letter, $firstacquidate, $irregularity, $numberpattern,
-    $callnumber, $hemisphere, $manualhistory, $internalnotes, $serialsadditems,
+    $locale, $callnumber, $manualhistory, $internalnotes, $serialsadditems,
     $staffdisplaycount, $opacdisplaycount, $graceperiod, $location, $enddate, $skip_serialseq);
 
 Create a new subscription with value given on input args.
@@ -1533,14 +1497,14 @@ sub NewSubscription {
     my $pattern = C4::Serials::Numberpattern::GetSubscriptionNumberpattern($subscription->{numberpattern});
 
     # calculate issue number
-    my $serialseq = GetSeq($subscription, $pattern);
+    my $serialseq = GetSeq($subscription, $pattern) || q{};
     $query = qq|
         INSERT INTO serial
             (serialseq,subscriptionid,biblionumber,status, planneddate, publisheddate)
         VALUES (?,?,?,?,?,?)
     |;
     $sth = $dbh->prepare($query);
-    $sth->execute( "$serialseq", $subscriptionid, $biblionumber, 1, $firstacquidate, $firstacquidate );
+    $sth->execute( $serialseq, $subscriptionid, $biblionumber, 1, $firstacquidate, $firstacquidate );
 
     logaction( "SERIAL", "ADD", $subscriptionid, "" ) if C4::Context->preference("SubscriptionLog");
 
@@ -2011,7 +1975,7 @@ name,title,planneddate,serialseq,serial.subscriptionid from tables : subscriptio
 sub GetLateOrMissingIssues {
     my ( $supplierid, $serialid, $order ) = @_;
 
-    return unless ($supplierid);
+    return unless ( $supplierid or $serialid );
 
     my $dbh = C4::Context->dbh;
     my $sth;
@@ -2028,15 +1992,16 @@ sub GetLateOrMissingIssues {
         $sth = $dbh->prepare(
             "SELECT
                 serialid,      aqbooksellerid,        name,
-                biblio.title,  planneddate,           serialseq,
+                biblio.title,  biblioitems.issn,      planneddate,    serialseq,
                 serial.status, serial.subscriptionid, claimdate,
                 subscription.branchcode
             FROM      serial 
                 LEFT JOIN subscription  ON serial.subscriptionid=subscription.subscriptionid 
                 LEFT JOIN biblio        ON subscription.biblionumber=biblio.biblionumber
+                LEFT JOIN biblioitems   ON subscription.biblionumber=biblioitems.biblionumber
                 LEFT JOIN aqbooksellers ON subscription.aqbooksellerid = aqbooksellers.id
                 WHERE subscription.subscriptionid = serial.subscriptionid 
-                AND (serial.STATUS = 4 OR ((planneddate < now() AND serial.STATUS =1) OR serial.STATUS = 3 OR serial.STATUS = 7))
+                AND (serial.STATUS IN (4, 41, 42, 43, 44) OR ((planneddate < now() AND serial.STATUS =1) OR serial.STATUS = 3 OR serial.STATUS = 7))
                 AND subscription.aqbooksellerid=$supplierid
                 $byserial
                 ORDER BY $order"
@@ -2053,7 +2018,7 @@ sub GetLateOrMissingIssues {
                 LEFT JOIN biblio ON subscription.biblionumber=biblio.biblionumber
                 LEFT JOIN aqbooksellers ON subscription.aqbooksellerid = aqbooksellers.id
                 WHERE subscription.subscriptionid = serial.subscriptionid 
-                        AND (serial.STATUS = 4 OR ((planneddate < now() AND serial.STATUS =1) OR serial.STATUS = 3 OR serial.STATUS = 7))
+                        AND (serial.STATUS IN (4, 41, 42, 43, 44) OR ((planneddate < now() AND serial.STATUS =1) OR serial.STATUS = 3 OR serial.STATUS = 7))
                 $byserial
                 ORDER BY $order"
         );
@@ -2063,9 +2028,11 @@ sub GetLateOrMissingIssues {
     while ( my $line = $sth->fetchrow_hashref ) {
 
         if ($line->{planneddate} && $line->{planneddate} !~/^0+\-/) {
+            $line->{planneddateISO} = $line->{planneddate};
             $line->{planneddate} = format_date( $line->{planneddate} );
         }
         if ($line->{claimdate} && $line->{claimdate} !~/^0+\-/) {
+            $line->{claimdateISO} = $line->{claimdate};
             $line->{claimdate}   = format_date( $line->{claimdate} );
         }
         $line->{"status".$line->{status}}   = 1;
@@ -2532,13 +2499,15 @@ skipped then the returned date will be 2007-05-10
 return :
 $resultdate - then next date in the sequence (ISO date)
 
-Return $publisheddate if subscription is irregular
+Return undef if subscription is irregular
 
 =cut
 
 sub GetNextDate {
     my ( $subscription, $publisheddate, $updatecount ) = @_;
 
+    return unless $subscription and $publisheddate;
+
     my $freqdata = GetSubscriptionFrequency($subscription->{'periodicity'});
 
     if ($freqdata->{'unit'}) {
@@ -2549,10 +2518,12 @@ sub GetNextDate {
         # irreg1;irreg2;irreg3
         # where irregX is the number of issue which will not be received
         # (the first issue takes the number 1, the 2nd the number 2 and so on)
-        my @irreg = split /;/, $subscription->{'irregularity'} ;
         my %irregularities;
-        foreach my $irregularity (@irreg) {
-            $irregularities{$irregularity} = 1;
+        if ( $subscription->{irregularity} ) {
+            my @irreg = split /;/, $subscription->{'irregularity'} ;
+            foreach my $irregularity (@irreg) {
+                $irregularities{$irregularity} = 1;
+            }
         }
 
         # Get the 'fictive' next issue number
@@ -2676,9 +2647,6 @@ sub GetNextDate {
         }
         return sprintf("%04d-%02d-%02d", $year, $month, $day);
     }
-    else {
-        return $publisheddate;
-    }
 }
 
 =head2 _numeration
@@ -2697,44 +2665,35 @@ num_type can take :
 sub _numeration {
     my ($value, $num_type, $locale) = @_;
     $value ||= 0;
-    my $initlocale = setlocale(LC_TIME);
-    if($locale and $locale ne $initlocale) {
-        $locale = setlocale(LC_TIME, $locale);
-    }
-    $locale ||= $initlocale;
-    my $string;
     $num_type //= '';
-    given ($num_type) {
-        when (/^dayname$/) {
-              $value = $value % 7;
-              $string = POSIX::strftime("%A",0,0,0,0,0,0,$value);
-        }
-        when (/^monthname$/) {
-              $value = $value % 12;
-              $string = POSIX::strftime("%B",0,0,0,1,$value,0,0,0,0);
-        }
-        when (/^season$/) {
-              my $seasonlocale = ($locale)
-                               ? (substr $locale,0,2)
-                               : "en";
-              my %seasons=(
-                 "en" =>
-                    [qw(Spring Summer Fall Winter)],
-                 "fr"=>
-                    [qw(Printemps Été Automne Hiver)],
-              );
-              $value = $value % 4;
-              $string = ($seasons{$seasonlocale})
-                      ? $seasons{$seasonlocale}->[$value]
-                      : $seasons{'en'}->[$value];
-        }
-        default {
-            $string = $value;
-        }
-    }
-    if($locale ne $initlocale) {
-        setlocale(LC_TIME, $initlocale);
+    $locale ||= 'en';
+    my $string;
+    if ( $num_type =~ /^dayname$/ ) {
+        # 1970-11-01 was a Sunday
+        $value = $value % 7;
+        my $dt = DateTime->new(
+            year    => 1970,
+            month   => 11,
+            day     => $value + 1,
+            locale  => $locale,
+        );
+        $string = $dt->strftime("%A");
+    } elsif ( $num_type =~ /^monthname$/ ) {
+        $value = $value % 12;
+        my $dt = DateTime->new(
+            year    => 1970,
+            month   => $value + 1,
+            locale  => $locale,
+        );
+        $string = $dt->strftime("%B");
+    } elsif ( $num_type =~ /^season$/ ) {
+        my @seasons= qw( Spring Summer Fall Winter );
+        $value = $value % 4;
+        $string = $seasons[$value];
+    } else {
+        $string = $value;
     }
+
     return $string;
 }
 
@@ -2828,6 +2787,65 @@ sub subscriptionCurrentlyOnOrder {
     return $sth->fetchrow_array;
 }
 
+=head2 can_edit_subscription
+
+    $can = can_edit_subscription( $subscriptionid[, $userid] );
+
+Return 1 if the subscription can be edited by the current logged user (or a given $userid), else 0.
+
+=cut
+
+sub can_edit_subscription {
+    my ( $subscription, $userid ) = @_;
+    return _can_do_on_subscription( $subscription, $userid, 'edit_subscription' );
+}
+
+=head2 can_show_subscription
+
+    $can = can_show_subscription( $subscriptionid[, $userid] );
+
+Return 1 if the subscription can be shown by the current logged user (or a given $userid), else 0.
+
+=cut
+
+sub can_show_subscription {
+    my ( $subscription, $userid ) = @_;
+    return _can_do_on_subscription( $subscription, $userid, '*' );
+}
+
+sub _can_do_on_subscription {
+    my ( $subscription, $userid, $permission ) = @_;
+    return 0 unless C4::Context->userenv;
+    my $flags = C4::Context->userenv->{flags};
+    $userid ||= C4::Context->userenv->{'id'};
+
+    if ( C4::Context->preference('IndependentBranches') ) {
+        return 1
+          if C4::Context->IsSuperLibrarian()
+              or
+              C4::Auth::haspermission( $userid, { serials => 'superserials' } )
+              or (
+                  C4::Auth::haspermission( $userid,
+                      { serials => $permission } )
+                  and (  not defined $subscription->{branchcode}
+                      or $subscription->{branchcode} eq ''
+                      or $subscription->{branchcode} eq
+                      C4::Context->userenv->{'branch'} )
+              );
+    }
+    else {
+        return 1
+          if C4::Context->IsSuperLibrarian()
+              or
+              C4::Auth::haspermission( $userid, { serials => 'superserials' } )
+              or C4::Auth::haspermission(
+                  $userid, { serials => $permission }
+              ),
+        ;
+    }
+    return 0;
+}
+
 1;
 __END__