@@ -, +, @@ - No. of ordered titles - No. of received titles - Date closed on the left (Edit, Close and export as PDF, View, Reopen, Export as CSV) --- C4/Acquisition.pm | 8 +- Koha/Acquisition/Basket.pm | 22 +++ Koha/Acquisition/Basketgroup.pm | 133 +++++++++++++ Koha/Acquisition/Basketgroups.pm | 50 +++++ acqui/basket.pl | 4 +- acqui/basketgroup.pl | 187 +++++++++--------- acqui/basketgroups.pl | 52 +++++ .../prog/en/includes/acquisitions-menu.inc | 3 + .../prog/en/includes/datatables.inc | 2 + .../prog/en/includes/vendor-menu.inc | 2 +- .../prog/en/modules/acqui/basketgroup.tt | 132 ++----------- .../prog/en/modules/acqui/basketgroups.tt | 163 +++++++++++++++ .../intranet-tmpl/prog/js/basketgroup.js | 8 - koha-tmpl/intranet-tmpl/prog/js/datatables.js | 95 ++++++--- 14 files changed, 614 insertions(+), 247 deletions(-) create mode 100644 Koha/Acquisition/Basketgroup.pm create mode 100644 Koha/Acquisition/Basketgroups.pm create mode 100755 acqui/basketgroups.pl create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basketgroups.tt --- a/C4/Acquisition.pm +++ a/C4/Acquisition.pm @@ -1510,7 +1510,9 @@ sub ModReceiveOrder { $order->{datereceived} = $datereceived; $order->{invoiceid} = $invoice->{invoiceid}; $order->{orderstatus} = 'complete'; - $new_ordernumber = Koha::Acquisition::Order->new($order)->store->ordernumber; # TODO What if the store fails? + my @columns = Koha::Acquisition::Orders->columns; + my %filtered_order = map { exists $order->{$_} ? ($_ => $order->{$_}) : () } @columns; + $new_ordernumber = Koha::Acquisition::Order->new(\%filtered_order)->store->ordernumber; if ($received_items) { foreach my $itemnumber (@$received_items) { @@ -2008,7 +2010,9 @@ sub TransferOrder { delete $order->{parent_ordernumber}; $order->{'basketno'} = $basketno; - my $newordernumber = Koha::Acquisition::Order->new($order)->store->ordernumber; + my @columns = Koha::Acquisition::Orders->columns; + my %filtered_order = map { exists $order->{$_} ? ($_ => $order->{$_}) : () } @columns; + my $newordernumber = Koha::Acquisition::Order->new(\%filtered_order)->store->ordernumber; $query = q{ UPDATE aqorders_items --- a/Koha/Acquisition/Basket.pm +++ a/Koha/Acquisition/Basket.pm @@ -21,6 +21,7 @@ use Modern::Perl; use Koha::Database; use Koha::Acquisition::BasketGroups; +use Koha::Acquisition::Orders; use base qw( Koha::Object ); @@ -71,6 +72,27 @@ sub effective_create_items { return $self->create_items || C4::Context->preference('AcqCreateItem'); } +=head3 orders + +Returns basket's orders + + # As an arrayref + my $orders = $basket->orders; + + # As an array + my @orders = $basket->orders; + +=cut + +sub orders { + my ($self) = @_; + + $self->{_orders} ||= Koha::Acquisition::Orders->search({ basketno => $self->basketno }); + + return wantarray ? $self->{_orders}->as_list : $self->{_orders}; +} + + =head2 Internal methods =head3 _type --- a/Koha/Acquisition/Basketgroup.pm +++ a/Koha/Acquisition/Basketgroup.pm @@ -0,0 +1,133 @@ +package Koha::Acquisition::Basketgroup; + +# 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 3 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. + +use Modern::Perl; + +use List::MoreUtils qw/uniq/; + +use Koha::Acquisition::Baskets; + +use base qw(Koha::Object); + +=head1 NAME + +Koha::Acquisition::Basketgroup + +=head1 API + +=head2 Methods + +=head3 bookseller + +Returns the basketgroup's bookseller (Koha::Acquisition::Bookseller) + + my $bookseller = $basketgroup->bookseller; + +=cut + +sub bookseller { + my ($self) = @_; + + return scalar Koha::Acquisition::Booksellers->find($self->booksellerid); +} + +=head3 baskets + +Returns the basketgroup's baskets + + my $baskets = $basketgroup->baskets; # Koha::Acquisition::Baskets + my @baskets = $basketgroup->baskets; # array of Koha::Acquisition::Basket + +=cut + +sub baskets { + my ($self) = @_; + + $self->{_baskets} ||= Koha::Acquisition::Baskets->search({ basketgroupid => $self->id }); + + return wantarray ? $self->{_baskets}->as_list : $self->{_baskets}; +} + +=head3 baskets_count + +Returns the number of baskets contained in a basket group + + my $count = $basketgroup->baskets_count; + +=cut + +sub baskets_count { + my ($self) = @_; + + return $self->baskets->count; +} + +=head3 ordered_titles_count + +Returns the number of ordered titles contained in a basket group + + my $count = $basketgroup->ordered_titles_count; + +=cut + +sub ordered_titles_count { + my ($self) = @_; + + my @biblionumbers; + foreach my $basket ($self->baskets) { + foreach my $order ($basket->orders) { + push @biblionumbers, $order->biblionumber; + } + } + + return scalar uniq @biblionumbers; +} + +=head3 received_titles_count + +Returns the number of received titles contained in a basket group + + my $count = $basketgroup->ordered_titles_count; + +=cut + +sub received_titles_count { + my ($self) = @_; + + my @biblionumbers; + foreach my $basket ($self->baskets) { + foreach my $order ($basket->orders) { + if ($order->datereceived) { + push @biblionumbers, $order->biblionumber; + } + } + } + + return scalar uniq @biblionumbers; +} + +=head2 Internal Methods + +=head3 _type + +=cut + +sub _type { + return 'Aqbasketgroup'; +} + +1; --- a/Koha/Acquisition/Basketgroups.pm +++ a/Koha/Acquisition/Basketgroups.pm @@ -0,0 +1,50 @@ +package Koha::Acquisition::Basketgroups; + +# 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 3 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. + +use Modern::Perl; + +use Koha::Acquisition::Basketgroup; + +use base qw(Koha::Objects); + +=head1 NAME + +Koha::Acquisition::Basketgroups + +=head1 API + +=head2 Internal methods + +=cut + +=head3 _type + +=cut + +sub _type { + return 'Aqbasketgroup'; +} + +=head3 object_class + +=cut + +sub object_class { + return 'Koha::Acquisition::Basketgroup'; +} + +1; --- a/acqui/basket.pl +++ a/acqui/basket.pl @@ -207,7 +207,7 @@ if ( $op eq 'delete_confirm' ) { }); ModBasket( { basketno => $basketno, basketgroupid => $basketgroupid } ); - print $query->redirect('/cgi-bin/koha/acqui/basketgroup.pl?booksellerid='.$booksellerid.'&closed=1'); + print $query->redirect('/cgi-bin/koha/acqui/basketgroups.pl?booksellerid='.$booksellerid); } else { print $query->redirect('/cgi-bin/koha/acqui/booksellers.pl?booksellerid=' . $booksellerid); } @@ -554,7 +554,7 @@ sub edi_close_and_order { } ); print $query->redirect( -"/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=$booksellerid&closed=1" + "/cgi-bin/koha/acqui/basketgroups.pl?booksellerid=$booksellerid" ); } else { --- a/acqui/basketgroup.pl +++ a/acqui/basketgroup.pl @@ -58,6 +58,8 @@ use Koha::Acquisition::Booksellers; use Koha::ItemTypes; use Koha::Patrons; +use List::MoreUtils qw/uniq/; + our $input=new CGI; our ($template, $loggedinuser, $cookie) @@ -87,9 +89,7 @@ sub BasketTotal { #displays all basketgroups and all closed baskets (in their respective groups) sub displaybasketgroups { - my $basketgroups = shift; - my $bookseller = shift; - my $baskets = shift; + my ($basketgroups, $bookseller, $baskets, $template) = @_; if (scalar @$basketgroups != 0) { foreach my $basketgroup (@$basketgroups){ my $i = 0; @@ -123,29 +123,31 @@ sub displaybasketgroups { sub printbasketgrouppdf{ my ($basketgroupid) = @_; - + my $pdfformat = C4::Context->preference("OrderPdfFormat"); if ($pdfformat eq 'pdfformat::layout3pages' || $pdfformat eq 'pdfformat::layout2pages' || $pdfformat eq 'pdfformat::layout3pagesfr' || $pdfformat eq 'pdfformat::layout2pagesde'){ - eval { - eval "require $pdfformat"; - import $pdfformat; - }; - if ($@){ - } + eval { + my $pdfformatfile = './' . ($pdfformat =~ s,::,/,gr) . '.pm'; + require $pdfformatfile; + import $pdfformat; + }; + if ($@){ + warn $@; + } } else { - print $input->header; - print $input->start_html; # FIXME Should do a nicer page - print "

Invalid PDF Format set

"; - print "Please go to the systempreferences and set a valid pdfformat"; - exit; + print $input->header; + print $input->start_html; # FIXME Should do a nicer page + print "

Invalid PDF Format set

"; + print "Please go to the systempreferences and set a valid pdfformat"; + exit; } - + my $basketgroup = GetBasketgroup($basketgroupid); my $bookseller = Koha::Acquisition::Booksellers->find( $basketgroup->{booksellerid} ); my $baskets = GetBasketsByBasketgroup($basketgroupid); - + my %orders; for my $basket (@$baskets) { my @ba_orders; @@ -212,7 +214,6 @@ sub printbasketgrouppdf{ ); my $pdf = printpdf($basketgroup, $bookseller, $baskets, \%orders, $bookseller->tax_rate // C4::Context->preference("gist")) || die "pdf generation failed"; print $pdf; - } sub generate_edifact_orders { @@ -226,70 +227,25 @@ sub generate_edifact_orders { return; } -my $op = $input->param('op') || 'display'; # possible values of $op : -# - add : adds a new basketgroup, or edit an open basketgroup, or display a closed basketgroup # - mod_basket : modify an individual basket of the basketgroup -# - closeandprint : close and print an closed basketgroup in pdf. called by clicking on "Close and print" button in closed basketgroups list -# - print : print a closed basketgroup. called by clicking on "Print" button in closed basketgroups list +# - closeandprint : close and print an closed basketgroup in pdf. called by +# clicking on "Close and print" button in closed basketgroups list +# - print : print a closed basketgroup. called by clicking on "Print" button in +# closed basketgroups list # - ediprint : generate edi order messages for the baskets in the group -# - export : export in CSV a closed basketgroup. called by clicking on "Export" button in closed basketgroups list -# - delete : delete an open basketgroup. called by clicking on "Delete" button in open basketgroups list -# - reopen : reopen a closed basketgroup. called by clicking on "Reopen" button in closed basketgroup list -# - attachbasket : save a modified basketgroup, or creates a new basketgroup when a basket is closed. called from basket page -# - display : display the list of all basketgroups for a vendor +# - export : export in CSV a closed basketgroup. called by clicking on "Export" +# button in closed basketgroups list +# - delete : delete an open basketgroup. called by clicking on "Delete" button +# in open basketgroups list +# - reopen : reopen a closed basketgroup. called by clicking on "Reopen" button +# in closed basketgroup list +# - attachbasket : save a modified basketgroup, or creates a new basketgroup +# when a basket is closed. called from basket page +my $op = $input->param('op'); my $booksellerid = $input->param('booksellerid'); -$template->param(booksellerid => $booksellerid); -if ( $op eq "add" ) { -# -# if no param('basketgroupid') is not defined, adds a new basketgroup -# else, edit (if it is open) or display (if it is close) the basketgroup basketgroupid -# the template will know if basketgroup must be displayed or edited, depending on the value of closed key -# - my $bookseller = Koha::Acquisition::Booksellers->find( $booksellerid ); - my $basketgroupid = $input->param('basketgroupid'); - my $billingplace; - my $deliveryplace; - my $freedeliveryplace; - if ( $basketgroupid ) { - # Get the selected baskets in the basketgroup to display them - my $selecteds = GetBasketsByBasketgroup($basketgroupid); - foreach my $basket(@{$selecteds}){ - $basket->{total} = BasketTotal($basket->{basketno}, $bookseller); - } - $template->param(basketgroupid => $basketgroupid, - selectedbaskets => $selecteds); - - # Get general informations about the basket group to prefill the form - my $basketgroup = GetBasketgroup($basketgroupid); - $template->param( - name => $basketgroup->{name}, - deliverycomment => $basketgroup->{deliverycomment}, - freedeliveryplace => $basketgroup->{freedeliveryplace}, - ); - $billingplace = $basketgroup->{billingplace}; - $deliveryplace = $basketgroup->{deliveryplace}; - $freedeliveryplace = $basketgroup->{freedeliveryplace}; - $template->param( closedbg => ($basketgroup ->{'closed'}) ? 1 : 0); - } else { - $template->param( closedbg => 0); - } - # determine default billing and delivery places depending on librarian homebranch and existing basketgroup data - my $patron = Koha::Patrons->find( $loggedinuser ); # FIXME Not needed if billingplace and deliveryplace are set - $billingplace = $billingplace || $patron->branchcode; - $deliveryplace = $deliveryplace || $patron->branchcode; - - $template->param( billingplace => $billingplace ); - $template->param( deliveryplace => $deliveryplace ); - $template->param( booksellerid => $booksellerid ); - - # the template will display a unique basketgroup - $template->param(grouping => 1); - my $basketgroups = &GetBasketgroups($booksellerid); - my $baskets = &GetBasketsByBookseller($booksellerid); - displaybasketgroups($basketgroups, $bookseller, $baskets); -} elsif ($op eq 'mod_basket') { +if ($op eq 'mod_basket') { # # edit an individual basket contained in this basketgroup # @@ -330,7 +286,8 @@ if ( $op eq "add" ) { # my $basketgroupid = $input->param('basketgroupid'); DelBasketgroup($basketgroupid); - print $input->redirect('/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=' . $booksellerid.'&listclosed=1'); + print $input->redirect('/cgi-bin/koha/acqui/basketgroups.pl?booksellerid=' . $booksellerid); + exit; }elsif ( $op eq 'reopen'){ # # reopen a closed basketgroup @@ -338,8 +295,15 @@ if ( $op eq "add" ) { my $basketgroupid = $input->param('basketgroupid'); my $booksellerid = $input->param('booksellerid'); ReOpenBasketgroup($basketgroupid); - my $redirectpath = ((defined $input->param('mode'))&& ($input->param('mode') eq 'singlebg')) ?'/cgi-bin/koha/acqui/basketgroup.pl?op=add&basketgroupid='.$basketgroupid.'&booksellerid='.$booksellerid : '/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=' .$booksellerid.'&listclosed=1'; + my $redirectpath; + my $mode = $input->param('mode'); + if (defined $mode && $mode eq 'singlebg') { + $redirectpath = '/cgi-bin/koha/acqui/basketgroup.pl?op=add&basketgroupid='.$basketgroupid.'&booksellerid='.$booksellerid; + } else { + $redirectpath = '/cgi-bin/koha/acqui/basketgroups.pl?booksellerid=' .$booksellerid; + } print $input->redirect($redirectpath); + exit; } elsif ( $op eq 'attachbasket') { # # save a modified basketgroup, or creates a new basketgroup when a basket is closed. called from basket page @@ -385,22 +349,63 @@ if ( $op eq "add" ) { }; $basketgroupid = NewBasketgroup($basketgroup); } - my $redirectpath = ((defined $input->param('mode')) && ($input->param('mode') eq 'singlebg')) ?'/cgi-bin/koha/acqui/basketgroup.pl?op=add&basketgroupid='.$basketgroupid.'&booksellerid='.$booksellerid : '/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=' . $booksellerid; - $redirectpath .= "&listclosed=1" if $closedbg ; - print $input->redirect($redirectpath ); - + my $redirectpath; + my $mode = $input->param('mode'); + if (defined $mode && $mode eq 'singlebg') { + $redirectpath = '/cgi-bin/koha/acqui/basketgroup.pl?op=add&basketgroupid='.$basketgroupid.'&booksellerid='.$booksellerid; + } else { + $redirectpath = '/cgi-bin/koha/acqui/basketgroups.pl?booksellerid=' . $booksellerid; + } + print $input->redirect($redirectpath); + exit; } elsif ( $op eq 'ediprint') { my $basketgroupid = $input->param('basketgroupid'); generate_edifact_orders( $basketgroupid ); exit; -}else{ -# no param : display the list of all basketgroups for a given vendor - my $basketgroups = &GetBasketgroups($booksellerid); - my $bookseller = Koha::Acquisition::Booksellers->find( $booksellerid ); - my $baskets = &GetBasketsByBookseller($booksellerid); +} - displaybasketgroups($basketgroups, $bookseller, $baskets); +# if no param('basketgroupid') is not defined, adds a new basketgroup else, edit +# (if it is open) or display (if it is close) the basketgroup basketgroupid the +# template will know if basketgroup must be displayed or edited, depending on +# the value of closed key + +my $bookseller = Koha::Acquisition::Booksellers->find($booksellerid); +my $basketgroupid = $input->param('basketgroupid'); +my $billingplace; +my $deliveryplace; +my $freedeliveryplace; +if ( $basketgroupid ) { + # Get the selected baskets in the basketgroup to display them + my $selecteds = GetBasketsByBasketgroup($basketgroupid); + foreach my $basket(@{$selecteds}){ + $basket->{total} = BasketTotal($basket->{basketno}, $bookseller); + } + $template->param(basketgroupid => $basketgroupid, + selectedbaskets => $selecteds); + + # Get general informations about the basket group to prefill the form + my $basketgroup = GetBasketgroup($basketgroupid); + $template->param( + name => $basketgroup->{name}, + billingplace => $basketgroup->{billingplace}, + deliveryplace => $basketgroup->{deliveryplace}, + deliverycomment => $basketgroup->{deliverycomment}, + freedeliveryplace => $basketgroup->{freedeliveryplace}, + closedbg => $basketgroup->{closed} ? 1 : 0 + ); +} else { + $template->param( closedbg => 0); } -$template->param(listclosed => ((defined $input->param('listclosed')) && ($input->param('listclosed') eq '1'))? 1:0 ); -#prolly won't use all these, maybe just use print, the rest can be done inside validate +# determine default billing and delivery places depending on librarian homebranch and existing basketgroup data +my $borrower = Koha::Patrons->find( $loggedinuser ); +$billingplace = $billingplace || $borrower->branchcode; +$deliveryplace = $deliveryplace || $borrower->branchcode; + +$template->param( booksellerid => $booksellerid ); + +# the template will display a unique basketgroup +my $basketgroups = &GetBasketgroups($booksellerid); +my $baskets = &GetBasketsByBookseller($booksellerid); +displaybasketgroups($basketgroups, $bookseller, $baskets, $template); + output_html_with_http_headers $input, $cookie, $template->output; --- a/acqui/basketgroups.pl +++ a/acqui/basketgroups.pl @@ -0,0 +1,52 @@ +#!/usr/bin/perl + +# 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 3 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, see . + +use Modern::Perl; + +use CGI qw(-utf8); + +use C4::Auth; +use C4::Output; + +use Koha::Acquisition::Basketgroups; +use Koha::Acquisition::Booksellers; + +my $cgi = new CGI; + +my ($template, $loggedinuser, $cookie) = get_template_and_user({ + template_name => 'acqui/basketgroups.tt', + query => $cgi, + type => 'intranet', + flagsrequired => { acquisition => 'group_manage' }, +}); + +my $booksellerid = $cgi->param('booksellerid'); + +my $params = {}; +if ($booksellerid) { + $params->{booksellerid} = $booksellerid; + my $bookseller = Koha::Acquisition::Booksellers->find($booksellerid); + $template->param(bookseller => $bookseller); +} + +my @basketgroups = Koha::Acquisition::Basketgroups->search($params); + +$template->param( + basketgroups => \@basketgroups, +); + +output_html_with_http_headers $cgi, $cookie, $template->output; --- a/koha-tmpl/intranet-tmpl/prog/en/includes/acquisitions-menu.inc +++ a/koha-tmpl/intranet-tmpl/prog/en/includes/acquisitions-menu.inc @@ -3,6 +3,9 @@
Acquisitions