X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=C4%2FSerials.pm;h=d127066596a42b748bada89ea3bc94e8fae1e0d3;hb=4958a8a0f67d04c41eb300d9247c915f2346acf0;hp=72d6badfa102ebe8b4153050197e9a579c8f2613;hpb=d2052311cb232f98c801eb52d602b8970b38bc26;p=koha.git diff --git a/C4/Serials.pm b/C4/Serials.pm index 72d6badfa1..d127066596 100644 --- a/C4/Serials.pm +++ b/C4/Serials.pm @@ -20,10 +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; @@ -94,14 +96,14 @@ the array is in name order sub GetSuppliersWithLateIssues { my $dbh = C4::Context->dbh; my $query = qq| - SELECT DISTINCT id, name + SELECT DISTINCT id, name FROM subscription LEFT JOIN serial ON serial.subscriptionid=subscription.subscriptionid LEFT JOIN aqbooksellers ON subscription.aqbooksellerid = aqbooksellers.id 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, 7) ) AND subscription.closed = 0 ORDER BY name|; @@ -308,8 +310,12 @@ sub UpdateClaimdateIssues { my $dbh = C4::Context->dbh; $date = strftime( "%Y-%m-%d", localtime ) unless ($date); my $query = " - UPDATE serial SET claimdate = ?, status = 7 - WHERE serialid in (" . join( ",", map { '?' } @$serialids ) . ")"; + UPDATE serial + SET claimdate = ?, + status = 7, + claims_count = claims_count + 1 + WHERE serialid in (" . join( ",", map { '?' } @$serialids ) . ") + "; my $rq = $dbh->prepare($query); $rq->execute($date, @$serialids); return $rq->rows; @@ -418,13 +424,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'}; @@ -627,13 +635,27 @@ sub GetSubscriptions { =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 @@ -681,6 +703,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}%"; @@ -693,6 +719,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}"; @@ -709,9 +743,7 @@ sub SearchSubscriptions { for my $subscription ( @$results ) { $subscription->{cannotedit} = not can_edit_subscription( $subscription ); - $subscription->{cannotdisplay} = - ( C4::Context->preference("IndependentBranches") - and $subscription->{branchcode} ne C4::Context->userenv->{'branch'} ) ? 1 : 0; + $subscription->{cannotdisplay} = not can_show_subscription( $subscription ); } return @$results; @@ -742,7 +774,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); @@ -763,7 +795,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); @@ -819,7 +851,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 { @@ -851,7 +883,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); @@ -1129,50 +1161,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) @@ -1205,10 +1193,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 ); @@ -1217,14 +1201,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 ); } } @@ -1428,7 +1430,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. @@ -1499,14 +1501,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"); @@ -1977,7 +1979,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; @@ -1994,32 +1996,33 @@ sub GetLateOrMissingIssues { $sth = $dbh->prepare( "SELECT serialid, aqbooksellerid, name, - biblio.title, planneddate, serialseq, - serial.status, serial.subscriptionid, claimdate, + biblio.title, biblioitems.issn, planneddate, serialseq, + serial.status, serial.subscriptionid, claimdate, claims_count, subscription.branchcode - FROM serial - LEFT JOIN subscription ON serial.subscriptionid=subscription.subscriptionid + 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)) + WHERE subscription.subscriptionid = serial.subscriptionid + 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" ); } else { $sth = $dbh->prepare( - "SELECT + "SELECT serialid, aqbooksellerid, name, biblio.title, planneddate, serialseq, - serial.status, serial.subscriptionid, claimdate, + serial.status, serial.subscriptionid, claimdate, claims_count, subscription.branchcode - FROM serial - LEFT JOIN subscription ON serial.subscriptionid=subscription.subscriptionid + FROM serial + LEFT JOIN subscription ON serial.subscriptionid=subscription.subscriptionid 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)) + WHERE subscription.subscriptionid = serial.subscriptionid + 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" ); @@ -2029,9 +2032,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; @@ -2094,12 +2099,12 @@ called from claims.pl file sub updateClaim { my ($serialid) = @_; my $dbh = C4::Context->dbh; - my $sth = $dbh->prepare( - "UPDATE serial SET claimdate = now() - WHERE serialid = ? - " - ); - $sth->execute($serialid); + $dbh->do(q| + UPDATE serial + SET claimdate = NOW(), + claims_count = claims_count + 1 + WHERE serialid = ? + |, {}, $serialid ); return; } @@ -2498,13 +2503,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'}) { @@ -2515,10 +2522,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 @@ -2642,9 +2651,6 @@ sub GetNextDate { } return sprintf("%04d-%02d-%02d", $year, $month, $day); } - else { - return $publisheddate; - } } =head2 _numeration @@ -2663,44 +2669,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; } @@ -2794,22 +2791,63 @@ 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'}; - 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; + + 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;