Bug 10403: (follow-up) fix test to use vendor created earlier during test
[koha.git] / C4 / Serials.pm
index 3cbd042..6d188e7 100644 (file)
@@ -20,6 +20,8 @@ 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 Date::Calc qw(:all);
 use POSIX qw(strftime setlocale LC_TIME);
@@ -58,6 +60,7 @@ BEGIN {
       &CountIssues
       HasItems
       &GetSubscriptionsFromBorrower
+      &subscriptionCurrentlyOnOrder
 
     );
 }
@@ -120,6 +123,9 @@ name,title,planneddate,serialseq,serial.subscriptionid from tables : subscriptio
 
 sub GetLateIssues {
     my ($supplierid) = @_;
+
+    return unless ($supplierid);
+
     my $dbh = C4::Context->dbh;
     my $sth;
     if ($supplierid) {
@@ -152,10 +158,8 @@ sub GetLateIssues {
     }
     my @issuelist;
     my $last_title;
-    my $odd   = 0;
     while ( my $line = $sth->fetchrow_hashref ) {
-        $odd++ unless $line->{title} eq $last_title;
-        $line->{title} = "" if $line->{title} eq $last_title;
+        $line->{title} = "" if $last_title and $line->{title} eq $last_title;
         $last_title = $line->{title} if ( $line->{title} );
         $line->{planneddate} = format_date( $line->{planneddate} );
         push @issuelist, $line;
@@ -226,15 +230,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('IndependantBranches')
-        && 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 = ?
     |;
@@ -273,6 +269,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;
 }
 
@@ -286,6 +283,9 @@ returns the number of rows affected
 
 sub AddItem2Serial {
     my ( $serialid, $itemnumber ) = @_;
+
+    return unless ($serialid and $itemnumber);
+
     my $dbh = C4::Context->dbh;
     my $rq  = $dbh->prepare("INSERT INTO `serialitems` SET serialid=? , itemnumber=?");
     $rq->execute( $serialid, $itemnumber );
@@ -303,6 +303,9 @@ Update Claimdate for issues in @$serialids list with date $date
 
 sub UpdateClaimdateIssues {
     my ( $serialids, $date ) = @_;
+
+    return unless ($serialids);
+
     my $dbh = C4::Context->dbh;
     $date = strftime( "%Y-%m-%d", localtime ) unless ($date);
     my $query = "
@@ -331,15 +334,7 @@ sub GetSubscription {
                 subscriptionhistory.*,
                 aqbooksellers.name AS aqbooksellername,
                 biblio.title AS bibliotitle,
-                subscription.biblionumber as bibnum);
-    if (   C4::Context->preference('IndependantBranches')
-        && 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
@@ -347,16 +342,12 @@ sub GetSubscription {
        WHERE subscription.subscriptionid = ?
     );
 
-    #     if (C4::Context->preference('IndependantBranches') &&
-    #         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
@@ -368,6 +359,9 @@ sub GetSubscription {
 
 sub GetFullSubscription {
     my ($subscriptionid) = @_;
+
+    return unless ($subscriptionid);
+
     my $dbh              = C4::Context->dbh;
     my $query            = qq|
   SELECT    serial.serialid,
@@ -380,15 +374,7 @@ sub GetFullSubscription {
             aqbooksellers.name as aqbooksellername,
             biblio.title as bibliotitle,
             subscription.branchcode AS branchcode,
-            subscription.subscriptionid AS subscriptionid |;
-    if (   C4::Context->preference('IndependantBranches')
-        && 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 )
@@ -402,7 +388,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
@@ -414,6 +404,9 @@ sub GetFullSubscription {
 
 sub PrepareSerialsData {
     my ($lines) = @_;
+
+    return unless ($lines);
+
     my %tmpresults;
     my $year;
     my @res;
@@ -430,9 +423,6 @@ sub PrepareSerialsData {
             if (!defined $subs->{$datefield} or $subs->{$datefield}=~m/^00/) {
                 $subs->{$datefield} = 'XXX';
             }
-            else {
-                $subs->{$datefield} = format_date( $subs->{$datefield}  );
-            }
         }
         $subs->{ "status" . $subs->{'status'} } = 1;
         $subs->{"checked"}                      = $subs->{'status'} =~ /1|3|4|7/;
@@ -473,6 +463,9 @@ startdate, histstartdate,opacnote,missinglist,recievedlist,periodicity,status &
 
 sub GetSubscriptionsFromBiblionumber {
     my ($biblionumber) = @_;
+
+    return unless ($biblionumber);
+
     my $dbh            = C4::Context->dbh;
     my $query          = qq(
         SELECT subscription.*,
@@ -500,13 +493,6 @@ sub GetSubscriptionsFromBiblionumber {
         $subs->{ "periodicity" . $subs->{periodicity} }     = 1;
         $subs->{ "numberpattern" . $subs->{numberpattern} } = 1;
         $subs->{ "status" . $subs->{'status'} }             = 1;
-        $subs->{'cannotedit'} =
-          (      C4::Context->preference('IndependantBranches')
-              && 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} = '';
@@ -515,6 +501,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;
@@ -540,16 +527,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('IndependantBranches')
-        && 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)
@@ -562,7 +540,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
@@ -637,19 +619,11 @@ 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('IndependantBranches')
-              && 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
@@ -668,7 +642,14 @@ sub SearchSubscriptions {
     my ( $args ) = @_;
 
     my $query = qq{
-        SELECT subscription.*, subscriptionhistory.*, biblio.*, biblioitems.issn
+        SELECT
+            subscription.notes AS publicnotes,
+            subscription.*,
+            subscriptionhistory.*,
+            biblio.notes AS biblionotes,
+            biblio.title,
+            biblio.author,
+            biblioitems.issn
         FROM subscription
             LEFT JOIN subscriptionhistory USING(subscriptionid)
             LEFT JOIN biblio ON biblio.biblionumber = subscription.biblionumber
@@ -727,6 +708,14 @@ sub SearchSubscriptions {
     my $results = $sth->fetchall_arrayref( {} );
     $sth->finish;
 
+    for my $subscription ( @$results ) {
+        $subscription->{cannotedit} = not can_edit_subscription( $subscription );
+        $subscription->{cannotdisplay} =
+            ( C4::Context->preference("IndependentBranches") &&
+              C4::Context->userenv &&
+              $subscription->{branchcode} ne C4::Context->userenv->{'branch'} ) ? 1 : 0;
+    }
+
     return @$results;
 }
 
@@ -744,6 +733,9 @@ FIXME: We should return \@serials.
 
 sub GetSerials {
     my ( $subscriptionid, $count ) = @_;
+
+    return unless $subscriptionid;
+
     my $dbh = C4::Context->dbh;
 
     # status = 2 is "arrived"
@@ -810,6 +802,9 @@ this number is used to see if a subscription can be deleted (=it must have only
 
 sub GetSerials2 {
     my ( $subscription, $status ) = @_;
+
+    return unless ($subscription and $status);
+
     my $dbh   = C4::Context->dbh;
     my $query = qq|
                  SELECT   serialid,serialseq, status, planneddate, publisheddate,notes, routingnotes
@@ -849,10 +844,13 @@ a ref to an array which contains all of the latest serials stored into a hash.
 
 sub GetLatestSerials {
     my ( $subscriptionid, $limit ) = @_;
+
+    return unless ($subscriptionid and $limit);
+
     my $dbh = C4::Context->dbh;
 
     # status = 2 is "arrived"
-    my $strsth = "SELECT   serialid,serialseq, status, planneddate, notes
+    my $strsth = "SELECT   serialid,serialseq, status, planneddate, publisheddate, notes
                         FROM     serial
                         WHERE    subscriptionid = ?
                         AND      (status =2 or status=4)
@@ -864,6 +862,7 @@ sub GetLatestSerials {
     while ( my $line = $sth->fetchrow_hashref ) {
         $line->{ "status" . $line->{status} } = 1;                        # fills a "statusX" value, used for template status select list
         $line->{"planneddate"} = format_date( $line->{"planneddate"} );
+        $line->{"publisheddate"} = format_date( $line->{"publisheddate"} );
         push @serials, $line;
     }
 
@@ -880,7 +879,10 @@ This function returns the field distributedto for the subscription matching subs
 sub GetDistributedTo {
     my $dbh = C4::Context->dbh;
     my $distributedto;
-    my $subscriptionid = @_;
+    my ($subscriptionid) = @_;
+
+    return unless ($subscriptionid);
+
     my $query          = "SELECT distributedto FROM subscription WHERE subscriptionid=?";
     my $sth            = $dbh->prepare($query);
     $sth->execute($subscriptionid);
@@ -889,26 +891,35 @@ sub GetDistributedTo {
 
 =head2 GetNextSeq
 
-GetNextSeq($val)
-$val is a hashref containing all the attributes of the table 'subscription'
+    my (
+        $nextseq,       $newlastvalue1, $newlastvalue2, $newlastvalue3,
+        $newinnerloop1, $newinnerloop2, $newinnerloop3
+    ) = GetNextSeq( $subscription, $pattern, $planneddate );
+
+$subscription is a hashref containing all the attributes of the table
+'subscription'.
+$pattern is a hashref containing all the attributes of the table
+'subscription_numberpatterns'.
+$planneddate is a C4::Dates object.
 This function get the next issue for the subscription given on input arg
-return:
-a list containing all the input params updated.
 
 =cut
 
 sub GetNextSeq {
-    my ($val, $planneddate) = @_;
-    my ( $calculated, $newlastvalue1, $newlastvalue2, $newlastvalue3,
+    my ($subscription, $pattern, $planneddate) = @_;
+
+    return unless ($subscription and $pattern);
+
+    my ( $newlastvalue1, $newlastvalue2, $newlastvalue3,
     $newinnerloop1, $newinnerloop2, $newinnerloop3 );
     my $count = 1;
 
-    if($val->{'skip_serialseq'}) {
-        my @irreg = split /;/, $val->{'irregularity'};
+    if ($subscription->{'skip_serialseq'}) {
+        my @irreg = split /;/, $subscription->{'irregularity'};
         if(@irreg > 0) {
             my $irregularities = {};
             $irregularities->{$_} = 1 foreach(@irreg);
-            my $issueno = GetFictiveIssueNumber($val, $planneddate) + 1;
+            my $issueno = GetFictiveIssueNumber($subscription, $planneddate) + 1;
             while($irregularities->{$issueno}) {
                 $count++;
                 $issueno++;
@@ -916,64 +927,67 @@ sub GetNextSeq {
         }
     }
 
-    my $pattern = $val->{numberpattern};
-    $calculated    = $val->{numberingmethod};
-    my $locale = $val->{locale};
-    $newlastvalue1 = $val->{lastvalue1} || 0;
-    $newlastvalue2 = $val->{lastvalue2} || 0;
-    $newlastvalue3 = $val->{lastvalue3} || 0;
-    $newinnerloop1 = $val->{innerloop1} || 0;
-    $newinnerloop2 = $val->{innerloop2} || 0;
-    $newinnerloop3 = $val->{innerloop3} || 0;
-    my %calc;
-    foreach(qw/X Y Z/) {
-        $calc{$_} = 1 if ($val->{'numberingmethod'} =~ /\{$_\}/);
-    }
+    my $numberingmethod = $pattern->{numberingmethod};
+    my $calculated = "";
+    if ($numberingmethod) {
+        $calculated    = $numberingmethod;
+        my $locale = $subscription->{locale};
+        $newlastvalue1 = $subscription->{lastvalue1} || 0;
+        $newlastvalue2 = $subscription->{lastvalue2} || 0;
+        $newlastvalue3 = $subscription->{lastvalue3} || 0;
+        $newinnerloop1 = $subscription->{innerloop1} || 0;
+        $newinnerloop2 = $subscription->{innerloop2} || 0;
+        $newinnerloop3 = $subscription->{innerloop3} || 0;
+        my %calc;
+        foreach(qw/X Y Z/) {
+            $calc{$_} = 1 if ($numberingmethod =~ /\{$_\}/);
+        }
 
-    for(my $i = 0; $i < $count; $i++) {
-        if($calc{'X'}) {
-            # check if we have to increase the new value.
-            $newinnerloop1 += 1;
-            if ($newinnerloop1 >= $val->{every1}) {
-                $newinnerloop1  = 0;
-                $newlastvalue1 += $val->{add1};
+        for(my $i = 0; $i < $count; $i++) {
+            if($calc{'X'}) {
+                # check if we have to increase the new value.
+                $newinnerloop1 += 1;
+                if ($newinnerloop1 >= $pattern->{every1}) {
+                    $newinnerloop1  = 0;
+                    $newlastvalue1 += $pattern->{add1};
+                }
+                # reset counter if needed.
+                $newlastvalue1 = $pattern->{setto1} if ($newlastvalue1 > $pattern->{whenmorethan1});
+            }
+            if($calc{'Y'}) {
+                # check if we have to increase the new value.
+                $newinnerloop2 += 1;
+                if ($newinnerloop2 >= $pattern->{every2}) {
+                    $newinnerloop2  = 0;
+                    $newlastvalue2 += $pattern->{add2};
+                }
+                # reset counter if needed.
+                $newlastvalue2 = $pattern->{setto2} if ($newlastvalue2 > $pattern->{whenmorethan2});
+            }
+            if($calc{'Z'}) {
+                # check if we have to increase the new value.
+                $newinnerloop3 += 1;
+                if ($newinnerloop3 >= $pattern->{every3}) {
+                    $newinnerloop3  = 0;
+                    $newlastvalue3 += $pattern->{add3};
+                }
+                # reset counter if needed.
+                $newlastvalue3 = $pattern->{setto3} if ($newlastvalue3 > $pattern->{whenmorethan3});
             }
-            # reset counter if needed.
-            $newlastvalue1 = $val->{setto1} if ($newlastvalue1 > $val->{whenmorethan1});
+        }
+        if($calc{'X'}) {
+            my $newlastvalue1string = _numeration( $newlastvalue1, $pattern->{numbering1}, $locale );
+            $calculated =~ s/\{X\}/$newlastvalue1string/g;
         }
         if($calc{'Y'}) {
-            # check if we have to increase the new value.
-            $newinnerloop2 += 1;
-            if ($newinnerloop2 >= $val->{every2}) {
-                $newinnerloop2  = 0;
-                $newlastvalue2 += $val->{add2};
-            }
-            # reset counter if needed.
-            $newlastvalue2 = $val->{setto2} if ($newlastvalue2 > $val->{whenmorethan2});
+            my $newlastvalue2string = _numeration( $newlastvalue2, $pattern->{numbering2}, $locale );
+            $calculated =~ s/\{Y\}/$newlastvalue2string/g;
         }
         if($calc{'Z'}) {
-            # check if we have to increase the new value.
-            $newinnerloop3 += 1;
-            if ($newinnerloop3 >= $val->{every3}) {
-                $newinnerloop3  = 0;
-                $newlastvalue3 += $val->{add3};
-            }
-            # reset counter if needed.
-            $newlastvalue3 = $val->{setto3} if ($newlastvalue3 > $val->{whenmorethan3});
+            my $newlastvalue3string = _numeration( $newlastvalue3, $pattern->{numbering3}, $locale );
+            $calculated =~ s/\{Z\}/$newlastvalue3string/g;
         }
     }
-    if($calc{'X'}) {
-        my $newlastvalue1string = _numeration( $newlastvalue1, $val->{numbering1}, $locale );
-        $calculated =~ s/\{X\}/$newlastvalue1string/g;
-    }
-    if($calc{'Y'}) {
-        my $newlastvalue2string = _numeration( $newlastvalue2, $val->{numbering2}, $locale );
-        $calculated =~ s/\{Y\}/$newlastvalue2string/g;
-    }
-    if($calc{'Z'}) {
-        my $newlastvalue3string = _numeration( $newlastvalue3, $val->{numbering3}, $locale );
-        $calculated =~ s/\{Z\}/$newlastvalue3string/g;
-    }
 
     return ($calculated,
             $newlastvalue1, $newlastvalue2, $newlastvalue3,
@@ -982,31 +996,34 @@ sub GetNextSeq {
 
 =head2 GetSeq
 
-$calculated = GetSeq($val)
-$val is a hashref containing all the attributes of the table 'subscription'
+$calculated = GetSeq($subscription, $pattern)
+$subscription is a hashref containing all the attributes of the table 'subscription'
+$pattern is a hashref containing all the attributes of the table 'subscription_numberpatterns'
 this function transforms {X},{Y},{Z} to 150,0,0 for example.
 return:
-the sequence in integer format
+the sequence in string format
 
 =cut
 
 sub GetSeq {
-    my ($val) = @_;
-    my $locale = $val->{locale};
+    my ($subscription, $pattern) = @_;
 
-    my $pattern = $val->{numberpattern};
-    my $calculated = $val->{numberingmethod};
+    return unless ($subscription and $pattern);
 
-    my $newlastvalue1 = $val->{'lastvalue1'} || 0;
-    $newlastvalue1 = _numeration($newlastvalue1, $val->{numbering1}, $locale) if ($val->{numbering1}); # reset counter if needed.
+    my $locale = $subscription->{locale};
+
+    my $calculated = $pattern->{numberingmethod};
+
+    my $newlastvalue1 = $subscription->{'lastvalue1'} || 0;
+    $newlastvalue1 = _numeration($newlastvalue1, $pattern->{numbering1}, $locale) if ($pattern->{numbering1}); # reset counter if needed.
     $calculated =~ s/\{X\}/$newlastvalue1/g;
 
-    my $newlastvalue2 = $val->{'lastvalue2'} || 0;
-    $newlastvalue2 = _numeration($newlastvalue2, $val->{numbering2}, $locale) if ($val->{numbering2}); # reset counter if needed.
+    my $newlastvalue2 = $subscription->{'lastvalue2'} || 0;
+    $newlastvalue2 = _numeration($newlastvalue2, $pattern->{numbering2}, $locale) if ($pattern->{numbering2}); # reset counter if needed.
     $calculated =~ s/\{Y\}/$newlastvalue2/g;
 
-    my $newlastvalue3 = $val->{'lastvalue3'} || 0;
-    $newlastvalue3 = _numeration($newlastvalue3, $val->{numbering3}, $locale) if ($val->{numbering3}); # reset counter if needed.
+    my $newlastvalue3 = $subscription->{'lastvalue3'} || 0;
+    $newlastvalue3 = _numeration($newlastvalue3, $pattern->{numbering3}, $locale) if ($pattern->{numbering3}); # reset counter if needed.
     $calculated =~ s/\{Z\}/$newlastvalue3/g;
     return $calculated;
 }
@@ -1024,6 +1041,9 @@ the enddate or undef
 
 sub GetExpirationDate {
     my ( $subscriptionid, $startdate ) = @_;
+
+    return unless ($subscriptionid);
+
     my $dbh          = C4::Context->dbh;
     my $subscription = GetSubscription($subscriptionid);
     my $enddate;
@@ -1073,6 +1093,9 @@ the number of subscriptions
 
 sub CountSubscriptionFromBiblionumber {
     my ($biblionumber) = @_;
+
+    return unless ($biblionumber);
+
     my $dbh            = C4::Context->dbh;
     my $query          = "SELECT count(*) FROM subscription WHERE biblionumber=?";
     my $sth            = $dbh->prepare($query);
@@ -1092,6 +1115,9 @@ returns the number of rows affected
 
 sub ModSubscriptionHistory {
     my ( $subscriptionid, $histstartdate, $enddate, $receivedlist, $missinglist, $opacnote, $librariannote ) = @_;
+
+    return unless ($subscriptionid);
+
     my $dbh   = C4::Context->dbh;
     my $query = "UPDATE subscriptionhistory 
                     SET histstartdate=?,histenddate=?,recievedlist=?,missinglist=?,opacnote=?,librariannote=?
@@ -1161,6 +1187,7 @@ Note : if we change from "waited" to something else,then we will have to create
 sub ModSerialStatus {
     my ( $serialid, $serialseq, $planneddate, $publisheddate, $status, $notes ) = @_;
 
+    return unless ($serialid);
 
     #It is a usual serial
     # 1st, get previous status :
@@ -1205,34 +1232,29 @@ sub ModSerialStatus {
 
     # create new waited entry if needed (ie : was a "waited" and has changed)
     if ( $oldstatus == 1 && $status != 1 ) {
-        my $query = qq{
-            SELECT subscription.*, subscription_numberpatterns.*,
-                   subscription_frequencies.*
-            FROM subscription
-            LEFT JOIN subscription_numberpatterns ON subscription.numberpattern = subscription_numberpatterns.id
-            LEFT JOIN subscription_frequencies ON subscription.periodicity = subscription_frequencies.id
-            WHERE subscriptionid = ?
-        };
-        $sth = $dbh->prepare($query);
-        $sth->execute($subscriptionid);
-        my $val = $sth->fetchrow_hashref;
+        my $subscription = GetSubscription($subscriptionid);
+        my $pattern = C4::Serials::Numberpattern::GetSubscriptionNumberpattern($subscription->{numberpattern});
 
         # next issue number
-        my ( $newserialseq, $newlastvalue1, $newlastvalue2, $newlastvalue3, $newinnerloop1, $newinnerloop2, $newinnerloop3 ) = GetNextSeq($val, $publisheddate);
+        my (
+            $newserialseq,  $newlastvalue1, $newlastvalue2, $newlastvalue3,
+            $newinnerloop1, $newinnerloop2, $newinnerloop3
+          )
+          = GetNextSeq( $subscription, $pattern, $publisheddate );
 
         # next date (calculated from actual date & frequency parameters)
-        my $nextpublisheddate = GetNextDate($val, $publisheddate, 1);
+        my $nextpublisheddate = GetNextDate($subscription, $publisheddate, 1);
         my $nextpubdate = $nextpublisheddate;
-        NewIssue( $newserialseq, $subscriptionid, $val->{'biblionumber'}, 1, $nextpubdate, $nextpubdate );
+        NewIssue( $newserialseq, $subscriptionid, $subscription->{'biblionumber'}, 1, $nextpubdate, $nextpubdate );
         $query = "UPDATE subscription SET lastvalue1=?, lastvalue2=?, lastvalue3=?, innerloop1=?, innerloop2=?, innerloop3=?
                     WHERE  subscriptionid = ?";
         $sth = $dbh->prepare($query);
         $sth->execute( $newlastvalue1, $newlastvalue2, $newlastvalue3, $newinnerloop1, $newinnerloop2, $newinnerloop3, $subscriptionid );
 
         # check if an alert must be sent... (= a letter is defined & status became "arrived"
-        if ( $val->{letter} && $status == 2 && $oldstatus != 2 ) {
+        if ( $subscription->{letter} && $status == 2 && $oldstatus != 2 ) {
             require C4::Letters;
-            C4::Letters::SendAlerts( 'issue', $val->{subscriptionid}, $val->{letter} );
+            C4::Letters::SendAlerts( 'issue', $subscription->{subscriptionid}, $subscription->{letter} );
         }
     }
 
@@ -1275,7 +1297,7 @@ sub GetNextExpected {
             SELECT *
             FROM serial
             WHERE subscriptionid = ?
-            ORDER BY planneddate DESC
+            ORDER BY publisheddate DESC
             LIMIT 1
         };
         $sth = $dbh->prepare($query);
@@ -1323,7 +1345,7 @@ sub ModNextExpected {
 
 =head2 GetSubscriptionIrregularities
 
-=over4
+=over 4
 
 =item @irreg = &GetSubscriptionIrregularities($subscriptionid);
 get the list of irregularities for a subscription
@@ -1335,7 +1357,7 @@ get the list of irregularities for a subscription
 sub GetSubscriptionIrregularities {
     my $subscriptionid = shift;
 
-    return undef unless $subscriptionid;
+    return unless $subscriptionid;
 
     my $dbh = C4::Context->dbh;
     my $query = qq{
@@ -1405,7 +1427,7 @@ sub ModSubscription {
 =head2 NewSubscription
 
 $subscriptionid = &NewSubscription($auser,branchcode,$aqbooksellerid,$cost,$aqbudgetid,$biblionumber,
-    $startdate,$periodicity,$dow,$numberlength,$weeklength,$monthlength,
+    $startdate,$periodicity,$numberlength,$weeklength,$monthlength,
     $lastvalue1,$innerloop1,$lastvalue2,$innerloop2,$lastvalue3,$innerloop3,
     $status, $notes, $letter, $firstacquidate, $irregularity, $numberpattern,
     $callnumber, $hemisphere, $manualhistory, $internalnotes, $serialsadditems,
@@ -1475,18 +1497,11 @@ sub NewSubscription {
     $sth->execute( $biblionumber, $subscriptionid, $startdate, $notes, $internalnotes );
 
     # reread subscription to get a hash (for calculation of the 1st issue number)
-    $query = qq(
-        SELECT *
-        FROM   subscription
-        LEFT JOIN subscription_numberpatterns ON subscription.numberpattern = subscription_numberpatterns.id
-        WHERE  subscriptionid = ?
-    );
-    $sth = $dbh->prepare($query);
-    $sth->execute($subscriptionid);
-    my $val = $sth->fetchrow_hashref;
+    my $subscription = GetSubscription($subscriptionid);
+    my $pattern = C4::Serials::Numberpattern::GetSubscriptionNumberpattern($subscription->{numberpattern});
 
     # calculate issue number
-    my $serialseq = GetSeq($val);
+    my $serialseq = GetSeq($subscription, $pattern);
     $query = qq|
         INSERT INTO serial
             (serialseq,subscriptionid,biblionumber,status, planneddate, publisheddate)
@@ -1548,7 +1563,7 @@ sub ReNewSubscription {
     # renew subscription
     $query = qq|
         UPDATE subscription
-        SET    startdate=?,numberlength=?,weeklength=?,monthlength=?
+        SET    startdate=?,numberlength=?,weeklength=?,monthlength=?,reneweddate=NOW()
         WHERE  subscriptionid=?
     |;
     $sth = $dbh->prepare($query);
@@ -1588,6 +1603,8 @@ sub NewIssue {
     my ( $serialseq, $subscriptionid, $biblionumber, $status, $planneddate, $publisheddate, $notes ) = @_;
     ### FIXME biblionumber CAN be provided by subscriptionid. So Do we STILL NEED IT ?
 
+    return unless ($subscriptionid);
+
     my $dbh   = C4::Context->dbh;
     my $query = qq|
         INSERT INTO serial
@@ -1640,6 +1657,9 @@ return :
 
 sub ItemizeSerials {
     my ( $serialid, $info ) = @_;
+
+    return unless ($serialid);
+
     my $now = POSIX::strftime( "%Y-%m-%d", localtime );
 
     my $dbh   = C4::Context->dbh;
@@ -1774,6 +1794,9 @@ sub HasSubscriptionStrictlyExpired {
 
     # Getting end of subscription date
     my ($subscriptionid) = @_;
+
+    return unless ($subscriptionid);
+
     my $dbh              = C4::Context->dbh;
     my $subscription     = GetSubscription($subscriptionid);
     my $expirationdate = $subscription->{enddate} || GetExpirationDate($subscriptionid);
@@ -1815,6 +1838,9 @@ return :
 
 sub HasSubscriptionExpired {
     my ($subscriptionid) = @_;
+
+    return unless ($subscriptionid);
+
     my $dbh              = C4::Context->dbh;
     my $subscription     = GetSubscription($subscriptionid);
     my $frequency = C4::Serials::Frequency::GetSubscriptionFrequency($subscription->{periodicity});
@@ -1952,6 +1978,9 @@ name,title,planneddate,serialseq,serial.subscriptionid from tables : subscriptio
 
 sub GetLateOrMissingIssues {
     my ( $supplierid, $serialid, $order ) = @_;
+
+    return unless ( $supplierid or $serialid );
+
     my $dbh = C4::Context->dbh;
     my $sth;
     my $byserial = '';
@@ -2026,6 +2055,9 @@ called when a missing issue is found from the serials-recieve.pl file
 
 sub removeMissingIssue {
     my ( $sequence, $subscriptionid ) = @_;
+
+    return unless ($sequence and $subscriptionid);
+
     my $dbh = C4::Context->dbh;
     my $sth = $dbh->prepare("SELECT * FROM subscriptionhistory WHERE subscriptionid = ?");
     $sth->execute($subscriptionid);
@@ -2111,6 +2143,9 @@ used to show either an 'add' or 'edit' link
 
 sub check_routing {
     my ($subscriptionid) = @_;
+
+    return unless ($subscriptionid);
+
     my $dbh              = C4::Context->dbh;
     my $sth              = $dbh->prepare(
         "SELECT count(routingid) routingids FROM subscription LEFT JOIN subscriptionroutinglist 
@@ -2136,6 +2171,9 @@ of either 1 or highest current rank + 1
 
 sub addroutingmember {
     my ( $borrowernumber, $subscriptionid ) = @_;
+
+    return unless ($borrowernumber and $subscriptionid);
+
     my $rank;
     my $dbh = C4::Context->dbh;
     my $sth = $dbh->prepare( "SELECT max(ranking) rank FROM subscriptionroutinglist WHERE subscriptionid = ?" );
@@ -2736,6 +2774,55 @@ sub ReopenSubscription {
     $sth->execute( $subscriptionid );
 }
 
+=head2 subscriptionCurrentlyOnOrder
+
+    $bool = subscriptionCurrentlyOnOrder( $subscriptionid );
+
+Return 1 if subscription is currently on order else 0.
+
+=cut
+
+sub subscriptionCurrentlyOnOrder {
+    my ( $subscriptionid ) = @_;
+    my $dbh = C4::Context->dbh;
+    my $query = qq|
+        SELECT COUNT(*) FROM aqorders
+        WHERE subscriptionid = ?
+            AND datereceived IS NULL
+            AND datecancellationprinted IS NULL
+    |;
+    my $sth = $dbh->prepare( $query );
+    $sth->execute($subscriptionid);
+    return $sth->fetchrow_array;
+}
+
+=head2 can_edit_subscription
+
+    $can = can_edit_subscription( $subscriptionid[, $userid] );
+
+Return 1 if the subscription is editable by the current logged user (or a given $userid), else 0.
+
+=cut
+
+sub can_edit_subscription {
+    my ( $subscription, $userid ) = @_;
+    return 0 unless C4::Context->userenv;
+    my $flags = C4::Context->userenv->{flags};
+    $userid ||= C4::Context->userenv->{'id'};
+    my $independent_branches = C4::Context->preference('IndependentBranches');
+    return 1 unless $independent_branches;
+    if( $flags % 2 == 1 # superlibrarian
+        or C4::Auth::haspermission( $userid, {serials => 'superserials'}),
+        or C4::Auth::haspermission( $userid, {serials => 'edit_subscription'}),
+        or not defined $subscription->{branchcode}
+        or $subscription->{branchcode} eq ''
+        or $subscription->{branchcode} eq C4::Context->userenv->{'branch'}
+    ) {
+        return 1;
+    }
+     return 0;
+}
+
 1;
 __END__