From: Paul Poulain Date: Fri, 23 Mar 2012 09:24:19 +0000 (+0100) Subject: Merge remote-tracking branch 'origin/new/bug_7548' X-Git-Tag: v3.08.00~216 X-Git-Url: http://koha-dev.rot13.org:8081/gitweb/?a=commitdiff_plain;h=1474d95c103c27f90361b5b9b93851aff5d92d0c;hp=c7256d3447db9ad4cc27f04a6557eba19e1bc6dc;p=koha_gimpoz Merge remote-tracking branch 'origin/new/bug_7548' --- diff --git a/C4/Auth_with_cas.pm b/C4/Auth_with_cas.pm index b09623295c..e00e3a4d61 100644 --- a/C4/Auth_with_cas.pm +++ b/C4/Auth_with_cas.pm @@ -66,7 +66,7 @@ sub getMultipleAuth { # Logout from CAS sub logout_cas { my ($query) = @_; - my $uri = $ENV{'SCRIPT_URI'}; + my $uri = C4::Context->preference('OPACBaseURL') . $query->script_name(); my $casparam = $query->param('cas'); # FIXME: This should be more generic and handle whatever parameters there might be $uri .= "?cas=" . $casparam if (defined $casparam); @@ -78,7 +78,7 @@ sub logout_cas { # Login to CAS sub login_cas { my ($query) = @_; - my $uri = $ENV{'SCRIPT_URI'}; + my $uri = C4::Context->preference('OPACBaseURL') . $query->script_name(); my $casparam = $query->param('cas'); # FIXME: This should be more generic and handle whatever parameters there might be $uri .= "?cas=" . $casparam if (defined $casparam); @@ -91,7 +91,7 @@ sub login_cas { sub login_cas_url { my ($query, $key) = @_; - my $uri = $ENV{'SCRIPT_URI'}; + my $uri = C4::Context->preference('OPACBaseURL') . $query->script_name(); my $casparam = $query->param('cas'); # FIXME: This should be more generic and handle whatever parameters there might be $uri .= "?cas=" . $casparam if (defined $casparam); @@ -107,7 +107,7 @@ sub checkpw_cas { $debug and warn "checkpw_cas"; my ($dbh, $ticket, $query) = @_; my $retnumber; - my $uri = $ENV{'SCRIPT_URI'}; + my $uri = C4::Context->preference('OPACBaseURL') . $query->script_name(); my $casparam = $query->param('cas'); # FIXME: This should be more generic and handle whatever parameters there might be $uri .= "?cas=" . $casparam if (defined $casparam); @@ -157,7 +157,7 @@ sub check_api_auth_cas { $debug and warn "check_api_auth_cas"; my ($dbh, $PT, $query) = @_; my $retnumber; - my $url = $query->url(); + my $url = C4::Context->preference('OPACBaseURL') . $query->script_name(); my $casparam = $query->param('cas'); $casparam = $defaultcasserver if (not defined $casparam); diff --git a/C4/Biblio.pm b/C4/Biblio.pm index 39a2b7abd4..54db228e94 100644 --- a/C4/Biblio.pm +++ b/C4/Biblio.pm @@ -1686,7 +1686,7 @@ sub GetMarcSubjects { # ignore $9 my @this_link_loop = @link_loop; - push @subfields_loop, { code => $code, value => $value, link_loop => \@this_link_loop, separator => $separator } unless ( $subject_subfield->[0] eq 9 ); + push @subfields_loop, { code => $code, value => $value, link_loop => \@this_link_loop, separator => $separator } unless ( $subject_subfield->[0] eq 9 || $subject_subfield->[0] eq '0' ); $counter++; } @@ -1770,7 +1770,7 @@ sub GetMarcAuthors { link_loop => \@this_link_loop, separator => $separator } - unless ( $authors_subfield->[0] eq '9' ); + unless ( $authors_subfield->[0] eq '9' || $authors_subfield->[0] eq '0'); $count_auth++; } push @marcauthors, { MARCAUTHOR_SUBFIELDS_LOOP => \@subfields_loop }; diff --git a/C4/Branch.pm b/C4/Branch.pm index 7bd03264b7..21530287fb 100644 --- a/C4/Branch.pm +++ b/C4/Branch.pm @@ -204,8 +204,8 @@ sub ModBranch { (branchcode,branchname,branchaddress1, branchaddress2,branchaddress3,branchzip,branchcity,branchstate, branchcountry,branchphone,branchfax,branchemail, - branchurl,branchip,branchprinter,branchnotes) - VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) + branchurl,branchip,branchprinter,branchnotes,opac_info) + VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) "; my $sth = $dbh->prepare($query); $sth->execute( @@ -217,7 +217,7 @@ sub ModBranch { $data->{'branchphone'}, $data->{'branchfax'}, $data->{'branchemail'}, $data->{'branchurl'}, $data->{'branchip'}, $data->{'branchprinter'}, - $data->{'branchnotes'}, + $data->{'branchnotes'}, $data->{opac_info}, ); return 1 if $dbh->err; } else { @@ -227,7 +227,7 @@ sub ModBranch { branchaddress2=?,branchaddress3=?,branchzip=?, branchcity=?,branchstate=?,branchcountry=?,branchphone=?, branchfax=?,branchemail=?,branchurl=?,branchip=?, - branchprinter=?,branchnotes=? + branchprinter=?,branchnotes=?,opac_info=? WHERE branchcode=? "; my $sth = $dbh->prepare($query); @@ -240,7 +240,7 @@ sub ModBranch { $data->{'branchphone'}, $data->{'branchfax'}, $data->{'branchemail'}, $data->{'branchurl'}, $data->{'branchip'}, $data->{'branchprinter'}, - $data->{'branchnotes'}, + $data->{'branchnotes'}, $data->{opac_info}, $data->{'branchcode'}, ); } diff --git a/C4/Circulation.pm b/C4/Circulation.pm index b6e86e0d45..9c43f362b0 100644 --- a/C4/Circulation.pm +++ b/C4/Circulation.pm @@ -21,6 +21,7 @@ package C4::Circulation; use strict; #use warnings; FIXME - Bug 2505 +use DateTime; use C4::Context; use C4::Stats; use C4::Reserves; @@ -28,28 +29,18 @@ use C4::Biblio; use C4::Items; use C4::Members; use C4::Dates; -use C4::Calendar; +use C4::Dates qw(format_date); use C4::Accounts; use C4::ItemCirculationAlertPreference; -use C4::Dates qw(format_date); use C4::Message; use C4::Debug; -use Date::Calc qw( - Today - Today_and_Now - Add_Delta_YM - Add_Delta_DHMS - Date_to_Days - Day_of_Week - Add_Delta_Days - check_date - Delta_Days -); -use POSIX qw(strftime); use C4::Branch; # GetBranches use C4::Log; # logaction use Data::Dumper; +use Koha::DateUtils; +use Koha::Calendar; +use Carp; use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); @@ -442,7 +433,7 @@ sub TooMany { my $branch_borrower_circ_rule = GetBranchBorrowerCircRule($branch, $cat_borrower); if (defined($branch_borrower_circ_rule->{maxissueqty})) { my @bind_params = (); - my $branch_count_query = "SELECT COUNT(*) FROM issues + my $branch_count_query = "SELECT COUNT(*) FROM issues JOIN items USING (itemnumber) WHERE borrowernumber = ? "; push @bind_params, $borrower->{borrowernumber}; @@ -691,21 +682,28 @@ sub CanBookBeIssued { # # DUE DATE is OK ? -- should already have checked. # + if ($duedate && ref $duedate ne 'DateTime') { + $duedate = dt_from_string($duedate); + } + my $now = DateTime->now( time_zone => C4::Context->tz() ); unless ( $duedate ) { - my $issuedate = strftime( "%Y-%m-%d", localtime ); + my $issuedate = $now->clone(); my $branch = _GetCircControlBranch($item,$borrower); my $itype = ( C4::Context->preference('item-level_itypes') ) ? $item->{'itype'} : $biblioitem->{'itemtype'}; - $duedate = CalcDateDue( C4::Dates->new( $issuedate, 'iso' ), $itype, $branch, $borrower ); + $duedate = CalcDateDue( $issuedate, $itype, $branch, $borrower ); # Offline circ calls AddIssue directly, doesn't run through here # So issuingimpossible should be ok. } if ($duedate) { - $needsconfirmation{INVALID_DATE} = $duedate->output('syspref') - unless $duedate->output('iso') ge C4::Dates->today('iso'); + my $today = $now->clone(); + $today->truncate( to => 'minutes'); + if (DateTime->compare($duedate,$today) == -1 ) { # duedate cannot be before now + $needsconfirmation{INVALID_DATE} = output_pref($duedate); + } } else { - $issuingimpossible{INVALID_DATE} = $duedate->output('syspref'); + $issuingimpossible{INVALID_DATE} = output_pref($duedate); } # @@ -726,13 +724,25 @@ sub CanBookBeIssued { if ( $borrower->{flags}->{'DBARRED'} ) { $issuingimpossible{DEBARRED} = 1; } - if ( $borrower->{'dateexpiry'} eq '0000-00-00') { + if ( !defined $borrower->{dateexpiry} || $borrower->{'dateexpiry'} eq '0000-00-00') { $issuingimpossible{EXPIRED} = 1; } else { - my @expirydate= split /-/,$borrower->{'dateexpiry'}; - if($expirydate[0]==0 || $expirydate[1]==0|| $expirydate[2]==0 || - Date_to_Days(Today) > Date_to_Days( @expirydate )) { - $issuingimpossible{EXPIRED} = 1; + my ($y, $m, $d) = split /-/,$borrower->{'dateexpiry'}; + if ($y && $m && $d) { # are we really writing oinvalid dates to borrs + my $expiry_dt = DateTime->new( + year => $y, + month => $m, + day => $d, + time_zone => C4::Context->tz, + ); + $expiry_dt->truncate( to => 'days'); + my $today = $now->clone()->truncate(to => 'days'); + if (DateTime->compare($today, $expiry_dt) == 1) { + $issuingimpossible{EXPIRED} = 1; + } + } else { + carp("Invalid expity date in borr"); + $issuingimpossible{EXPIRED} = 1; } } # @@ -741,7 +751,7 @@ sub CanBookBeIssued { # DEBTS my ($amount) = - C4::Members::GetMemberAccountRecords( $borrower->{'borrowernumber'}, '' && $duedate->output('iso') ); + C4::Members::GetMemberAccountRecords( $borrower->{'borrowernumber'}, '' && $duedate->ymd() ); my $amountlimit = C4::Context->preference("noissuescharge"); my $allowfineoverride = C4::Context->preference("AllowFineOverride"); my $allfinesneedoverride = C4::Context->preference("AllFinesNeedOverride"); @@ -783,7 +793,7 @@ sub CanBookBeIssued { # my ($current_loan_count, $max_loans_allowed) = TooMany( $borrower, $item->{biblionumber}, $item ); # if TooMany max_loans_allowed returns 0 the user doesn't have permission to check out this book - if ($max_loans_allowed eq 0) { + if (defined $max_loans_allowed && $max_loans_allowed == 0) { $needsconfirmation{PATRON_CANT} = 1; } else { if($max_loans_allowed){ @@ -958,13 +968,20 @@ sub AddIssue { my ( $borrower, $barcode, $datedue, $cancelreserve, $issuedate, $sipmode) = @_; my $dbh = C4::Context->dbh; my $barcodecheck=CheckValidBarcode($barcode); + if ($datedue && ref $datedue ne 'DateTime') { + $datedue = dt_from_string($datedue); + } # $issuedate defaults to today. if ( ! defined $issuedate ) { - $issuedate = strftime( "%Y-%m-%d", localtime ); - # TODO: for hourly circ, this will need to be a C4::Dates object - # and all calls to AddIssue including issuedate will need to pass a Dates object. + $issuedate = DateTime->now(time_zone => C4::Context->tz()); } - if ($borrower and $barcode and $barcodecheck ne '0'){ + else { + if ( ref $issuedate ne 'DateTime') { + $issuedate = dt_from_string($issuedate); + + } + } + if ($borrower and $barcode and $barcodecheck ne '0'){#??? wtf # find which item we issue my $item = GetItem('', $barcode) or return undef; # if we don't get an Item, abort. my $branch = _GetCircControlBranch($item,$borrower); @@ -979,12 +996,12 @@ sub AddIssue { # check if we just renew the issue. # if ($actualissue->{borrowernumber} eq $borrower->{'borrowernumber'}) { - $datedue = AddRenewal( - $borrower->{'borrowernumber'}, - $item->{'itemnumber'}, - $branch, - $datedue, - $issuedate, # here interpreted as the renewal date + $datedue = AddRenewal( + $borrower->{'borrowernumber'}, + $item->{'itemnumber'}, + $branch, + $datedue, + $issuedate, # here interpreted as the renewal date ); } else { @@ -999,7 +1016,6 @@ sub AddIssue { } MoveReserve( $item->{'itemnumber'}, $borrower->{'borrowernumber'}, $cancelreserve ); - # Starting process for transfer job (checking transfert and validate it if we have one) my ($datesent) = GetTransfers($item->{'itemnumber'}); if ($datesent) { @@ -1018,23 +1034,23 @@ sub AddIssue { # Record in the database the fact that the book was issued. my $sth = $dbh->prepare( - "INSERT INTO issues + "INSERT INTO issues (borrowernumber, itemnumber,issuedate, date_due, branchcode) VALUES (?,?,?,?,?)" ); unless ($datedue) { my $itype = ( C4::Context->preference('item-level_itypes') ) ? $biblio->{'itype'} : $biblio->{'itemtype'}; - $datedue = CalcDateDue( C4::Dates->new( $issuedate, 'iso' ), $itype, $branch, $borrower ); + $datedue = CalcDateDue( $issuedate, $itype, $branch, $borrower ); } + $datedue->truncate( to => 'minutes'); $sth->execute( $borrower->{'borrowernumber'}, # borrowernumber $item->{'itemnumber'}, # itemnumber - $issuedate, # issuedate - $datedue->output('iso'), # date_due + $issuedate->strftime('%Y-%m-%d %H:%M:00'), # issuedate + $datedue->strftime('%Y-%m-%d %H:%M:00'), # date_due C4::Context->userenv->{'branch'} # branchcode ); - $sth->finish; if ( C4::Context->preference('ReturnToShelvingCart') ) { ## ReturnToShelvingCart is on, anything issued should be taken off the cart. CartToShelf( $item->{'itemnumber'} ); } @@ -1048,8 +1064,8 @@ sub AddIssue { ModItem({ issues => $item->{'issues'}, holdingbranch => C4::Context->userenv->{'branch'}, itemlost => 0, - datelastborrowed => C4::Dates->new()->output('iso'), - onloan => $datedue->output('iso'), + datelastborrowed => DateTime->now(time_zone => C4::Context->tz())->ymd(), + onloan => $datedue->ymd(), }, $item->{'biblionumber'}, $item->{'itemnumber'}); ModDateLastSeen( $item->{'itemnumber'} ); @@ -1111,53 +1127,57 @@ sub GetLoanLength { my $dbh = C4::Context->dbh; my $sth = $dbh->prepare( -"select issuelength from issuingrules where categorycode=? and itemtype=? and branchcode=? and issuelength is not null" +'select issuelength, lengthunit from issuingrules where categorycode=? and itemtype=? and branchcode=? and issuelength is not null' ); # warn "in get loan lenght $borrowertype $itemtype $branchcode "; # try to find issuelength & return the 1st available. # check with borrowertype, itemtype and branchcode, then without one of those parameters $sth->execute( $borrowertype, $itemtype, $branchcode ); my $loanlength = $sth->fetchrow_hashref; - return $loanlength->{issuelength} - if defined($loanlength) && $loanlength->{issuelength} ne 'NULL'; + return $loanlength + if defined($loanlength) && $loanlength->{issuelength}; - $sth->execute( $borrowertype, "*", $branchcode ); + $sth->execute( $borrowertype, '*', $branchcode ); $loanlength = $sth->fetchrow_hashref; - return $loanlength->{issuelength} - if defined($loanlength) && $loanlength->{issuelength} ne 'NULL'; + return $loanlength + if defined($loanlength) && $loanlength->{issuelength}; - $sth->execute( "*", $itemtype, $branchcode ); + $sth->execute( '*', $itemtype, $branchcode ); $loanlength = $sth->fetchrow_hashref; - return $loanlength->{issuelength} - if defined($loanlength) && $loanlength->{issuelength} ne 'NULL'; + return $loanlength + if defined($loanlength) && $loanlength->{issuelength}; - $sth->execute( "*", "*", $branchcode ); + $sth->execute( '*', '*', $branchcode ); $loanlength = $sth->fetchrow_hashref; - return $loanlength->{issuelength} - if defined($loanlength) && $loanlength->{issuelength} ne 'NULL'; + return $loanlength + if defined($loanlength) && $loanlength->{issuelength}; - $sth->execute( $borrowertype, $itemtype, "*" ); + $sth->execute( $borrowertype, $itemtype, '*' ); $loanlength = $sth->fetchrow_hashref; - return $loanlength->{issuelength} - if defined($loanlength) && $loanlength->{issuelength} ne 'NULL'; + return $loanlength + if defined($loanlength) && $loanlength->{issuelength}; - $sth->execute( $borrowertype, "*", "*" ); + $sth->execute( $borrowertype, '*', '*' ); $loanlength = $sth->fetchrow_hashref; - return $loanlength->{issuelength} - if defined($loanlength) && $loanlength->{issuelength} ne 'NULL'; + return $loanlength + if defined($loanlength) && $loanlength->{issuelength}; - $sth->execute( "*", $itemtype, "*" ); + $sth->execute( '*', $itemtype, '*' ); $loanlength = $sth->fetchrow_hashref; - return $loanlength->{issuelength} - if defined($loanlength) && $loanlength->{issuelength} ne 'NULL'; + return $loanlength + if defined($loanlength) && $loanlength->{issuelength}; - $sth->execute( "*", "*", "*" ); + $sth->execute( '*', '*', '*' ); $loanlength = $sth->fetchrow_hashref; - return $loanlength->{issuelength} - if defined($loanlength) && $loanlength->{issuelength} ne 'NULL'; + return $loanlength + if defined($loanlength) && $loanlength->{issuelength}; # if no rule is set => 21 days (hardcoded) - return 21; + return { + issuelength => 21, + lengthunit => 'days', + }; + } @@ -1178,43 +1198,43 @@ sub GetHardDueDate { ); $sth->execute( $borrowertype, $itemtype, $branchcode ); my $results = $sth->fetchrow_hashref; - return (C4::Dates->new($results->{hardduedate}, 'iso'),$results->{hardduedatecompare}) - if defined($results) && $results->{hardduedate} ne 'NULL'; + return (dt_from_string($results->{hardduedate}, 'iso'),$results->{hardduedatecompare}) + if defined($results) && $results->{hardduedate}; $sth->execute( $borrowertype, "*", $branchcode ); $results = $sth->fetchrow_hashref; - return (C4::Dates->new($results->{hardduedate}, 'iso'),$results->{hardduedatecompare}) - if defined($results) && $results->{hardduedate} ne 'NULL'; + return (dt_from_string($results->{hardduedate}, 'iso'),$results->{hardduedatecompare}) + if defined($results) && $results->{hardduedate}; $sth->execute( "*", $itemtype, $branchcode ); $results = $sth->fetchrow_hashref; - return (C4::Dates->new($results->{hardduedate}, 'iso'),$results->{hardduedatecompare}) - if defined($results) && $results->{hardduedate} ne 'NULL'; + return (dt_from_string($results->{hardduedate}, 'iso'),$results->{hardduedatecompare}) + if defined($results) && $results->{hardduedate}; $sth->execute( "*", "*", $branchcode ); $results = $sth->fetchrow_hashref; - return (C4::Dates->new($results->{hardduedate}, 'iso'),$results->{hardduedatecompare}) - if defined($results) && $results->{hardduedate} ne 'NULL'; + return (dt_from_string($results->{hardduedate}, 'iso'),$results->{hardduedatecompare}) + if defined($results) && $results->{hardduedate}; $sth->execute( $borrowertype, $itemtype, "*" ); $results = $sth->fetchrow_hashref; - return (C4::Dates->new($results->{hardduedate}, 'iso'),$results->{hardduedatecompare}) - if defined($results) && $results->{hardduedate} ne 'NULL'; + return (dt_from_string($results->{hardduedate}, 'iso'),$results->{hardduedatecompare}) + if defined($results) && $results->{hardduedate}; $sth->execute( $borrowertype, "*", "*" ); $results = $sth->fetchrow_hashref; - return (C4::Dates->new($results->{hardduedate}, 'iso'),$results->{hardduedatecompare}) - if defined($results) && $results->{hardduedate} ne 'NULL'; + return (dt_from_string($results->{hardduedate}, 'iso'),$results->{hardduedatecompare}) + if defined($results) && $results->{hardduedate}; $sth->execute( "*", $itemtype, "*" ); $results = $sth->fetchrow_hashref; - return (C4::Dates->new($results->{hardduedate}, 'iso'),$results->{hardduedatecompare}) - if defined($results) && $results->{hardduedate} ne 'NULL'; + return (dt_from_string($results->{hardduedate}, 'iso'),$results->{hardduedatecompare}) + if defined($results) && $results->{hardduedate}; $sth->execute( "*", "*", "*" ); $results = $sth->fetchrow_hashref; - return (C4::Dates->new($results->{hardduedate}, 'iso'),$results->{hardduedatecompare}) - if defined($results) && $results->{hardduedate} ne 'NULL'; + return (dt_from_string($results->{hardduedate}, 'iso'),$results->{hardduedatecompare}) + if defined($results) && $results->{hardduedate}; # if no rule is set => return undefined return (undef, undef); @@ -1581,7 +1601,8 @@ sub AddReturn { # define circControlBranch only if dropbox mode is set # don't allow dropbox mode to create an invalid entry in issues (issuedate > today) # FIXME: check issuedate > returndate, factoring in holidays - $circControlBranch = _GetCircControlBranch($item,$borrower) unless ( $item->{'issuedate'} eq C4::Dates->today('iso') );; + #$circControlBranch = _GetCircControlBranch($item,$borrower) unless ( $item->{'issuedate'} eq C4::Dates->today('iso') );; + $circControlBranch = _GetCircControlBranch($item,$borrower); } if ($borrowernumber) { @@ -1718,27 +1739,27 @@ routine in C. sub MarkIssueReturned { my ( $borrowernumber, $itemnumber, $dropbox_branch, $returndate, $privacy ) = @_; my $dbh = C4::Context->dbh; - my $query = "UPDATE issues SET returndate="; + my $query = 'UPDATE issues SET returndate='; my @bind; if ($dropbox_branch) { - my $calendar = C4::Calendar->new( branchcode => $dropbox_branch ); - my $dropboxdate = $calendar->addDate( C4::Dates->new(), -1 ); - $query .= " ? "; - push @bind, $dropboxdate->output('iso'); + my $calendar = Koha::Calendar->new( branchcode => $dropbox_branch ); + my $dropboxdate = $calendar->addDate( DateTime->now( time_zone => C4::Context->tz), -1 ); + $query .= ' ? '; + push @bind, $dropboxdate->strftime('%Y-%m-%d %H:%M'); } elsif ($returndate) { - $query .= " ? "; + $query .= ' ? '; push @bind, $returndate; } else { - $query .= " now() "; + $query .= ' now() '; } - $query .= " WHERE borrowernumber = ? AND itemnumber = ?"; + $query .= ' WHERE borrowernumber = ? AND itemnumber = ?'; push @bind, $borrowernumber, $itemnumber; # FIXME transaction my $sth_upd = $dbh->prepare($query); $sth_upd->execute(@bind); - my $sth_copy = $dbh->prepare("INSERT INTO old_issues SELECT * FROM issues + my $sth_copy = $dbh->prepare('INSERT INTO old_issues SELECT * FROM issues WHERE borrowernumber = ? - AND itemnumber = ?"); + AND itemnumber = ?'); $sth_copy->execute($borrowernumber, $itemnumber); # anonymise patron checkout immediately if $privacy set to 2 and AnonymousPatron is set to a valid borrowernumber if ( $privacy == 2) { @@ -1772,18 +1793,16 @@ Internal function, called only by AddReturn that calculate and update the user f sub _FixFineDaysOnReturn { my ( $borrower, $item, $datedue ) = @_; - - if ($datedue) { - $datedue = C4::Dates->new( $datedue, "iso" ); - } else { - return; - } + return unless ($datedue); + + my $dt_due = dt_from_string( $datedue ); + my $dt_today = DateTime->now( time_zone => C4::Context->tz() ); my $branchcode = _GetCircControlBranch( $item, $borrower ); - my $calendar = C4::Calendar->new( branchcode => $branchcode ); - my $today = C4::Dates->new(); + my $calendar = Koha::Calendar->new( branchcode => $branchcode ); - my $deltadays = $calendar->daysBetween( $datedue, C4::Dates->new() ); + # $deltadays is a DateTime::Duration object + my $deltadays = $calendar->days_between( $dt_due, $dt_today ); my $circcontrol = C4::Context::preference('CircControl'); my $issuingrule = GetIssuingRule( $borrower->{categorycode}, $item->{itype}, $branchcode ); @@ -1791,22 +1810,22 @@ sub _FixFineDaysOnReturn { # exit if no finedays defined return unless $finedays; - my $grace = $issuingrule->{firstremind}; - - if ( $deltadays - $grace > 0 ) { - my @newdate = Add_Delta_Days( Today(), $deltadays * $finedays ); - my $isonewdate = join( '-', @newdate ); - my ( $deby, $debm, $debd ) = split( /-/, $borrower->{debarred} ); - if ( check_date( $deby, $debm, $debd ) ) { - my @olddate = split( /-/, $borrower->{debarred} ); - - if ( Delta_Days( @olddate, @newdate ) > 0 ) { - C4::Members::DebarMember( $borrower->{borrowernumber}, $isonewdate ); - return $isonewdate; + my $grace = DateTime::Duration->new( days => $issuingrule->{firstremind} ); + + if ( ( $deltadays - $grace )->is_positive ) { # you can't compare DateTime::Durations with logical operators + my $new_debar_dt = $dt_today->clone()->add_duration( $deltadays * $finedays ); + my $borrower_debar_dt = dt_from_string( $borrower->{debarred} ); + # check to see if the current debar date is a valid date + if ( $borrower->{debarred} && $borrower_debar_dt ) { + # if so, is it before the new date? update only if true + if ( DateTime->compare( $borrower_debar_dt, $new_debar_dt ) == -1 ) { + C4::Members::DebarMember( $borrower->{borrowernumber}, $new_debar_dt->ymd() ); + return $new_debar_dt->ymd(); } + # if the borrower's debar date is not set or valid, debar them } else { - C4::Members::DebarMember( $borrower->{borrowernumber}, $isonewdate ); - return $isonewdate; + C4::Members::DebarMember( $borrower->{borrowernumber}, $new_debar_dt->ymd() ); + return $new_debar_dt->ymd(); } } } @@ -2024,14 +2043,19 @@ sub GetItemIssue { return unless $itemnumber; my $sth = C4::Context->dbh->prepare( "SELECT * - FROM issues + FROM issues LEFT JOIN items ON issues.itemnumber=items.itemnumber WHERE issues.itemnumber=?"); $sth->execute($itemnumber); my $data = $sth->fetchrow_hashref; return unless $data; - $data->{'overdue'} = ($data->{'date_due'} lt C4::Dates->today('iso')) ? 1 : 0; - return ($data); + $data->{issuedate} = dt_from_string($data->{issuedate}, 'sql'); + $data->{issuedate}->truncate(to => 'minutes'); + $data->{date_due} = dt_from_string($data->{date_due}, 'sql'); + $data->{date_due}->truncate(to => 'minutes'); + my $dt = DateTime->now( time_zone => C4::Context->tz)->truncate( to => 'minutes'); + $data->{'overdue'} = DateTime->compare($data->{'date_due'}, $dt ) == -1 ? 1 : 0; + return $data; } =head2 GetOpenIssue @@ -2073,14 +2097,15 @@ Returns reference to an array of hashes sub GetItemIssues { my ( $itemnumber, $history ) = @_; - my $today = C4::Dates->today('iso'); # get today date - my $sql = "SELECT * FROM issues + my $today = DateTime->now( time_zome => C4::Context->tz); # get today date + $today->truncate( to => 'minutes' ); + my $sql = "SELECT * FROM issues JOIN borrowers USING (borrowernumber) JOIN items USING (itemnumber) WHERE issues.itemnumber = ? "; if ($history) { $sql .= "UNION ALL - SELECT * FROM old_issues + SELECT * FROM old_issues LEFT JOIN borrowers USING (borrowernumber) JOIN items USING (itemnumber) WHERE old_issues.itemnumber = ? "; @@ -2094,7 +2119,10 @@ sub GetItemIssues { } my $results = $sth->fetchall_arrayref({}); foreach (@$results) { - $_->{'overdue'} = ($_->{'date_due'} lt $today) ? 1 : 0; + my $date_due = dt_from_string($_->{date_due},'sql'); + $date_due->truncate( to => 'minutes' ); + + $_->{overdue} = (DateTime->compare($date_due, $today) == -1) ? 1 : 0; } return $results; } @@ -2224,7 +2252,7 @@ sub CanBookBeRenewed { SELECT borrowers.categorycode, biblioitems.itemtype, issues.renewals, renewalsallowed, $controlbranch FROM issuingrules, - issues + issues LEFT JOIN items USING (itemnumber) LEFT JOIN borrowers USING (borrowernumber) LEFT JOIN biblioitems USING (biblioitemnumber) @@ -2295,7 +2323,7 @@ sub AddRenewal { my $itemnumber = shift or return undef; my $branch = shift; my $datedue = shift; - my $lastreneweddate = shift || C4::Dates->new()->output('iso'); + my $lastreneweddate = shift || DateTime->now(time_zone => C4::Context->tz)->ymd(); my $item = GetItem($itemnumber) or return undef; my $biblio = GetBiblioFromItemNumber($itemnumber) or return undef; @@ -2309,9 +2337,9 @@ sub AddRenewal { $sth->execute( $borrowernumber, $itemnumber ); my $issuedata = $sth->fetchrow_hashref; $sth->finish; - if($datedue && ! $datedue->output('iso')){ - warn "Invalid date passed to AddRenewal."; - return undef; + if(defined $datedue && ref $datedue ne 'DateTime' ) { + carp 'Invalid date passed to AddRenewal.'; + return; } # If the due date wasn't specified, calculate it by adding the # book's loan length to today's date or the current due date @@ -2322,8 +2350,8 @@ sub AddRenewal { my $itemtype = (C4::Context->preference('item-level_itypes')) ? $biblio->{'itype'} : $biblio->{'itemtype'}; $datedue = (C4::Context->preference('RenewalPeriodBase') eq 'date_due') ? - C4::Dates->new($issuedata->{date_due}, 'iso') : - C4::Dates->new(); + $issuedata->{date_due} : + DateTime->now( time_zone => C4::Context->tz()); $datedue = CalcDateDue($datedue,$itemtype,$issuedata->{'branchcode'},$borrower); } @@ -2334,12 +2362,13 @@ sub AddRenewal { WHERE borrowernumber=? AND itemnumber=?" ); - $sth->execute( $datedue->output('iso'), $renews, $lastreneweddate, $borrowernumber, $itemnumber ); + + $sth->execute( $datedue->strftime('%Y-%m-%d %H:%M'), $renews, $lastreneweddate, $borrowernumber, $itemnumber ); $sth->finish; # Update the renewal count on the item, and tell zebra to reindex $renews = $biblio->{'renewals'} + 1; - ModItem({ renewals => $renews, onloan => $datedue->output('iso') }, $biblio->{'biblionumber'}, $itemnumber); + ModItem({ renewals => $renews, onloan => $datedue->strftime('%Y-%m-%d %H:%M')}, $biblio->{'biblionumber'}, $itemnumber); # Charge a new rental fee, if applicable? my ( $charge, $type ) = GetIssuingCharges( $itemnumber, $borrowernumber ); @@ -2357,7 +2386,6 @@ sub AddRenewal { $sth->execute( $borrowernumber, $accountno, $charge, $manager_id, "Renewal of Rental Item $item->{'title'} $item->{'barcode'}", 'Rent', $charge, $itemnumber ); - $sth->finish; } # Log the renewal UpdateStats( $branch, 'renew', $charge, '', $itemnumber, $item->{itype}, $borrowernumber); @@ -2767,88 +2795,89 @@ C<$borrower> = Borrower object =cut -sub CalcDateDue { - my ($startdate,$itemtype,$branch,$borrower) = @_; - my $datedue; - my $loanlength = GetLoanLength($borrower->{'categorycode'},$itemtype, $branch); +sub CalcDateDue { + my ( $startdate, $itemtype, $branch, $borrower ) = @_; - # if globalDueDate ON the datedue is set to that date - if ( C4::Context->preference('globalDueDate') - && ( C4::Context->preference('globalDueDate') =~ C4::Dates->regexp('syspref') ) ) { - $datedue = C4::Dates->new( C4::Context->preference('globalDueDate') ); - } else { - # otherwise, calculate the datedue as normal - if(C4::Context->preference('useDaysMode') eq 'Days') { # ignoring calendar - my $timedue = time + ($loanlength) * 86400; - #FIXME - assumes now even though we take a startdate - my @datearr = localtime($timedue); - $datedue = C4::Dates->new( sprintf("%04d-%02d-%02d", 1900 + $datearr[5], $datearr[4] + 1, $datearr[3]), 'iso'); - } else { - my $calendar = C4::Calendar->new( branchcode => $branch ); - $datedue = $calendar->addDate($startdate, $loanlength); - } - } + # loanlength now a href + my $loanlength = + GetLoanLength( $borrower->{'categorycode'}, $itemtype, $branch ); - # if Hard Due Dates are used, retreive them and apply as necessary - my ($hardduedate, $hardduedatecompare) = GetHardDueDate($borrower->{'categorycode'},$itemtype, $branch); - if ( $hardduedate && $hardduedate->output('iso') && $hardduedate->output('iso') ne '0000-00-00') { - # if the calculated due date is after the 'before' Hard Due Date (ceiling), override - if ( $datedue->output( 'iso' ) gt $hardduedate->output( 'iso' ) && $hardduedatecompare == -1) { - $datedue = $hardduedate; - # if the calculated date is before the 'after' Hard Due Date (floor), override - } elsif ( $datedue->output( 'iso' ) lt $hardduedate->output( 'iso' ) && $hardduedatecompare == 1) { - $datedue = $hardduedate; - # if the hard due date is set to 'exactly', overrride - } elsif ( $hardduedatecompare == 0) { - $datedue = $hardduedate; - } - # in all other cases, keep the date due as it is - } + my $datedue; - # if ReturnBeforeExpiry ON the datedue can't be after borrower expirydate - if ( C4::Context->preference('ReturnBeforeExpiry') && $datedue->output('iso') gt $borrower->{dateexpiry} ) { - $datedue = C4::Dates->new( $borrower->{dateexpiry}, 'iso' ); - } - - return $datedue; -} - -=head2 CheckValidDatedue - - $newdatedue = CheckValidDatedue($date_due,$itemnumber,$branchcode); + # if globalDueDate ON the datedue is set to that date + if (C4::Context->preference('globalDueDate') + && ( C4::Context->preference('globalDueDate') =~ + C4::Dates->regexp('syspref') ) + ) { + $datedue = dt_from_string( + C4::Context->preference('globalDueDate'), + C4::Context->preference('dateformat') + ); + } else { -This function does not account for holiday exceptions nor does it handle the 'useDaysMode' syspref . -To be replaced by CalcDateDue() once C4::Calendar use is tested. + # otherwise, calculate the datedue as normal + if ( C4::Context->preference('useDaysMode') eq 'Days' ) + { # ignoring calendar + my $dt = + DateTime->now( time_zone => C4::Context->tz() ) + ->truncate( to => 'minute' ); + if ( $loanlength->{lengthunit} eq 'hours' ) { + $dt->add( hours => $loanlength->{issuelength} ); + return $dt; + } else { # days + $dt->add( days => $loanlength->{issuelength} ); + $dt->set_hour(23); + $dt->set_minute(59); + return $dt; + } + } else { + my $dur; + if ($loanlength->{lengthunit} eq 'hours') { + $dur = DateTime::Duration->new( hours => $loanlength->{issuelength}); + } + else { # days + $dur = DateTime::Duration->new( days => $loanlength->{issuelength}); + } + if (ref $startdate ne 'DateTime' ) { + $startdate = dt_from_string($startdate); + } + my $calendar = Koha::Calendar->new( branchcode => $branch ); + $datedue = $calendar->addDate( $startdate, $dur, $loanlength->{lengthunit} ); + if ($loanlength->{lengthunit} eq 'days') { + $datedue->set_hour(23); + $datedue->set_minute(59); + } + } + } -this function validates the loan length against the holidays calendar, and adjusts the due date as per the 'useDaysMode' syspref. -C<$date_due> = returndate calculate with no day check -C<$itemnumber> = itemnumber -C<$branchcode> = location of issue (affected by 'CircControl' syspref) -C<$loanlength> = loan length prior to adjustment + # if Hard Due Dates are used, retreive them and apply as necessary + my ( $hardduedate, $hardduedatecompare ) = + GetHardDueDate( $borrower->{'categorycode'}, $itemtype, $branch ); + if ($hardduedate) { # hardduedates are currently dates + $hardduedate->truncate( to => 'minute' ); + $hardduedate->set_hour(23); + $hardduedate->set_minute(59); + my $cmp = DateTime->compare( $hardduedate, $datedue ); + +# if the calculated due date is after the 'before' Hard Due Date (ceiling), override +# if the calculated date is before the 'after' Hard Due Date (floor), override +# if the hard due date is set to 'exactly', overrride + if ( $hardduedatecompare == 0 || $hardduedatecompare == $cmp ) { + $datedue = $hardduedate->clone; + } -=cut + # in all other cases, keep the date due as it is + } -sub CheckValidDatedue { -my ($date_due,$itemnumber,$branchcode)=@_; -my @datedue=split('-',$date_due->output('iso')); -my $years=$datedue[0]; -my $month=$datedue[1]; -my $day=$datedue[2]; -# die "Item# $itemnumber ($branchcode) due: " . ${date_due}->output() . "\n(Y,M,D) = ($years,$month,$day)": -my $dow; -for (my $i=0;$i<2;$i++){ - $dow=Day_of_Week($years,$month,$day); - ($dow=0) if ($dow>6); - my $result=CheckRepeatableHolidays($itemnumber,$dow,$branchcode); - my $countspecial=CheckSpecialHolidays($years,$month,$day,$itemnumber,$branchcode); - my $countspecialrepeatable=CheckRepeatableSpecialHolidays($month,$day,$itemnumber,$branchcode); - if (($result ne '0') or ($countspecial ne '0') or ($countspecialrepeatable ne '0') ){ - $i=0; - (($years,$month,$day) = Add_Delta_Days($years,$month,$day, 1))if ($i ne '1'); + # if ReturnBeforeExpiry ON the datedue can't be after borrower expirydate + if ( C4::Context->preference('ReturnBeforeExpiry') ) { + my $expiry_dt = dt_from_string( $borrower->{dateexpiry}, 'iso' ); + if ( DateTime->compare( $datedue, $expiry_dt ) == 1 ) { + $datedue = $expiry_dt->clone; } } - my $newdatedue=C4::Dates->new(sprintf("%04d-%02d-%02d",$years,$month,$day),'iso'); -return $newdatedue; + + return $datedue; } diff --git a/C4/Context.pm b/C4/Context.pm index 0417c45075..67d31ee947 100644 --- a/C4/Context.pm +++ b/C4/Context.pm @@ -104,6 +104,7 @@ use XML::Simple; use C4::Boolean; use C4::Debug; use POSIX (); +use DateTime::TimeZone; =head1 NAME @@ -384,6 +385,7 @@ sub new { $self->{"userenv"} = undef; # User env $self->{"activeuser"} = undef; # current active user $self->{"shelves"} = undef; + $self->{tz} = undef; # local timezone object bless $self, $class; return $self; @@ -1112,6 +1114,24 @@ sub get_versions { } +=head2 tz + + C4::Context->tz + + Returns a DateTime::TimeZone object for the system timezone + +=cut + +sub tz { + my $self = shift; + if (!defined $context->{tz}) { + $context->{tz} = DateTime::TimeZone->new(name => 'local'); + } + return $context->{tz}; +} + + + 1; __END__ diff --git a/C4/ILSDI/Services.pm b/C4/ILSDI/Services.pm index 067afd7a98..2940c00fea 100644 --- a/C4/ILSDI/Services.pm +++ b/C4/ILSDI/Services.pm @@ -33,6 +33,7 @@ use C4::ILSDI::Utility; use XML::Simple; use HTML::Entities; use CGI; +use DateTime; =head1 NAME @@ -558,7 +559,7 @@ sub RenewLoan { # Hashref building my $out; $out->{'renewals'} = $issue->{'renewals'}; - $out->{'date_due'} = $issue->{'date_due'}; + $out->{date_due} = $issue->{date_due}->strftime('%Y-%m-%d %H:%S'); $out->{'success'} = $renewal[0]; $out->{'error'} = $renewal[1]; diff --git a/C4/Installer/PerlDependencies.pm b/C4/Installer/PerlDependencies.pm index 0a888a8124..ae012084b5 100644 --- a/C4/Installer/PerlDependencies.pm +++ b/C4/Installer/PerlDependencies.pm @@ -197,7 +197,37 @@ our $PERL_DEPS = { 'DateTime' => { 'usage' => 'Core', 'required' => '1', - 'min_ver' => '0.51' + 'min_ver' => '0.58' + }, + 'DateTime::TimeZone' => { + 'usage' => 'Core', + 'required' => '1', + 'min_ver' => '1.26' + }, + 'DateTime::Format::DateParse' => { + 'usage' => 'Core', + 'required' => '1', + 'min_ver' => '0.04' + }, + 'DateTime::Set' => { + 'usage' => 'Core', + 'required' => '1', + 'min_ver' => '0.28' + }, + 'DateTime::Event::ICal' => { + 'usage' => 'Core', + 'required' => '1', + 'min_ver' => '0.08' + }, + 'Readonly' => { + 'usage' => 'Core', + 'required' => '1', + 'min_ver' => '1.03' + }, + 'Readonly::XS' => { + 'usage' => 'Core', + 'required' => '0', + 'min_ver' => '1.02' }, 'Graphics::Magick' => { 'usage' => 'Patron Card Creator Feature', diff --git a/C4/Items.pm b/C4/Items.pm index 2f32c988ef..365c1b3651 100644 --- a/C4/Items.pm +++ b/C4/Items.pm @@ -1186,7 +1186,9 @@ sub GetItemsInfo { items.notforloan as itemnotforloan, itemtypes.description, itemtypes.notforloan as notforloan_per_itemtype, - holding.branchurl + holding.branchurl, + holding.branchname, + holding.opac_info as branch_opac_info FROM items LEFT JOIN branches AS holding ON items.holdingbranch = holding.branchcode LEFT JOIN branches AS home ON items.homebranch=home.branchcode diff --git a/C4/Members.pm b/C4/Members.pm index 4aa689f63c..6161ac9f30 100644 --- a/C4/Members.pm +++ b/C4/Members.pm @@ -35,6 +35,9 @@ use C4::Letters; use C4::SQLHelper qw(InsertInTable UpdateInTable SearchInTable); use C4::Members::Attributes qw(SearchIdMatchingAttribute); use C4::NewsChannels; #get slip news +use DateTime; +use DateTime::Format::DateParse; +use Koha::DateUtils; our ($VERSION,@ISA,@EXPORT,@EXPORT_OK,$debug); @@ -639,7 +642,7 @@ sub IsMemberBlocked { "SELECT COUNT(*) as latedocs FROM issues WHERE borrowernumber = ? - AND date_due < curdate()" + AND date_due < now()" ); $sth->execute($borrowernumber); my $latedocs = $sth->fetchrow_hashref->{'latedocs'}; @@ -677,7 +680,7 @@ sub GetMemberIssuesAndFines { $sth = $dbh->prepare( "SELECT COUNT(*) FROM issues WHERE borrowernumber = ? - AND date_due < curdate()" + AND date_due < now()" ); $sth->execute($borrowernumber); my $overdue_count = $sth->fetchrow_arrayref->[0]; @@ -1032,9 +1035,15 @@ sub GetPendingIssues { my $sth = C4::Context->dbh->prepare($query); $sth->execute(@borrowernumbers); my $data = $sth->fetchall_arrayref({}); - my $today = C4::Dates->new->output('iso'); + my $tz = C4::Context->tz(); + my $today = DateTime->now( time_zone => $tz); foreach (@{$data}) { - if ($_->{date_due} and $_->{date_due} lt $today) { + if ($_->{issuedate}) { + $_->{issuedate} = dt_from_string($_->{issuedate}, 'sql'); + } + $_->{date_due} or next; + $_->{date_due} = DateTime::Format::DateParse->parse_datetime($_->{date_due}, $tz->name()); + if ( DateTime->compare($_->{date_due}, $today) == -1 ) { $_->{overdue} = 1; } } diff --git a/C4/Members/AttributeTypes.pm b/C4/Members/AttributeTypes.pm index e36557ba5d..8c96e54c0f 100644 --- a/C4/Members/AttributeTypes.pm +++ b/C4/Members/AttributeTypes.pm @@ -70,7 +70,7 @@ If $all_fields is true, then each hashref also contains the other fields from bo sub GetAttributeTypes { my ($all) = @_; - my $select = $all ? '*' : 'code, description'; + my $select = $all ? '*' : 'code, description, class'; my $dbh = C4::Context->dbh; my $sth = $dbh->prepare("SELECT $select FROM borrower_attribute_types ORDER by code"); $sth->execute(); @@ -120,6 +120,9 @@ sub new { $self->{'staff_searchable'} = 0; $self->{'display_checkout'} = 0; $self->{'authorised_value_category'} = ''; + $self->{'category_code'} = ''; + $self->{'category_description'} = ''; + $self->{'class'} = ''; bless $self, $class; return $self; @@ -140,11 +143,15 @@ sub fetch { my $self = {}; my $dbh = C4::Context->dbh(); - my $sth = $dbh->prepare_cached("SELECT * FROM borrower_attribute_types WHERE code = ?"); + my $sth = $dbh->prepare_cached(" + SELECT borrower_attribute_types.*, categories.description AS category_description + FROM borrower_attribute_types + LEFT JOIN categories ON borrower_attribute_types.category_code=categories.categorycode + WHERE code =?"); $sth->execute($code); my $row = $sth->fetchrow_hashref; $sth->finish(); - return undef unless defined $row; + return undef unless defined $row; $self->{'code'} = $row->{'code'}; $self->{'description'} = $row->{'description'}; @@ -155,6 +162,9 @@ sub fetch { $self->{'staff_searchable'} = $row->{'staff_searchable'}; $self->{'display_checkout'} = $row->{'display_checkout'}; $self->{'authorised_value_category'} = $row->{'authorised_value_category'}; + $self->{'category_code'} = $row->{'category_code'}; + $self->{'category_description'} = $row->{'category_description'}; + $self->{'class'} = $row->{'class'}; bless $self, $class; return $self; @@ -185,14 +195,16 @@ sub store { password_allowed = ?, staff_searchable = ?, authorised_value_category = ?, - display_checkout = ? + display_checkout = ?, + category_code = ?, + class = ? WHERE code = ?"); } else { $sth = $dbh->prepare_cached("INSERT INTO borrower_attribute_types (description, repeatable, unique_id, opac_display, password_allowed, - staff_searchable, authorised_value_category, display_checkout, code) + staff_searchable, authorised_value_category, display_checkout, category_code, class, code) VALUES (?, ?, ?, ?, ?, - ?, ?, ?, ?)"); + ?, ?, ?, ?, ?, ?)"); } $sth->bind_param(1, $self->{'description'}); $sth->bind_param(2, $self->{'repeatable'}); @@ -202,7 +214,9 @@ sub store { $sth->bind_param(6, $self->{'staff_searchable'}); $sth->bind_param(7, $self->{'authorised_value_category'}); $sth->bind_param(8, $self->{'display_checkout'}); - $sth->bind_param(9, $self->{'code'}); + $sth->bind_param(9, $self->{'category_code'} || undef); + $sth->bind_param(10, $self->{'class'}); + $sth->bind_param(11, $self->{'code'}); $sth->execute; } @@ -341,6 +355,61 @@ sub authorised_value_category { @_ ? $self->{'authorised_value_category'} = shift : $self->{'authorised_value_category'}; } +=head2 category_code + +=over 4 + +my $category_code = $attr_type->category_code(); +$attr_type->category_code($category_code); + +=back + +Accessor. + +=cut + +sub category_code { + my $self = shift; + @_ ? $self->{'category_code'} = shift : $self->{'category_code'}; +} + +=head2 category_description + +=over 4 + +my $category_description = $attr_type->category_description(); +$attr_type->category_description($category_description); + +=back + +Accessor. + +=cut + +sub category_description { + my $self = shift; + @_ ? $self->{'category_description'} = shift : $self->{'category_description'}; +} + +=head2 class + +=over 4 + +my $class = $attr_type->class(); +$attr_type->class($class); + +=back + +Accessor. + +=cut + +sub class { + my $self = shift; + @_ ? $self->{'class'} = shift : $self->{'class'}; +} + + =head2 delete $attr_type->delete(); diff --git a/C4/Members/Attributes.pm b/C4/Members/Attributes.pm index 33affa86cb..33d2407602 100644 --- a/C4/Members/Attributes.pm +++ b/C4/Members/Attributes.pm @@ -72,7 +72,7 @@ sub GetBorrowerAttributes { my $opac_only = @_ ? shift : 0; my $dbh = C4::Context->dbh(); - my $query = "SELECT code, description, attribute, lib, password, display_checkout + my $query = "SELECT code, description, attribute, lib, password, display_checkout, category_code, class FROM borrower_attributes JOIN borrower_attribute_types USING (code) LEFT JOIN authorised_values ON (category = authorised_value_category AND attribute = authorised_value) @@ -90,6 +90,8 @@ sub GetBorrowerAttributes { value_description => $row->{'lib'}, password => $row->{'password'}, display_checkout => $row->{'display_checkout'}, + category_code => $row->{'category_code'}, + class => $row->{'class'}, } } return \@results; diff --git a/C4/Overdues.pm b/C4/Overdues.pm index 660e10b830..7676a87283 100644 --- a/C4/Overdues.pm +++ b/C4/Overdues.pm @@ -124,7 +124,7 @@ sub Getoverdues { SELECT issues.*, items.itype as itemtype, items.homebranch, items.barcode FROM issues LEFT JOIN items USING (itemnumber) - WHERE date_due < CURDATE() + WHERE date_due < NOW() "; } else { $statement = " @@ -132,7 +132,7 @@ LEFT JOIN items USING (itemnumber) FROM issues LEFT JOIN items USING (itemnumber) LEFT JOIN biblioitems USING (biblioitemnumber) - WHERE date_due < CURDATE() + WHERE date_due < NOW() "; } @@ -199,7 +199,7 @@ sub checkoverdues { LEFT JOIN biblio ON items.biblionumber = biblio.biblionumber LEFT JOIN biblioitems ON items.biblioitemnumber = biblioitems.biblioitemnumber WHERE issues.borrowernumber = ? - AND issues.date_due < CURDATE()" + AND issues.date_due < NOW()" ); # FIXME: SELECT * across 4 tables? do we really need the marc AND marcxml blobs?? $sth->execute($borrowernumber); @@ -209,9 +209,9 @@ sub checkoverdues { =head2 CalcFine - ($amount, $chargename, $daycount, $daycounttotal) = &CalcFine($item, - $categorycode, $branch, $days_overdue, - $description, $start_date, $end_date ); + ($amount, $chargename, $daycounttotal) = &CalcFine($item, + $categorycode, $branch, + $start_dt, $end_dt ); Calculates the fine for a book. @@ -229,13 +229,8 @@ the book. C<$branchcode> is the library (string) whose issuingrules govern this transaction. -C<$days_overdue> is the number of days elapsed since the book's due date. - NOTE: supplying days_overdue is deprecated. - -C<$start_date> & C<$end_date> are C4::Dates objects +C<$start_date> & C<$end_date> are DateTime objects defining the date range over which to determine the fine. -Note that if these are defined, we ignore C<$difference> and C<$dues> , -but retain these for backwards-comptibility with extant fines scripts. Fines scripts should just supply the date range over which to calculate the fine. @@ -249,8 +244,6 @@ the categoryitem table, whatever that is. C<$daycount> is the number of days between start and end dates, Calendar adjusted (where needed), minus any applicable grace period. -C<$daycounttotal> is C<$daycount> without consideration of grace period. - FIXME - What is chargename supposed to be ? FIXME: previously attempted to return C<$message> as a text message, either "First Notice", "Second Notice", @@ -259,48 +252,39 @@ or "Final Notice". But CalcFine never defined any value. =cut sub CalcFine { - my ( $item, $bortype, $branchcode, $difference ,$dues , $start_date, $end_date ) = @_; - $debug and warn sprintf("CalcFine(%s, %s, %s, %s, %s, %s, %s)", - ($item ? '{item}' : 'UNDEF'), - ($bortype || 'UNDEF'), - ($branchcode || 'UNDEF'), - ($difference || 'UNDEF'), - ($dues || 'UNDEF'), - ($start_date ? ($start_date->output('iso') || 'Not a C4::Dates object') : 'UNDEF'), - ( $end_date ? ( $end_date->output('iso') || 'Not a C4::Dates object') : 'UNDEF') - ); + my ( $item, $bortype, $branchcode, $due_dt, $end_date ) = @_; + my $start_date = $due_dt->clone(); my $dbh = C4::Context->dbh; my $amount = 0; - my $daystocharge; - # get issuingrules (fines part will be used) - $debug and warn sprintf("CalcFine calling GetIssuingRule(%s, %s, %s)", $bortype, $item->{'itemtype'}, $branchcode); - my $data = C4::Circulation::GetIssuingRule($bortype, $item->{'itemtype'}, $branchcode); - if($difference) { - # if $difference is supplied, the difference has already been calculated, but we still need to adjust for the calendar. - # use copy-pasted functions from calendar module. (deprecated -- these functions will be removed from C4::Overdues ). - my $countspecialday = &GetSpecialHolidays($dues,$item->{itemnumber}); - my $countrepeatableday = &GetRepeatableHolidays($dues,$item->{itemnumber},$difference); - my $countalldayclosed = $countspecialday + $countrepeatableday; - $daystocharge = $difference - $countalldayclosed; - } else { - # if $difference is not supplied, we have C4::Dates objects giving us the date range, and we use the calendar module. - if(C4::Context->preference('finesCalendar') eq 'noFinesWhenClosed') { - my $calendar = C4::Calendar->new( branchcode => $branchcode ); - $daystocharge = $calendar->daysBetween( $start_date, $end_date ); - } else { - $daystocharge = Date_to_Days(split('-',$end_date->output('iso'))) - Date_to_Days(split('-',$start_date->output('iso'))); - } - } - # correct for grace period. - my $days_minus_grace = $daystocharge - $data->{'firstremind'}; - if ($data->{'chargeperiod'} > 0 && $days_minus_grace > 0 ) { - $amount = int($daystocharge / $data->{'chargeperiod'}) * $data->{'fine'}; + my $charge_duration; + # get issuingrules (fines part will be used) + my $data = C4::Circulation::GetIssuingRule($bortype, $item->{itemtype}, $branchcode); + if(C4::Context->preference('finesCalendar') eq 'noFinesWhenClosed') { + my $calendar = Koha::Calendar->new( branchcode => $branchcode ); + $charge_duration = $calendar->days_between( $start_date, $end_date ); + } else { + $charge_duration = $end_date - $start_date; + } + # correct for grace period. + my $fine_unit = $data->{lengthunit}; + $fine_unit ||= 'days'; + my $chargeable_units; + if ($fine_unit eq 'hours') { + $chargeable_units = $charge_duration->hours(); # TODO closed times??? + } + else { + $chargeable_units = $charge_duration->days; + } + my $days_minus_grace = $chargeable_units - $data->{firstremind}; + if ($data->{'chargeperiod'} && $days_minus_grace ) { + $amount = int($chargeable_units / $data->{'chargeperiod'}) * $data->{'fine'};# TODO fine calc should be in cents } else { # a zero (or null) chargeperiod means no charge. } - $amount = C4::Context->preference('maxFine') if(C4::Context->preference('maxFine') && ( $amount > C4::Context->preference('maxFine'))); - $debug and warn sprintf("CalcFine returning (%s, %s, %s, %s)", $amount, $data->{'chargename'}, $days_minus_grace, $daystocharge); - return ($amount, $data->{'chargename'}, $days_minus_grace, $daystocharge); + if(C4::Context->preference('maxFine') && ( $amount > C4::Context->preference('maxFine'))) { + $amount = C4::Context->preference('maxFine'); + } + return ($amount, $data->{chargename}, $days_minus_grace); # FIXME: chargename is NEVER populated anywhere. } @@ -1218,7 +1202,7 @@ sub GetOverduesForBranch { WHERE (accountlines.amountoutstanding != '0.000000') AND (accountlines.accounttype = 'FU' ) AND (issues.branchcode = ? ) - AND (issues.date_due < CURDATE()) + AND (issues.date_due < NOW()) "; my @getoverdues; my $i = 0; diff --git a/C4/SIP/ILS/Patron.pm b/C4/SIP/ILS/Patron.pm index 95981fb227..99fd6e7edf 100644 --- a/C4/SIP/ILS/Patron.pm +++ b/C4/SIP/ILS/Patron.pm @@ -17,7 +17,6 @@ use Data::Dumper; use C4::Debug; use C4::Context; -# use C4::Dates; use C4::Koha; use C4::Members; use C4::Reserves; diff --git a/C4/SIP/ILS/Transaction/Checkout.pm b/C4/SIP/ILS/Transaction/Checkout.pm index 617a4ebc5f..d483e1625e 100644 --- a/C4/SIP/ILS/Transaction/Checkout.pm +++ b/C4/SIP/ILS/Transaction/Checkout.pm @@ -122,11 +122,14 @@ sub do_checkout { $debug and warn "do_checkout: calling AddIssue(\$borrower,$barcode, undef, 0)\n" # . "w/ \$borrower: " . Dumper($borrower) . "w/ C4::Context->userenv: " . Dumper(C4::Context->userenv); - my $c4due = AddIssue($borrower, $barcode, undef, 0); - my $due = $c4due->output('iso') || undef; - $debug and warn "Item due: $due"; - $self->{'due'} = $due; - $self->{item}->due_date($due); + my $due_dt = AddIssue($borrower, $barcode, undef, 0); + if ($due_dt) { + $self->{due} = $due_dt->clone(); + } else { + $self->{due} = undef; + } + + #$self->{item}->due_date($due); $self->ok(1); return $self; } diff --git a/C4/SIP/ILS/Transaction/Renew.pm b/C4/SIP/ILS/Transaction/Renew.pm index 73acaa3456..d7f949b091 100644 --- a/C4/SIP/ILS/Transaction/Renew.pm +++ b/C4/SIP/ILS/Transaction/Renew.pm @@ -37,8 +37,7 @@ sub do_renew_for ($$) { my $borrower = shift; my ($renewokay,$renewerror) = CanBookBeRenewed($borrower->{borrowernumber},$self->{item}->{itemnumber}); if ($renewokay){ - my $datedue = AddIssue( $borrower, $self->{item}->id, undef, 0 ); - $self->{due} = $datedue; + $self->{due} = AddIssue( $borrower, $self->{item}->id, undef, 0 ); $self->renewal_ok(1); } else { $self->screen_msg(($self->screen_msg || '') . " " . $renewerror); diff --git a/C4/SIP/ILS/Transaction/RenewAll.pm b/C4/SIP/ILS/Transaction/RenewAll.pm index 2e49bf7ed2..10fb27d7de 100644 --- a/C4/SIP/ILS/Transaction/RenewAll.pm +++ b/C4/SIP/ILS/Transaction/RenewAll.pm @@ -53,8 +53,8 @@ sub do_renew_all { $self->{item} = $item; $self->do_renew_for($borrower); if ($self->ok) { - $item->{due_date} = $self->{due}; - push @{$self->{renewed} }, $item_id; + $item->{due_date} = $self->{due}->clone(); + push @{$self->renewed }, $item_id; } else { push @{$self->{unrenewed}}, $item_id; } diff --git a/C4/SIP/Sip.pm b/C4/SIP/Sip.pm index 337cc0e4d0..4e3f299afb 100644 --- a/C4/SIP/Sip.pm +++ b/C4/SIP/Sip.pm @@ -50,7 +50,9 @@ our $last_response = ''; sub timestamp { my $time = $_[0] || time(); - if ($time=~m/^(\d{4})\-(\d{2})\-(\d{2})/) { + if ( ref $time eq 'DateTime') { + return $time->strftime(SIP_DATETIME); + } elsif ($time=~m/^(\d{4})\-(\d{2})\-(\d{2})/) { # passing a db returned date as is + bogus time return sprintf( '%04d%02d%02d 235900', $1, $2, $3); } diff --git a/Koha/Calendar.pm b/Koha/Calendar.pm new file mode 100644 index 0000000000..1e7299c083 --- /dev/null +++ b/Koha/Calendar.pm @@ -0,0 +1,300 @@ +package Koha::Calendar; +use strict; +use warnings; +use 5.010; + +use DateTime; +use DateTime::Set; +use DateTime::Duration; +use C4::Context; +use Carp; +use Readonly; + +sub new { + my ( $classname, %options ) = @_; + my $self = {}; + bless $self, $classname; + for my $o_name ( keys %options ) { + my $o = lc $o_name; + $self->{$o} = $options{$o_name}; + } + if ( exists $options{TEST_MODE} ) { + $self->_mockinit(); + return $self; + } + if ( !defined $self->{branchcode} ) { + croak 'No branchcode argument passed to Koha::Calendar->new'; + } + $self->_init(); + return $self; +} + +sub _init { + my $self = shift; + my $branch = $self->{branchcode}; + my $dbh = C4::Context->dbh(); + my $repeat_sth = $dbh->prepare( +'SELECT * from repeatable_holidays WHERE branchcode = ? AND ISNULL(weekday) = ?' + ); + $repeat_sth->execute( $branch, 0 ); + $self->{weekly_closed_days} = [ 0, 0, 0, 0, 0, 0, 0 ]; + Readonly::Scalar my $sunday => 7; + while ( my $tuple = $repeat_sth->fetchrow_hashref ) { + $self->{weekly_closed_days}->[ $tuple->{weekday} ] = 1; + } + $repeat_sth->execute( $branch, 1 ); + $self->{day_month_closed_days} = {}; + while ( my $tuple = $repeat_sth->fetchrow_hashref ) { + $self->{day_month_closed_days}->{ $tuple->{day} }->{ $tuple->{month} } = + 1; + } + my $special = $dbh->prepare( +'SELECT day, month, year, title, description FROM special_holidays WHERE ( branchcode = ? ) AND (isexception = ?)' + ); + $special->execute( $branch, 1 ); + my $dates = []; + while ( my ( $day, $month, $year, $title, $description ) = + $special->fetchrow ) { + push @{$dates}, + DateTime->new( + day => $day, + month => $month, + year => $year, + time_zone => C4::Context->tz() + )->truncate( to => 'day' ); + } + $self->{exception_holidays} = + DateTime::Set->from_datetimes( dates => $dates ); + $special->execute( $branch, 1 ); + $dates = []; + while ( my ( $day, $month, $year, $title, $description ) = + $special->fetchrow ) { + push @{$dates}, + DateTime->new( + day => $day, + month => $month, + year => $year, + time_zone => C4::Context->tz() + )->truncate( to => 'day' ); + } + $self->{single_holidays} = DateTime::Set->from_datetimes( dates => $dates ); + $self->{days_mode} = C4::Context->preference('useDaysMode'); + return; +} + +sub addDate { + my ( $self, $startdate, $add_duration, $unit ) = @_; + my $base_date = $startdate->clone(); + if ( ref $add_duration ne 'DateTime::Duration' ) { + $add_duration = DateTime::Duration->new( days => $add_duration ); + } + $unit ||= q{}; # default days ? + my $days_mode = $self->{days_mode}; + Readonly::Scalar my $return_by_hour => 10; + my $day_dur = DateTime::Duration->new( days => 1 ); + if ( $add_duration->is_negative() ) { + $day_dur->inverse(); + } + if ( $days_mode eq 'Datedue' ) { + + my $dt = $base_date + $add_duration; + while ( $self->is_holiday($dt) ) { + + # TODOP if hours set to 10 am + $dt->add_duration($day_dur); + if ( $unit eq 'hours' ) { + $dt->set_hour($return_by_hour); # Staffs specific + } + } + return $dt; + } elsif ( $days_mode eq 'Calendar' ) { + if ( $unit eq 'hours' ) { + $base_date->add_duration($add_duration); + while ( $self->is_holiday($base_date) ) { + $base_date->add_duration($day_dur); + + } + + } else { + my $days = abs $add_duration->in_units('days'); + while ($days) { + $base_date->add_duration($day_dur); + if ( $self->is_holiday($base_date) ) { + next; + } else { + --$days; + } + } + } + if ( $unit eq 'hours' ) { + my $dt = $base_date->clone()->subtract( days => 1 ); + if ( $self->is_holiday($dt) ) { + $base_date->set_hour($return_by_hour); # Staffs specific + } + } + return $base_date; + } else { # Days + return $base_date + $add_duration; + } +} + +sub is_holiday { + my ( $self, $dt ) = @_; + my $dow = $dt->day_of_week; + if ( $dow == 7 ) { + $dow = 0; + } + if ( $self->{weekly_closed_days}->[$dow] == 1 ) { + return 1; + } + $dt->truncate( to => 'days' ); + my $day = $dt->day; + my $month = $dt->month; + if ( exists $self->{day_month_closed_days}->{$month}->{$day} ) { + return 1; + } + if ( $self->{exception_holidays}->contains($dt) ) { + return 1; + } + if ( $self->{single_holidays}->contains($dt) ) { + return 1; + } + + # damn have to go to work after all + return 0; +} + +sub days_between { + my $self = shift; + my $start_dt = shift; + my $end_dt = shift; + $start_dt->truncate( to => 'hours' ); + $end_dt->truncate( to => 'hours' ); + + # start and end should not be closed days + my $duration = $end_dt - $start_dt; + $start_dt->truncate( to => 'days' ); + $end_dt->truncate( to => 'days' ); + while ( DateTime->compare( $start_dt, $end_dt ) == -1 ) { + $start_dt->add( days => 1 ); + if ( $self->is_holiday($start_dt) ) { + $duration->subtract( days => 1 ); + } + } + return $duration; + +} + +sub _mockinit { + my $self = shift; + $self->{weekly_closed_days} = [ 1, 0, 0, 0, 0, 0, 0 ]; # Sunday only + $self->{day_month_closed_days} = { 6 => { 16 => 1, } }; + my $dates = []; + $self->{exception_holidays} = + DateTime::Set->from_datetimes( dates => $dates ); + my $special = DateTime->new( + year => 2011, + month => 6, + day => 1, + time_zone => 'Europe/London', + ); + push @{$dates}, $special; + $self->{single_holidays} = DateTime::Set->from_datetimes( dates => $dates ); + $self->{days_mode} = 'Calendar'; + return; +} + +1; +__END__ + +=head1 NAME + +Koha::Calendar - Object containing a branches calendar + +=head1 VERSION + +This documentation refers to Koha::Calendar version 0.0.1 + +=head1 SYNOPSIS + + use Koha::Calendat + + my $c = Koha::Calender->new( branchcode => 'MAIN' ); + my $dt = DateTime->now(); + + # are we open + $open = $c->is_holiday($dt); + # when will item be due if loan period = $dur (a DateTime::Duration object) + $duedate = $c->addDate($dt,$dur,'days'); + + +=head1 DESCRIPTION + + Implements those features of C4::Calendar needed for Staffs Rolling Loans + +=head1 METHODS + +=head2 new : Create a calendar object + +my $calendar = Koha::Calendar->new( branchcode => 'MAIN' ); + +The option branchcode is required + + +=head2 addDate + + my $dt = $calendar->addDate($date, $dur, $unit) + +C<$date> is a DateTime object representing the starting date of the interval. + +C<$offset> is a DateTime::Duration to add to it + +C<$unit> is a string value 'days' or 'hours' toflag granularity of duration + +Currently unit is only used to invoke Staffs return Monday at 10 am rule this +parameter will be removed when issuingrules properly cope with that + + +=head2 is_holiday + +$yesno = $calendar->is_holiday($dt); + +passed at DateTime object returns 1 if it is a closed day +0 if not according to the calendar + +=head2 days_between + +$duration = $calendar->days_between($start_dt, $end_dt); + +Passed two dates returns a DateTime::Duration object measuring the length between them +ignoring closed days + +=head1 DIAGNOSTICS + +Will croak if not passed a branchcode in new + +=head1 BUGS AND LIMITATIONS + +This only contains a limited subset of the functionality in C4::Calendar +Only enough to support Staffs Rolling loans + +=head1 AUTHOR + +Colin Campbell colin.campbell@ptfs-europe.com + +=head1 LICENSE AND COPYRIGHT + +Copyright (c) 2011 PTFS-Europe Ltd All rights reserved + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . diff --git a/Koha/DateUtils.pm b/Koha/DateUtils.pm new file mode 100644 index 0000000000..e2e92bd494 --- /dev/null +++ b/Koha/DateUtils.pm @@ -0,0 +1,187 @@ +package Koha::DateUtils; + +# Copyright (c) 2011 PTFS-Europe Ltd. +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# Koha is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place, +# Suite 330, Boston, MA 02111-1307 USA + +use strict; +use warnings; +use 5.010; +use DateTime; +use DateTime::Format::DateParse; +use C4::Context; + +use base 'Exporter'; +use version; our $VERSION = qv('1.0.0'); + +our @EXPORT = ( + qw( dt_from_string output_pref format_sqldatetime output_pref_due format_sqlduedatetime) +); + +=head1 DateUtils + +Koha::DateUtils - Transitional wrappers to ease use of DateTime + +=head1 DESCRIPTION + +Koha has historically only used dates not datetimes and been content to +handle these as strings. It also has confused formatting with actual dates +this is a temporary module for wrappers to hide the complexity of switch to DateTime + +=cut + +=head2 dt_ftom_string + +$dt = dt_from_string($date_string, [$format, $timezone ]); + +Passed a date string returns a DateTime object format and timezone default +to the system preferences. If the date string is empty DateTime->now is returned + +=cut + +sub dt_from_string { + my ( $date_string, $date_format, $tz ) = @_; + if ( !$tz ) { + $tz = C4::Context->tz; + } + if ( !$date_format ) { + $date_format = C4::Context->preference('dateformat'); + } + if ($date_string) { + if ( ref($date_string) eq 'DateTime' ) { # already a dt return it + return $date_string; + } + + if ( $date_format eq 'metric' ) { + $date_string =~ s#-#/#g; + $date_string =~ s/^00/01/; # system allows the 0th of the month + $date_string =~ s#^(\d{1,2})/(\d{1,2})#$2/$1#; + } else { + if ( $date_format eq 'iso' ) { + $date_string =~ s/-00/-01/; + if ( $date_string =~ m/^0000-0/ ) { + return; # invalid date in db + } + } elsif ( $date_format eq 'us' ) { + $date_string =~ s#-#/#g; + $date_string =~ s[/00/][/01/]; + } elsif ( $date_format eq 'sql' ) { + $date_string =~ +s/(\d{4})(\d{2})(\d{2})\s+(\d{2})(\d{2})(\d{2})/$1-$2-$3T$4:$5:$6/; + $date_string =~ s/00T/01T/; + } + } + return DateTime::Format::DateParse->parse_datetime( $date_string, + $tz->name() ); + } + return DateTime->now( time_zone => $tz ); + +} + +=head2 output_pref + +$date_string = output_pref($dt, [$format] ); + +Returns a string containing the time & date formatted as per the C4::Context setting + +A second parameter allows overriding of the syspref value. This is for testing only +In usage use the DateTime objects own methods for non standard formatting + +=cut + +sub output_pref { + my $dt = shift; + my $force_pref = shift; # if testing we want to override Context + my $pref = + defined $force_pref ? $force_pref : C4::Context->preference('dateformat'); + given ($pref) { + when (/^iso/) { + return $dt->strftime('%Y-%m-%d %H:%M'); + } + when (/^metric/) { + return $dt->strftime('%d/%m/%Y %H:%M'); + } + when (/^us/) { + return $dt->strftime('%m/%d/%Y %H:%M'); + } + default { + return $dt->strftime('%Y-%m-%d %H:%M'); + } + + } + return; +} + +=head2 output_pref_due + +$date_string = output_pref_due($dt, [$format] ); + +Returns a string containing the time & date formatted as per the C4::Context setting + +A second parameter allows overriding of the syspref value. This is for testing only +In usage use the DateTime objects own methods for non standard formatting + +This is effectivelyt a wrapper around output_pref for due dates +the time portion is stripped if it is '23:59' + +=cut + +sub output_pref_due { + my $disp_str = output_pref(@_); + $disp_str =~ s/ 23:59//; + return $disp_str; +} + +=head2 format_sqldatetime + +$string = format_sqldatetime( $string_as_returned_from_db ); + +a convenience routine for calling dt_from_string and formatting the result +with output_pref as it is a frequent activity in scripts + +=cut + +sub format_sqldatetime { + my $str = shift; + my $force_pref = shift; # if testing we want to override Context + if ( defined $str && $str =~ m/^\d{4}-\d{2}-\d{2}/ ) { + my $dt = dt_from_string( $str, 'sql' ); + $dt->truncate( to => 'minutes' ); + return output_pref( $dt, $force_pref ); + } + return q{}; +} + +=head2 format_sqlduedatetime + +$string = format_sqldatetime( $string_as_returned_from_db ); + +a convenience routine for calling dt_from_string and formatting the result +with output_pref_due as it is a frequent activity in scripts + +=cut + +sub format_sqlduedatetime { + my $str = shift; + my $force_pref = shift; # if testing we want to override Context + if ( defined $str && $str =~ m/^\d{4}-\d{2}-\d{2}/ ) { + my $dt = dt_from_string( $str, 'sql' ); + $dt->truncate( to => 'minutes' ); + return output_pref_due( $dt, $force_pref ); + } + return q{}; +} + +1; diff --git a/acqui/addorderiso2709.pl b/acqui/addorderiso2709.pl index 660d633d5c..8d9c0e3fc5 100755 --- a/acqui/addorderiso2709.pl +++ b/acqui/addorderiso2709.pl @@ -41,7 +41,6 @@ use C4::Koha; use C4::Budgets; use C4::Acquisition; use C4::Bookseller qw/GetBookSellerFromId/; -use C4::Dates; use C4::Suggestions; # GetSuggestion use C4::Branch; # GetBranches use C4::Members; @@ -343,11 +342,13 @@ sub import_batches_list { # check if there is at least 1 line still staged my $stagedList=GetImportBibliosRange($batch->{'import_batch_id'}, undef, undef, 'staged'); if (scalar @$stagedList) { + my ($staged_date, $staged_hour) = split (/ /, $batch->{'upload_timestamp'}); push @list, { import_batch_id => $batch->{'import_batch_id'}, num_biblios => $batch->{'num_biblios'}, num_items => $batch->{'num_items'}, - upload_timestamp => $batch->{'upload_timestamp'}, + staged_date => $staged_date, + staged_hour => $staged_hour, import_status => $batch->{'import_status'}, file_name => $batch->{'file_name'}, comments => $batch->{'comments'}, diff --git a/acqui/basketgroup.pl b/acqui/basketgroup.pl index d2e185624e..3300cea9ba 100755 --- a/acqui/basketgroup.pl +++ b/acqui/basketgroup.pl @@ -60,7 +60,7 @@ use C4::Members qw/GetMember/; my $input=new CGI; -my ($template, $loggedinuser, $cookie) +our ($template, $loggedinuser, $cookie) = get_template_and_user({template_name => "acqui/basketgroup.tmpl", query => $input, type => "intranet", diff --git a/acqui/booksellers.pl b/acqui/booksellers.pl index 025fbd1fb7..5a1c2480d1 100755 --- a/acqui/booksellers.pl +++ b/acqui/booksellers.pl @@ -56,7 +56,6 @@ use C4::Biblio; use C4::Output; use CGI; -use C4::Dates qw/format_date/; use C4::Acquisition qw/ GetBasketsInfosByBookseller /; use C4::Bookseller qw/ GetBookSellerFromId GetBookSeller /; use C4::Members qw/GetMember/; @@ -126,11 +125,6 @@ for my $vendor (@suppliers) { ) ) ) { - for my $date_field (qw( creationdate closedate)) { - if ( $basket->{$date_field} ) { - $basket->{$date_field} = format_date( $basket->{$date_field} ); - } - } foreach (qw(total_items total_biblios expected_items)) { $basket->{$_} ||= 0; } diff --git a/acqui/supplier.pl b/acqui/supplier.pl index fdeef06f5b..6746d8d444 100755 --- a/acqui/supplier.pl +++ b/acqui/supplier.pl @@ -46,7 +46,6 @@ use C4::Auth; use C4::Contract qw/GetContract/; use C4::Biblio; use C4::Output; -use C4::Dates qw/format_date /; use CGI; use C4::Bookseller qw( GetBookSellerFromId DelBookseller ); @@ -79,11 +78,6 @@ if ( $op eq 'display' ) { my $contracts = GetContract( { booksellerid => $booksellerid } ); - for ( @{$contracts} ) { - $_->{contractstartdate} = format_date( $_->{contractstartdate} ); - $_->{contractenddate} = format_date( $_->{contractenddate} ); - } - $template->param( booksellerid => $booksellerid, name => $supplier->{'name'}, diff --git a/acqui/z3950_search.pl b/acqui/z3950_search.pl index 80503e0d82..9dc8b6e2ae 100755 --- a/acqui/z3950_search.pl +++ b/acqui/z3950_search.pl @@ -64,7 +64,6 @@ my $op = $input->param('op'); my $booksellerid = $input->param('booksellerid'); my $basketno = $input->param('basketno'); my $noconnection; -my $numberpending; my $attr = ''; my $term; my $host; @@ -88,7 +87,7 @@ unless ($random) $random = rand(1000000000); } -my $DEBUG = 0; # if set to 1, many debug message are send on syslog. +my $DEBUG = $ENV{DEBUG} || 0; # if set to 1, many debug message are send on syslog. # get framework list my $frameworks = getframeworks; @@ -131,11 +130,12 @@ if ( $op ne "do_search" ) { biblionumber => $biblionumber, ); output_html_with_http_headers $input, $cookie, $template->output; + exit; } -else { + my @id = $input->param('id'); - if ( not defined @id ) { + if ( not @id ) { # empty server list -> report and exit $template->param( emptyserverlist => 1 ); output_html_with_http_headers $input, $cookie, $template->output; @@ -228,7 +228,10 @@ warn "query ".$query if $DEBUG; # $oResult[$z] = $oConnection[$z]->search_pqf($query); } -sub displayresults { + warn "# nremaining = $nremaining\n" if $DEBUG; + + while ( $nremaining-- ) { + my $k; my $event; while ( ( $k = ZOOM::event( \@oConnection ) ) != 0 ) { @@ -241,7 +244,7 @@ sub displayresults { if ( $k != 0 ) { $k--; - warn $serverhost[$k] if $DEBUG; + warn "event from $k server = ",$serverhost[$k] if $DEBUG; my ( $error, $errmsg, $addinfo, $diagset ) = $oConnection[$k]->error_x(); if ($error) { @@ -252,6 +255,7 @@ sub displayresults { } else { my $numresults = $oResult[$k]->size(); + warn "numresults = $numresults" if $DEBUG; my $i; my $result = ''; if ( $numresults > 0 ) { @@ -305,20 +309,15 @@ sub displayresults { } #$numresults } } # if $k !=0 - $numberpending = $nremaining - 1; - $template->param( - breeding_loop => \@breeding_loop, - server => $servername[$k], - numberpending => $numberpending, - errconn => \@errconn - ); - output_html_with_http_headers $input, $cookie, $template->output if $numberpending == 0; - # print $template->output if $firstresult !=1; $firstresult++; -} -displayresults(); -while ( --$nremaining > 0 ) { - displayresults(); - } -} ## if op=search + + } # while nremaining + +$template->param( +breeding_loop => \@breeding_loop, +#server => $servername[$k], +numberpending => $nremaining > 0 ? $nremaining : 0, +errconn => \@errconn +); +output_html_with_http_headers $input, $cookie, $template->output; diff --git a/admin/branches.pl b/admin/branches.pl index 12c49e28ba..c12762d78e 100755 --- a/admin/branches.pl +++ b/admin/branches.pl @@ -328,6 +328,7 @@ sub branchinfotable { # - branchfax | # - branchemail / # - branchurl / + # - opac_info (can contain HTML) # - address-empty-p (1 if no address information, 0 otherwise) # - categories (containing a static error message) # - category_list (loop containing "categoryname") @@ -343,7 +344,7 @@ sub branchinfotable { 'branchaddress3', 'branchzip', 'branchcity', 'branchstate', 'branchcountry', 'branchphone', 'branchfax', - 'branchemail', 'branchurl', + 'branchemail', 'branchurl', 'opac_info', 'branchip', 'branchprinter', 'branchnotes' ) { @@ -406,6 +407,7 @@ sub _branch_to_template { branchfax => $data->{'branchfax'}, branchemail => $data->{'branchemail'}, branchurl => $data->{'branchurl'}, + opac_info => $data->{'opac_info'}, branchip => $data->{'branchip'}, branchnotes => $data->{'branchnotes'}, ); diff --git a/admin/patron-attr-types.pl b/admin/patron-attr-types.pl index 29a0d901ad..660a2274e4 100755 --- a/admin/patron-attr-types.pl +++ b/admin/patron-attr-types.pl @@ -22,10 +22,13 @@ use strict; use warnings; use CGI; +use List::MoreUtils qw/uniq/; + use C4::Auth; use C4::Context; use C4::Output; use C4::Koha; +use C4::Members qw/GetBorrowercategoryList/; use C4::Members::AttributeTypes; my $script_name = "/cgi-bin/koha/admin/patron-attr-types.pl"; @@ -82,8 +85,10 @@ sub add_attribute_type_form { $template->param( attribute_type_form => 1, confirm_op => 'add_attribute_type_confirmed', + categories => GetBorrowercategoryList, ); authorised_value_category_list($template); + pa_classes($template); } sub error_add_attribute_type_form { @@ -110,6 +115,9 @@ sub error_add_attribute_type_form { $template->param(display_checkout_checked => 'checked="checked"'); } + $template->param( category_code => $input->param('category_code') ); + $template->param( class => $input->param('class') ); + $template->param( attribute_type_form => 1, confirm_op => 'add_attribute_type_confirmed', @@ -152,6 +160,8 @@ sub add_update_attribute_type { $attr_type->password_allowed($password_allowed); my $display_checkout = $input->param('display_checkout'); $attr_type->display_checkout($display_checkout); + $attr_type->category_code($input->param('category_code')); + $attr_type->class($input->param('class')); if ($op eq 'edit') { $template->param(edited_attribute_type => $attr_type->code()); @@ -209,6 +219,7 @@ sub edit_attribute_type_form { $template->param(code => $code); $template->param(description => $attr_type->description()); + $template->param(class => $attr_type->class()); if ($attr_type->repeatable()) { $template->param(repeatable_checked => 1); @@ -231,20 +242,41 @@ sub edit_attribute_type_form { $template->param(display_checkout_checked => 'checked="checked"'); } authorised_value_category_list($template, $attr_type->authorised_value_category()); + pa_classes( $template, $attr_type->class ); + + $template->param ( category_code => $attr_type->category_code ); + $template->param ( category_description => $attr_type->category_description ); $template->param( attribute_type_form => 1, edit_attribute_type => 1, confirm_op => 'edit_attribute_type_confirmed', + categories => GetBorrowercategoryList, ); } sub patron_attribute_type_list { my $template = shift; - + my @attr_types = C4::Members::AttributeTypes::GetAttributeTypes(); - $template->param(available_attribute_types => \@attr_types); + my @classes = uniq( map {$_->{class}} @attr_types ); + @classes = sort @classes; + + my @attributes_loop; + for my $class (@classes) { + my @items; + for my $attr (@attr_types) { + push @items, $attr if $attr->{class} eq $class + } + my $lib = GetAuthorisedValueByCode( 'PA_CLASS', $class ) || $class; + push @attributes_loop, { + class => $class, + items => \@items, + lib => $lib, + }; + } + $template->param(available_attribute_types => \@attributes_loop); $template->param(display_list => 1); } @@ -261,3 +293,10 @@ sub authorised_value_category_list { } $template->param(authorised_value_categories => \@list); } + +sub pa_classes { + my $template = shift; + my $selected = @_ ? shift : ''; + + $template->param(classes_val_loop => GetAuthorisedValues( 'PA_CLASS', $selected ) ); +} diff --git a/admin/smart-rules.pl b/admin/smart-rules.pl index dcfcfc58ba..0b8012fabc 100755 --- a/admin/smart-rules.pl +++ b/admin/smart-rules.pl @@ -100,9 +100,9 @@ elsif ($op eq 'delete-branch-item') { } # save the values entered elsif ($op eq 'add') { - my $sth_search = $dbh->prepare("SELECT COUNT(*) AS total FROM issuingrules WHERE branchcode=? AND categorycode=? AND itemtype=?"); - my $sth_insert = $dbh->prepare("INSERT INTO issuingrules (branchcode, categorycode, itemtype, maxissueqty, renewalsallowed, reservesallowed, issuelength, hardduedate, hardduedatecompare, fine, finedays, firstremind, chargeperiod,rentaldiscount) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?)"); - my $sth_update=$dbh->prepare("UPDATE issuingrules SET fine=?, finedays=?, firstremind=?, chargeperiod=?, maxissueqty=?, renewalsallowed=?, reservesallowed=?, issuelength=?, hardduedate=?, hardduedatecompare=?, rentaldiscount=? WHERE branchcode=? AND categorycode=? AND itemtype=?"); + my $sth_search = $dbh->prepare('SELECT COUNT(*) AS total FROM issuingrules WHERE branchcode=? AND categorycode=? AND itemtype=?'); + my $sth_insert = $dbh->prepare('INSERT INTO issuingrules (branchcode, categorycode, itemtype, maxissueqty, renewalsallowed, reservesallowed, issuelength, lengthunit, hardduedate, hardduedatecompare, fine, finedays, firstremind, chargeperiod,rentaldiscount) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)'); + my $sth_update=$dbh->prepare("UPDATE issuingrules SET fine=?, finedays=?, firstremind=?, chargeperiod=?, maxissueqty=?, renewalsallowed=?, reservesallowed=?, issuelength=?, lengthunit = ?, hardduedate=?, hardduedatecompare=?, rentaldiscount=? WHERE branchcode=? AND categorycode=? AND itemtype=?"); my $br = $branch; # branch my $bor = $input->param('categorycode'); # borrower category @@ -117,6 +117,7 @@ elsif ($op eq 'add') { $maxissueqty =~ s/\s//g; $maxissueqty = undef if $maxissueqty !~ /^\d+/; my $issuelength = $input->param('issuelength'); + my $lengthunit = $input->param('lengthunit'); my $hardduedate = $input->param('hardduedate'); $hardduedate = format_date_in_iso($hardduedate); my $hardduedatecompare = $input->param('hardduedatecompare'); @@ -126,9 +127,9 @@ elsif ($op eq 'add') { $sth_search->execute($br,$bor,$cat); my $res = $sth_search->fetchrow_hashref(); if ($res->{total}) { - $sth_update->execute($fine, $finedays,$firstremind, $chargeperiod, $maxissueqty, $renewalsallowed,$reservesallowed, $issuelength,$hardduedate,$hardduedatecompare,$rentaldiscount, $br,$bor,$cat); + $sth_update->execute($fine, $finedays,$firstremind, $chargeperiod, $maxissueqty, $renewalsallowed,$reservesallowed, $issuelength,$lengthunit, $hardduedate,$hardduedatecompare,$rentaldiscount, $br,$bor,$cat); } else { - $sth_insert->execute($br,$bor,$cat,$maxissueqty,$renewalsallowed,$reservesallowed,$issuelength,$hardduedate,$hardduedatecompare,$fine,$finedays,$firstremind,$chargeperiod,$rentaldiscount); + $sth_insert->execute($br,$bor,$cat,$maxissueqty,$renewalsallowed,$reservesallowed,$issuelength,$lengthunit,$hardduedate,$hardduedatecompare,$fine,$finedays,$firstremind,$chargeperiod,$rentaldiscount); } } elsif ($op eq "set-branch-defaults") { diff --git a/admin/z3950servers.pl b/admin/z3950servers.pl index f0a4dbb4ca..14603f6ba5 100755 --- a/admin/z3950servers.pl +++ b/admin/z3950servers.pl @@ -20,7 +20,7 @@ # - we delete the record having primkey=$primkey use strict; -#use warnings; FIXME - Bug 2505 +use warnings; use CGI; use C4::Context; use C4::Auth; @@ -29,16 +29,34 @@ use C4::Output; sub StringSearch { my ($searchstring,$type)=@_; my $dbh = C4::Context->dbh; - $searchstring=~ s/\'/\\\'/g; - my @data=split(' ',$searchstring); - my $count=@data; - my $sth=$dbh->prepare("Select host,port,db,userid,password,name,id,checked,rank,syntax,encoding from z3950servers where (name like ?) order by rank,name"); - $sth->execute("$data[0]\%"); + my @data = ('%'); + my $count = 1; + if ( defined $searchstring ) { + $searchstring =~ s/\'/\\\'/g; + @data=split(' ',$searchstring); + $count=@data; + } + else { + $searchstring = ''; + } + + my $query = "SELECT host,port,db,userid,password,name,id,checked,rank,syntax,encoding,timeout"; + $query .= " FROM z3950servers"; + if ( $searchstring ne '' ) { $query .= " WHERE (name like ?)" } + $query .= " ORDER BY rank,name"; + my $sth=$dbh->prepare($query); + + if ( $searchstring ne '' ) { + $sth->execute("$data[0]\%"); + } + else { + $sth->execute; + } + my @results; while (my $data=$sth->fetchrow_hashref) { push(@results,$data); } - # $sth->execute; $sth->finish; $dbh->disconnect; return (scalar(@results),\@results); @@ -46,11 +64,11 @@ sub StringSearch { my $input = new CGI; my $searchfield=$input->param('searchfield'); -my $offset=$input->param('offset'); +my $offset=$input->param('offset') || 0; my $script_name="/cgi-bin/koha/admin/z3950servers.pl"; my $pagesize=20; -my $op = $input->param('op'); +my $op = $input->param('op') || ''; my ($template, $loggedinuser, $cookie) = get_template_and_user({template_name => "admin/z3950servers.tmpl", @@ -74,13 +92,13 @@ if ($op eq 'add_form') { my $data; if ($searchfield) { my $dbh = C4::Context->dbh; - my $sth=$dbh->prepare("select host,port,db,userid,password,name,id,checked,rank,syntax,encoding from z3950servers where (name = ?) order by rank,name"); + my $sth=$dbh->prepare("select host,port,db,userid,password,name,id,checked,rank,syntax,encoding,timeout from z3950servers where (name = ?) order by rank,name"); $sth->execute($searchfield); $data=$sth->fetchrow_hashref; $sth->finish; } $template->param( $_ => $data->{$_} ) - for ( qw( host port db userid password checked rank ) ); + for ( qw( host port db userid password checked rank timeout ) ); $template->param( $_ . $data->{$_} => 1) for ( qw( syntax encoding ) ); # END $OP eq ADD_FORM @@ -93,7 +111,7 @@ if ($op eq 'add_form') { $sth->execute($input->param('searchfield')); my $checked = $input->param('checked') ? 1 : 0; if ($sth->rows) { - $sth=$dbh->prepare("update z3950servers set host=?, port=?, db=?, userid=?, password=?, name=?, checked=?, rank=?,syntax=?,encoding=? where name=?"); + $sth=$dbh->prepare("update z3950servers set host=?, port=?, db=?, userid=?, password=?, name=?, checked=?, rank=?,syntax=?,encoding=?,timeout=? where name=?"); $sth->execute($input->param('host'), $input->param('port'), $input->param('db'), @@ -104,14 +122,15 @@ if ($op eq 'add_form') { $input->param('rank'), $input->param('syntax'), $input->param('encoding'), + $input->param('timeout'), $input->param('searchfield'), ); } else { $sth=$dbh->prepare( "INSERT INTO z3950servers " . - "(host,port,db,userid,password,name,checked,rank,syntax,encoding) " . - "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" ); + "(host,port,db,userid,password,name,checked,rank,syntax,encoding,timeout) " . + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" ); $sth->execute( $input->param( 'host' ), $input->param( 'port' ), @@ -119,9 +138,10 @@ if ($op eq 'add_form') { $input->param( 'userid' ), $input->param( 'password' ), $input->param( 'searchfield' ), - $input->param( 'checked' ), + $checked, $input->param( 'rank' ), $input->param( 'syntax' ), + $input->param( 'timeout' ), $input->param( 'encoding' ) ); } $sth->finish; @@ -132,7 +152,7 @@ if ($op eq 'add_form') { $template->param(delete_confirm => 1); my $dbh = C4::Context->dbh; - my $sth2=$dbh->prepare("select host,port,db,userid,password,name,id,checked,rank,syntax,encoding from z3950servers where (name = ?) order by rank,name"); + my $sth2=$dbh->prepare("select host,port,db,userid,password,name,id,checked,rank,syntax,encoding,timeout from z3950servers where (name = ?) order by rank,name"); $sth2->execute($searchfield); my $data=$sth2->fetchrow_hashref; $sth2->finish; @@ -145,6 +165,7 @@ if ($op eq 'add_form') { checked => $data->{'checked'}, rank => $data->{'rank'}, syntax => $data->{'syntax'}, + timeout => $data->{'timeout'}, encoding => $data->{'encoding'} ); # END $OP eq DELETE_CONFIRM @@ -162,8 +183,8 @@ if ($op eq 'add_form') { $template->param(else => 1); my ($count,$results)=StringSearch($searchfield,'web'); my @loop; + for (my $i=$offset; $i < ($offset+$pagesize<$count?$offset+$pagesize:$count); $i++){ - my $urlsearchfield=$results->[$i]{name}; $urlsearchfield=~s/ /%20/g; my %row = ( name => $results->[$i]{'name'}, @@ -175,7 +196,8 @@ if ($op eq 'add_form') { checked => $results->[$i]{'checked'}, rank => $results->[$i]{'rank'}, syntax => $results->[$i]{'syntax'}, - encoding => $results->[$i]{'encoding'}); + encoding => $results->[$i]{'encoding'}, + timeout => $results->[$i]{'timeout'}); push @loop, \%row; } diff --git a/catalogue/detail.pl b/catalogue/detail.pl index db38551fde..da62e07e50 100755 --- a/catalogue/detail.pl +++ b/catalogue/detail.pl @@ -39,6 +39,7 @@ use C4::Tags qw(get_tags); use C4::VirtualShelves; use C4::XSLT; use C4::Images; +use Koha::DateUtils; # use Smart::Comments; @@ -192,9 +193,10 @@ foreach my $item (@items) { $item->{imageurl} = defined $item->{itype} ? getitemtypeimagelocation('intranet', $itemtypes->{ $item->{itype} }{imageurl}) : ''; - foreach (qw(datedue datelastseen onloan)) { + foreach (qw(datelastseen onloan)) { $item->{$_} = format_date($item->{$_}); - } + } + $item->{datedue} = format_sqldatetime($item->{datedue}); # item damaged, lost, withdrawn loops $item->{itemlostloop} = GetAuthorisedValues($authvalcode_items_itemlost, $item->{itemlost}) if $authvalcode_items_itemlost; if ($item->{damaged}) { diff --git a/catalogue/issuehistory.pl b/catalogue/issuehistory.pl index 3fb936ec36..288182ccd8 100755 --- a/catalogue/issuehistory.pl +++ b/catalogue/issuehistory.pl @@ -25,8 +25,8 @@ use C4::Output; use C4::Circulation; # GetBiblioIssues use C4::Biblio; # GetBiblio GetBiblioFromItemNumber -use C4::Dates qw/format_date/; use C4::Search; # enabled_staff_search_views +use Koha::DateUtils; my $query = new CGI; my ( $template, $borrowernumber, $cookie ) = get_template_and_user( @@ -67,11 +67,11 @@ if ($itemnumber){ %{$biblio[0]}, ); } -foreach (@$issues){ - $_->{date_due} = format_date($_->{date_due}); - $_->{issuedate} = format_date($_->{issuedate}); - $_->{returndate} = format_date($_->{returndate}); - $_->{lastreneweddate} = format_date($_->{lastreneweddate}); +foreach (@{$issues}){ + $_->{date_due} = format_sqldatetime($_->{date_due}); + $_->{issuedate} = format_sqldatetime($_->{issuedate}); + $_->{returndate} = format_sqldatetime($_->{returndate}); + $_->{lastreneweddate} = format_sqldatetime($_->{lastreneweddate}); } $template->param( total => scalar @$issues, diff --git a/catalogue/moredetail.pl b/catalogue/moredetail.pl index c9d202ced1..9d5465b910 100755 --- a/catalogue/moredetail.pl +++ b/catalogue/moredetail.pl @@ -35,6 +35,7 @@ use C4::Circulation; # to use itemissues use C4::Members; # to use GetMember use C4::Search; # enabled_staff_search_views use C4::Members qw/GetHideLostItemsPreference/; +use Koha::DateUtils; my $query=new CGI; diff --git a/cataloguing/additem.pl b/cataloguing/additem.pl index 4bf06b584a..695181be26 100755 --- a/cataloguing/additem.pl +++ b/cataloguing/additem.pl @@ -308,8 +308,6 @@ my ($template, $loggedinuser, $cookie) my $today_iso = C4::Dates->today('iso'); -$template->param(today_iso => $today_iso); - my $tagslib = &GetMarcStructure(1,$frameworkcode); my $record = GetMarcBiblio($biblionumber); my $oldrecord = TransformMarcToKoha($dbh,$record); diff --git a/cataloguing/value_builder/dateaccessioned.pl b/cataloguing/value_builder/dateaccessioned.pl index af1a285f82..5e834a453b 100755 --- a/cataloguing/value_builder/dateaccessioned.pl +++ b/cataloguing/value_builder/dateaccessioned.pl @@ -18,7 +18,7 @@ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. use strict; -#use warnings; FIXME - Bug 2505 +use warnings; =head1 @@ -71,14 +71,21 @@ function Focus$function_name(subfield_managed, id, force) { // summary += i + ": " + document.f.tag[i].value + " " + document.f.subfield[i].value + ": " + document.f.field_value[i].value + "\\n"; //} //alert("Got focus, subfieldmanaged: " + subfield_managed + "\\n" + summary); - set_to_today(id); // defined in additem.pl HEAD + set_to_today(id); return 0; } function Clic$function_name(id) { - set_to_today(id, 1); // defined in additem.pl HEAD + set_to_today(id, 1); return 0; } + +function set_to_today(id, force) { + if (! id) { alert(_("Bad id ") + id + _(" sent to set_to_today()")); return 0; } + if (\$("#" + id).val() == '' || \$("#" + id).val() == '0000-00-00' || force) { + \$("#" + id).val("$date"); + } +} //]]> END_OF_JS diff --git a/cataloguing/z3950_search.pl b/cataloguing/z3950_search.pl index b12a9c9f3d..10320e2b25 100755 --- a/cataloguing/z3950_search.pl +++ b/cataloguing/z3950_search.pl @@ -179,6 +179,7 @@ warn "query ".$query if $DEBUG; $option1->option('user', $server->{userid} ) if $server->{userid}; $option1->option('password', $server->{password}) if $server->{password}; $option1->option('preferredRecordSyntax', $server->{syntax}); + $option1->option( 'timeout', $server->{timeout} ) if ($server->{timeout}); $oConnection[$s] = create ZOOM::Connection($option1) || $DEBUG && warn( "" . $oConnection[$s]->errmsg() ); @@ -222,7 +223,7 @@ warn "query ".$query if $DEBUG; $oConnection[$k]->error_x(); if ($error) { if ($error =~ m/^(10000|10007)$/ ) { - push(@errconn, {'server' => $serverhost[$k]}); + push(@errconn, {'server' => $serverhost[$k], 'error' => $error}); } $DEBUG and warn "$k $serverhost[$k] error $query: $errmsg ($error) $addinfo\n"; } diff --git a/circ/branchoverdues.pl b/circ/branchoverdues.pl index 5c1dcafea6..dc89d60292 100755 --- a/circ/branchoverdues.pl +++ b/circ/branchoverdues.pl @@ -22,12 +22,12 @@ use C4::Context; use CGI; use C4::Output; use C4::Auth; -use C4::Dates qw/format_date/; use C4::Overdues; # AddNotifyLine use C4::Biblio; use C4::Koha; use C4::Debug; use C4::Branch; +use Data::Dumper; =head1 branchoverdues.pl @@ -97,7 +97,6 @@ elsif ( $input->param('action') eq 'remove' ) { my @overduesloop; my @getoverdues = GetOverduesForBranch( $default, $location ); -use Data::Dumper; $debug and warn "HERE : $default / $location" . Dumper(@getoverdues); # search for location authorised value my ($tag,$subfield) = GetMarcFromKohaField('items.location',''); @@ -114,7 +113,8 @@ foreach my $num (@getoverdues) { if ($record){ $overdueforbranch{'subtitle'} = GetRecordValue('subtitle',$record,'')->[0]->{subfield}; } - $overdueforbranch{'date_due'} = format_date( $num->{'date_due'} ); + my $dt = dt_from_string($num->{date_due}, 'sql'); + $overdueforbranch{'date_due'} = output_pref($dt); $overdueforbranch{'title'} = $num->{'title'}; $overdueforbranch{'description'} = $num->{'description'}; $overdueforbranch{'barcode'} = $num->{'barcode'}; @@ -151,7 +151,6 @@ foreach my $num (@getoverdues) { # initiate the templates for the overdueloop $template->param( overduesloop => \@overduesloop, - show_date => format_date(C4::Dates->today('iso')), location => $location, ); diff --git a/circ/circulation.pl b/circ/circulation.pl index 69289665c3..082b3d4d0e 100755 --- a/circ/circulation.pl +++ b/circ/circulation.pl @@ -4,6 +4,7 @@ # Copyright 2000-2002 Katipo Communications # copyright 2010 BibLibre +# Copyright 2011 PTFS-Europe Ltd. # # This file is part of Koha. # @@ -21,7 +22,7 @@ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. use strict; -#use warnings; FIXME - Bug 2505 +use warnings; use CGI; use C4::Output; use C4::Auth qw/:DEFAULT get_session/; @@ -36,6 +37,7 @@ use C4::Reserves; use C4::Context; use CGI::Session; use C4::Members::Attributes qw(GetBorrowerAttributes); +use Koha::DateUtils; use Date::Calc qw( Today @@ -144,14 +146,9 @@ my $duedatespec_allow = C4::Context->preference('SpecifyDueDate'); if($duedatespec_allow){ if ($duedatespec) { if ($duedatespec =~ C4::Dates->regexp('syspref')) { - my $tempdate = C4::Dates->new($duedatespec); -# if ($tempdate and $tempdate->output('iso') gt C4::Dates->new()->output('iso')) { -# # i.e., it has to be later than today/now - $datedue = $tempdate; -# } else { -# $invalidduedate = 1; -# $template->param(IMPOSSIBLE=>1, INVALID_DATE=>$duedatespec); -# } + $datedue = dt_from_string($duedatespec); + $datedue->set_hour(23); + $datedue->set_minute(59); } else { $invalidduedate = 1; $template->param(IMPOSSIBLE=>1, INVALID_DATE=>$duedatespec); @@ -451,9 +448,10 @@ sub build_issue_data { $totalprice += $it->{'replacementprice'}; $it->{'itemtype'} = $itemtypeinfo->{'description'}; $it->{'itemtype_image'} = $itemtypeinfo->{'imageurl'}; - $it->{'dd'} = format_date($it->{'date_due'}); - $it->{'displaydate'} = format_date($it->{'issuedate'}); - $it->{'od'} = ( $it->{'date_due'} lt $todaysdate ) ? 1 : 0 ; + $it->{'dd'} = output_pref($it->{'date_due'}); + $it->{'displaydate'} = output_pref($it->{'issuedate'}); + #$it->{'od'} = ( $it->{'date_due'} lt $todaysdate ) ? 1 : 0 ; + $it->{'od'} = $it->{'overdue'}; ($it->{'author'} eq '') and $it->{'author'} = ' '; $it->{'renew_failed'} = $renew_failed{$it->{'itemnumber'}}; diff --git a/circ/overdue.pl b/circ/overdue.pl index c25a1d6d2e..a4cfa7acf9 100755 --- a/circ/overdue.pl +++ b/circ/overdue.pl @@ -28,8 +28,9 @@ use C4::Auth; use C4::Branch; use C4::Debug; use C4::Dates qw/format_date format_date_in_iso/; -use Date::Calc qw/Today/; use Text::CSV_XS; +use Koha::DateUtils; +use DateTime; my $input = new CGI; my $order = $input->param('order') || ''; @@ -42,6 +43,14 @@ my $branchfilter = $input->param('branch') || ''; my $op = $input->param('op') || ''; my $dateduefrom = format_date_in_iso($input->param( 'dateduefrom' )) || ''; my $datedueto = format_date_in_iso($input->param( 'datedueto' )) || ''; +# FIXME This is a kludge to include times +if ($datedueto) { + $datedueto .= ' 23:59'; +} +if ($dateduefrom) { + $dateduefrom .= ' 00:00'; +} +# kludge end my $isfiltered = $op =~ /apply/i && $op =~ /filter/i; my $noreport = C4::Context->preference('FilterBeforeOverdueReport') && ! $isfiltered && $op ne "csv"; @@ -229,7 +238,9 @@ if ($noreport) { # FIX 2: ensure there are indexes for columns participating in the WHERE clauses, where feasible/reasonable - my $todaysdate = sprintf("%-04.4d-%-02.2d-%02.2d", Today()); + my $today_dt = DateTime->now(time_zone => C4::Context->tz); + $today_dt->truncate(to => 'minutes'); + my $todaysdate = $today_dt->strftime('%Y-%m-%d %H:%M'); $bornamefilter =~s/\*/\%/g; $bornamefilter =~s/\?/\_/g; @@ -318,9 +329,10 @@ if ($noreport) { my @displayvalues = map { $_->[1] } @{ $pattrs->{$pattr_filter->{code}} }; # grab second value from each subarray push @patron_attr_value_loop, { value => join(', ', sort { lc $a cmp lc $b } @displayvalues) }; } + my $dt = dt_from_string($data->{date_due}, 'sql'); push @overduedata, { - duedate => format_date($data->{date_due}), + duedate => output_pref($dt), borrowernumber => $data->{borrowernumber}, barcode => $data->{barcode}, itemnum => $data->{itemnumber}, @@ -389,7 +401,7 @@ if ($noreport) { $template->param( csv_param_string => $csv_param_string, - todaysdate => format_date($todaysdate), + todaysdate => output_pref($today_dt), overdueloop => \@overduedata, nnoverdue => scalar(@overduedata), noverdue_is_plural => scalar(@overduedata) != 1, diff --git a/circ/returns.pl b/circ/returns.pl index e142117eb2..83817a8310 100755 --- a/circ/returns.pl +++ b/circ/returns.pl @@ -4,6 +4,7 @@ # 2006 SAN-OP # 2007-2010 BibLibre, Paul POULAIN # 2010 Catalyst IT +# 2011 PTFS-Europe Ltd. # # This file is part of Koha. # @@ -30,13 +31,11 @@ use strict; #use warnings; FIXME - Bug 2505 use CGI; +use DateTime; use C4::Context; use C4::Auth qw/:DEFAULT get_session/; use C4::Output; use C4::Circulation; -use C4::Dates qw/format_date/; -use Date::Calc qw/Add_Delta_Days/; -use C4::Calendar; use C4::Print; use C4::Reserves; use C4::Biblio; @@ -45,6 +44,8 @@ use C4::Members; use C4::Branch; # GetBranches GetBranchName use C4::Koha; # FIXME : is it still useful ? use C4::RotatingCollections; +use Koha::DateUtils; +use Koha::Calendar; my $query = new CGI; @@ -175,10 +176,9 @@ my $dropboxmode = $query->param('dropboxmode'); my $dotransfer = $query->param('dotransfer'); my $canceltransfer = $query->param('canceltransfer'); my $dest = $query->param('dest'); -my $calendar = C4::Calendar->new( branchcode => $userenv_branch ); +my $calendar = Koha::Calendar->new( branchcode => $userenv_branch ); #dropbox: get last open day (today - 1) -my $today = C4::Dates->new(); -my $today_iso = $today->output('iso'); +my $today = DateTime->now( time_zone => C4::Context->tz()); my $dropboxdate = $calendar->addDate($today, -1); if ($dotransfer){ # An item has been returned to a branch other than the homebranch, and the librarian has chosen to initiate a transfer @@ -249,13 +249,14 @@ if ($barcode) { ); if ($returned) { - my $duedate = $issueinformation->{'date_due'}; + my $time_now = DateTime->now( time_zone => C4::Context->tz )->truncate( to => 'minutes'); + my $duedate = $issueinformation->{date_due}->strftime('%Y-%m-%d %H:%M'); $returneditems{0} = $barcode; $riborrowernumber{0} = $borrower->{'borrowernumber'}; $riduedate{0} = $duedate; $input{borrowernumber} = $borrower->{'borrowernumber'}; $input{duedate} = $duedate; - $input{return_overdue} = 1 if ($duedate and $duedate lt $today->output('iso')); + $input{return_overdue} = 1 if (DateTime->compare($issueinformation->{date_due}, $time_now) == -1); push( @inputloop, \%input ); if ( C4::Context->preference("FineNotifyAtCheckin") ) { @@ -463,7 +464,7 @@ foreach my $code ( keys %$messages ) { elsif ( $code eq 'Wrongbranch' ) { } elsif ( $code eq 'Debarred' ) { - $err{debarred} = format_date( $messages->{'Debarred'} ); + $err{debarred} = $messages->{'Debarred'}; $err{debarcardnumber} = $borrower->{cardnumber}; $err{debarborrowernumber} = $borrower->{borrowernumber}; $err{debarname} = "$borrower->{firstname} $borrower->{surname}"; @@ -519,7 +520,7 @@ if ($borrower) { { my $biblio = GetBiblioFromItemNumber( $item->{'itemnumber'}); push @itemloop, { - duedate => format_date($item->{'date_due'}), + duedate => format_sqldatetime($item->{date_due}), biblionum => $biblio->{'biblionumber'}, barcode => $biblio->{'barcode'}, title => $biblio->{'title'}, @@ -545,7 +546,6 @@ if ($borrower) { riborfirstname => $borrower->{'firstname'} ); } - #set up so only the last 8 returned items display (make for faster loading pages) my $returned_counter = ( C4::Context->preference('numReturnedItemsToShow') ) ? C4::Context->preference('numReturnedItemsToShow') : 8; my $count = 0; @@ -555,15 +555,16 @@ foreach ( sort { $a <=> $b } keys %returneditems ) { my %ri; if ( $count++ < $returned_counter ) { my $bar_code = $returneditems{$_}; - my $duedate = $riduedate{$_}; - if ($duedate) { - my @tempdate = split( /-/, $duedate ); - $ri{year} = $tempdate[0]; - $ri{month} = $tempdate[1]; - $ri{day} = $tempdate[2]; - $ri{duedate} = format_date($duedate); + if ($riduedate{$_}) { + my $duedate = dt_from_string( $riduedate{$_}, 'sql'); + $ri{year} = $duedate->year(); + $ri{month} = $duedate->month(); + $ri{day} = $duedate->day(); + $ri{hour} = $duedate->hour(); + $ri{minute} = $duedate->minute(); + $ri{duedate} = output_pref($duedate); my ($b) = GetMemberDetails( $riborrowernumber{$_}, 0 ); - $ri{return_overdue} = 1 if ($duedate lt $today->output('iso')); + $ri{return_overdue} = 1 if (DateTime->compare($duedate, DateTime->now()) == -1 ); $ri{borrowernumber} = $b->{'borrowernumber'}; $ri{borcnum} = $b->{'cardnumber'}; $ri{borfirstname} = $b->{'firstname'}; @@ -600,7 +601,6 @@ foreach ( sort { $a <=> $b } keys %returneditems ) { } push @riloop, \%ri; } - $template->param( riloop => \@riloop, genbrname => $branches->{$userenv_branch}->{'branchname'}, @@ -610,7 +610,7 @@ $template->param( errmsgloop => \@errmsgloop, exemptfine => $exemptfine, dropboxmode => $dropboxmode, - dropboxdate => $dropboxdate->output(), + dropboxdate => output_pref($dropboxdate), overduecharges => $overduecharges, soundon => C4::Context->preference("SoundOn"), ); diff --git a/installer/data/mysql/atomicupdate/hourlyloans.sql b/installer/data/mysql/atomicupdate/hourlyloans.sql new file mode 100644 index 0000000000..664142d9dd --- /dev/null +++ b/installer/data/mysql/atomicupdate/hourlyloans.sql @@ -0,0 +1 @@ +alter table issuingrules add column lengthunit varchar(10) default 'days' after issuelength; diff --git a/installer/data/mysql/atomicupdate/issuedate_times.pl b/installer/data/mysql/atomicupdate/issuedate_times.pl new file mode 100644 index 0000000000..864109a1fe --- /dev/null +++ b/installer/data/mysql/atomicupdate/issuedate_times.pl @@ -0,0 +1,17 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use C4::Context; + +my $dbh = C4::Context->dbh; + +$dbh->do("ALTER TABLE issues CHANGE date_due date_due datetime"); +$dbh->do("ALTER TABLE issues CHANGE returndate returndate datetime"); +$dbh->do("ALTER TABLE issues CHANGE lastreneweddate lastreneweddate datetime"); +$dbh->do("ALTER TABLE issues CHANGE issuedate issuedate datetime"); +$dbh->do("ALTER TABLE old_issues CHANGE date_due date_due datetime"); +$dbh->do("ALTER TABLE old_issues CHANGE returndate returndate datetime"); +$dbh->do("ALTER TABLE old_issues CHANGE lastreneweddate lastreneweddate datetime"); +$dbh->do("ALTER TABLE old_issues CHANGE issuedate issuedate datetime"); +$dbh->do(q{update issues set date_due = addtime(date_due, '0 23:0:0') where hour(date_due) = 0}); diff --git a/installer/data/mysql/fr-FR/1-Obligatoire/sample_notices.sql b/installer/data/mysql/fr-FR/1-Obligatoire/sample_notices.sql index 4eb1210fcd..1056d14c10 100644 --- a/installer/data/mysql/fr-FR/1-Obligatoire/sample_notices.sql +++ b/installer/data/mysql/fr-FR/1-Obligatoire/sample_notices.sql @@ -1,20 +1,20 @@ INSERT IGNORE INTO `letter` (module, code, name, title, content) VALUES -('circulation','ODUE','Overdue Notice','Item Overdue','Dear <> <>,\n\nAccording to our current records, you have items that are overdue.Your library does not charge late fines, but please return or renew them at the branch below as soon as possible.\n\n<>\n<>\n<> <>\nPhone: <>\nFax: <>\nEmail: <>\n\nIf you have registered a password with the library, and you have a renewal available, you may renew online. If an item becomes more than 30 days overdue, you will be unable to use your library card until the item is returned.\n\nThe following item(s) is/are currently overdue:\n\n"<>" by <>, <>, Barcode: <> Fine: GBP\n\nThank-you for your prompt attention to this matter.\n\n<> Staff\n'), -('claimacquisition','ACQCLAIM','Acquisition Claim','Item Not Received','<>\r\n<>\r\n<>\r\n<>\r\n<>\r\n<>\r\n\r\nOrdernumber <> (<>) (<> ordered) ($<> each) has not been received.'), -('serial','RLIST','Routing List','Serial is now available','<> <>,\r\n\r\nThe following issue is now available:\r\n\r\n<>, <> (<>)\r\n\r\nPlease pick it up at your convenience.'), -('members','ACCTDETAILS','Account Details Template - DEFAULT','Your new Koha account details.','Hello <> <> <>.\r\n\r\nYour new Koha account details are:\r\n\r\nUser: <>\r\nPassword: <>\r\n\r\nIf you have any problems or questions regarding your account, please contact your Koha Administrator.\r\n\r\nThank you,\r\nKoha Administrator\r\nkohaadmin@yoursite.org'), -('circulation','DUE','Item Due Reminder','Item Due Reminder','Dear <> <>,\r\n\r\nThe following item is now due:\r\n\r\n<>, <> (<>)'), -('circulation','DUEDGST','Item Due Reminder (Digest)','Item Due Reminder','You have <> items due'), -('circulation','PREDUE','Advance Notice of Item Due','Advance Notice of Item Due','Dear <> <>,\r\n\r\nThe following item will be due soon:\r\n\r\n<>, <> (<>)'), -('circulation','PREDUEDGST','Advance Notice of Item Due (Digest)','Advance Notice of Item Due','You have <> items due soon'), -('reserves', 'HOLD', 'Hold Available for Pickup', 'Hold Available for Pickup at <>', 'Dear <> <>,\r\n\r\nYou have a hold available for pickup as of <>:\r\n\r\nTitle: <>\r\nAuthor: <>\r\nCopy: <>\r\nLocation: <>\r\n<>\r\n<>\r\n<>'), -('reserves', 'HOLD_PRINT', 'Hold Available for Pickup (print notice)', 'Hold Available for Pickup at <>', '<>\n<>\n<>\n\n\nChange Service Requested\n\n\n\n\n\n\n\n<> <>\n<>\n<> <>\n\n\n\n\n\n\n\n\n\n\n<> <> <>\n\nYou have a hold available for pickup as of <>:\r\n\r\nTitle: <>\r\nAuthor: <>\r\nCopy: <>\r\n'), -('circulation','CHECKIN','Item Check-in (Digest)','Check-ins','The following items have been checked in:\r\n----\r\n<>\r\n----\r\nThank you.'), -('circulation','CHECKOUT','Item Check-out (Digest)','Checkouts','The following items have been checked out:\r\n----\r\n<>\r\n----\r\nThank you for visiting <>.'), -('reserves', 'HOLDPLACED', 'Hold Placed on Item', 'Hold Placed on Item','A hold has been placed on the following item : <> (<>) by the user <> <> (<>).'), -('suggestions','ACCEPTED','Suggestion accepted', 'Purchase suggestion accepted','Dear <> <>,\n\nYou have suggested that the library acquire <> by <>.\n\nThe library has reviewed your suggestion today. The item will be ordered as soon as possible. You will be notified by mail when the order is completed, and again when the item arrives at the library.\n\nIf you have any questions, please email us at <>.\n\nThank you,\n\n<>'), -('suggestions','AVAILABLE','Suggestion available', 'Suggested purchase available','Dear <> <>,\n\nYou have suggested that the library acquire <> by <>.\n\nWe are pleased to inform you that the item you requested is now part of the collection.\n\nIf you have any questions, please email us at <>.\n\nThank you,\n\n<>'), -('suggestions','ORDERED','Suggestion ordered', 'Suggested item ordered','Dear <> <>,\n\nYou have suggested that the library acquire <> by <>.\n\nWe are pleased to inform you that the item you requested has now been ordered. It should arrive soon, at which time it will be processed for addition into the collection.\n\nYou will be notified again when the book is available.\n\nIf you have any questions, please email us at <>\n\nThank you,\n\n<>'), -('suggestions','REJECTED','Suggestion rejected', 'Purchase suggestion declined','Dear <> <>,\n\nYou have suggested that the library acquire <> by <>.\n\nThe library has reviewed your request today, and has decided not to accept the suggestion at this time.\n\nThe reason given is: <>\n\nIf you have any questions, please email us at <>.\n\nThank you,\n\n<>'); +('circulation','ODUE','Avis de retard','Document en retard','Cher(e) <> <>,\n\nSelon nos informations actuelles, vous avez des documents signalés en retard dans votre compte.La Bibliothèque n\'applique pas les pénalités, mais nous vous invitons à retourner ou renouveler ces documents au plus vite dans la Bibliothèque suivante.\n\n<>\n<>\n<> <>\nTéléphone: <>\nFax: <>\nCourriel: <>\n\nSi vous possédez un identifiant et un mot de passe pour vous connecter à notre catalogue en ligne,vous pouvez depuis celui-ci prolonger la durée de prêt des documents. Si les documents ont plus de 3à jours de retard, vous ne pourrez plus utiliser votre carte d\'adhérent tant que les documents ne seront pas rendus.\n\nLe(s) document(s) actuellement en retard:\n\n"<>" de <>, <>, Code barres: <> Pénalité: GBP\n\nAvec nos remerciements.\n\n<> La banque de prêt\n'), +('claimacquisition','ACQCLAIM','Réclamation Acquisitions','Document non reçu','<>\r\n<>\r\n<>\r\n<>\r\n<>\r\n<>\r\n\r\nCommande <> (<>) (<> ordered) ($<> each) pas encore reçue.'), +('serial','RLIST','Liste de routage','Fascicule de périodique disponible','<> <>,\r\n\r\nLe numéro suivant est disponible:\r\n\r\n<>, <> (<>)\r\n\r\nVous pouvez venir le retirer quand vous voulez.'), +('members','ACCTDETAILS','Nouveau compte adhérent','Votre nouveau compte adhérent.','Bonjour <> <> <>.\r\n\r\nLes informations de votre nouveau compte sont:\r\n\r\nIdentifiant: <>\r\nMot de passe: <>\r\n\r\nSi vous avez des questions au sujet de votre nouveau compte, merci de prendre contact à l\'acceuil de la Bibliothèque.\r\n\r\nMerci,\r\nLa Bibliothèque\r\nkohaadmin@yoursite.org'), +('circulation','DUE','Document à rendre ','Document à rendre','Cher(e) <> <>,\r\n\r\nLe document suivant doit être rendu aujourd\'hui:\r\n\r\n<>, <> (<>)'), +('circulation','DUEDGST','Document à rendre (résumé)','Document à rendre','Vous avez <> document(s) à rendre'), +('circulation','PREDUE','Document à rendre bientôt','Document à rendre bientôt','Cher(e) <> <>,\r\n\r\nLa date de retour du doucment suivant est proche:\r\n\r\n<>, <> (<>)'), +('circulation','PREDUEDGST','Document à rendre bientôt (résumé)','Document à rendre bientôt','Vous avez <> document(s) dont la date de retour est proche'), +('reserves', 'HOLD', 'Réservation disponible pour retrait', 'Réservation disponible à la banque de retrait du site <>', 'Cher(e) <> <>,\r\n\r\nVous avez une réservation disponible pour retrait depuis le <>:\r\n\r\nTitre: <>\r\nAuteur: <>\r\nNuméro de fascicule: <>\r\nSite: <>\r\n<>\r\n<>\r\n<>'), +('reserves', 'HOLD_PRINT', 'Réservation disponible pour retrait (papier)', 'Réservation disponible à la banque de retrait du site <>', '<>\n<>\n<>\n\n\nLe service des réservations\n\n\n\n\n\n\n\n<> <>\n<>\n<> <>\n\n\n\n\n\n\n\n\n\n\n<> <> <>\n\nVotre réservation est disponible pour retrait depuis le <>:\r\n\r\nTitre: <>\r\nAuteur: <>\r\nNuméro de fascicule: <>\r\n'), +('circulation','CHECKIN','Document rendu (résumé)','Retours','Les documents suivants ont été rendus:\r\n----\r\n<>\r\n----\r\nMerci.'), +('circulation','CHECKOUT','Document prêté (résumé)','Prêts','Les documents suivants ont été prêtés:\r\n----\r\n<>\r\n----\r\nMerci de votre visite <>.'), +('reserves', 'HOLDPLACED', 'Demande de réservation', 'Demande de réservation','Une demande de réservation a été placée sur le document : <> (<>) par l\'adhérent <> <> (<>).'), +('suggestions','ACCEPTED','Suggestion accceptée', 'Suggestion acceptée','Cher(e) <> <>,\n\nVous avez crée une suggestion d\'achat au sujet du document <> de <>.\n\nLa Bibliothèque a reçu votre demande ce jour. Nous donnerons suite à votre demande aussi vite que possible. Vous serez averti par courriel dès que la commande sera envoyée,et quand les documents seront arrivés à la Bibliothèque.\n\nSi vous avez des questions, merci de nous contacter à l\'adresse suivante <>.\n\nMerci,\n\n<>'), +('suggestions','AVAILABLE','Suggestion disponible', 'Suggestion d\'achat disponible','cher(e) <> <>,\n\nVous avez effectué une suggestion d\'achat pour le docuement <> de <>.\n\nNous sommes heureux de vous informer que le document que vous aviez demandé est maintenant disponible dans nos collections.\n\nSi vous avez des questions, merci de nous contacter par courriel à l\'adresse <>.\n\nMerci,\n\n<>'), +('suggestions','ORDERED','Suggestion commandée', 'Suggestion commandée','Cher(e) <> <>,\n\nVous avez effectué une demande de suggestion d\'achat sur le docuement <> de <>.\n\nNous sommes heureux de vous informer que le document que vous avez demandé est maintenant en commande. Le document devrait arriver rapidement dans nos collections.\n\nVous serez averti quand le docuement sera disponible.\n\nSi vous avez des questions, merci de nous contacter à l\'adresse <>\n\nMerci,\n\n<>'), +('suggestions','REJECTED','Suggestion rejetée', 'Suggestion d\'achat rejeté','Cher(e) <> <>,\n\nVous avez fait la demande du document <> de <>.\n\nla Bibliothèque a examiné votre demande ce jour, et a décidé de ne pas retenir la suggestion pour l\'instant.\n\nLa raison est la suivante: <>\n\nSi vous avez des questions, merci de nous contacter à l\'adresse <>.\n\nMerci,\n\n<>'); diff --git a/installer/data/mysql/fr-FR/1-Obligatoire/sample_notices.txt b/installer/data/mysql/fr-FR/1-Obligatoire/sample_notices.txt index 82e2ff84d6..99b3e93c17 100644 --- a/installer/data/mysql/fr-FR/1-Obligatoire/sample_notices.txt +++ b/installer/data/mysql/fr-FR/1-Obligatoire/sample_notices.txt @@ -1 +1 @@ -Sample Notices +Notifications d'exemple diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql index f5d8a2410b..77423d17a2 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -286,6 +286,8 @@ CREATE TABLE `borrower_attribute_types` ( -- definitions for custom patron field `staff_searchable` tinyint(1) NOT NULL default 0, -- defines if this field is searchable via the patron search in the staff client (1 for yes, 0 for no) `authorised_value_category` varchar(10) default NULL, -- foreign key from authorised_values that links this custom field to an authorized value category `display_checkout` tinyint(1) NOT NULL default 0,-- defines if this field displays in checkout screens + `category_code` VARCHAR(1) NOT NULL DEFAULT '',-- defines a category for an attribute_type + `class` VARCHAR(255) NOT NULL DEFAULT '',-- defines a class for an attribute_type PRIMARY KEY (`code`), KEY `auth_val_cat_idx` (`authorised_value_category`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -362,6 +364,7 @@ CREATE TABLE `branches` ( -- information about your libraries or branches are st `branchip` varchar(15) default NULL, -- the IP address for your library or branch `branchprinter` varchar(100) default NULL, -- unused in Koha `branchnotes` mediumtext, -- notes related to your library or branch + opac_info text, -- HTML that displays in OPAC UNIQUE KEY `branchcode` (`branchcode`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -953,15 +956,15 @@ DROP TABLE IF EXISTS `issues`; CREATE TABLE `issues` ( -- information related to check outs or issues `borrowernumber` int(11), -- foreign key, linking this to the borrowers table for the patron this item was checked out to `itemnumber` int(11), -- foreign key, linking this to the items table for the item that was checked out - `date_due` date default NULL, -- date the item is due (yyyy-mm-dd) + `date_due` datetime default NULL, -- datetime the item is due (yyyy-mm-dd hh:mm::ss) `branchcode` varchar(10) default NULL, -- foreign key, linking to the branches table for the location the item was checked out `issuingbranch` varchar(18) default NULL, - `returndate` date default NULL, -- date the item was returned, will be NULL until moved to old_issues - `lastreneweddate` date default NULL, -- date the item was last renewed + `returndate` datetime default NULL, -- date the item was returned, will be NULL until moved to old_issues + `lastreneweddate` datetime default NULL, -- date the item was last renewed `return` varchar(4) default NULL, `renewals` tinyint(4) default NULL, -- lists the number of times the item was renewed `timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, -- the date and time this record was last touched - `issuedate` date default NULL, -- date the item was checked out or issued + `issuedate` datetime default NULL, -- date the item was checked out or issued KEY `issuesborridx` (`borrowernumber`), KEY `bordate` (`borrowernumber`,`timestamp`), CONSTRAINT `issues_ibfk_1` FOREIGN KEY (`borrowernumber`) REFERENCES `borrowers` (`borrowernumber`) ON DELETE RESTRICT ON UPDATE CASCADE, @@ -1416,15 +1419,15 @@ DROP TABLE IF EXISTS `old_issues`; CREATE TABLE `old_issues` ( -- lists items that were checked out and have been returned `borrowernumber` int(11) default NULL, -- foreign key, linking this to the borrowers table for the patron this item was checked out to `itemnumber` int(11) default NULL, -- foreign key, linking this to the items table for the item that was checked out - `date_due` date default NULL, -- date the item is due (yyyy-mm-dd) + `date_due` datetime default NULL, -- date the item is due (yyyy-mm-dd) `branchcode` varchar(10) default NULL, -- foreign key, linking to the branches table for the location the item was checked out `issuingbranch` varchar(18) default NULL, - `returndate` date default NULL, -- date the item was returned - `lastreneweddate` date default NULL, -- date the item was last renewed + `returndate` datetime default NULL, -- date the item was returned + `lastreneweddate` datetime default NULL, -- date the item was last renewed `return` varchar(4) default NULL, `renewals` tinyint(4) default NULL, -- lists the number of times the item was renewed `timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, -- the date and time this record was last touched - `issuedate` date default NULL, -- date the item was checked out or issued + `issuedate` datetime default NULL, -- date the item was checked out or issued KEY `old_issuesborridx` (`borrowernumber`), KEY `old_issuesitemidx` (`itemnumber`), KEY `old_bordate` (`borrowernumber`,`timestamp`), @@ -2115,6 +2118,7 @@ CREATE TABLE `z3950servers` ( -- connection information for the Z39.50 targets u `checked` smallint(6) default NULL, -- whether this target is checked by default (1 for yes, 0 for no) `rank` int(11) default NULL, -- where this target appears in the list of targets `syntax` varchar(80) default NULL, -- marc format provided by this target + `timeout` int(11) NOT NULL DEFAULT '0', `icon` text, -- unused in Koha `position` enum('primary','secondary','') NOT NULL default 'primary', `type` enum('zed','opensearch') NOT NULL default 'zed', diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl index 1c8be0ffb2..8259bf286a 100755 --- a/installer/data/mysql/updatedatabase.pl +++ b/installer/data/mysql/updatedatabase.pl @@ -4932,7 +4932,6 @@ if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) { SetVersion($DBversion); } - $DBversion = "3.07.00.029"; if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) { my $installer = C4::Installer->new(); @@ -4967,8 +4966,8 @@ if (C4::Context->preference("Version") < TransformToNum($DBversion)) { SetVersion ($DBversion); } -$DBversion = "3.07.99.032"; -if ( C4::Context->preference("Version") lt TransformToNum($DBversion) ) { +$DBversion = "3.07.00.032"; +if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) { $dbh->do("ALTER TABLE virtualshelves MODIFY COLUMN owner int"); #should have been int already (fk to borrowers) $dbh->do("UPDATE virtualshelves vi LEFT JOIN borrowers bo ON bo.borrowernumber=vi.owner SET vi.owner=NULL where bo.borrowernumber IS NULL"); #before adding the constraint on borrowernumber, we need to get rid of deleted owners $dbh->do("DELETE FROM virtualshelves WHERE owner IS NULL and category=1"); #delete private lists without owner (cascades to shelfcontents) @@ -4994,6 +4993,49 @@ if ( C4::Context->preference("Version") lt TransformToNum($DBversion) ) { SetVersion($DBversion); } +$DBversion = "3.07.00.033"; +if (C4::Context->preference("Version") < TransformToNum($DBversion)) { + $dbh->do("ALTER TABLE branches ADD opac_info text;"); + print "Upgrade to $DBversion done add opac_info to branches \n"; + SetVersion($DBversion); +} + + + + +$DBversion = "3.07.00.034"; +if (C4::Context->preference("Version") < TransformToNum($DBversion)) { + $dbh->do("ALTER TABLE borrower_attribute_types ADD COLUMN category_code VARCHAR(10) NULL DEFAULT NULL AFTER `display_checkout`"); + $dbh->do("ALTER TABLE borrower_attribute_types ADD COLUMN class VARCHAR(255) NOT NULL DEFAULT '' AFTER `category_code`"); + $dbh->do("ALTER TABLE borrower_attribute_types ADD CONSTRAINT category_code_fk FOREIGN KEY (category_code) REFERENCES categories(categorycode)"); + print "Upgrade to $DBversion done (New fields category_code and class in borrower_attribute_types table)\n"; + SetVersion($DBversion); +} + +$DBversion = "3.07.00.035"; +if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) { + $dbh->do("ALTER TABLE issues CHANGE date_due date_due datetime"); + $dbh->do("ALTER TABLE issues CHANGE returndate returndate datetime"); + $dbh->do("ALTER TABLE issues CHANGE lastreneweddate lastreneweddate datetime"); + $dbh->do("ALTER TABLE issues CHANGE issuedate issuedate datetime"); + $dbh->do("ALTER TABLE old_issues CHANGE date_due date_due datetime"); + $dbh->do("ALTER TABLE old_issues CHANGE returndate returndate datetime"); + $dbh->do("ALTER TABLE old_issues CHANGE lastreneweddate lastreneweddate datetime"); + $dbh->do("ALTER TABLE old_issues CHANGE issuedate issuedate datetime"); + $dbh->do("alter table issuingrules add column lengthunit varchar(10) default 'days' after issuelength"); + print "Upgrade to $DBversion done (Setting up issues tables for hourly loans)\n"; + SetVersion($DBversion); +} + +$DBversion = "3.07.00.036"; +if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) { + $dbh->do(qq{ + ALTER TABLE `z3950servers` ADD `timeout` INT( 11 ) NOT NULL DEFAULT '0' AFTER `syntax`; + }); + print "Upgrade to $DBversion done (New timeout field in z3950servers)\n"; + SetVersion($DBversion); +} + =head1 FUNCTIONS =head2 DropAllForeignKeys($table) diff --git a/koha-tmpl/intranet-tmpl/prog/en/columns.def b/koha-tmpl/intranet-tmpl/prog/en/columns.def index 3c6794946f..726ecc632f 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/columns.def +++ b/koha-tmpl/intranet-tmpl/prog/en/columns.def @@ -1,124 +1,140 @@ -borrowers.borrowernumber Borrower Number -borrowers.cardnumber Card Number +borrowers.borrowernumber Borrower number +borrowers.title Salutation borrowers.surname Surname -borrowers.firstname Firstname -borrowers.title Title -borrowers.othernames Other Names -borrowers.initials Initials -borrowers.streetaddress Street Address -borrowers.suburb Suburb -borrowers.city City -borrowers.phone Phone -borrowers.emailaddress Email -borrowers.faxnumber Fax -borrowers.textmessaging Opac Message -borrowers.altstreetaddress Alternative Street Address -borrowers.altsuburb Alternative Suburb -borrowers.altcity Alternative City -borrowers.altphone Alternative Phone -borrowers.dateofbirth Date of Birth -borrowers.branchcode Branch Code -borrowers.categorycode Borrowers Category -borrowers.dateenrolled Date Enrolled -borrowers.gonenoaddress Address Missing -borrowers.lost Lost Card -borrowers.debarred Restricted -borrowers.studentnumber Student Id number -borrowers.school School -borrowers.contactname Contact Name -borrowers.borrowernotes Circulation Notes -borrowers.guarantor Guarantor(parent) -borrowers.area Area -borrowers.ethnicity Ethnicity -borrowers.ethnotes Ethnicity Notes +borrowers.firstname First name +borrowers.dateofbirth Date of birth +borrowers.initials Initials +borrowers.othernames Other name borrowers.sex Gender -borrowers.expiry Expiry Date -borrowers.altnotes Alternative Contact Notes -borrowers.altrelationship Relationship of Alternative Contact -borrowers.streetcity Streetcity?? -borrowers.phoneday Work Phone -borrowers.preferredcont Preferred method of Contact -borrowers.physstreet Physical Street Address -borrowers.password Password -borrowers.flags Warnings -borrowers.userid Login ID -borrowers.homezipcode Zip/Post Code -borrowers.zipcode Zip/Post Code 2? -borrowers.sort1 Sorting Column -borrowers.sort2 Sorting Column 2 -borrowers.cellph Cellphone number -borrowers.borlog -borrowers.checkhist -items.itemnumber Item Number (koha internal) -items.biblionumber Biblio Number (koha internal) -items.multivolumepart Item one part of a Multi volume set -items.biblioitemnumber Biblioitem Number (koha internal) +borrowers.relationship Relationship +borrowers.guarantorid Guarantor borrower number +borrowers.streetnumber Street number +borrowers.streettype Street type +borrowers.address Address +borrowers.address2 Address 2 +borrowers.city City +borrowers.state State +borrowers.zipcode Zip/postal code +borrowers.country Country +borrowers.phone Primary phone +borrowers.phonepro Secondary phone +borrowers.mobile Other phone +borrowers.email Primary email +borrowers.emailpro Secondary email +borrowers.fax Fax +borrowers.B_streetnumber Alternate address: Street number +borrowers.B_streettype Alternate address: Street type +borrowers.B_address Alternate address: Address +borrowers.B_address2 Alternate address: Address 2 +borrowers.B_city Alternate address: City +borrowers.B_state Alternate address: State +borrowers.B_zipcode Alternate address: Zip/postal code +borrowers.B_country Alternate address: Country +borrowers.B_phone Alternate address: Phone +borrowers.B_email Alternate address: Email +borrowers.contactnote Alternate contact: Note +borrowers.altcontactfirstname Alternate contact: Last name +borrowers.altcontactsurname Alternate contact: First name +borrowers.altcontactaddress1 Alternate contact: Address +borrowers.altcontactaddress2 Alternate contact: Address 2 +borrowers.altcontactaddress3 Alternate contact: City +borrowers.contactname Alternate contact: Surname +borrowers.contactfirstname Alternate contact: First name +borrowers.contacttitle Alternate contact: Title +borrowers.altcontactstate Alternate contact: State +borrowers.altcontactzipcode Alternate contact: Zip/postal code +borrowers.altcontactcountry Alternate contact: Country +borrowers.altcontactphone Alternate contact: Phone +borrowers.cardnumber Card number +borrowers.branchcode Home library +borrowers.categorycode Category +borrowers.sort1 Sort 1 +borrowers.sort2 Sort 2 +borrowers.dateenrolled Registration date +borrowers.dateexpiry Expiry date +borrowers.opacnote OPAC note +borrowers.borrowernotes Circulation note +borrowers.userid Username +borrowers.password Password +borrowers.flags System permissions +borrowers.gonenoaddress Gone no address flag +borrowers.lost Lost card flag +borrowers.debarred Restricted [until] flag +borrowers.debarredcomment Comment +borrowers.smsalertnumber Mobile phone number +borrowers.privacy Privacy settings +items.itemnumber Item number (internal) +items.biblionumber Biblio number (internal) +items.biblioitemnumber Biblioitem number (internal) items.barcode Barcode -items.dateaccessioned Accession Date -items.booksellerid Supplier ID -items.homebranch Home Branch +items.dateaccessioned Date acquired +items.booksellerid Source of acquisition +items.homebranch Permanent library items.price Price -items.replacementprice Replacement Price -items.replacementpricedate Date Replacement Price was set -items.datelastborrowed Date Item last issued -items.datelastseen Date Item was last seen by Koha -items.multivolume Volume Number (if part of a multivolume work) -items.stack Is the item in the stack? -items.onloan On loan -items.notforloan Item Not for loan -items.itemlost Item Lost -items.wthdrawn Item Cancelled -items.itemcallnumber Item Call Number -items.issues Issues Count -items.renewals Renewals Count -items.reserves Reserves Count -items.restricted Item Restricted -items.binding Item needs binding -items.itemnotes Item Notes -items.holdingbranch Holding Branch -items.paidfor Has Item been lost and then paid for +items.replacementprice Replacement price +items.replacementpricedate Price effective from +items.datelastborrowed Date last checked out +items.datelastseen Date last seen +items.stack Shelving control number +items.onloan Due date +items.cn_source Source of classification / shelving scheme +items.cn_sort Koha normalized classification for sorting +items.notforloan Not for loan +items.itemlost Lost status +items.wthdrawn Withdrawn status +items.itemcallnumber Call number +items.issues Total checkouts +items.renewals Total renewals +items.reserves Total holds +items.restricted Use restrictions +items.itemnotes Public note +items.holdingbranch Current library +items.paidfor items.timestamp Timestamp -items.location Location -items.ccode Koha Collection -items.itype Item-level Item Type -items.spystatus -items.spydescr -items.itemlog -items.spycopydata -statistics.datetime Statistics Date and Time -statistics.branch Branch Code -statistics.proccode Type of Procedure +items.location Shelving location +items.ccode Collection code +items.itype Koha itemtype +items.stocknumber Inventory number +items.damaged Damaged status +items.materials Materials specified +items.uri Uniform Resource Identifier +items.more_subfields_xml Additional subfields (XML) +items.enumchron Serial enumeraton/chronology +items.copynumber Copy number +statistics.datetime Statistics date and time +statistics.branch Library +statistics.proccode Type of procedure statistics.value Value statistics.type Type statistics.other -statistics.usercode User Code -statistics.itemnumber Item Number -statistics.itemtype Item Type -statistics.borrowernumber Borrower Number -biblio.frameworkcode Framework Code +statistics.usercode User code +statistics.itemnumber Item number +statistics.itemtype Itemtype +statistics.borrowernumber Borrower number +biblio.frameworkcode Framework code biblio.author Author -biblio.datecreated Creation Date -biblio.timestamp Modification Date -biblioitems.biblioitemnumber Biblioitem Number -biblioitems.biblionumber Biblio Number -biblioitems.volume Volume Number +biblio.datecreated Creation date +biblio.timestamp Modification date +biblioitems.biblioitemnumber Biblioitem number +biblioitems.biblionumber Biblio number +biblioitems.volume Volume number biblioitems.number Number biblioitems.classification Classification -biblioitems.itemtype Biblio-level Item Type +biblioitems.itemtype Biblio-level item type biblioitems.isbn ISBN biblioitems.issn ISSN -biblioitems.dewey Dewey/Classification -biblioitems.subclass Sub Classification -biblioitems.publicationyear Publication Date +biblioitems.dewey Dewey/classification +biblioitems.subclass Sub classification +biblioitems.publicationyear Publication date biblioitems.publishercode Publisher -biblioitems.volumedate Volume Date -biblioitems.volumeddesc Volume Information +biblioitems.volumedate Volume date +biblioitems.volumedesc Volume information biblioitems.timestamp Timestamp biblioitems.illus Illustrator -biblioitems.pages Number of Pages +biblioitems.pages Number of pages biblioitems.notes Notes biblioitems.size Size -biblioitems.place Place of Publication +biblioitems.place Place of publication biblioitems.lccn LCCN -biblioitems.marc MARC Blob +biblioitems.marcxml MARC blob biblioitems.url URL diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/tools-menu.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/tools-menu.inc index 8a739d5e36..53360b0750 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/tools-menu.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/tools-menu.inc @@ -23,7 +23,7 @@
  • Import patrons
  • [% END %] [% IF ( CAN_user_tools_edit_notices ) %] -
  • Notices
  • +
  • Notices & Slips
  • [% END %] [% IF ( CAN_user_tools_edit_notice_status_triggers ) %]
  • Overdue notice/status triggers
  • diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/acqui-home.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/acqui-home.tt index b8e81b7f8e..9acc451904 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/acqui-home.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/acqui-home.tt @@ -23,7 +23,7 @@ $(document).ready(function() { - + [% INCLUDE 'header.inc' %] [% INCLUDE 'acquisitions-search.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/addorderiso2709.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/addorderiso2709.tt index 9b85af3cef..80f88f9925 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/addorderiso2709.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/addorderiso2709.tt @@ -1,3 +1,4 @@ +[% USE KohaDates %] [% INCLUDE 'doc-head-open.inc' %] Koha › Acquisitions › Order Staged MARC Records [% IF ( batch_details ) %] @@ -21,7 +22,7 @@ //]]> </script> </head> -<body> +<body id="acq_addorderiso2709" class="acq"> [% INCLUDE 'header.inc' %] [% INCLUDE 'acquisitions-search.inc' %] <div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> › <a href="/cgi-bin/koha/acqui/acqui-home.pl">Acquisitions</a> › <a href="/cgi-bin/koha/acqui/supplier.pl?booksellerid=[% booksellerid %]">[% booksellername %]</a> › <a href="/cgi-bin/koha/acqui/basket.pl?basketno=[% basketno %]">Basket [% basketno %]</a> › Add orders from iso2709 file</div> @@ -90,7 +91,7 @@ <td>[% batch_lis.file_name %]</td> <td>[% batch_lis.comments %]</td> <td>[% batch_lis.import_status %]</td> - <td>[% batch_lis.upload_timestamp %]</td> + <td>[% batch_lis.staged_date | $KohaDates %] [% batch_lis.staged_hour %]</td> <td>[% batch_lis.num_biblios %]</td> <td><a href="[% batch_lis.scriptname %]?import_batch_id=[% batch_lis.import_batch_id %]&basketno=[% basketno %]&booksellerid=[% booksellerid %]">Add orders</a></td> </tr> diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basket.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basket.tt index cc64caeecc..401e484252 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basket.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basket.tt @@ -72,7 +72,7 @@ .sortmsg {font-size: 80%;} </style> </head> -<body> +<body id="acq_basket" class="acq"> [% INCLUDE 'header.inc' %] [% INCLUDE 'acquisitions-search.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basketgroup.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basketgroup.tt index c651e0060a..f19b29969b 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basketgroup.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basketgroup.tt @@ -133,7 +133,7 @@ function yuiToolbar() { //]]> </script> </head> -<body> +<body id="acq_basketgroup" class="acq"> [% INCLUDE 'header.inc' %] [% INCLUDE 'acquisitions-search.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basketheader.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basketheader.tt index 160c5f6d00..1ac8d969f8 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basketheader.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basketheader.tt @@ -13,8 +13,8 @@ // to check if the data are correctly entered. function Check(ff) { var ok=0; - var _alertString="Form not submitted because of the following problem(s)\n"; - _alertString +="-------------------------------------------------------------------\n\n"; + var _alertString="Form not submitted because of the following problem(s)"; + _alertString +="\n-------------------------------------------------------------------\n\n"; if (!(isNotNull(ff.basketname,0))){ ok=1; _alertString += "- name missing\n"; @@ -84,7 +84,7 @@ li.list2 { </style> </head> -<body> +<body id="acq_basketheader" class="acq"> [% INCLUDE 'header.inc' %] [% INCLUDE 'acquisitions-search.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/booksellers.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/booksellers.tt index 0e6aaa34bf..798c2e7a94 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/booksellers.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/booksellers.tt @@ -1,3 +1,4 @@ +[% USE KohaDates %] [% INCLUDE 'doc-head-open.inc' %] <title>Koha › Search for vendor [% supplier %] [% INCLUDE 'doc-head-close.inc' %] @@ -33,7 +34,7 @@ $(document).ready(function() { - + [% INCLUDE 'header.inc' %] [% INCLUDE 'acquisitions-search.inc' %] @@ -110,10 +111,10 @@ $(document).ready(function() { [% basket.authorisedby_firstname %] [% basket.authorisedby_surname %] - [% basket.creationdate %] + [% basket.creationdate | $KohaDates %] [% IF ( basket.closedate ) %] - closed on [% basket.closedate %] + closed on [% basket.closedate | $KohaDates %] View [% ELSE %] [% IF ( basket.active ) %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/histsearch.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/histsearch.tt index fb6982df44..1d6c242983 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/histsearch.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/histsearch.tt @@ -4,7 +4,7 @@ [% INCLUDE 'doc-head-close.inc' %] [% INCLUDE 'calendar.inc' %] - + [% INCLUDE 'header.inc' %] [% INCLUDE 'acquisitions-search.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/lateorders.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/lateorders.tt index cdb871122f..33473f60e6 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/lateorders.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/lateorders.tt @@ -19,7 +19,7 @@ $(document).ready(function() { //]]> - + [% INCLUDE 'header.inc' %] [% INCLUDE 'acquisitions-search.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/neworderbiblio.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/neworderbiblio.tt index c888ccb562..5e1ee9a46f 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/neworderbiblio.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/neworderbiblio.tt @@ -3,7 +3,7 @@ [% INCLUDE 'greybox.inc' %] [% INCLUDE 'doc-head-close.inc' %] - + [% INCLUDE 'header.inc' %] [% INCLUDE 'acquisitions-search.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/neworderempty.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/neworderempty.tt index 9c2d70a675..f7bfb58bab 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/neworderempty.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/neworderempty.tt @@ -148,7 +148,7 @@ $(document).ready(function() //]]> - + [% INCLUDE 'header.inc' %] [% INCLUDE 'acquisitions-search.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/neworderempty_duplicate.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/neworderempty_duplicate.tt index fd990c87e1..78ad410a4f 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/neworderempty_duplicate.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/neworderempty_duplicate.tt @@ -2,7 +2,7 @@ Koha › Acquisitions › Basket [% basketno %] › Duplicate warning [% INCLUDE 'doc-head-close.inc' %] - + [% INCLUDE 'header.inc' %] [% INCLUDE 'acquisitions-search.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/newordersuggestion.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/newordersuggestion.tt index 8629e1d6a3..2843ee2082 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/newordersuggestion.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/newordersuggestion.tt @@ -2,7 +2,7 @@ Koha › Acquisitions › Add order from a suggestion [% INCLUDE 'doc-head-close.inc' %] - + [% INCLUDE 'header.inc' %] [% INCLUDE 'suggestions-add-search.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/ordered.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/ordered.tt index a0cabbc9d9..379d0429d1 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/ordered.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/ordered.tt @@ -3,7 +3,7 @@ Koha › Acquisitions › Ordered [% INCLUDE 'doc-head-close.inc' %] - + [% INCLUDE 'header.inc' %] [% INCLUDE 'acquisitions-search.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/orderreceive.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/orderreceive.tt index 3eb3e2369c..cfd0e3b411 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/orderreceive.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/orderreceive.tt @@ -3,7 +3,7 @@ [% INCLUDE 'doc-head-close.inc' %] - + [% INCLUDE 'header.inc' %] [% INCLUDE 'acquisitions-search.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/parcel.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/parcel.tt index 93a9fbaa2b..4ddfc7d4aa 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/parcel.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/parcel.tt @@ -153,7 +153,7 @@ - + [% INCLUDE 'header.inc' %] [% INCLUDE 'acquisitions-search.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/parcels.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/parcels.tt index fb937f0263..712c47284c 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/parcels.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/parcels.tt @@ -3,7 +3,7 @@ [% INCLUDE 'doc-head-close.inc' %] [% INCLUDE 'calendar.inc' %] - + [% INCLUDE 'header.inc' %] [% INCLUDE 'acquisitions-search.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/spent.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/spent.tt index a944419fbb..622604ba55 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/spent.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/spent.tt @@ -3,7 +3,7 @@ Koha › Acquisitions › Spent [% INCLUDE 'doc-head-close.inc' %] - + [% INCLUDE 'header.inc' %] [% INCLUDE 'acquisitions-search.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/supplier.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/supplier.tt index 05b7fac08c..6ace8daf9b 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/supplier.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/supplier.tt @@ -1,3 +1,4 @@ +[% USE KohaDates %] [% INCLUDE 'doc-head-open.inc' %] Koha › Vendor [% bookselname %] [% INCLUDE 'doc-head-close.inc' %] @@ -18,7 +19,7 @@ if (f.company.value == "") { //]]> - + [% INCLUDE 'header.inc' %] [% INCLUDE 'acquisitions-search.inc' %] @@ -217,8 +218,8 @@ if (f.company.value == "") { [% contract.contractname %] [% contract.contractdescription %] - [% contract.contractstartdate %] - [% contract.contractenddate %] + [% contract.contractstartdate | $KohaDates %] + [% contract.contractenddate | $KohaDates %] Edit Delete diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/uncertainprice.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/uncertainprice.tt index 613153cb9b..5717034cc6 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/uncertainprice.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/uncertainprice.tt @@ -10,7 +10,7 @@ function check(form) { //]]> - + [% INCLUDE 'header.inc' %] [% INCLUDE 'acquisitions-search.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/z3950_search.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/z3950_search.tt index 2449c8e007..176922dfd5 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/z3950_search.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/z3950_search.tt @@ -59,7 +59,7 @@ $.tablesorter.addParser({ tr.selected { background-color : #FFFFCC; } tr.selected td { background-color : transparent !important; } - + [% INCLUDE 'header.inc' %] [% INCLUDE 'acquisitions-search.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/admin-home.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/admin-home.tt index f3f8707c3a..6b339f8a44 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/admin-home.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/admin-home.tt @@ -2,7 +2,7 @@ Koha › Administration [% INCLUDE 'doc-head-close.inc' %] - + [% INCLUDE 'header.inc' %] [% INCLUDE 'cat-search.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/aqbudget_owner_search.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/aqbudget_owner_search.tt index 5fc623d6b7..84da262593 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/aqbudget_owner_search.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/aqbudget_owner_search.tt @@ -20,7 +20,7 @@ function returnOwner(ownerId, ownerName){ - +
    diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/aqbudgetperiods.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/aqbudgetperiods.tt index 29dcf7f799..f3c52d505a 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/aqbudgetperiods.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/aqbudgetperiods.tt @@ -101,7 +101,7 @@ - + [% INCLUDE 'header.inc' %] [% INCLUDE 'budgets-admin-search.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/aqbudgets.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/aqbudgets.tt index 7fa91f77fd..cae23062c8 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/aqbudgets.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/aqbudgets.tt @@ -140,7 +140,7 @@ [% END %] - + [% INCLUDE 'header.inc' %] [% INCLUDE 'budgets-admin-search.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/aqcontract.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/aqcontract.tt index 19861b9eee..9eb908808f 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/aqcontract.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/aqcontract.tt @@ -51,7 +51,7 @@ function Check(ff) { //]]> - + [% INCLUDE 'header.inc' %] [% INCLUDE 'contracts-admin-search.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/aqplan.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/aqplan.tt index 10ca4ce9ce..a836138bf2 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/aqplan.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/aqplan.tt @@ -66,7 +66,7 @@ YAHOO.util.Event.onAvailable("popmenu", function () { - + [% INCLUDE 'header.inc' %] [% INCLUDE 'budgets-admin-search.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/auth_subfields_structure.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/auth_subfields_structure.tt index a8f2b46fb0..e7ea422d68 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/auth_subfields_structure.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/auth_subfields_structure.tt @@ -22,7 +22,7 @@ function displayMoreConstraint(numlayer){ //]]> - + [% INCLUDE 'header.inc' %] [% INCLUDE 'cat-search.inc' %]