From: Paul Poulain Date: Wed, 19 Sep 2012 09:43:04 +0000 (+0200) Subject: Merge remote-tracking branch 'origin/new/bug_8597' X-Git-Url: http://git.rot13.org/?a=commitdiff_plain;h=659a4aab574e77e65d8e0eb604763f832a5c0574;hp=81ba4ca9793501f79d320f3d9e6251c5292ca3d3;p=koha.git Merge remote-tracking branch 'origin/new/bug_8597' --- diff --git a/C4/Acquisition.pm b/C4/Acquisition.pm index 21e7640afe..03a55cca08 100644 --- a/C4/Acquisition.pm +++ b/C4/Acquisition.pm @@ -64,6 +64,14 @@ BEGIN { &GetParcels &GetParcel &GetContracts &GetContract + &GetInvoices + &GetInvoice + &GetInvoiceDetails + &AddInvoice + &ModInvoice + &CloseInvoice + &ReopenInvoice + &GetItemnumbersFromOrder &AddClaim @@ -1245,15 +1253,14 @@ sub GetCancelledOrders { =head3 ModReceiveOrder &ModReceiveOrder($biblionumber, $ordernumber, $quantityreceived, $user, - $unitprice, $booksellerinvoicenumber, $biblioitemnumber, - $freight, $bookfund, $rrp); + $unitprice, $invoiceid, $biblioitemnumber, + $bookfund, $rrp, \@received_itemnumbers); Updates an order, to reflect the fact that it was received, at least in part. All arguments not mentioned below update the fields with the same name in the aqorders table of the Koha database. -If a partial order is received, splits the order into two. The received -portion must have a booksellerinvoicenumber. +If a partial order is received, splits the order into two. Updates the order with bibilionumber C<$biblionumber> and ordernumber C<$ordernumber>. @@ -1264,7 +1271,7 @@ C<$ordernumber>. sub ModReceiveOrder { my ( $biblionumber, $ordernumber, $quantrec, $user, $cost, - $invoiceno, $freight, $rrp, $budget_id, $datereceived, $received_items + $invoiceid, $rrp, $budget_id, $datereceived, $received_items ) = @_; @@ -1305,9 +1312,8 @@ sub ModReceiveOrder { $order->{'quantity'} = $quantrec; $order->{'quantityreceived'} = $quantrec; $order->{'datereceived'} = $datereceived; - $order->{'booksellerinvoicenumber'} = $invoiceno; + $order->{'invoiceid'} = $invoiceid; $order->{'unitprice'} = $cost; - $order->{'freight'} = $freight; $order->{'rrp'} = $rrp; $order->{'orderstatus'} = 3; # totally received $new_ordernumber = NewOrder($order); @@ -1319,10 +1325,10 @@ sub ModReceiveOrder { } } else { $sth=$dbh->prepare("update aqorders - set quantityreceived=?,datereceived=?,booksellerinvoicenumber=?, - unitprice=?,freight=?,rrp=? + set quantityreceived=?,datereceived=?,invoiceid=?, + unitprice=?,rrp=? where biblionumber=? and ordernumber=?"); - $sth->execute($quantrec,$datereceived,$invoiceno,$cost,$freight,$rrp,$biblionumber,$ordernumber); + $sth->execute($quantrec,$datereceived,$invoiceid,$cost,$rrp,$biblionumber,$ordernumber); $sth->finish; } return ($datereceived, $new_ordernumber); @@ -1370,7 +1376,7 @@ sub CancelReceipt { UPDATE aqorders SET quantityreceived = ?, datereceived = ?, - booksellerinvoicenumber = ? + invoiceid = ? WHERE ordernumber = ? }; $sth = $dbh->prepare($query); @@ -1597,9 +1603,10 @@ sub GetParcel { LEFT JOIN aqbasket ON aqbasket.basketno=aqorders.basketno LEFT JOIN borrowers ON aqbasket.authorisedby=borrowers.borrowernumber LEFT JOIN biblio ON aqorders.biblionumber=biblio.biblionumber + LEFT JOIN aqinvoices ON aqorders.invoiceid = aqinvoices.invoiceid WHERE aqbasket.booksellerid = ? - AND aqorders.booksellerinvoicenumber LIKE ? + AND aqinvoices.invoicenumber LIKE ? AND aqorders.datereceived = ? "; my @query_params = ( $supplierid, $code, $datereceived ); @@ -1672,18 +1679,19 @@ sub GetParcels { my $dbh = C4::Context->dbh; my @query_params = (); my $strsth =" - SELECT aqorders.booksellerinvoicenumber, + SELECT aqinvoices.invoicenumber, datereceived,purchaseordernumber, count(DISTINCT biblionumber) AS biblio, sum(quantity) AS itemsexpected, sum(quantityreceived) AS itemsreceived FROM aqorders LEFT JOIN aqbasket ON aqbasket.basketno = aqorders.basketno + LEFT JOIN aqinvoices ON aqorders.invoiceid = aqinvoices.invoiceid WHERE aqbasket.booksellerid = ? and datereceived IS NOT NULL "; push @query_params, $bookseller; if ( defined $code ) { - $strsth .= ' and aqorders.booksellerinvoicenumber like ? '; + $strsth .= ' and aqinvoices.invoicenumber like ? '; # add a % to the end of the code to allow stemming. push @query_params, "$code%"; } @@ -1698,7 +1706,7 @@ sub GetParcels { push @query_params, $dateto; } - $strsth .= "group by aqorders.booksellerinvoicenumber,datereceived "; + $strsth .= "group by aqinvoices.invoicenumber,datereceived "; # can't use a placeholder to place this column name. # but, we could probably be checking to make sure it is a column that will be fetched. @@ -1915,7 +1923,7 @@ sub GetHistory { aqorders.quantityreceived, aqorders.ecost, aqorders.ordernumber, - aqorders.booksellerinvoicenumber as invoicenumber, + aqinvoices.invoicenumber, aqbooksellers.id as id, aqorders.biblionumber FROM aqorders @@ -1923,7 +1931,8 @@ sub GetHistory { LEFT JOIN aqbasketgroups ON aqbasket.basketgroupid=aqbasketgroups.id LEFT JOIN aqbooksellers ON aqbasket.booksellerid=aqbooksellers.id LEFT JOIN biblioitems ON biblioitems.biblionumber=aqorders.biblionumber - LEFT JOIN biblio ON biblio.biblionumber=aqorders.biblionumber"; + LEFT JOIN biblio ON biblio.biblionumber=aqorders.biblionumber + LEFT JOIN aqinvoices ON aqorders.invoiceid = aqinvoices.invoiceid"; $query .= " LEFT JOIN borrowers ON aqbasket.authorisedby=borrowers.borrowernumber" if ( C4::Context->preference("IndependantBranches") ); @@ -1977,8 +1986,8 @@ sub GetHistory { } if ($booksellerinvoicenumber) { - $query .= " AND (aqorders.booksellerinvoicenumber LIKE ? OR aqbasket.booksellerinvoicenumber LIKE ?)"; - push @query_params, "%$booksellerinvoicenumber%", "%$booksellerinvoicenumber%"; + $query .= " AND aqinvoices.invoicenumber LIKE ? "; + push @query_params, "%$booksellerinvoicenumber%"; } if ($basketgroupname) { @@ -2124,7 +2133,345 @@ sub AddClaim { "; my $sth = $dbh->prepare($query); $sth->execute($ordernumber); +} + +=head3 GetInvoices + + my @invoices = GetInvoices( + invoicenumber => $invoicenumber, + suppliername => $suppliername, + shipmentdatefrom => $shipmentdatefrom, # ISO format + shipmentdateto => $shipmentdateto, # ISO format + billingdatefrom => $billingdatefrom, # ISO format + billingdateto => $billingdateto, # ISO format + isbneanissn => $isbn_or_ean_or_issn, + title => $title, + author => $author, + publisher => $publisher, + publicationyear => $publicationyear, + branchcode => $branchcode, + order_by => $order_by + ); + +Return a list of invoices that match all given criteria. + +$order_by is "column_name (asc|desc)", where column_name is any of +'invoicenumber', 'booksellerid', 'shipmentdate', 'billingdate', 'closedate', +'shipmentcost', 'shipmentcost_budgetid'. + +asc is the default if omitted + +=cut + +sub GetInvoices { + my %args = @_; + + my @columns = qw(invoicenumber booksellerid shipmentdate billingdate + closedate shipmentcost shipmentcost_budgetid); + + my $dbh = C4::Context->dbh; + my $query = qq{ + SELECT aqinvoices.*, aqbooksellers.name AS suppliername, + COUNT( + DISTINCT IF( + aqorders.datereceived IS NOT NULL, + aqorders.biblionumber, + NULL + ) + ) AS receivedbiblios, + SUM(aqorders.quantityreceived) AS receiveditems + FROM aqinvoices + LEFT JOIN aqbooksellers ON aqbooksellers.id = aqinvoices.booksellerid + LEFT JOIN aqorders ON aqorders.invoiceid = aqinvoices.invoiceid + LEFT JOIN biblio ON aqorders.biblionumber = biblio.biblionumber + LEFT JOIN biblioitems ON biblio.biblionumber = biblioitems.biblionumber + LEFT JOIN subscription ON biblio.biblionumber = subscription.biblionumber + }; + + my @bind_args; + my @bind_strs; + if($args{supplierid}) { + push @bind_strs, " aqinvoices.booksellerid = ? "; + push @bind_args, $args{supplierid}; + } + if($args{invoicenumber}) { + push @bind_strs, " aqinvoices.invoicenumber LIKE ? "; + push @bind_args, "%$args{invoicenumber}%"; + } + if($args{suppliername}) { + push @bind_strs, " aqbooksellers.name LIKE ? "; + push @bind_args, "%$args{suppliername}%"; + } + if($args{shipmentdatefrom}) { + push @bind_strs, " aqinvoices.shipementdate >= ? "; + push @bind_args, $args{shipementdatefrom}; + } + if($args{shipmentdateto}) { + push @bind_strs, " aqinvoices.shipementdate <= ? "; + push @bind_args, $args{shipementdateto}; + } + if($args{billingdatefrom}) { + push @bind_strs, " aqinvoices.billingdate >= ? "; + push @bind_args, $args{billingdatefrom}; + } + if($args{billingdateto}) { + push @bind_strs, " aqinvoices.billingdate <= ? "; + push @bind_args, $args{billingdateto}; + } + if($args{isbneanissn}) { + push @bind_strs, " (biblioitems.isbn LIKE ? OR biblioitems.ean LIKE ? OR biblioitems.issn LIKE ? ) "; + push @bind_args, $args{isbneanissn}, $args{isbneanissn}, $args{isbneanissn}; + } + if($args{title}) { + push @bind_strs, " biblio.title LIKE ? "; + push @bind_args, $args{title}; + } + if($args{author}) { + push @bind_strs, " biblio.author LIKE ? "; + push @bind_args, $args{author}; + } + if($args{publisher}) { + push @bind_strs, " biblioitems.publishercode LIKE ? "; + push @bind_args, $args{publisher}; + } + if($args{publicationyear}) { + push @bind_strs, " biblioitems.publicationyear = ? "; + push @bind_args, $args{publicationyear}; + } + if($args{branchcode}) { + push @bind_strs, " aqorders.branchcode = ? "; + push @bind_args, $args{branchcode}; + } + + $query .= " WHERE " . join(" AND ", @bind_strs) if @bind_strs; + $query .= " GROUP BY aqinvoices.invoiceid "; + + if($args{order_by}) { + my ($column, $direction) = split / /, $args{order_by}; + if(grep /^$column$/, @columns) { + $direction ||= 'ASC'; + $query .= " ORDER BY $column $direction"; + } + } + my $sth = $dbh->prepare($query); + $sth->execute(@bind_args); + + my $results = $sth->fetchall_arrayref({}); + return @$results; +} + +=head3 GetInvoice + + my $invoice = GetInvoice($invoiceid); + +Get informations about invoice with given $invoiceid + +Return a hash filled with aqinvoices.* fields + +=cut + +sub GetInvoice { + my ($invoiceid) = @_; + my $invoice; + + return unless $invoiceid; + + my $dbh = C4::Context->dbh; + my $query = qq{ + SELECT * + FROM aqinvoices + WHERE invoiceid = ? + }; + my $sth = $dbh->prepare($query); + $sth->execute($invoiceid); + + $invoice = $sth->fetchrow_hashref; + return $invoice; +} + +=head3 GetInvoiceDetails + + my $invoice = GetInvoiceDetails($invoiceid) + +Return informations about an invoice + the list of related order lines + +Orders informations are in $invoice->{orders} (array ref) + +=cut + +sub GetInvoiceDetails { + my ($invoiceid) = @_; + my $invoice; + + return unless $invoiceid; + + my $dbh = C4::Context->dbh; + my $query = qq{ + SELECT aqinvoices.*, aqbooksellers.name AS suppliername + FROM aqinvoices + LEFT JOIN aqbooksellers ON aqinvoices.booksellerid = aqbooksellers.id + WHERE invoiceid = ? + }; + my $sth = $dbh->prepare($query); + $sth->execute($invoiceid); + + $invoice = $sth->fetchrow_hashref; + + $query = qq{ + SELECT aqorders.*, biblio.* + FROM aqorders + LEFT JOIN biblio ON aqorders.biblionumber = biblio.biblionumber + WHERE invoiceid = ? + }; + $sth = $dbh->prepare($query); + $sth->execute($invoiceid); + $invoice->{orders} = $sth->fetchall_arrayref({}); + $invoice->{orders} ||= []; # force an empty arrayref if fetchall_arrayref fails + + return $invoice; +} + +=head3 AddInvoice + + my $invoiceid = AddInvoice( + invoicenumber => $invoicenumber, + booksellerid => $booksellerid, + shipmentdate => $shipmentdate, + billingdate => $billingdate, + closedate => $closedate, + shipmentcost => $shipmentcost, + shipmentcost_budgetid => $shipmentcost_budgetid + ); + +Create a new invoice and return its id or undef if it fails. + +=cut + +sub AddInvoice { + my %invoice = @_; + + return unless(%invoice and $invoice{invoicenumber}); + + my @columns = qw(invoicenumber booksellerid shipmentdate billingdate + closedate shipmentcost shipmentcost_budgetid); + + my @set_strs; + my @set_args; + foreach my $key (keys %invoice) { + if(0 < grep(/^$key$/, @columns)) { + push @set_strs, "$key = ?"; + push @set_args, ($invoice{$key} || undef); + } + } + + my $rv; + if(@set_args > 0) { + my $dbh = C4::Context->dbh; + my $query = "INSERT INTO aqinvoices SET "; + $query .= join (",", @set_strs); + my $sth = $dbh->prepare($query); + $rv = $sth->execute(@set_args); + if($rv) { + $rv = $dbh->last_insert_id(undef, undef, 'aqinvoices', undef); + } + } + return $rv; +} + +=head3 ModInvoice + + ModInvoice( + invoiceid => $invoiceid, # Mandatory + invoicenumber => $invoicenumber, + booksellerid => $booksellerid, + shipmentdate => $shipmentdate, + billingdate => $billingdate, + closedate => $closedate, + shipmentcost => $shipmentcost, + shipmentcost_budgetid => $shipmentcost_budgetid + ); + +Modify an invoice, invoiceid is mandatory. + +Return undef if it fails. + +=cut + +sub ModInvoice { + my %invoice = @_; + + return unless(%invoice and $invoice{invoiceid}); + + my @columns = qw(invoicenumber booksellerid shipmentdate billingdate + closedate shipmentcost shipmentcost_budgetid); + + my @set_strs; + my @set_args; + foreach my $key (keys %invoice) { + if(0 < grep(/^$key$/, @columns)) { + push @set_strs, "$key = ?"; + push @set_args, ($invoice{$key} || undef); + } + } + + my $dbh = C4::Context->dbh; + my $query = "UPDATE aqinvoices SET "; + $query .= join(",", @set_strs); + $query .= " WHERE invoiceid = ?"; + + my $sth = $dbh->prepare($query); + $sth->execute(@set_args, $invoice{invoiceid}); +} + +=head3 CloseInvoice + + CloseInvoice($invoiceid); + +Close an invoice. + +Equivalent to ModInvoice(invoiceid => $invoiceid, closedate => undef); + +=cut + +sub CloseInvoice { + my ($invoiceid) = @_; + + return unless $invoiceid; + + my $dbh = C4::Context->dbh; + my $query = qq{ + UPDATE aqinvoices + SET closedate = CAST(NOW() AS DATE) + WHERE invoiceid = ? + }; + my $sth = $dbh->prepare($query); + $sth->execute($invoiceid); +} + +=head3 ReopenInvoice + + ReopenInvoice($invoiceid); + +Reopen an invoice + +Equivalent to ModInvoice(invoiceid => $invoiceid, closedate => C4::Dates->new()->output('iso')) + +=cut + +sub ReopenInvoice { + my ($invoiceid) = @_; + + return unless $invoiceid; + + my $dbh = C4::Context->dbh; + my $query = qq{ + UPDATE aqinvoices + SET closedate = NULL + WHERE invoiceid = ? + }; + my $sth = $dbh->prepare($query); + $sth->execute($invoiceid); } 1; diff --git a/C4/Biblio.pm b/C4/Biblio.pm index 533fcb67d4..ab4cc36030 100644 --- a/C4/Biblio.pm +++ b/C4/Biblio.pm @@ -1704,10 +1704,12 @@ sub GetMarcSubjects { # if there is an authority link, build the links with an= subfield9 my $subfield9 = $field->subfield('9'); + my $authoritylink; if ($subfield9) { my $linkvalue = $subfield9; $linkvalue =~ s/(\(|\))//g; @link_loop = ( { limit => 'an', 'link' => $linkvalue } ); + $authoritylink = $linkvalue } # other subfields @@ -1743,7 +1745,10 @@ sub GetMarcSubjects { } } - push @marcsubjects, { MARCSUBJECT_SUBFIELDS_LOOP => \@subfields_loop }; + push @marcsubjects, { + MARCSUBJECT_SUBFIELDS_LOOP => \@subfields_loop, + authoritylink => $authoritylink, + }; } return \@marcsubjects; @@ -1829,7 +1834,10 @@ sub GetMarcAuthors { }; } } - push @marcauthors, { MARCAUTHOR_SUBFIELDS_LOOP => \@subfields_loop }; + push @marcauthors, { + MARCAUTHOR_SUBFIELDS_LOOP => \@subfields_loop, + authoritylink => $subfield9, + }; } return \@marcauthors; } diff --git a/C4/Budgets.pm b/C4/Budgets.pm index e9732ac83a..d07dc75df2 100644 --- a/C4/Budgets.pm +++ b/C4/Budgets.pm @@ -314,9 +314,19 @@ sub GetBudgetSpent { quantityreceived > 0 AND datecancellationprinted IS NULL |); - $sth->execute($budget_id); my $sum = $sth->fetchrow_array; + + $sth = $dbh->prepare(qq| + SELECT SUM(shipmentcost) AS sum + FROM aqinvoices + WHERE shipmentcost_budgetid = ? + AND closedate IS NOT NULL + |); + $sth->execute($budget_id); + my ($shipmentcost_sum) = $sth->fetchrow_array; + $sum += $shipmentcost_sum; + return $sum; } @@ -330,9 +340,19 @@ sub GetBudgetOrdered { quantityreceived = 0 AND datecancellationprinted IS NULL |); - $sth->execute($budget_id); my $sum = $sth->fetchrow_array; + + $sth = $dbh->prepare(qq| + SELECT SUM(shipmentcost) AS sum + FROM aqinvoices + WHERE shipmentcost_budgetid = ? + AND closedate IS NULL + |); + $sth->execute($budget_id); + my ($shipmentcost_sum) = $sth->fetchrow_array; + $sum += $shipmentcost_sum; + return $sum; } diff --git a/C4/Circulation.pm b/C4/Circulation.pm index 499fd518a5..8f60d80a4d 100644 --- a/C4/Circulation.pm +++ b/C4/Circulation.pm @@ -1005,6 +1005,22 @@ sub CanBookBeIssued { } } } + +## check for high holds decreasing loan period + my $decrease_loan = C4::Context->preference('decreaseLoanHighHolds'); + if ( $decrease_loan && $decrease_loan == 1 ) { + my ( $reserved, $num, $duration, $returndate ) = + checkHighHolds( $item, $borrower ); + + if ( $num >= C4::Context->preference('decreaseLoanHighHoldsValue') ) { + $needsconfirmation{HIGHHOLDS} = { + num_holds => $num, + duration => $duration, + returndate => output_pref($returndate), + }; + } + } + return ( \%issuingimpossible, \%needsconfirmation, \%alerts ); } @@ -1030,6 +1046,8 @@ Returns: =item C<$message> is the branchcode where the item SHOULD be returned, if the return is not allowed +=back + =cut sub CanBookBeReturned { @@ -1055,6 +1073,50 @@ sub CanBookBeReturned { return ($allowed, $message); } +=head2 CheckHighHolds + + used when syspref decreaseLoanHighHolds is active. Returns 1 or 0 to define whether the minimum value held in + decreaseLoanHighHoldsValue is exceeded, the total number of outstanding holds, the number of days the loan + has been decreased to (held in syspref decreaseLoanHighHoldsValue), and the new due date + +=cut + +sub checkHighHolds { + my ( $item, $borrower ) = @_; + my $biblio = GetBiblioFromItemNumber( $item->{itemnumber} ); + my $branch = _GetCircControlBranch( $item, $borrower ); + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare( +'select count(borrowernumber) as num_holds from reserves where biblionumber=?' + ); + $sth->execute( $item->{'biblionumber'} ); + my ($holds) = $sth->fetchrow_array; + if ($holds) { + my $issuedate = DateTime->now( time_zone => C4::Context->tz() ); + + my $calendar = Koha::Calendar->new( branchcode => $branch ); + + my $itype = + ( C4::Context->preference('item-level_itypes') ) + ? $biblio->{'itype'} + : $biblio->{'itemtype'}; + my $orig_due = + C4::Circulation::CalcDateDue( $issuedate, $itype, $branch, + $borrower ); + + my $reduced_datedue = + $calendar->addDate( $issuedate, + C4::Context->preference('decreaseLoanHighHoldsDuration') ); + + if ( DateTime->compare( $reduced_datedue, $orig_due ) == -1 ) { + return ( 1, $holds, + C4::Context->preference('decreaseLoanHighHoldsDuration'), + $reduced_datedue ); + } + } + return ( 0, 0, 0, undef ); +} + =head2 AddIssue &AddIssue($borrower, $barcode, [$datedue], [$cancelreserve], [$issuedate]) diff --git a/C4/Reports/Guided.pm b/C4/Reports/Guided.pm index e5c28f3d6e..377a55aae1 100644 --- a/C4/Reports/Guided.pm +++ b/C4/Reports/Guided.pm @@ -26,7 +26,8 @@ use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); use C4::Context; use C4::Dates qw/format_date format_date_in_iso/; use C4::Templates qw/themelanguage/; -use C4::Dates; +use C4::Koha; +use C4::Output; use XML::Simple; use XML::Dumper; use C4::Debug; @@ -34,75 +35,82 @@ use C4::Debug; # use Data::Dumper; BEGIN { - # set the version for version checking + # set the version for version checking $VERSION = 3.07.00.049; - require Exporter; - @ISA = qw(Exporter); - @EXPORT = qw( - get_report_types get_report_areas get_columns build_query get_criteria - save_report get_saved_reports execute_query get_saved_report create_compound run_compound - get_column_type get_distinct_values save_dictionary get_from_dictionary - delete_definition delete_report format_results get_sql - nb_rows update_sql - ); + require Exporter; + @ISA = qw(Exporter); + @EXPORT = qw( + get_report_types get_report_areas get_report_groups get_columns build_query get_criteria + save_report get_saved_reports execute_query get_saved_report create_compound run_compound + get_column_type get_distinct_values save_dictionary get_from_dictionary + delete_definition delete_report format_results get_sql + nb_rows update_sql build_authorised_value_list + ); } -our %table_areas; -$table_areas{'1'} = - [ 'borrowers', 'statistics','items', 'biblioitems' ]; # circulation -$table_areas{'2'} = [ 'items', 'biblioitems', 'biblio' ]; # catalogue -$table_areas{'3'} = [ 'borrowers' ]; # patrons -$table_areas{'4'} = ['aqorders', 'biblio', 'items']; # acquisitions -$table_areas{'5'} = [ 'borrowers', 'accountlines' ]; # accounts -our %keys; -$keys{'1'} = [ - 'statistics.borrowernumber=borrowers.borrowernumber', - 'items.itemnumber = statistics.itemnumber', - 'biblioitems.biblioitemnumber = items.biblioitemnumber' -]; -$keys{'2'} = [ - 'items.biblioitemnumber=biblioitems.biblioitemnumber', - 'biblioitems.biblionumber=biblio.biblionumber' -]; -$keys{'3'} = [ ]; -$keys{'4'} = [ - 'aqorders.biblionumber=biblio.biblionumber', - 'biblio.biblionumber=items.biblionumber' -]; -$keys{'5'} = ['borrowers.borrowernumber=accountlines.borrowernumber']; +=item get_report_areas() -# have to do someting here to know if its dropdown, free text, date etc +This will return a list of all the available report areas -our %criteria; -# reports on circulation -$criteria{'1'} = [ - 'statistics.type', 'borrowers.categorycode', - 'statistics.branch', - 'biblioitems.publicationyear|date', - 'items.dateaccessioned|date' -]; -# reports on catalogue -$criteria{'2'} = - [ 'items.itemnumber|textrange', 'items.biblionumber|textrange', 'items.barcode|textrange', - 'biblio.frameworkcode', 'items.holdingbranch', 'items.homebranch', - 'biblio.datecreated|daterange', 'biblio.timestamp|daterange', 'items.onloan|daterange', - 'items.ccode', 'items.itemcallnumber|textrange', 'items.itype', - 'items.itemlost', 'items.location' ]; -# reports on borrowers -$criteria{'3'} = ['borrowers.branchcode', 'borrowers.categorycode']; -# reports on acquisition -$criteria{'4'} = ['aqorders.datereceived|date']; - -# reports on accounting -$criteria{'5'} = ['borrowers.branchcode', 'borrowers.categorycode']; +=cut + +my @REPORT_AREA = ( + [CIRC => "Circulation"], + [CAT => "Catalogue"], + [PAT => "Patrons"], + [ACQ => "Acquisition"], + [ACC => "Accounts"], +); +my $AREA_NAME_SQL_SNIPPET + = "CASE report_area " . + join (" ", map "WHEN '$_->[0]' THEN '$_->[1]'", @REPORT_AREA) . + " END AS areaname"; +sub get_report_areas { + return \@REPORT_AREA +} + +my %table_areas = ( + CIRC => [ 'borrowers', 'statistics', 'items', 'biblioitems' ], + CAT => [ 'items', 'biblioitems', 'biblio' ], + PAT => ['borrowers'], + ACQ => [ 'aqorders', 'biblio', 'items' ], + ACC => [ 'borrowers', 'accountlines' ], +); +my %keys = ( + CIRC => [ 'statistics.borrowernumber=borrowers.borrowernumber', + 'items.itemnumber = statistics.itemnumber', + 'biblioitems.biblioitemnumber = items.biblioitemnumber' ], + CAT => [ 'items.biblioitemnumber=biblioitems.biblioitemnumber', + 'biblioitems.biblionumber=biblio.biblionumber' ], + PAT => [], + ACQ => [ 'aqorders.biblionumber=biblio.biblionumber', + 'biblio.biblionumber=items.biblionumber' ], + ACC => ['borrowers.borrowernumber=accountlines.borrowernumber'], +); + +# have to do someting here to know if its dropdown, free text, date etc +my %criteria = ( + CIRC => [ 'statistics.type', 'borrowers.categorycode', 'statistics.branch', + 'biblioitems.publicationyear|date', 'items.dateaccessioned|date' ], + CAT => [ 'items.itemnumber|textrange', 'items.biblionumber|textrange', + 'items.barcode|textrange', 'biblio.frameworkcode', + 'items.holdingbranch', 'items.homebranch', + 'biblio.datecreated|daterange', 'biblio.timestamp|daterange', + 'items.onloan|daterange', 'items.ccode', + 'items.itemcallnumber|textrange', 'items.itype', 'items.itemlost', + 'items.location' ], + PAT => [ 'borrowers.branchcode', 'borrowers.categorycode' ], + ACQ => ['aqorders.datereceived|date'], + ACC => [ 'borrowers.branchcode', 'borrowers.categorycode' ], +); # Adds itemtypes to criteria, according to the syspref -if (C4::Context->preference('item-level_itypes')) { - unshift @{ $criteria{'1'} }, 'items.itype'; - unshift @{ $criteria{'2'} }, 'items.itype'; +if ( C4::Context->preference('item-level_itypes') ) { + unshift @{ $criteria{'CIRC'} }, 'items.itype'; + unshift @{ $criteria{'CAT'} }, 'items.itype'; } else { - unshift @{ $criteria{'1'} }, 'biblioitems.itemtype'; - unshift @{ $criteria{'2'} }, 'biblioitems.itemtype'; + unshift @{ $criteria{'CIRC'} }, 'biblioitems.itemtype'; + unshift @{ $criteria{'CAT'} }, 'biblioitems.itemtype'; } =head1 NAME @@ -145,26 +153,33 @@ sub get_report_types { } -=item get_report_areas() +=item get_report_groups() -This will return a list of all the available report areas +This will return a list of all the available report areas with groups =cut -sub get_report_areas { +sub get_report_groups { my $dbh = C4::Context->dbh(); - # FIXME these should be in the database - my @reports = ( 'Circulation', 'Catalog', 'Patrons', 'Acquisitions', 'Accounts'); - my @reports2; - for ( my $i = 0 ; $i < 5 ; $i++ ) { - my %hashrep; - $hashrep{id} = $i + 1; - $hashrep{name} = $reports[$i]; - push @reports2, \%hashrep; + my $groups = GetAuthorisedValues('REPORT_GROUP'); + my $subgroups = GetAuthorisedValues('REPORT_SUBGROUP'); + + my %groups_with_subgroups = map { $_->{authorised_value} => { + name => $_->{lib}, + groups => {} + } } @$groups; + foreach (@$subgroups) { + my $sg = $_->{authorised_value}; + my $g = $_->{lib_opac} + or warn( qq{REPORT_SUBGROUP "$sg" without REPORT_GROUP (lib_opac)} ), + next; + my $g_sg = $groups_with_subgroups{$g} + or warn( qq{REPORT_SUBGROUP "$sg" with invalid REPORT_GROUP "$g"} ), + next; + $g_sg->{subgroups}{$sg} = $_->{lib}; } - return ( \@reports2 ); - + return \%groups_with_subgroups } =item get_all_tables() @@ -196,8 +211,10 @@ This will return a list of all columns for a report area sub get_columns { # this calls the internal fucntion _get_columns - my ($area,$cgi) = @_; - my $tables = $table_areas{$area}; + my ( $area, $cgi ) = @_; + my $tables = $table_areas{$area} + or die qq{Unsuported report area "$area"}; + my @allcolumns; my $first = 1; foreach my $table (@$tables) { @@ -383,7 +400,7 @@ sub nb_rows($) { =item execute_query - ($results, $total, $error) = execute_query($sql, $offset, $limit) + ($results, $error) = execute_query($sql, $offset, $limit) When passed C<$sql>, this function returns an array ref containing a result set @@ -505,37 +522,47 @@ Returns id of the newly created report =cut sub save_report { - my ( $borrowernumber, $sql, $name, $type, $notes, $cache_expiry, $public ) = @_; - $cache_expiry ||= 300; + my ($fields) = @_; + my $borrowernumber = $fields->{borrowernumber}; + my $sql = $fields->{sql}; + my $name = $fields->{name}; + my $type = $fields->{type}; + my $notes = $fields->{notes}; + my $area = $fields->{area}; + my $group = $fields->{group}; + my $subgroup = $fields->{subgroup}; + my $cache_expiry = $fields->{cache_expiry} || 300; + my $public = $fields->{public}; + my $dbh = C4::Context->dbh(); - $sql =~ s/(\s*\;\s*)$//; # removes trailing whitespace and /;/ - my $query = -"INSERT INTO saved_sql (borrowernumber,date_created,last_modified,savedsql,report_name,type,notes,cache_expiry, public) VALUES (?,now(),now(),?,?,?,?,?,?)"; - $dbh->do( $query, undef, $borrowernumber, $sql, $name, $type, $notes, $cache_expiry, $public ); + $sql =~ s/(\s*\;\s*)$//; # removes trailing whitespace and /;/ + my $query = "INSERT INTO saved_sql (borrowernumber,date_created,last_modified,savedsql,report_name,report_area,report_group,report_subgroup,type,notes,cache_expiry,public) VALUES (?,now(),now(),?,?,?,?,?,?,?,?,?)"; + $dbh->do($query, undef, $borrowernumber, $sql, $name, $area, $group, $subgroup, $type, $notes, $cache_expiry, $public); + my $id = $dbh->selectrow_array("SELECT max(id) FROM saved_sql WHERE borrowernumber=? AND report_name=?", undef, $borrowernumber, $name); return $id; } sub update_sql { - my $id = shift || croak "No Id given"; - my $sql = shift; - my $reportname = shift; - my $notes = shift; - my $cache_expiry = shift; - my $public = shift; - - # not entirely a magic number, Cache::Memcached::Set assumed any expiry >= (60*60*24*30) is an absolute unix timestamp (rather than relative seconds) + my $id = shift || croak "No Id given"; + my $fields = shift; + my $sql = $fields->{sql}; + my $name = $fields->{name}; + my $notes = $fields->{notes}; + my $group = $fields->{group}; + my $subgroup = $fields->{subgroup}; + my $cache_expiry = $fields->{cache_expiry}; + my $public = $fields->{public}; + if( $cache_expiry >= 2592000 ){ die "Please specify a cache expiry less than 30 days\n"; } - my $dbh = C4::Context->dbh(); - $sql =~ s/(\s*\;\s*)$//; # removes trailing whitespace and /;/ - my $query = "UPDATE saved_sql SET savedsql = ?, last_modified = now(), report_name = ?, notes = ?, cache_expiry = ?, public = ? WHERE id = ? "; - my $sth = $dbh->prepare($query); - $sth->execute( $sql, $reportname, $notes, $cache_expiry, $public, $id ); - $sth->finish(); + my $dbh = C4::Context->dbh(); + $sql =~ s/(\s*\;\s*)$//; # removes trailing whitespace and /;/ + my $query = "UPDATE saved_sql SET savedsql = ?, last_modified = now(), report_name = ?, report_group = ?, report_subgroup = ?, notes = ?, cache_expiry = ?, public = ? WHERE id = ? "; + $dbh->do($query, undef, $sql, $name, $group, $subgroup, $notes, $cache_expiry, $public, $id ); } sub store_results { @@ -582,30 +609,34 @@ sub format_results { } sub delete_report { - my ( $id ) = @_; - my $dbh = C4::Context->dbh(); - my $query = "DELETE FROM saved_sql WHERE id = ?"; - my $sth = $dbh->prepare($query); - $sth->execute($id); + my ($id) = @_; + my $dbh = C4::Context->dbh(); + my $query = "DELETE FROM saved_sql WHERE id = ?"; + my $sth = $dbh->prepare($query); + $sth->execute($id); } -# $filter is either { date => $d, author => $a, keyword => $kw } -# or $keyword. Optional. + +my $SAVED_REPORTS_BASE_QRY = < $d, author => $a, keyword => $kw, } +# or $keyword. Optional. my ($filter) = @_; $filter = { keyword => $filter } if $filter && !ref( $filter ); + my ($group, $subgroup) = @_; my $dbh = C4::Context->dbh(); + my $query = $SAVED_REPORTS_BASE_QRY; my (@cond,@args); - my $query = "SELECT saved_sql.id, report_id, report, - date_run, date_created, last_modified, savedsql, last_run, - report_name, type, notes, - borrowernumber, surname as borrowersurname, firstname as borrowerfirstname, - cache_expiry, public - FROM saved_sql - LEFT JOIN saved_reports ON saved_reports.report_id = saved_sql.id - LEFT OUTER JOIN borrowers USING (borrowernumber)"; if ($filter) { if (my $date = $filter->{date}) { $date = format_date_in_iso($date); @@ -629,6 +660,14 @@ sub get_saved_reports { savedsql LIKE ?"; push @args, $keyword, $keyword, $keyword, $keyword; } + if ($filter->{group}) { + push @cond, "report_group = ?"; + push @args, $filter->{group}; + } + if ($filter->{subgroup}) { + push @cond, "report_subgroup = ?"; + push @args, $filter->{subgroup}; + } } $query .= " WHERE ".join( " AND ", map "($_)", @cond ) if @cond; $query .= " ORDER by date_created"; @@ -642,7 +681,6 @@ sub get_saved_reports { sub get_saved_report { my $dbh = C4::Context->dbh(); my $query; - my $sth; my $report_arg; if ($#_ == 0 && ref $_[0] ne 'HASH') { ($report_arg) = @_; @@ -661,10 +699,7 @@ sub get_saved_report { } else { return; } - $sth = $dbh->prepare($query); - $sth->execute($report_arg); - my $data = $sth->fetchrow_hashref(); - return ( $data->{'savedsql'}, $data->{'type'}, $data->{'report_name'}, $data->{'notes'}, $data->{'cache_expiry'}, $data->{'public'}, $data->{'id'} ); + return $dbh->selectrow_hashref($query, undef, $report_arg); } =item create_compound($masterID,$subreportID) @@ -674,22 +709,27 @@ This will take 2 reports and create a compound report using both of them =cut sub create_compound { - my ($masterID,$subreportID) = @_; - my $dbh = C4::Context->dbh(); - # get the reports - my ($mastersql,$mastertype) = get_saved_report($masterID); - my ($subsql,$subtype) = get_saved_report($subreportID); - - # now we have to do some checking to see how these two will fit together - # or if they will - my ($mastertables,$subtables); - if ($mastersql =~ / from (.*) where /i){ - $mastertables = $1; - } - if ($subsql =~ / from (.*) where /i){ - $subtables = $1; - } - return ($mastertables,$subtables); + my ( $masterID, $subreportID ) = @_; + my $dbh = C4::Context->dbh(); + + # get the reports + my $master = get_saved_report($masterID); + my $mastersql = $master->{savedsql}; + my $mastertype = $master->{type}; + my $sub = get_saved_report($subreportID); + my $subsql = $master->{savedsql}; + my $subtype = $master->{type}; + + # now we have to do some checking to see how these two will fit together + # or if they will + my ( $mastertables, $subtables ); + if ( $mastersql =~ / from (.*) where /i ) { + $mastertables = $1; + } + if ( $subsql =~ / from (.*) where /i ) { + $subtables = $1; + } + return ( $mastertables, $subtables ); } =item get_column_type($column) @@ -739,43 +779,41 @@ sub get_distinct_values { } sub save_dictionary { - my ($name,$description,$sql,$area) = @_; - my $dbh = C4::Context->dbh(); - my $query = "INSERT INTO reports_dictionary (name,description,saved_sql,area,date_created,date_modified) + my ( $name, $description, $sql, $area ) = @_; + my $dbh = C4::Context->dbh(); + my $query = "INSERT INTO reports_dictionary (name,description,saved_sql,report_area,date_created,date_modified) VALUES (?,?,?,?,now(),now())"; my $sth = $dbh->prepare($query); $sth->execute($name,$description,$sql,$area) || return 0; return 1; } +my $DICTIONARY_BASE_QRY = <dbh(); - my $query = "SELECT * FROM reports_dictionary"; - if ($area){ - $query.= " WHERE area = ?"; - } - elsif ($id){ - $query.= " WHERE id = ?" - } - my $sth = $dbh->prepare($query); - if ($id){ - $sth->execute($id); - } - elsif ($area) { - $sth->execute($area); - } - else { - $sth->execute(); - } - my @loop; - my @reports = ( 'Circulation', 'Catalog', 'Patrons', 'Acquisitions', 'Accounts'); - while (my $data = $sth->fetchrow_hashref()){ - $data->{'areaname'}=$reports[$data->{'area'}-1]; - push @loop,$data; - - } - return (\@loop); + my ( $area, $id ) = @_; + my $dbh = C4::Context->dbh(); + my $query = $DICTIONARY_BASE_QRY; + if ($area) { + $query .= " WHERE report_area = ?"; + } elsif ($id) { + $query .= " WHERE id = ?"; + } + my $sth = $dbh->prepare($query); + if ($id) { + $sth->execute($id); + } elsif ($area) { + $sth->execute($area); + } else { + $sth->execute(); + } + my @loop; + while ( my $data = $sth->fetchrow_hashref() ) { + push @loop, $data; + } + return ( \@loop ); } sub delete_definition { @@ -815,6 +853,72 @@ sub _get_column_defs { close COLUMNS; return \%columns; } + +=item build_authorised_value_list($authorised_value) + +Returns an arrayref - hashref pair. The hashref consists of +various code => name lists depending on the $authorised_value. +The arrayref is the hashref keys, in appropriate order + +=cut + +sub build_authorised_value_list { + my ( $authorised_value ) = @_; + + my $dbh = C4::Context->dbh; + my @authorised_values; + my %authorised_lib; + + # builds list, depending on authorised value... + if ( $authorised_value eq "branches" ) { + my $branches = GetBranchesLoop(); + foreach my $thisbranch (@$branches) { + push @authorised_values, $thisbranch->{value}; + $authorised_lib{ $thisbranch->{value} } = $thisbranch->{branchname}; + } + } elsif ( $authorised_value eq "itemtypes" ) { + my $sth = $dbh->prepare("SELECT itemtype,description FROM itemtypes ORDER BY description"); + $sth->execute; + while ( my ( $itemtype, $description ) = $sth->fetchrow_array ) { + push @authorised_values, $itemtype; + $authorised_lib{$itemtype} = $description; + } + } elsif ( $authorised_value eq "cn_source" ) { + my $class_sources = GetClassSources(); + my $default_source = C4::Context->preference("DefaultClassificationSource"); + foreach my $class_source ( sort keys %$class_sources ) { + next + unless $class_sources->{$class_source}->{'used'} + or ( $class_source eq $default_source ); + push @authorised_values, $class_source; + $authorised_lib{$class_source} = $class_sources->{$class_source}->{'description'}; + } + } elsif ( $authorised_value eq "categorycode" ) { + my $sth = $dbh->prepare("SELECT categorycode, description FROM categories ORDER BY description"); + $sth->execute; + while ( my ( $categorycode, $description ) = $sth->fetchrow_array ) { + push @authorised_values, $categorycode; + $authorised_lib{$categorycode} = $description; + } + + #---- "true" authorised value + } else { + my $authorised_values_sth = $dbh->prepare("SELECT authorised_value,lib FROM authorised_values WHERE category=? ORDER BY lib"); + + $authorised_values_sth->execute($authorised_value); + + while ( my ( $value, $lib ) = $authorised_values_sth->fetchrow_array ) { + push @authorised_values, $value; + $authorised_lib{$value} = $lib; + + # For item location, we show the code and the libelle + $authorised_lib{$value} = $lib; + } + } + + return (\@authorised_values, \%authorised_lib); +} + 1; __END__ diff --git a/C4/SIP/ILS/Transaction/Checkout.pm b/C4/SIP/ILS/Transaction/Checkout.pm index 38951fcf70..da7a1b0957 100644 --- a/C4/SIP/ILS/Transaction/Checkout.pm +++ b/C4/SIP/ILS/Transaction/Checkout.pm @@ -54,6 +54,7 @@ sub do_checkout { my $shelf = $self->{item}->hold_shelf; my $barcode = $self->{item}->id; my $patron_barcode = $self->{patron}->id; + my $overridden_duedate; # usually passed as undef to AddIssue $debug and warn "do_checkout: patron (" . $patron_barcode . ")"; my $borrower = $self->{patron}->getmemberdetails_object(); $debug and warn "do_checkout borrower: . " . Dumper $borrower; @@ -72,7 +73,7 @@ sub do_checkout { $noerror = 0; } } else { - foreach my $confirmation (keys %$needsconfirmation) { + foreach my $confirmation (keys %{$needsconfirmation}) { if ($confirmation eq 'RENEW_ISSUE'){ $self->screen_msg("Item already checked out to you: renewing item."); } elsif ($confirmation eq 'RESERVED' or $confirmation eq 'RESERVE_WAITING') { @@ -87,6 +88,9 @@ sub do_checkout { $self->screen_msg("Item already checked out to another patron. Please return item for check-in."); $noerror = 0; } elsif ($confirmation eq 'DEBT') { # don't do anything, it's the minor debt, and alarms fire elsewhere + } elsif ($confirmation eq 'HIGHHOLDS') { + $overridden_duedate = $needsconfirmation->{$confirmation}->{returndate}; + $self->screen_msg('Loan period reduced for high-demand item'); } else { $self->screen_msg($needsconfirmation->{$confirmation}); $noerror = 0; @@ -118,10 +122,10 @@ sub do_checkout { # TODO: adjust representation in $self->item } # can issue - $debug and warn "do_checkout: calling AddIssue(\$borrower,$barcode, undef, 0)\n" + $debug and warn "do_checkout: calling AddIssue(\$borrower,$barcode, $overridden_duedate, 0)\n" # . "w/ \$borrower: " . Dumper($borrower) . "w/ C4::Context->userenv: " . Dumper(C4::Context->userenv); - my $due_dt = AddIssue($borrower, $barcode, undef, 0); + my $due_dt = AddIssue($borrower, $barcode, $overridden_duedate, 0); if ($due_dt) { $self->{due} = $due_dt->clone(); } else { diff --git a/C4/Search.pm b/C4/Search.pm index b36c5f85c2..2b78f7594d 100644 --- a/C4/Search.pm +++ b/C4/Search.pm @@ -34,6 +34,8 @@ use C4::Charset; use YAML; use URI::Escape; use Business::ISBN; +use MARC::Record; +use MARC::Field; use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $DEBUG); @@ -1029,6 +1031,104 @@ sub getIndexes{ return \@indexes; } +=head2 _handle_exploding_index + + my $query = _handle_exploding_index($index, $term) + +Callback routine to generate the search for "exploding" indexes (i.e. +those indexes which are turned into multiple or-connected searches based +on authority data). + +=cut + +sub _handle_exploding_index { + my ( $index, $term ) = @_; + + return unless ($index =~ m/(su-br|su-na|su-rl)/ && $term); + + my $marcflavour = C4::Context->preference('marcflavour'); + + my $codesubfield = $marcflavour eq 'UNIMARC' ? '5' : 'w'; + my $wantedcodes = ''; + my @subqueries = ( "(su=\"$term\")"); + my ($error, $results, $total_hits) = SimpleSearch( "Heading,wrdl=$term", undef, undef, [ "authorityserver" ] ); + foreach my $auth (@$results) { + my $record = MARC::Record->new_from_usmarc($auth); + my @references = $record->field('5..'); + if (@references) { + if ($index eq 'su-br') { + $wantedcodes = 'g'; + } elsif ($index eq 'su-na') { + $wantedcodes = 'h'; + } elsif ($index eq 'su-rl') { + $wantedcodes = ''; + } + foreach my $reference (@references) { + my $codes = $reference->subfield($codesubfield); + push @subqueries, '(su="' . $reference->as_string('abcdefghijlmnopqrstuvxyz') . '")' if (($codes && $codes eq $wantedcodes) || !$wantedcodes); + } + } + } + return join(' or ', @subqueries); +} + +=head2 parseQuery + + ( $operators, $operands, $indexes, $limits, + $sort_by, $scan, $lang ) = + buildQuery ( $operators, $operands, $indexes, $limits, $sort_by, $scan, $lang); + +Shim function to ease the transition from buildQuery to a new QueryParser. +This function is called at the beginning of buildQuery, and modifies +buildQuery's input. If it can handle the input, it returns a query that +buildQuery will not try to parse. +=cut + +sub parseQuery { + my ( $operators, $operands, $indexes, $limits, $sort_by, $scan, $lang) = @_; + + my @operators = $operators ? @$operators : (); + my @indexes = $indexes ? @$indexes : (); + my @operands = $operands ? @$operands : (); + my @limits = $limits ? @$limits : (); + my @sort_by = $sort_by ? @$sort_by : (); + + my $query = $operands[0]; + my $index; + my $term; + +# TODO: once we are using QueryParser, all this special case code for +# exploded search indexes will be replaced by a callback to +# _handle_exploding_index + if ( $query =~ m/^(.*)\b(su-br|su-na|su-rl)[:=](\w.*)$/ ) { + $query = $1; + $index = $2; + $term = $3; + } else { + $query = ''; + for ( my $i = 0 ; $i <= @operands ; $i++ ) { + if ($operands[$i] && $indexes[$i] =~ m/(su-br|su-na|su-rl)/) { + $index = $indexes[$i]; + $term = $operands[$i]; + } elsif ($operands[$i]) { + $query .= $operators[$i] eq 'or' ? ' or ' : ' and ' if ($query); + $query .= "($indexes[$i]:$operands[$i])"; + } + } + } + + if ($index) { + my $queryPart = _handle_exploding_index($index, $term); + if ($queryPart) { + $query .= "($queryPart)"; + } + $operators = (); + $operands[0] = "ccl=$query"; + } + + return ( $operators, \@operands, $indexes, $limits, $sort_by, $scan, $lang); +} + =head2 buildQuery ( $error, $query, @@ -1050,6 +1150,8 @@ sub buildQuery { warn "---------\nEnter buildQuery\n---------" if $DEBUG; + ( $operators, $operands, $indexes, $limits, $sort_by, $scan, $lang) = parseQuery($operators, $operands, $indexes, $limits, $sort_by, $scan, $lang); + # dereference my @operators = $operators ? @$operators : (); my @indexes = $indexes ? @$indexes : (); diff --git a/C4/Serials.pm b/C4/Serials.pm index e31d5dfb82..eb620cc719 100644 --- a/C4/Serials.pm +++ b/C4/Serials.pm @@ -36,6 +36,7 @@ BEGIN { @EXPORT = qw( &NewSubscription &ModSubscription &DelSubscription &GetSubscriptions &GetSubscription &CountSubscriptionFromBiblionumber &GetSubscriptionsFromBiblionumber + &SearchSubscriptions &GetFullSubscriptionsFromBiblionumber &GetFullSubscription &ModSubscriptionHistory &HasSubscriptionStrictlyExpired &HasSubscriptionExpired &GetExpirationDate &abouttoexpire @@ -631,6 +632,74 @@ sub GetSubscriptions { return @results; } +=head2 SearchSubscriptions + +@results = SearchSubscriptions($args); +$args is a hashref. Its keys can be contained: title, issn, ean, publisher, bookseller and branchcode + +this function gets all subscriptions which have title like $title, ISSN like $issn, EAN like $ean, publisher like $publisher, bookseller like $bookseller AND branchcode eq $branch. + +return: +a table of hashref. Each hash containt the subscription. + +=cut + +sub SearchSubscriptions { + my ( $args ) = @_; + + my $query = qq{ + SELECT subscription.*, subscriptionhistory.*, biblio.*, biblioitems.issn + FROM subscription + LEFT JOIN subscriptionhistory USING(subscriptionid) + LEFT JOIN biblio ON biblio.biblionumber = subscription.biblionumber + LEFT JOIN biblioitems ON biblioitems.biblionumber = subscription.biblionumber + LEFT JOIN aqbooksellers ON subscription.aqbooksellerid = aqbooksellers.id + }; + my @where_strs; + my @where_args; + if( $args->{biblionumber} ) { + push @where_strs, "biblio.biblionumber = ?"; + push @where_args, $args->{biblionumber}; + } + if( $args->{title} ){ + push @where_strs, "biblio.title LIKE ?"; + push @where_args, "%$args->{title}%"; + } + if( $args->{issn} ){ + push @where_strs, "biblioitems.issn LIKE ?"; + push @where_args, "%$args->{issn}%"; + } + if( $args->{ean} ){ + push @where_strs, "biblioitems.ean LIKE ?"; + push @where_args, "%$args->{ean}%"; + } + if( $args->{publisher} ){ + push @where_strs, "biblioitems.publishercode LIKE ?"; + push @where_args, "%$args->{publisher}%"; + } + if( $args->{bookseller} ){ + push @where_strs, "aqbooksellers.name LIKE ?"; + push @where_args, "%$args->{bookseller}%"; + } + if( $args->{branch} ){ + push @where_strs, "subscription.branchcode = ?"; + push @where_args, "$args->{branch}"; + } + + if(@where_strs){ + $query .= " WHERE " . join(" AND ", @where_strs); + } + + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare($query); + $sth->execute(@where_args); + my $results = $sth->fetchall_arrayref( {} ); + $sth->finish; + + return @$results; +} + + =head2 GetSerials ($totalissues,@serials) = GetSerials($subscriptionid); diff --git a/acqui/addorderiso2709.pl b/acqui/addorderiso2709.pl index b1b49106bb..22001f1e67 100755 --- a/acqui/addorderiso2709.pl +++ b/acqui/addorderiso2709.pl @@ -191,13 +191,11 @@ if ($op eq ""){ # 3rd add order my $patron = C4::Members->GetMember( borrowernumber => $loggedinuser ); my $branch = C4::Branch->GetBranchDetail( $patron->{branchcode} ); - my ($invoice); # get quantity in the MARC record (1 if none) my $quantity = GetMarcQuantity($marcrecord, C4::Context->preference('marcflavour')) || 1; my %orderinfo = ( "biblionumber", $biblionumber, "basketno", $cgiparams->{'basketno'}, "quantity", $quantity, "branchcode", $branch, - "booksellerinvoicenumber", $invoice, "budget_id", $budget_id, "uncertainprice", 1, "sort1", $cgiparams->{'sort1'},"sort2", $cgiparams->{'sort2'}, "notes", $cgiparams->{'notes'}, "budget_id", $cgiparams->{'budget_id'}, diff --git a/acqui/finishreceive.pl b/acqui/finishreceive.pl index bfd8010516..bb4818dd5a 100755 --- a/acqui/finishreceive.pl +++ b/acqui/finishreceive.pl @@ -45,14 +45,14 @@ my $origquantityrec=$input->param('origquantityrec'); my $quantityrec=$input->param('quantityrec'); my $quantity=$input->param('quantity'); my $unitprice=$input->param('cost'); -my $invoiceno=$input->param('invoice'); -my $datereceived=$input->param('datereceived'); +my $invoiceid = $input->param('invoiceid'); +my $invoice = GetInvoice($invoiceid); +my $invoiceno = $invoice->{invoicenumber}; +my $datereceived= $invoice->{shipmentdate}; my $replacement=$input->param('rrp'); my $gst=$input->param('gst'); -my $freight=$input->param('freight'); my $booksellerid = $input->param('booksellerid'); my $cnt=0; -my $error_url_str; my $ecost = $input->param('ecost'); my $note = $input->param("note"); @@ -68,8 +68,7 @@ if ($quantityrec > $origquantityrec ) { if ( $quantityrec > 0 ) { ($datereceived, $new_ordernumber) = ModReceiveOrder( $biblionumber, $ordernumber, $quantityrec, $user, $unitprice, - $invoiceno, $freight, $replacement, undef, $datereceived, - \@received_items); + $invoiceid, $replacement, undef, $datereceived, \@received_items); } # now, add items if applicable @@ -112,7 +111,7 @@ if ($quantityrec > $origquantityrec ) { update_item( $_ ) foreach GetItemnumbersFromOrder( $ordernumber ); -print $input->redirect("/cgi-bin/koha/acqui/parcel.pl?invoice=$invoiceno&booksellerid=$booksellerid&freight=$freight&gst=$gst&datereceived=$datereceived$error_url_str"); +print $input->redirect("/cgi-bin/koha/acqui/parcel.pl?invoiceid=$invoiceid"); ################################ End of script ################################ diff --git a/acqui/invoice.pl b/acqui/invoice.pl new file mode 100755 index 0000000000..1dc97ee7e6 --- /dev/null +++ b/acqui/invoice.pl @@ -0,0 +1,227 @@ +#!/usr/bin/perl + +# Copyright 2011 BibLibre SARL +# 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., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +=head1 NAME + +invoice.pl + +=head1 DESCRIPTION + +Invoice details + +=cut + +use strict; +use warnings; + +use CGI; +use C4::Auth; +use C4::Output; +use C4::Acquisition; +use C4::Bookseller qw/GetBookSellerFromId/; +use C4::Budgets; + +my $input = new CGI; +my ( $template, $loggedinuser, $cookie, $flags ) = get_template_and_user( + { + template_name => 'acqui/invoice.tmpl', + query => $input, + type => 'intranet', + authnotrequired => 0, + flagsrequired => { 'acquisition' => '*' }, + debug => 1, + } +); + +my $invoiceid = $input->param('invoiceid'); +my $op = $input->param('op'); + +if ( $op && $op eq 'close' ) { + CloseInvoice($invoiceid); + my $referer = $input->param('referer'); + if ($referer) { + print $input->redirect($referer); + exit 0; + } +} +elsif ( $op && $op eq 'reopen' ) { + ReopenInvoice($invoiceid); + my $referer = $input->param('referer'); + if ($referer) { + print $input->redirect($referer); + exit 0; + } +} +elsif ( $op && $op eq 'mod' ) { + my $shipmentdate = $input->param('shipmentdate'); + my $billingdate = $input->param('billingdate'); + my $shipmentcost = $input->param('shipmentcost'); + my $shipment_budget_id = $input->param('shipment_budget_id'); + ModInvoice( + invoiceid => $invoiceid, + shipmentdate => C4::Dates->new($shipmentdate)->output("iso"), + billingdate => C4::Dates->new($billingdate)->output("iso"), + shipmentcost => $shipmentcost, + shipmentcost_budgetid => $shipment_budget_id + ); + $template->param( modified => 1 ); +} + +my $details = GetInvoiceDetails($invoiceid); +my $bookseller = GetBookSellerFromId( $details->{booksellerid} ); +my @orders_loop = (); +my $orders = $details->{'orders'}; +my $qty_total; +my @books_loop; +my @book_foot_loop; +my %foot; +my $total_quantity = 0; +my $total_rrp = 0; +my $total_est = 0; + +foreach my $order (@$orders) { + my $line = get_infos( $order, $bookseller ); + + $total_quantity += $$line{quantity}; + $total_rrp += $order->{quantity} * $order->{rrp}; + $total_est += $order->{quantity} * $order->{'ecost'}; + + my %row = ( %$order, %$line ); + push @orders_loop, \%row; +} + +my $gist = $bookseller->{gstrate} // C4::Context->preference("gist") // 0; +my $discount = + $bookseller->{'discount'} ? ( $bookseller->{discount} / 100 ) : 0; +my $total_est_gste; +my $total_est_gsti; +my $total_rrp_gsti; # RRP Total, GST included +my $total_rrp_gste; # RRP Total, GST excluded +my $gist_est; +my $gist_rrp; +if ($gist) { + + # if we have GST + if ( $bookseller->{'listincgst'} ) { + + # if prices already includes GST + + # we know $total_rrp_gsti + $total_rrp_gsti = $total_rrp; + + # and can reverse compute other values + $total_rrp_gste = $total_rrp_gsti / ( $gist + 1 ); + + $gist_rrp = $total_rrp_gsti - $total_rrp_gste; + $total_est_gste = $total_rrp_gste - ( $total_rrp_gste * $discount ); + $total_est_gsti = $total_est; + } + else { + # if prices does not include GST + + # then we use the common way to compute other values + $total_rrp_gste = $total_rrp; + $gist_rrp = $total_rrp_gste * $gist; + $total_rrp_gsti = $total_rrp_gste + $gist_rrp; + $total_est_gste = $total_est; + $total_est_gsti = $total_rrp_gsti - ( $total_rrp_gsti * $discount ); + } + $gist_est = $gist_rrp - ( $gist_rrp * $discount ); +} +else { + $total_rrp_gste = $total_rrp_gsti = $total_rrp; + $total_est_gste = $total_est_gsti = $total_est; + $gist_rrp = $gist_est = 0; +} +my $total_gsti_shipment = $total_est_gsti + $details->{shipmentcost}; + +my $format = "%.2f"; +$template->param( + total_rrp_gste => sprintf( $format, $total_rrp_gste ), + total_rrp_gsti => sprintf( $format, $total_rrp_gsti ), + total_est_gste => sprintf( $format, $total_est_gste ), + total_est_gsti => sprintf( $format, $total_est_gsti ), + gist_rrp => sprintf( $format, $gist_rrp ), + gist_est => sprintf( $format, $gist_est ), + total_gsti_shipment => sprintf( $format, $total_gsti_shipment ), + gist => sprintf( $format, $gist * 100 ), +); + +my $budgets = GetBudgets(); +my @budgets_loop; +my $shipmentcost_budgetid = $details->{shipmentcost_budgetid}; +foreach my $budget (@$budgets) { + next unless CanUserUseBudget( $loggedinuser, $budget, $flags ); + my %line = %{$budget}; + if ( $shipmentcost_budgetid + and $budget->{budget_id} == $shipmentcost_budgetid ) + { + $line{selected} = 1; + } + push @budgets_loop, \%line; +} + +$template->param( + invoiceid => $details->{'invoiceid'}, + invoicenumber => $details->{'invoicenumber'}, + suppliername => $details->{'suppliername'}, + supplierid => $details->{'booksellerid'}, + datereceived => $details->{'datereceived'}, + shipmentdate => $details->{'shipmentdate'}, + billingdate => $details->{'billingdate'}, + invoiceclosedate => $details->{'closedate'}, + shipmentcost => sprintf( $format, $details->{'shipmentcost'} || 0 ), + orders_loop => \@orders_loop, + total_quantity => $total_quantity, + invoiceincgst => $bookseller->{invoiceincgst}, + currency => $bookseller->{listprice}, + DHTMLcalendar_dateformat => C4::Dates->DHTMLcalendar(), + budgets_loop => \@budgets_loop, +); + +sub get_infos { + my $order = shift; + my $bookseller = shift; + my $qty = $order->{'quantity'} || 0; + if ( !defined $order->{quantityreceived} ) { + $order->{quantityreceived} = 0; + } + my $budget = GetBudget( $order->{'budget_id'} ); + + my %line = %{$order}; + $line{order_received} = ( $qty == $order->{'quantityreceived'} ); + $line{budget_name} = $budget->{budget_name}; + $line{total} = $qty * $order->{ecost}; + + if ( $line{uncertainprice} ) { + $line{rrp} .= ' (Uncertain)'; + } + if ( $line{'title'} ) { + my $volume = $order->{'volume'}; + my $seriestitle = $order->{'seriestitle'}; + $line{'title'} .= " / $seriestitle" if $seriestitle; + $line{'title'} .= " / $volume" if $volume; + } + else { + $line{'title'} = "Deleted bibliographic notice, can't find title."; + } + + return \%line; +} + +output_html_with_http_headers $input, $cookie, $template->output; diff --git a/acqui/invoices.pl b/acqui/invoices.pl new file mode 100755 index 0000000000..4b45e31dba --- /dev/null +++ b/acqui/invoices.pl @@ -0,0 +1,157 @@ +#!/usr/bin/perl + +# Copyright 2011 BibLibre SARL +# 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., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +=head1 NAME + +invoices.pl + +=head1 DESCRIPTION + +Search for invoices + +=cut + +use strict; +use warnings; + +use CGI; +use C4::Auth; +use C4::Output; + +use C4::Acquisition; +use C4::Bookseller qw/GetBookSeller/; +use C4::Branch; + +my $input = new CGI; +my ( $template, $loggedinuser, $cookie, $flags ) = get_template_and_user( + { + template_name => 'acqui/invoices.tmpl', + query => $input, + type => 'intranet', + authnotrequired => 0, + flagsrequired => { 'acquisition' => '*' }, + debug => 1, + } +); + +my $invoicenumber = $input->param('invoicenumber'); +my $supplier = $input->param('supplier'); +my $shipmentdatefrom = $input->param('shipmentdatefrom'); +my $shipmentdateto = $input->param('shipmentdateto'); +my $billingdatefrom = $input->param('billingdatefrom'); +my $billingdateto = $input->param('billingdateto'); +my $isbneanissn = $input->param('isbneanissn'); +my $title = $input->param('title'); +my $author = $input->param('author'); +my $publisher = $input->param('publisher'); +my $publicationyear = $input->param('publicationyear'); +my $branch = $input->param('branch'); +my $op = $input->param('op'); + +my @results_loop = (); +if ( $op and $op eq "do_search" ) { + my $shipmentdatefrom_iso = C4::Dates->new($shipmentdatefrom)->output("iso"); + my $shipmentdateto_iso = C4::Dates->new($shipmentdateto)->output("iso"); + my $billingdatefrom_iso = C4::Dates->new($billingdatefrom)->output("iso"); + my $billingdateto_iso = C4::Dates->new($billingdateto)->output("iso"); + my @invoices = GetInvoices( + invoicenumber => $invoicenumber, + suppliername => $supplier, + shipmentdatefrom => $shipmentdatefrom_iso, + shipmentdateto => $shipmentdateto_iso, + billingdatefrom => $billingdatefrom_iso, + billingdateto => $billingdateto_iso, + isbneanissn => $isbneanissn, + title => $title, + author => $author, + publisher => $publisher, + publicationyear => $publicationyear, + branchcode => $branch + ); + foreach (@invoices) { + my %row = ( + invoiceid => $_->{invoiceid}, + billingdate => $_->{billingdate}, + invoicenumber => $_->{invoicenumber}, + suppliername => $_->{suppliername}, + receivedbiblios => $_->{receivedbiblios}, + receiveditems => $_->{receiveditems}, + subscriptionid => $_->{subscriptionid}, + closedate => $_->{closedate}, + ); + push @results_loop, \%row; + } +} + +# Build suppliers list +my @suppliers = GetBookSeller(undef); +my @suppliers_loop = (); +my $suppliername; +foreach (@suppliers) { + my $selected = 0; + if ( $supplier && $supplier == $_->{'id'} ) { + $selected = 1; + $suppliername = $_->{'name'}; + } + my %row = ( + suppliername => $_->{'name'}, + supplierid => $_->{'id'}, + selected => $selected, + ); + push @suppliers_loop, \%row; +} + +# Build branches list +my $branches = GetBranches(); +my @branches_loop = (); +my $branchname; +foreach ( sort keys %$branches ) { + my $selected = 0; + if ( $branch && $branch eq $_ ) { + $selected = 1; + $branchname = $branches->{$_}->{'branchname'}; + } + my %row = ( + branchcode => $_, + branchname => $branches->{$_}->{'branchname'}, + selected => $selected, + ); + push @branches_loop, \%row; +} + +$template->param( + do_search => ( $op and $op eq "do_search" ) ? 1 : 0, + results_loop => \@results_loop, + invoicenumber => $invoicenumber, + supplier => $supplier, + suppliername => $suppliername, + billingdatefrom => $billingdatefrom, + billingdateto => $billingdateto, + isbneanissn => $isbneanissn, + title => $title, + author => $author, + publisher => $publisher, + publicationyear => $publicationyear, + branch => $branch, + branchname => $branchname, + suppliers_loop => \@suppliers_loop, + branches_loop => \@branches_loop, + DHTMLcalendar_dateformat => C4::Dates->DHTMLcalendar(), +); + +output_html_with_http_headers $input, $cookie, $template->output; diff --git a/acqui/orderreceive.pl b/acqui/orderreceive.pl index 85168d56d9..a0b933bebf 100755 --- a/acqui/orderreceive.pl +++ b/acqui/orderreceive.pl @@ -40,9 +40,9 @@ to know on what supplier this script has to display receive order. =item receive -=item invoice +=item invoiceid -the number of this invoice. +the id of this invoice. =item freight @@ -82,19 +82,18 @@ use C4::Suggestions; my $input = new CGI; my $dbh = C4::Context->dbh; -my $booksellerid = $input->param('booksellerid'); +my $invoiceid = $input->param('invoiceid'); +my $invoice = GetInvoice($invoiceid); +my $booksellerid = $invoice->{booksellerid}; +my $freight = $invoice->{shipmentcost}; +my $datereceived = $invoice->{shipmentdate}; my $ordernumber = $input->param('ordernumber'); my $search = $input->param('receive'); -my $invoice = $input->param('invoice'); -my $freight = $input->param('freight'); -my $datereceived = $input->param('datereceived'); - $datereceived = $datereceived ? C4::Dates->new($datereceived, 'iso') : C4::Dates->new(); my $bookseller = GetBookSellerFromId($booksellerid); -my $input_gst = ($input->param('gst') eq '' ? undef : $input->param('gst')); -my $gst= $input_gst // $bookseller->{gstrate} // C4::Context->preference("gist") // 0; +my $gst = $bookseller->{gstrate} // C4::Context->preference("gist") // 0; my $results = SearchOrder($ordernumber,$search); my ( $template, $loggedinuser, $cookie ) = get_template_and_user( @@ -195,7 +194,8 @@ if ( $count == 1 ) { unitprice => sprintf( "%.2f",$order->{'unitprice'}), memberfirstname => $member->{firstname} || "", membersurname => $member->{surname} || "", - invoice => $invoice, + invoiceid => $invoice->{invoiceid}, + invoice => $invoice->{invoicenumber}, datereceived => $datereceived->output(), datereceived_iso => $datereceived->output('iso'), notes => $order->{notes}, @@ -209,7 +209,7 @@ else { for ( my $i = 0 ; $i < $count ; $i++ ) { my %line = %{ @$results[$i] }; - $line{invoice} = $invoice; + $line{invoice} = $invoice->{invoicenumber}; $line{datereceived} = $datereceived->output(); $line{freight} = $freight; $line{gst} = $gst; @@ -221,7 +221,8 @@ else { $template->param( loop => \@loop, - booksellerid => $booksellerid, + booksellerid => $booksellerid, + invoiceid => $invoice->{invoiceid}, ); } my $op = $input->param('op'); diff --git a/acqui/parcel.pl b/acqui/parcel.pl index 1c1736de4c..7f50f0b69d 100755 --- a/acqui/parcel.pl +++ b/acqui/parcel.pl @@ -42,8 +42,6 @@ To know the supplier this script has to show orders. is the bookseller invoice number. -=item freight - =item gst @@ -57,7 +55,8 @@ To filter the results list on this given date. =cut use strict; -#use warnings; FIXME - Bug 2505 +use warnings; + use C4::Auth; use C4::Acquisition; use C4::Budgets; @@ -71,36 +70,20 @@ use C4::Suggestions; use JSON; my $input=new CGI; -my $booksellerid=$input->param('booksellerid'); -my $bookseller=GetBookSellerFromId($booksellerid); - -my $invoice=$input->param('invoice') || ''; -my $freight=$input->param('freight'); -my $input_gst = ($input->param('gst') eq '' ? undef : $input->param('gst')); -my $gst= $input_gst // $bookseller->{gstrate} // C4::Context->preference("gist") // 0; -my $op = $input->param('op') // ''; -my $datereceived = ( $op eq ('new' or 'search' ) ) - ? C4::Dates->new($input->param('datereceived')) - : C4::Dates->new($input->param('datereceived'), 'iso'); -$datereceived = C4::Dates->new() unless $datereceived; -my $code = $input->param('code'); -my @rcv_err = $input->param('error'); -my @rcv_err_barcode = $input->param('error_bc'); -my $startfrom=$input->param('startfrom'); -my $resultsperpage = $input->param('resultsperpage'); -$resultsperpage = 20 unless ($resultsperpage); -$startfrom=0 unless ($startfrom); my ($template, $loggedinuser, $cookie) = get_template_and_user({template_name => "acqui/parcel.tmpl", query => $input, - type => "intranet", + type => "intranet", authnotrequired => 0, flagsrequired => {acquisition => 'order_receive'}, debug => 1, }); -if($op eq 'cancelreceipt') { +my $invoiceid = $input->param('invoiceid'); +my $op = $input->param('op') // ''; + +if ($op eq 'cancelreceipt') { my $ordernumber = $input->param('ordernumber'); my $parent_ordernumber = CancelReceipt($ordernumber); unless($parent_ordernumber) { @@ -108,6 +91,21 @@ if($op eq 'cancelreceipt') { } } +my $invoice = GetInvoiceDetails($invoiceid); +my $booksellerid = $invoice->{booksellerid}; +my $bookseller = GetBookSellerFromId($booksellerid); +my $gst = $bookseller->{gstrate} // C4::Context->preference("gist") // 0; +my $datereceived = C4::Dates->new(); +my $code = $input->param('code'); +my @rcv_err = $input->param('error'); +my @rcv_err_barcode = $input->param('error_bc'); +my $startfrom=$input->param('startfrom'); +my $resultsperpage = $input->param('resultsperpage'); +$resultsperpage = 20 unless ($resultsperpage); +$startfrom=0 unless ($startfrom); + + + # If receiving error, report the error (coming from finishrecieve.pl(sic)). if( scalar(@rcv_err) ) { my $cnt=0; @@ -122,10 +120,9 @@ if( scalar(@rcv_err) ) { } my $cfstr = "%.2f"; # currency format string -- could get this from currency table. -my @parcelitems = GetParcel($booksellerid, $invoice, $datereceived->output('iso')); +my @parcelitems = @{ $invoice->{orders} }; my $countlines = scalar @parcelitems; my $totalprice = 0; -my $totalfreight = 0; my $totalquantity = 0; my $total; my $tototal; @@ -133,15 +130,14 @@ my @loop_received = (); for (my $i = 0 ; $i < $countlines ; $i++) { - #$total=($parcelitems[$i]->{'unitprice'} + $parcelitems[$i]->{'freight'}) * $parcelitems[$i]->{'quantityreceived'}; #weird, are the freight fees counted by book? (pierre) - $total = ($parcelitems[$i]->{'unitprice'}) * $parcelitems[$i]->{'quantityreceived'}; #weird, are the freight fees counted by book? (pierre) + $total = ($parcelitems[$i]->{'unitprice'}) * $parcelitems[$i]->{'quantityreceived'}; $parcelitems[$i]->{'unitprice'} += 0; my %line; %line = %{ $parcelitems[$i] }; - $line{invoice} = $invoice; + $line{invoice} = $invoice->{invoicenumber}; $line{gst} = $gst; $line{total} = sprintf($cfstr, $total); - $line{booksellerid} = $booksellerid; + $line{booksellerid} = $invoice->{booksellerid}; $totalprice += $parcelitems[$i]->{'unitprice'}; $line{unitprice} = sprintf($cfstr, $parcelitems[$i]->{'unitprice'}); @@ -159,156 +155,149 @@ for (my $i = 0 ; $i < $countlines ; $i++) { } push @loop_received, \%line; - #double FIXME - totalfreight is redefined later. - -# FIXME - each order in a parcel holds the freight for the whole parcel. This means if you receive a parcel with items from multiple budgets, you'll see the freight charge in each budget.. - if ($i > 0 && $totalfreight != $parcelitems[$i]->{'freight'}) { - warn "FREIGHT CHARGE MISMATCH!!"; - } - $totalfreight = $parcelitems[$i]->{'freight'}; $totalquantity += $parcelitems[$i]->{'quantityreceived'}; $tototal += $total; } -# We get the pending orders either all or filtered -my $pendingorders; -if($input->param('op') eq "search"){ - my $search = $input->param('summaryfilter') || ''; - my $ean = $input->param('eanfilter') || ''; - my $basketno = $input->param('basketfilter') || ''; - my $orderno = $input->param('orderfilter') || ''; - my $grouped; - my $owner; - $pendingorders = GetPendingOrders($booksellerid,$grouped,$owner,$basketno,$orderno,$search,$ean); -}else{ - $pendingorders = GetPendingOrders($booksellerid); -} -my $countpendings = scalar @$pendingorders; - -# pending orders totals -my ($totalPunitprice, $totalPquantity, $totalPecost, $totalPqtyrcvd); -my $ordergrandtotal; -my @loop_orders = (); -for (my $i = 0 ; $i < $countpendings ; $i++) { - my %line; - %line = %{$pendingorders->[$i]}; - - $line{quantity}+=0; - $line{quantityreceived}+=0; - $line{unitprice}+=0; - $totalPunitprice += $line{unitprice}; - $totalPquantity +=$line{quantity}; - $totalPqtyrcvd +=$line{quantityreceived}; - $totalPecost += $line{ecost}; - $line{ecost} = sprintf("%.2f",$line{ecost}); - $line{ordertotal} = sprintf("%.2f",$line{ecost}*$line{quantity}); - $line{unitprice} = sprintf("%.2f",$line{unitprice}); - $line{invoice} = $invoice; - $line{gst} = $gst; - $line{total} = $total; - $line{booksellerid} = $booksellerid; - $ordergrandtotal += $line{ecost} * $line{quantity}; - - my $biblionumber = $line{'biblionumber'}; - my $countbiblio = CountBiblioInOrders($biblionumber); - my $ordernumber = $line{'ordernumber'}; - my @subscriptions = GetSubscriptionsId ($biblionumber); - my $itemcount = GetItemsCount($biblionumber); - my $holds = GetHolds ($biblionumber); - my @items = GetItemnumbersFromOrder( $ordernumber ); - my $itemholds; - foreach my $item (@items){ - my $nb = GetItemHolds($biblionumber, $item); - if ($nb){ - $itemholds += $nb; +if(!defined $invoice->{closedate}) { + my $pendingorders; + if($input->param('op') eq "search"){ + my $search = $input->param('summaryfilter') || ''; + my $ean = $input->param('eanfilter') || ''; + my $basketno = $input->param('basketfilter') || ''; + my $orderno = $input->param('orderfilter') || ''; + my $grouped; + my $owner; + $pendingorders = GetPendingOrders($booksellerid,$grouped,$owner,$basketno,$orderno,$search,$ean); + }else{ + $pendingorders = GetPendingOrders($booksellerid); + } + my $countpendings = scalar @$pendingorders; + + # pending orders totals + my ($totalPunitprice, $totalPquantity, $totalPecost, $totalPqtyrcvd); + my $ordergrandtotal; + my @loop_orders = (); + for (my $i = 0 ; $i < $countpendings ; $i++) { + my %line; + %line = %{$pendingorders->[$i]}; + + $line{quantity}+=0; + $line{quantityreceived}+=0; + $line{unitprice}+=0; + $totalPunitprice += $line{unitprice}; + $totalPquantity +=$line{quantity}; + $totalPqtyrcvd +=$line{quantityreceived}; + $totalPecost += $line{ecost}; + $line{ecost} = sprintf("%.2f",$line{ecost}); + $line{ordertotal} = sprintf("%.2f",$line{ecost}*$line{quantity}); + $line{unitprice} = sprintf("%.2f",$line{unitprice}); + $line{invoice} = $invoice; + $line{gst} = $gst; + $line{total} = $total; + $line{booksellerid} = $booksellerid; + $ordergrandtotal += $line{ecost} * $line{quantity}; + + my $biblionumber = $line{'biblionumber'}; + my $countbiblio = CountBiblioInOrders($biblionumber); + my $ordernumber = $line{'ordernumber'}; + my @subscriptions = GetSubscriptionsId ($biblionumber); + my $itemcount = GetItemsCount($biblionumber); + my $holds = GetHolds ($biblionumber); + my @items = GetItemnumbersFromOrder( $ordernumber ); + my $itemholds; + foreach my $item (@items){ + my $nb = GetItemHolds($biblionumber, $item); + if ($nb){ + $itemholds += $nb; + } } + + my $suggestion = GetSuggestionInfoFromBiblionumber($line{biblionumber}); + $line{suggestionid} = $suggestion->{suggestionid}; + $line{surnamesuggestedby} = $suggestion->{surnamesuggestedby}; + $line{firstnamesuggestedby} = $suggestion->{firstnamesuggestedby}; + + # if the biblio is not in other orders and if there is no items elsewhere and no subscriptions and no holds we can then show the link "Delete order and Biblio" see bug 5680 + $line{can_del_bib} = 1 if $countbiblio <= 1 && $itemcount == scalar @items && !(@subscriptions) && !($holds); + $line{items} = ($itemcount) - (scalar @items); + $line{left_item} = 1 if $line{items} >= 1; + $line{left_biblio} = 1 if $countbiblio > 1; + $line{biblios} = $countbiblio - 1; + $line{left_subscription} = 1 if scalar @subscriptions >= 1; + $line{subscriptions} = scalar @subscriptions; + $line{left_holds} = ($holds >= 1) ? 1 : 0; + $line{left_holds_on_order} = 1 if $line{left_holds}==1 && ($line{items} == 0 || $itemholds ); + $line{holds} = $holds; + $line{holds_on_order} = $itemholds?$itemholds:$holds if $line{left_holds_on_order}; + + + push @loop_orders, \%line if ($i >= $startfrom and $i < $startfrom + $resultsperpage); } - my $suggestion = GetSuggestionInfoFromBiblionumber($line{biblionumber}); - $line{suggestionid} = $suggestion->{suggestionid}; - $line{surnamesuggestedby} = $suggestion->{surnamesuggestedby}; - $line{firstnamesuggestedby} = $suggestion->{firstnamesuggestedby}; + my $count = $countpendings; - # if the biblio is not in other orders and if there is no items elsewhere and no subscriptions and no holds we can then show the link "Delete order and Biblio" see bug 5680 - $line{can_del_bib} = 1 if $countbiblio <= 1 && $itemcount == scalar @items && !(@subscriptions) && !($holds); - $line{items} = ($itemcount) - (scalar @items); - $line{left_item} = 1 if $line{items} >= 1; - $line{left_biblio} = 1 if $countbiblio > 1; - $line{biblios} = $countbiblio - 1; - $line{left_subscription} = 1 if scalar @subscriptions >= 1; - $line{subscriptions} = scalar @subscriptions; - $line{left_holds} = 1 if $holds >= 1; - $line{left_holds_on_order} = 1 if $line{left_holds} == 1 && ($line{items} == 0 || $itemholds ); - $line{holds} = $holds; - $line{holds_on_order} = $itemholds?$itemholds:$holds if $line{left_holds_on_order}; - - - push @loop_orders, \%line if ($i >= $startfrom and $i < $startfrom + $resultsperpage); -} -$freight = $totalfreight unless $freight; -my $count = $countpendings; - -if ($count>$resultsperpage){ - my $displaynext=0; - my $displayprev=$startfrom; - if(($count - ($startfrom+$resultsperpage)) > 0 ) { - $displaynext = 1; - } + if ($count>$resultsperpage){ + my $displaynext=0; + my $displayprev=$startfrom; + if(($count - ($startfrom+$resultsperpage)) > 0 ) { + $displaynext = 1; + } - my @numbers = (); - for (my $i=1; $i<$count/$resultsperpage+1; $i++) { - my $highlight=0; - ($startfrom/$resultsperpage==($i-1)) && ($highlight=1); - push @numbers, { number => $i, - highlight => $highlight , - startfrom => ($i-1)*$resultsperpage}; - } + my @numbers = (); + for (my $i=1; $i<$count/$resultsperpage+1; $i++) { + my $highlight=0; + ($startfrom/$resultsperpage==($i-1)) && ($highlight=1); + push @numbers, { number => $i, + highlight => $highlight , + startfrom => ($i-1)*$resultsperpage}; + } - my $from = $startfrom*$resultsperpage+1; - my $to; - if($count < (($startfrom+1)*$resultsperpage)){ - $to = $count; - } else { - $to = (($startfrom+1)*$resultsperpage); + my $from = $startfrom*$resultsperpage+1; + my $to; + if($count < (($startfrom+1)*$resultsperpage)){ + $to = $count; + } else { + $to = (($startfrom+1)*$resultsperpage); + } + $template->param(numbers=>\@numbers, + displaynext=>$displaynext, + displayprev=>$displayprev, + nextstartfrom=>(($startfrom+$resultsperpage<$count)?$startfrom+$resultsperpage:$count), + prevstartfrom=>(($startfrom-$resultsperpage>0)?$startfrom-$resultsperpage:0) + ); } - $template->param(numbers=>\@numbers, - displaynext=>$displaynext, - displayprev=>$displayprev, - nextstartfrom=>(($startfrom+$resultsperpage<$count)?$startfrom+$resultsperpage:$count), - prevstartfrom=>(($startfrom-$resultsperpage>0)?$startfrom-$resultsperpage:0) - ); + + $template->param( + countpending => $countpendings, + loop_orders => \@loop_orders, + ordergrandtotal => sprintf($cfstr, $ordergrandtotal), + totalPunitprice => sprintf("%.2f", $totalPunitprice), + totalPquantity => $totalPquantity, + totalPqtyrcvd => $totalPqtyrcvd, + totalPecost => sprintf("%.2f", $totalPecost), + ); } -#$totalfreight=$freight; -$tototal = $tototal + $freight; $template->param( - invoice => $invoice, + invoiceid => $invoice->{invoiceid}, + invoice => $invoice->{invoicenumber}, + invoiceclosedate => $invoice->{closedate}, datereceived => $datereceived->output('iso'), invoicedatereceived => $datereceived->output('iso'), formatteddatereceived => $datereceived->output(), name => $bookseller->{'name'}, - booksellerid => $booksellerid, + booksellerid => $bookseller->{id}, gst => $gst, - freight => $freight, - invoice => $invoice, countreceived => $countlines, loop_received => \@loop_received, - countpending => $countpendings, - loop_orders => \@loop_orders, totalprice => sprintf($cfstr, $totalprice), - totalfreight => $totalfreight, totalquantity => $totalquantity, tototal => sprintf($cfstr, $tototal), - ordergrandtotal => sprintf($cfstr, $ordergrandtotal), gst => $gst, grandtot => sprintf($cfstr, $tototal + $gst), - totalPunitprice => sprintf("%.2f", $totalPunitprice), - totalPquantity => $totalPquantity, - totalPqtyrcvd => $totalPqtyrcvd, - totalPecost => sprintf("%.2f", $totalPecost), resultsperpage => $resultsperpage, (uc(C4::Context->preference("marcflavour"))) => 1 ); output_html_with_http_headers $input, $cookie, $template->output; - diff --git a/acqui/parcels.pl b/acqui/parcels.pl index fdb46d5744..4f2849d43f 100755 --- a/acqui/parcels.pl +++ b/acqui/parcels.pl @@ -44,9 +44,9 @@ To know the supplier this script has to show orders. sort list of order by 'orderby'. Orderby can be equals to * datereceived desc (default value) - * aqorders.booksellerinvoicenumber + * invoicenumber * datereceived - * aqorders.booksellerinvoicenumber desc + * invoicenumber desc =item filter @@ -75,6 +75,7 @@ use C4::Output; use C4::Dates qw/format_date/; use C4::Acquisition; use C4::Bookseller qw/ GetBookSellerFromId /; +use C4::Budgets; my $input = CGI->new; my $booksellerid = $input->param('booksellerid'); @@ -84,9 +85,10 @@ my $code = $input->param('filter'); my $datefrom = $input->param('datefrom'); my $dateto = $input->param('dateto'); my $resultsperpage = $input->param('resultsperpage'); +my $op = $input->param('op'); $resultsperpage ||= 20; -our ( $template, $loggedinuser, $cookie ) = get_template_and_user( +our ( $template, $loggedinuser, $cookie, $flags ) = get_template_and_user( { template_name => 'acqui/parcels.tmpl', query => $input, type => 'intranet', @@ -96,8 +98,38 @@ our ( $template, $loggedinuser, $cookie ) = get_template_and_user( } ); +if($op and $op eq 'new') { + my $invoicenumber = $input->param('invoice'); + my $shipmentdate = $input->param('shipmentdate'); + my $shipmentcost = $input->param('shipmentcost'); + my $shipmentcost_budgetid = $input->param('shipmentcost_budgetid'); + if($shipmentdate) { + $shipmentdate = C4::Dates->new($shipmentdate)->output('iso'); + } + my $invoiceid = AddInvoice( + invoicenumber => $invoicenumber, + booksellerid => $booksellerid, + shipmentdate => $shipmentdate, + shipmentcost => $shipmentcost, + shipmentcost_budgetid => $shipmentcost_budgetid, + ); + if(defined $invoiceid) { + # Successful 'Add' + print $input->redirect("/cgi-bin/koha/acqui/parcel.pl?invoiceid=$invoiceid"); + exit 0; + } else { + $template->param(error_failed_to_create_invoice => 1); + } +} + my $bookseller = GetBookSellerFromId($booksellerid); -my @parcels = GetParcels( $booksellerid, $order, $code, $datefrom, $dateto ); +my @parcels = GetInvoices( + supplierid => $booksellerid, + invoicenumber => $code, + shipmentdatefrom => $datefrom, + shipmentdateto => $dateto, + order_by => $order +); my $count_parcels = @parcels; # multi page display gestion @@ -114,19 +146,28 @@ for my $i ( $startfrom .. $last_row) { push @{$loopres}, { number => $i + 1, - code => $p->{booksellerinvoicenumber}, - nullcode => $p->{booksellerinvoicenumber} eq 'NULL', - emptycode => $p->{booksellerinvoicenumber} eq q{}, - raw_datereceived => $p->{datereceived}, - datereceived => format_date( $p->{datereceived} ), - bibcount => $p->{biblio}, - reccount => $p->{itemsreceived}, - itemcount => $p->{itemsexpected}, + invoiceid => $p->{invoiceid}, + code => $p->{invoicenumber}, + nullcode => $p->{invoicenumber} eq 'NULL', + emptycode => $p->{invoicenumber} eq q{}, + raw_datereceived => $p->{shipmentdate}, + datereceived => format_date( $p->{shipmentdate} ), + bibcount => $p->{receivedbiblios} || 0, + reccount => $p->{receiveditems} || 0, + itemcount => $p->{itemsexpected} || 0, }; } if ($count_parcels) { $template->param( searchresults => $loopres, count => $count_parcels ); } + +my $budgets = GetBudgets(); +my @budgets_loop; +foreach my $budget (@$budgets) { + next unless CanUserUseBudget($loggedinuser, $budget, $flags); + push @budgets_loop, $budget; +} + $template->param( orderby => $order, filter => $code, @@ -135,9 +176,10 @@ $template->param( resultsperpage => $resultsperpage, name => $bookseller->{'name'}, DHTMLcalendar_dateformat => C4::Dates->DHTMLcalendar(), - datereceived_today => C4::Dates->new()->output(), + shipmentdate_today => C4::Dates->new()->output(), booksellerid => $booksellerid, GST => C4::Context->preference('gist'), + budgets => \@budgets_loop, ); output_html_with_http_headers $input, $cookie, $template->output; diff --git a/acqui/spent.pl b/acqui/spent.pl index 0dcba98c65..2d555f9a76 100755 --- a/acqui/spent.pl +++ b/acqui/spent.pl @@ -60,10 +60,10 @@ SELECT aqbasket.booksellerid, itype, title, - aqorders.booksellerinvoicenumber, + aqorders.invoiceid, + aqinvoices.invoicenumber, quantityreceived, unitprice, - freight, datereceived, aqorders.biblionumber FROM (aqorders, aqbasket) @@ -73,6 +73,8 @@ LEFT JOIN biblio ON biblio.biblionumber=aqorders.biblionumber LEFT JOIN aqorders_items ON aqorders.ordernumber=aqorders_items.ordernumber +LEFT JOIN aqinvoices ON + aqorders.invoiceid = aqinvoices.invoiceid WHERE aqorders.basketno=aqbasket.basketno AND budget_id=? AND @@ -85,27 +87,48 @@ $sth->execute($bookfund); if ( $sth->err ) { die "An error occurred fetching records: " . $sth->errstr; } -my $total = 0; +my $subtotal = 0; my $toggle; my @spent; while ( my $data = $sth->fetchrow_hashref ) { my $recv = $data->{'quantityreceived'}; if ( $recv > 0 ) { - my $subtotal = $recv * ( $data->{'unitprice'} + $data->{'freight'} ); - $data->{'subtotal'} = sprintf( "%.2f", $subtotal ); - $data->{'freight'} = sprintf( "%.2f", $data->{'freight'} ); + my $rowtotal = $recv * $data->{'unitprice'}; + $data->{'rowtotal'} = sprintf( "%.2f", $rowtotal ); $data->{'unitprice'} = sprintf( "%.2f", $data->{'unitprice'} ); - $total += $subtotal; + $subtotal += $rowtotal; push @spent, $data; } } -$total = sprintf( "%.2f", $total ); -$template->{VARS}->{'fund'} = $bookfund; -$template->{VARS}->{'spent'} = \@spent; -$template->{VARS}->{'total'} = $total; -$template->{VARS}->{'fund_code'} = $fund_code; +my $total = $subtotal; +$query = qq{ + SELECT invoicenumber, shipmentcost + FROM aqinvoices + WHERE shipmentcost_budgetid = ? +}; +$sth = $dbh->prepare($query); +$sth->execute($bookfund); +my @shipmentcosts; +while (my $data = $sth->fetchrow_hashref) { + push @shipmentcosts, { + shipmentcost => sprintf("%.2f", $data->{shipmentcost}), + invoicenumber => $data->{invoicenumber} + }; + $total += $data->{shipmentcost}; +} $sth->finish; +$total = sprintf( "%.2f", $total ); + +$template->param( + fund => $bookfund, + spent => \@spent, + subtotal => $subtotal, + shipmentcosts => \@shipmentcosts, + total => $total, + fund_code => $fund_code +); + output_html_with_http_headers $input, $cookie, $template->output; diff --git a/admin/authorised_values.pl b/admin/authorised_values.pl index 949e4882a6..17917ce260 100755 --- a/admin/authorised_values.pl +++ b/admin/authorised_values.pl @@ -188,17 +188,18 @@ output_html_with_http_headers $input, $cookie, $template->output; exit 0; sub default_form { - # build categories list - my $sth = $dbh->prepare("select distinct category from authorised_values"); - $sth->execute; - my @category_list; - my %categories; # a hash, to check that some hardcoded categories exist. - while ( my ($category) = $sth->fetchrow_array) { - push(@category_list,$category); - $categories{$category} = 1; - } - # push koha system categories - foreach (qw(Asort1 Asort2 Bsort1 Bsort2 SUGGEST DAMAGED LOST)) { + # build categories list + my $sth = $dbh->prepare("select distinct category from authorised_values"); + $sth->execute; + my @category_list; + my %categories; # a hash, to check that some hardcoded categories exist. + while ( my ($category) = $sth->fetchrow_array ) { + push( @category_list, $category ); + $categories{$category} = 1; + } + + # push koha system categories + foreach (qw(Asort1 Asort2 Bsort1 Bsort2 SUGGEST DAMAGED LOST REPORT_GROUP REPORT_SUBGROUP)) { push @category_list, $_ unless $categories{$_}; } diff --git a/catalogue/moredetail.pl b/catalogue/moredetail.pl index 3eee676f5d..66d731bc6b 100755 --- a/catalogue/moredetail.pl +++ b/catalogue/moredetail.pl @@ -152,17 +152,19 @@ foreach my $item (@items){ } my $order = GetOrderFromItemnumber( $item->{'itemnumber'} ); - my $basket = GetBasket( $order->{'basketno'} ); - $item->{'booksellerid'} = $basket->{'booksellerid'}; $item->{'ordernumber'} = $order->{'ordernumber'}; $item->{'basketno'} = $order->{'basketno'}; - $item->{'booksellerinvoicenumber'} = $order->{'booksellerinvoicenumber'}; $item->{'orderdate'} = $order->{'entrydate'}; if ($item->{'basketno'}){ my $basket = GetBasket($item->{'basketno'}); my $bookseller = GetBookSellerFromId($basket->{'booksellerid'}); $item->{'vendor'} = $bookseller->{'name'}; } + $item->{'invoiceid'} = $order->{'invoiceid'}; + if($item->{invoiceid}) { + my $invoice = GetInvoice($item->{invoiceid}); + $item->{invoicenumber} = $invoice->{invoicenumber} if $invoice; + } $item->{'datereceived'} = $order->{'datereceived'}; if ($item->{notforloantext} or $item->{itemlost} or $item->{damaged} or $item->{wthdrawn}) { diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql index 68cdfecd2b..a514d99e24 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -97,7 +97,7 @@ CREATE TABLE `auth_types` ( DROP TABLE IF EXISTS `authorised_values`; CREATE TABLE `authorised_values` ( -- stores values for authorized values categories and values `id` int(11) NOT NULL auto_increment, -- unique key, used to identify the authorized value - `category` varchar(10) NOT NULL default '', -- key used to identify the authorized value category + `category` varchar(16) NOT NULL default '', -- key used to identify the authorized value category `authorised_value` varchar(80) NOT NULL default '', -- code use to identify the authorized value `lib` varchar(200) default NULL, -- authorized value description as printed in the staff client `lib_opac` varchar(200) default NULL, -- authorized value description as printed in the OPAC @@ -1626,8 +1626,9 @@ CREATE TABLE reports_dictionary ( -- definitions (or snippets of SQL) stored for `date_created` datetime default NULL, -- date and time this definition was created `date_modified` datetime default NULL, -- date and time this definition was last modified `saved_sql` text, -- SQL snippet for us in reports - `area` int(11) default NULL, -- Koha module this definition is for (1 = Circulation, 2 = Catalog, 3 = Patrons, 4 = Acquistions, 5 = Accounts) - PRIMARY KEY (`id`) + report_area varchar(6) DEFAULT NULL, -- Koha module this definition is for Circulation, Catalog, Patrons, Acquistions, Accounts) + PRIMARY KEY (id), + KEY dictionary_area_idx (report_area) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- @@ -1725,7 +1726,11 @@ CREATE TABLE saved_sql ( -- saved sql reports `notes` text, -- the notes or description given to this report `cache_expiry` int NOT NULL default 300, `public` boolean NOT NULL default FALSE, + report_area varchar(6) default NULL, + report_group varchar(80) default NULL, + report_subgroup varchar(80) default NULL, PRIMARY KEY (`id`), + KEY sql_area_group_idx (report_group, report_subgroup), KEY boridx (`borrowernumber`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -2748,7 +2753,7 @@ CREATE TABLE `aqorders` ( -- information related to the basket line items `listprice` decimal(28,6) default NULL, -- the vendor price for this line item `totalamount` decimal(28,6) default NULL, -- not used? always NULL `datereceived` date default NULL, -- the date this order was received - `booksellerinvoicenumber` mediumtext, -- the invoice number this line item was received on + invoiceid int(11) default NULL, -- id of invoice `freight` decimal(28,6) default NULL, -- shipping costs (not used) `unitprice` decimal(28,6) default NULL, -- the actual cost entered when receiving this line item `quantityreceived` smallint(6) NOT NULL default 0, -- the quantity that have been received so far @@ -2781,7 +2786,8 @@ CREATE TABLE `aqorders` ( -- information related to the basket line items KEY `biblionumber` (`biblionumber`), KEY `budget_id` (`budget_id`), CONSTRAINT `aqorders_ibfk_1` FOREIGN KEY (`basketno`) REFERENCES `aqbasket` (`basketno`) ON DELETE CASCADE ON UPDATE CASCADE, - CONSTRAINT `aqorders_ibfk_2` FOREIGN KEY (`biblionumber`) REFERENCES `biblio` (`biblionumber`) ON DELETE SET NULL ON UPDATE CASCADE + CONSTRAINT `aqorders_ibfk_2` FOREIGN KEY (`biblionumber`) REFERENCES `biblio` (`biblionumber`) ON DELETE SET NULL ON UPDATE CASCADE, + CONSTRAINT aqorders_ibfk_3 FOREIGN KEY (invoiceid) REFERENCES aqinvoices (invoiceid) ON DELETE SET NULL ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -2798,6 +2804,27 @@ CREATE TABLE `aqorders_items` ( -- information on items entered in the acquisiti KEY `ordernumber` (`ordernumber`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Table structure for table aqinvoices +-- + +DROP TABLE IF EXISTS aqinvoices; +CREATE TABLE aqinvoices ( + invoiceid int(11) NOT NULL AUTO_INCREMENT, -- ID of the invoice, primary key + invoicenumber mediumtext NOT NULL, -- Name of invoice + booksellerid int(11) NOT NULL, -- foreign key to aqbooksellers + shipmentdate date default NULL, -- date of shipment + billingdate date default NULL, -- date of billing + closedate date default NULL, -- invoice close date, NULL means the invoice is open + shipmentcost decimal(28,6) default NULL, -- shipment cost + shipmentcost_budgetid int(11) default NULL, -- foreign key to aqbudgets, link the shipment cost to a budget + PRIMARY KEY (invoiceid), + CONSTRAINT aqinvoices_fk_aqbooksellerid FOREIGN KEY (booksellerid) REFERENCES aqbooksellers (id) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT aqinvoices_fk_shipmentcost_budgetid FOREIGN KEY (shipmentcost_budgetid) REFERENCES aqbudgets (budget_id) ON DELETE SET NULL ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + + -- -- Table structure for table `fieldmapping` -- diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql index 4b4bf777f3..7b33ce6ae5 100644 --- a/installer/data/mysql/sysprefs.sql +++ b/installer/data/mysql/sysprefs.sql @@ -358,6 +358,9 @@ INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES ( INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('OpacStarRatings','all',NULL,'disable|all|details','Choice'); INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpacBrowseResults','1','Disable/enable browsing and paging search results from the OPAC detail page.',NULL,'YesNo'); INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('SvcMaxReportRows','10','Maximum number of rows to return via the report web service.',NULL,'Integer'); +INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES ('decreaseLoanHighHolds', NULL, '', 'Decreases the loan period for items with number of holds above the threshold specified in decreaseLoanHighHoldsValue', 'YesNo'); +INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES ('decreaseLoanHighHoldsValue', NULL, '', 'Specifies a threshold for the minimum number of holds needed to trigger a reduction in loan duration (used with decreaseLoanHighHolds)', 'Integer'); +INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES ('decreaseLoanHighHoldsDuration', NULL, '', 'Specifies a number of days that a loan is reduced to when used in conjunction with decreaseLoanHighHolds', 'Integer'); INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES ('ReservesControlBranch','PatronLibrary','ItemHomeLibrary|PatronLibrary','Branch checked for members reservations rights','Choice'); INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('IssueLostItem', 'alert', 'alert|confirm|nothing', 'Defines what should be done when an attempt is made to issue an item that has been marked as lost.', 'Choice'); INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('SuspendHoldsIntranet', '1', NULL , 'Allow holds to be suspended from the intranet.', 'YesNo'); diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl index 158f25ba15..8f0efc80ea 100755 --- a/installer/data/mysql/updatedatabase.pl +++ b/installer/data/mysql/updatedatabase.pl @@ -5827,6 +5827,98 @@ if(C4::Context->preference("Version") < TransformToNum($DBversion) ) { SetVersion($DBversion); } + + +$DBversion = "3.09.00.050"; +if (C4::Context->preference("Version") < TransformToNum($DBversion)) { + $dbh->do("ALTER TABLE authorised_values MODIFY category varchar(16) NOT NULL DEFAULT '';"); + $dbh->do("INSERT INTO authorised_values (category, authorised_value, lib) VALUES + ('REPORT_GROUP', 'CIRC', 'Circulation'), + ('REPORT_GROUP', 'CAT', 'Catalog'), + ('REPORT_GROUP', 'PAT', 'Patrons'), + ('REPORT_GROUP', 'ACQ', 'Acquisitions'), + ('REPORT_GROUP', 'ACC', 'Accounts');"); + + $dbh->do("ALTER TABLE reports_dictionary ADD report_area varchar(6) DEFAULT NULL;"); + $dbh->do("UPDATE reports_dictionary SET report_area = CASE area + WHEN 1 THEN 'CIRC' + WHEN 2 THEN 'CAT' + WHEN 3 THEN 'PAT' + WHEN 4 THEN 'ACQ' + WHEN 5 THEN 'ACC' + END;"); + $dbh->do("ALTER TABLE reports_dictionary DROP area;"); + $dbh->do("ALTER TABLE reports_dictionary ADD KEY dictionary_area_idx (report_area);"); + + $dbh->do("ALTER TABLE saved_sql ADD report_area varchar(6) DEFAULT NULL;"); + $dbh->do("ALTER TABLE saved_sql ADD report_group varchar(80) DEFAULT NULL;"); + $dbh->do("ALTER TABLE saved_sql ADD report_subgroup varchar(80) DEFAULT NULL;"); + $dbh->do("ALTER TABLE saved_sql ADD KEY sql_area_group_idx (report_group, report_subgroup);"); + + print "Upgrade to $DBversion done saved_sql new fields report_group and report_area; authorised_values.category 16 char \n"; + SetVersion($DBversion); +} + +$DBversion = "3.09.00.051"; +if (C4::Context->preference("Version") < TransformToNum($DBversion)) { + $dbh->do(" + CREATE TABLE aqinvoices ( + invoiceid int(11) NOT NULL AUTO_INCREMENT, + invoicenumber mediumtext NOT NULL, + booksellerid int(11) NOT NULL, + shipmentdate date default NULL, + billingdate date default NULL, + closedate date default NULL, + shipmentcost decimal(28,6) default NULL, + shipmentcost_budgetid int(11) default NULL, + PRIMARY KEY (invoiceid), + CONSTRAINT aqinvoices_fk_aqbooksellerid FOREIGN KEY (booksellerid) REFERENCES aqbooksellers (id) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT aqinvoices_fk_shipmentcost_budgetid FOREIGN KEY (shipmentcost_budgetid) REFERENCES aqbudgets (budget_id) ON DELETE SET NULL ON UPDATE CASCADE + ) ENGINE=InnoDB DEFAULT CHARSET=utf8 + "); + + # Fill this new table with existing invoices + my $sth = $dbh->prepare(" + SELECT aqorders.booksellerinvoicenumber AS invoicenumber, aqbasket.booksellerid, aqorders.datereceived + FROM aqorders + LEFT JOIN aqbasket ON aqorders.basketno = aqbasket.basketno + WHERE aqorders.booksellerinvoicenumber IS NOT NULL + AND aqorders.booksellerinvoicenumber != '' + GROUP BY aqorders.booksellerinvoicenumber + "); + $sth->execute; + my $results = $sth->fetchall_arrayref({}); + $sth = $dbh->prepare(" + INSERT INTO aqinvoices (invoicenumber, booksellerid, shipmentdate) VALUES (?,?,?) + "); + foreach(@$results) { + $sth->execute($_->{invoicenumber}, $_->{booksellerid}, $_->{datereceived}); + } + + # Add the column in aqorders, fill it with correct value + # and then drop booksellerinvoicenumber column + $dbh->do(" + ALTER TABLE aqorders + ADD COLUMN invoiceid int(11) default NULL AFTER booksellerinvoicenumber, + ADD CONSTRAINT aqorders_ibfk_3 FOREIGN KEY (invoiceid) REFERENCES aqinvoices (invoiceid) ON DELETE SET NULL ON UPDATE CASCADE + "); + + $dbh->do(" + UPDATE aqorders, aqinvoices + SET aqorders.invoiceid = aqinvoices.invoiceid + WHERE aqorders.booksellerinvoicenumber = aqinvoices.invoicenumber + "); + + $dbh->do(" + ALTER TABLE aqorders + DROP COLUMN booksellerinvoicenumber + "); + + print "Upgrade to $DBversion done (Add aqinvoices table) \n"; + SetVersion ($DBversion); +} + + =head1 FUNCTIONS =head2 TableExists($table) diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/acquisitions-menu.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/acquisitions-menu.inc index ac1a7a4ffd..439118d3d1 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/acquisitions-menu.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/acquisitions-menu.inc @@ -1,6 +1,7 @@
  • Late orders
  • [% IF ( suggestion ) %]
  • Suggestions
  • [% ELSE %][% END %] +
  • Invoices
  • [% IF ( CAN_user_acquisition_budget_manage ) %]
  • Budgets
  • Funds
  • diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/biblio-view-menu.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/biblio-view-menu.inc index 903cf3a758..b2edbe6ef0 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/biblio-view-menu.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/biblio-view-menu.inc @@ -25,7 +25,7 @@ [% END %] [% IF ( EasyAnalyticalRecords ) %][% IF ( analyze ) %]
  • [% ELSE %]
  • [% END %]Analytics
  • [% END %] - [% IF ( subscriptionsnumber ) %]
  • Subscription(s)
  • [% END %] + [% IF ( subscriptionsnumber ) %]
  • Subscription(s)
  • [% END %]
    [% IF ( issuehistoryview ) %]
  • [% ELSE %]
  • [% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/search_indexes.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/search_indexes.inc index 241321619d..09e748b556 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/search_indexes.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/search_indexes.inc @@ -13,6 +13,11 @@ + [% IF ( expanded_options ) %] + + + + [% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/serials-search.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/serials-search.inc index dfb908fc33..beb309c5fe 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/serials-search.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/serials-search.inc @@ -1,35 +1,37 @@
    -

    [% LibraryName %]

    -
    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 ef720e0bd0..5659c1dc7c 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/histsearch.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/histsearch.tt @@ -98,7 +98,11 @@
    [% suggestions_loo.author %]
    [% suggestions_loo.isbn %] [% suggestions_loo.name %] [% suggestions_loo.creationdate | $KohaDates %] - [% suggestions_loo.datereceived | $KohaDates %] + + [% IF suggestions_loo.datereceived %] + [% suggestions_loo.datereceived | $KohaDates %] + [% END %] + [% suggestions_loo.quantity %] [% suggestions_loo.ecost %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/invoice.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/invoice.tt new file mode 100644 index 0000000000..c03a4d7af1 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/invoice.tt @@ -0,0 +1,173 @@ +[% USE KohaDates %] + +[% INCLUDE 'doc-head-open.inc' %] +Koha › Acquisitions › Invoice + +[% INCLUDE 'doc-head-close.inc' %] +[% INCLUDE 'calendar.inc' %] + +[% INCLUDE 'datatables-strings.inc' %] + + + + + +[% INCLUDE 'header.inc' %] +[% INCLUDE 'acquisitions-search.inc' %] + + + +
    + +
    +
    +
    + [% IF ( modified ) %] +
    +

    Invoice has been modified

    +
    + [% END %] +

    Invoice: [% invoicenumber %]

    + +

    Supplier: [% suppliername %]

    +
    + + +

    + + +

    + + + + + + +
    + +
    +
    +

    Status: + [% IF ( invoiceclosedate ) %] + Closed on [% invoiceclosedate | $KohaDates %]. + + Reopen + + [% ELSE %] + Open. + + Close + + [% END %] +

    +

    + Go to receipt page +

    +

    Invoice details

    + [% IF orders_loop.size %] + + + + + + + + + + + + + + + [% FOREACH order IN orders_loop %] + + + + + + + + + + + [% END %] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    SummaryPublisherBranchRRPEst.Qty.TotalFund

    [% order.title %] + [% IF ( order.author ) %] +
    by [% order.author %] + [% END %] +

    + [% IF ( order.publishercode ) %] +

    [% order.publishercode %] + [% IF ( order.publicationyear ) %] + - [% order.publicationyear %] + [% END %] +

    + [% END %] +

    [% order.branchcode %]

    [% order.rrp %][% order.ecost %][% order.quantity %][% order.total %][% order.budget_name %]
    Total Tax Exc.[% total_rrp_gste %] [% total_quantity %][% total_est_gste %] 
    Tax ([% gist %]%)[% gist_rrp %]  [% gist_est %] 
    Total Tax Inc. ([% currency %])[% total_rrp_gsti %] [% total_quantity %][% total_est_gsti %] 
    Total + Shipment cost ([% currency %])  [% total_quantity %][% total_gsti_shipment %] 
    + [% ELSE %] +

    No orders yet

    + [% END %] +
    +
    +
    + [% INCLUDE 'acquisitions-menu.inc' %] +
    +
    +[% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/invoices.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/invoices.tt new file mode 100644 index 0000000000..c324882556 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/invoices.tt @@ -0,0 +1,232 @@ +[% USE KohaDates %] + +[% INCLUDE 'doc-head-open.inc' %] +Koha › Acquisitions › Invoices + +[% INCLUDE 'doc-head-close.inc' %] + +[% INCLUDE 'datatables-strings.inc' %] + +[% INCLUDE 'calendar.inc' %] + + + + +[% INCLUDE 'header.inc' %] +[% INCLUDE 'acquisitions-search.inc' %] + + + +
    + +
    +
    +
    +

    Invoices

    + [% IF ( do_search ) %] + [% IF ( results_loop ) %] + + + + + + + + + + + + + + [% FOREACH result IN results_loop %] + + + + + + + + + + [% END %] + +
    Invoice no.VendorBilling dateReceived bibliosReceived itemsStatus 
    [% result.invoicenumber %][% result.suppliername %] + [% IF (result.billingdate) %] + [% result.billingdate | $KohaDates %] + [% END %] + [% result.receivedbiblios %][% result.receiveditems %] + [% IF ( result.closedate ) %] + Closed on [% result.closedate | $KohaDates %] + [% ELSE %] + Open + [% END %] + + Details / + [% IF ( result.closedate ) %] + Reopen + [% ELSE %] + Close + [% END %] +
    + [% ELSE %] +

    Sorry, but there is no results for your search.

    +

    Search was: +

      + [% IF ( invoicenumber ) %] +
    • Invoice no.: [% invoicenumber %]
    • + [% END %] + [% IF ( supplier ) %] +
    • Vendor: [% suppliername %]
    • + [% END %] + [% IF ( billingdatefrom ) %] +
    • Billing date: + [% IF ( billingdateto ) %] + From [% billingdatefrom %] + To [% billingdateto %] + [% ELSE %] + All since [% billingdatefrom %] + [% END %] +
    • + [% ELSE %] + [% IF ( billingdateto ) %] +
    • Billing date: + All until [% billingdateto %] +
    • + [% END %] + [% END %] + [% IF ( isbneanissn ) %] +
    • ISBN/EAN/ISSN: [% isbneanissn %]
    • + [% END %] + [% IF ( title ) %] +
    • Title: [% title %]
    • + [% END %] + [% IF ( author ) %] +
    • Author: [% author %]
    • + [% END %] + [% IF ( publisher ) %] +
    • Publisher: [% publisher %]
    • + [% END %] + [% IF ( publicationyear ) %] +
    • Publication year: [% publicationyear %]
    • + [% END %] + [% IF ( branch ) %] +
    • Branch: [% branchname %]
    • + [% END %] +
    +

    + [% END %] + [% ELSE %] +

    Please fill in the form to the left to make a search.

    + [% END %] +
    +
    +
    +
    +
    +

    Search filters

    +
      +
    1. + + +
    2. +
    3. + + +
    4. +
    5. +
      + Shipment date +
        +
      1. + + +
      2. +
      3. + + +
      4. +
      +
      +
    6. +
    7. +
      + Billing date +
        +
      1. + + +
      2. +
      3. + + +
      4. +
      +
      +
    8. +
    9. + + +
    10. +
    11. + + +
    12. +
    13. + + +
    14. +
    15. + + +
    16. +
    17. + + +
    18. +
    19. + + +
    20. +
    +
    + +
    +
    + +
    + [% INCLUDE 'acquisitions-menu.inc' %] +
    +
    +[% INCLUDE 'intranet-bottom.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 1e19f8b083..612b5bcdf9 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/orderreceive.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/orderreceive.tt @@ -258,11 +258,11 @@ [% END %] [% END %] + -
    @@ -318,13 +318,12 @@ [% END %]
  • - [% ELSE %]
    @@ -341,7 +340,7 @@ [% loo.basketno %] [% loo.isbn %] - [% loo.title |html %] + [% loo.title |html %] [% loo.author %] [% loo.quantity %] [% loo.quantityreceived %] 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 d8ff600c4a..554f0afff1 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/parcel.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/parcel.tt @@ -45,6 +45,7 @@ null, null, null, + null ], "sPaginationType": "four_button" } ) ); @@ -125,11 +126,17 @@ [% INCLUDE 'header.inc' %] [% INCLUDE 'acquisitions-search.inc' %] - +
    @@ -185,8 +192,9 @@

    Invoice number: [% invoice %] Received by: [% loggedinusername %] On: [% formatteddatereceived %]

    - +

    Go to invoice details

    +[% UNLESS (invoiceclosedate) %] +
    +[% ELSE %] +

    + Invoice is close, so you can't receive orders. + Reopen it. +

    +[% END %] +

    Already received

    @@ -378,7 +393,7 @@ Can't cancel receipt [% ELSE %] - Cancel receipt + Cancel receipt [% END %] 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 5374c8ca23..616139c4c7 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/parcels.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/parcels.tt @@ -27,7 +27,12 @@
    - + +[% IF ( error_failed_to_create_invoice ) %] +
    +

    An error has occured. Invoice cannot be created.

    +
    +[% END %]

    Receive shipment from vendor [% name %]

    [% IF ( count ) %] @@ -58,11 +63,14 @@ [% searchresult.number %] - - [% searchresult.datereceived %] + [% searchresult.datereceived %] - [% IF ( searchresult.code ) %][% searchresult.code %][% ELSE %]n/a[% END %] + [% IF ( searchresult.code ) %] + [% searchresult.code %] + [% ELSE %] + n/a + [% END %] [% searchresult.reccount %] @@ -98,7 +106,7 @@ [% END %]
    -
    +
    Receive a new shipment
    1. @@ -118,9 +126,24 @@
    2. --> -
    3. - -
      [% INCLUDE 'date-format.inc' %]
    4. +
    5. + + +
      [% INCLUDE 'date-format.inc' %]
      +
    6. +
    7. + + +
    8. +
    9. + + +
    Cancel
    @@ -138,10 +161,10 @@


  • [% IF ( areas ) %] - Filter by area [% FOREACH area IN areas %] [% IF ( area.selected ) %] @@ -103,7 +103,7 @@
    1. - [% FOREACH area IN areas %] [% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/guided_reports_start.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/guided_reports_start.tt index 21d8235d5c..aa6a6271be 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/guided_reports_start.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/reports/guided_reports_start.tt @@ -24,6 +24,25 @@ + [% END %] +
    2. +
    3. + [% END %]
    @@ -553,6 +604,11 @@ canned reports and writing custom SQL reports.

    [% END %] [% IF ( create ) %] +
    Create report from SQL @@ -561,6 +617,31 @@ canned reports and writing custom SQL reports.

    [% IF ( reportname ) %] [% ELSE %][% END %]
  • + [% IF groups_with_subgroups %] +
  • +
  • + [% END %] [% IF (public) %]
  • [% ELSE %] @@ -645,6 +726,11 @@ Sub report: @@ -652,6 +738,31 @@ Sub report: + [% IF groups_with_subgroups %] +
  • +
  • + [% END %] [% IF (public) %]
  • [% ELSE %] @@ -719,12 +830,43 @@ Sub report:

    Filter

      +
    1. + + +
    2. [% INCLUDE 'date-format.inc' %]
      diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/serials/serial-issues.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/serials/serial-issues.tt index a22b97b47c..7bc9feb763 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/serials/serial-issues.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/serials/serial-issues.tt @@ -16,7 +16,7 @@

      Subscription information for [% bibliotitle %]

      diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/serials/serials-home.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/serials/serials-home.tt index a0cd35efdd..eaafc944f7 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/serials/serials-home.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/serials/serials-home.tt @@ -1,168 +1,23 @@ [% INCLUDE 'doc-head-open.inc' %] [% USE KohaDates %] Koha › Serials [% biblionumber %] - [% INCLUDE 'doc-head-close.inc' %] - -[% INCLUDE 'datatables-strings.inc' %] - - [% INCLUDE 'header.inc' %] [% INCLUDE 'serials-search.inc' %] - +
      - -
      -
      -
      - [% INCLUDE 'serials-toolbar.inc' %] - -[% IF ( information ) %] -Serials updated : - - - - - - - - -[% FOREACH informatio IN information %] - - - - - - - -[% END %] -
      - Serialseq - - Status - - Published date - - Planned date - - Notes -
      - [% informatio.serialseq %] - - [% informatio.status %] - - [% informatio.publisheddate %] - - [% informatio.planneddate %] - - [% informatio.notes %] -
      -[% END %] - [% IF ( done_searched ) %] -

      Serials subscriptions

      - - - - - - - - - - - [% IF ( routing && CAN_user_serials_routing ) %] - - [% END %] - - - - - - - - - - - - - [% IF ( routing && CAN_user_serials_routing ) %][% END %] - - - - - - [% FOREACH subscription IN subscriptions %] - - - - - - - - [% IF ( routing && CAN_user_serials_routing ) %] - - [% END %] - - - - [% END %] - -
      ISSNTitle Notes LibraryCall numberExpiration dateRouting list  
      - [% IF ( subscription.issn ) %][% subscription.issn %] - [% END %] - [% subscription.title |html %] - [% IF ( subscription.notes ) %][% subscription.notes %][% END %] - [% IF ( subscription.internalnotes ) %]([% subscription.internalnotes %])[% END %] - - [% IF ( subscription.branchname ) %][% subscription.branchname %][% END %] - - [% IF ( subscription.callnumber ) %][% subscription.callnumber %][% END %] - - [% IF ( subscription.enddate ) %][% subscription.enddate | $KohaDates %][% END %] - - [% IF ( subscription.cannotedit ) %] -   - [% ELSE %] - [% IF ( subscription.routingedit ) %] - Edit - ([% subscription.routingedit %]) - [% ELSE %] - New - [% END %] - [% END %] - Issue history - - [% IF ( subscription.cannotedit ) %] -   - [% ELSE %] - [% IF ( CAN_user_serials_receive_serials ) %]Serial receive[% END %] - [% END %] -
      - - [% END %] - -
      -
      - -
      -[% INCLUDE 'serials-menu.inc' %] -
      +
      +
      +
      + [% INCLUDE 'serials-toolbar.inc' %] +
      +
      +
      + [% INCLUDE 'serials-menu.inc' %] +
      [% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/serials/serials-search.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/serials/serials-search.tt new file mode 100644 index 0000000000..b5e7f542cf --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/serials/serials-search.tt @@ -0,0 +1,185 @@ +[% INCLUDE 'doc-head-open.inc' %] +[% USE KohaDates %] +Koha › Serials [% biblionumber %] + +[% INCLUDE 'doc-head-close.inc' %] + +[% INCLUDE 'datatables-strings.inc' %] + + + + +[% INCLUDE 'header.inc' %] +[% INCLUDE 'serials-search.inc' %] + + + +
      +
      +
      +
      + [% INCLUDE 'serials-toolbar.inc' %] + +

      Serials subscriptions

      + +
      + +
      + + Search subscriptions + + [% IF ( done_searched ) %] +
      + +
      + + [% IF ( done_searched ) %] + [% IF ( subscriptions ) %] + + + + + + + + + + [% IF ( routing && CAN_user_serials_routing ) %] + + [% END %] + + + + + + + + + + + + + [% IF ( routing && CAN_user_serials_routing ) %][% END %] + + + + + + [% FOREACH subscription IN subscriptions %] + + + + + + + + [% IF ( routing && CAN_user_serials_routing ) %] + + [% END %] + + + + [% END %] + +
      ISSNTitle Notes LibraryCall numberExpiration dateRouting list  
      + [% IF ( subscription.issn ) %][% subscription.issn %] + [% END %] + [% subscription.title |html %] + [% IF ( subscription.notes ) %][% subscription.notes %][% END %] + [% IF ( subscription.internalnotes ) %]([% subscription.internalnotes %])[% END %] + + [% IF ( subscription.branchname ) %][% subscription.branchname %][% END %] + + [% IF ( subscription.callnumber ) %][% subscription.callnumber %][% END %] + + [% IF ( subscription.enddate ) %][% subscription.enddate | $KohaDates %][% END %] + + [% IF ( subscription.cannotedit ) %] +   + [% ELSE %] + [% IF ( subscription.routingedit ) %] + Edit + ([% subscription.routingedit %]) + [% ELSE %] + New + [% END %] + [% END %] + Issue history + + [% IF ( subscription.cannotedit ) %] +   + [% ELSE %] + [% IF ( CAN_user_serials_receive_serials ) %]Serial receive[% END %] + [% END %] +
      + [% ELSE %] + There is no subscription for your search. + [% END %] + [% END %] +
      +
      + +
      + [% INCLUDE 'serials-menu.inc' %] +
      +
      +[% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/opac-tmpl/prog/en/css/opac.css b/koha-tmpl/opac-tmpl/prog/en/css/opac.css index 2c756e843a..e13c2e28d5 100644 --- a/koha-tmpl/opac-tmpl/prog/en/css/opac.css +++ b/koha-tmpl/opac-tmpl/prog/en/css/opac.css @@ -2706,6 +2706,10 @@ ul.ui-tabs-nav li { display: inline-block; } +.authlink { + padding-left: 0.25em; +} + /* jQuery UI Datepicker */ .ui-datepicker table {width: 100%; font-size: .9em; border : 0; border-collapse: collapse; margin:0 0 .4em; } .ui-datepicker th { background : transparent none; padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-advsearch.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-advsearch.tt index 6ed2b86710..cca5d0de01 100644 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-advsearch.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-advsearch.tt @@ -67,8 +67,11 @@