From 3c83e117869e501275fffc88ac10c9e1aee92160 Mon Sep 17 00:00:00 2001 From: Blou Date: Thu, 26 Mar 2015 16:07:44 -0400 Subject: [PATCH] Bug 8612: Use CSV profile for exporting basket MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This patch allows the user to use a CSV export profile to create the fields to export the basket as CSV in a basket page. Test plan: 1) Apply the patch 2) Go to Tools › CSV export profiles and create a profile of type "SQL for basket export in acquisition" example: biblionumber=biblio.biblionumber|auteur=biblio.author|titre=biblio.title|date=biblioitems.copyrightdate|editeur=biblioitems.publishercode|isbn=biblioitems.isbn|quantite=aqorders.quantity|prix=aqorders.rrp|panier=aqorders.basketno 3) In acquisition module, create a new basket and add an order to the basket 4) On basket detail page, there should be the split button labelled "Export to CSV" 5) Try to use the button and export CSV with your CSV profile you defined in step 2 6) Validate the CSV file. 7) Repeat 4-6 with a closed basket. a) close the basket b) View the basket c) validate that there is an export button d) test it with an export 8) prove t/db_dependent/Acquisition/GetBasketAsCSV.t t/db_dependent/Koha/CsvProfiles.t Initial work: Sponsored by: CCSR Signed-off-by: Josef Moravec Signed-off-by: mehdi Signed-off-by: Marcel de Rooy Signed-off-by: Jonathan Druart --- C4/Acquisition.pm | 116 ++++++++++++------ acqui/basket.pl | 9 +- .../data/mysql/atomicupdate/bug_8612.sql | 1 + .../prog/en/modules/acqui/basket.tt | 39 +++++- .../prog/en/modules/tools/csv-profiles.tt | 36 +++--- serials/claims.pl | 2 +- t/db_dependent/Acquisition/GetBasketAsCSV.t | 76 ++++++++++++ t/db_dependent/Koha/CsvProfiles.t | 2 +- 8 files changed, 225 insertions(+), 56 deletions(-) create mode 100644 installer/data/mysql/atomicupdate/bug_8612.sql create mode 100644 t/db_dependent/Acquisition/GetBasketAsCSV.t diff --git a/C4/Acquisition.pm b/C4/Acquisition.pm index 4c2ead7281..22dee154dc 100644 --- a/C4/Acquisition.pm +++ b/C4/Acquisition.pm @@ -33,6 +33,7 @@ use Koha::Acquisition::Booksellers; use Koha::Biblios; use Koha::Number::Price; use Koha::Libraries; +use Koha::CsvProfiles; use C4::Koha; @@ -277,7 +278,7 @@ $cgi parameter is needed for column name translation =cut sub GetBasketAsCSV { - my ($basketno, $cgi) = @_; + my ($basketno, $cgi, $csv_profile_id) = @_; my $basket = GetBasket($basketno); my @orders = GetOrders($basketno); my $contract = GetContract({ @@ -285,48 +286,93 @@ sub GetBasketAsCSV { }); my $template = C4::Templates::gettemplate("acqui/csv/basket.tt", "intranet", $cgi); - my @rows; - foreach my $order (@orders) { - my $bd = GetBiblioData( $order->{'biblionumber'} ); - my $row = { - contractname => $contract->{'contractname'}, - ordernumber => $order->{'ordernumber'}, - entrydate => $order->{'entrydate'}, - isbn => $order->{'isbn'}, - author => $bd->{'author'}, - title => $bd->{'title'}, - publicationyear => $bd->{'publicationyear'}, - publishercode => $bd->{'publishercode'}, - collectiontitle => $bd->{'collectiontitle'}, - notes => $order->{'order_vendornote'}, - quantity => $order->{'quantity'}, - rrp => $order->{'rrp'}, - }; - for my $place ( qw( deliveryplace billingplace ) ) { - if ( my $library = Koha::Libraries->find( $row->{deliveryplace} ) ) { - $row->{$place} = $library->branchname + if ($csv_profile_id) { + my $csv_profile = Koha::CsvProfiles->find( $csv_profile_id ); + die "There is no valid csv profile given" unless $csv_profile; + + my $csv = Text::CSV_XS->new({'quote_char'=>'"','escape_char'=>'"','sep_char'=>$csv_profile->csv_separator,'binary'=>1}); + my $csv_profile_content = $csv_profile->content; + my ( @headers, @fields ); + while ( $csv_profile_content =~ / + ([^=]+) # header + = + ([^\|]+) # fieldname (table.row or row) + \|? /gxms + ) { + push @headers, $1; + my $field = $2; + $field =~ s/[^\.]*\.?//; # Remove the table name if exists. + push @fields, $field; + } + for my $order (@orders) { + my @row; + my $bd = GetBiblioData( $order->{'biblionumber'} ); + my @biblioitems = GetBiblioItemByBiblioNumber( $order->{'biblionumber'}); + for my $biblioitem (@biblioitems) { + if ($biblioitem->{isbn} eq $order->{isbn}) { + $order = {%$order, %$biblioitem}; + } + } + if ($contract) { + $order = {%$order, %$contract}; + } + $order = {%$order, %$basket, %$bd}; + for my $field (@fields) { + push @row, $order->{$field}; } + push @rows, \@row; } - foreach(qw( - contractname author title publishercode collectiontitle notes - deliveryplace billingplace - ) ) { - # Double the quotes to not be interpreted as a field end - $row->{$_} =~ s/"/""/g if $row->{$_}; + my $content = join( $csv_profile->csv_separator, @headers ) . "\n"; + for my $row ( @rows ) { + $csv->combine(@$row); + my $string = $csv->string; + $content .= $string . "\n"; } - push @rows, $row; + return $content; } + else { + foreach my $order (@orders) { + my $bd = GetBiblioData( $order->{'biblionumber'} ); + my $row = { + contractname => $contract->{'contractname'}, + ordernumber => $order->{'ordernumber'}, + entrydate => $order->{'entrydate'}, + isbn => $order->{'isbn'}, + author => $bd->{'author'}, + title => $bd->{'title'}, + publicationyear => $bd->{'publicationyear'}, + publishercode => $bd->{'publishercode'}, + collectiontitle => $bd->{'collectiontitle'}, + notes => $order->{'order_vendornote'}, + quantity => $order->{'quantity'}, + rrp => $order->{'rrp'}, + }; + for my $place ( qw( deliveryplace billingplace ) ) { + if ( my $library = Koha::Libraries->find( $row->{deliveryplace} ) ) { + $row->{$place} = $library->branchname + } + } + foreach(qw( + contractname author title publishercode collectiontitle notes + deliveryplace billingplace + ) ) { + # Double the quotes to not be interpreted as a field end + $row->{$_} =~ s/"/""/g if $row->{$_}; + } + push @rows, $row; + } - @rows = sort { - if(defined $a->{publishercode} and defined $b->{publishercode}) { - $a->{publishercode} cmp $b->{publishercode}; - } - } @rows; + @rows = sort { + if(defined $a->{publishercode} and defined $b->{publishercode}) { + $a->{publishercode} cmp $b->{publishercode}; + } + } @rows; - $template->param(rows => \@rows); + $template->param(rows => \@rows); - return $template->output; + return $template->output; + } } diff --git a/acqui/basket.pl b/acqui/basket.pl index 55aca4cf0d..779d64b9e4 100755 --- a/acqui/basket.pl +++ b/acqui/basket.pl @@ -40,6 +40,7 @@ use C4::Letters qw/SendAlerts/; use Date::Calc qw/Add_Delta_Days/; use Koha::Database; use Koha::EDI qw( create_edi_order get_edifact_ean ); +use Koha::CsvProfiles; =head1 NAME @@ -169,7 +170,12 @@ if ( $op eq 'delete_confirm' ) { -type => 'text/csv', -attachment => 'basket' . $basket->{'basketno'} . '.csv', ); - print GetBasketAsCSV($query->param('basketno'), $query); + if ( $query->param('csv_profile') eq 'default'){ + print GetBasketAsCSV($query->param('basketno'), $query); + } else { + my $csv_profile_id = $query->param('csv_profile'); + print GetBasketAsCSV($query->param('basketno'), $query, $csv_profile_id); + } exit; } elsif ($op eq 'email') { my $err = eval { @@ -425,6 +431,7 @@ if ( $op eq 'list' ) { unclosable => @orders ? $basket->{is_standing} : 1, has_budgets => $has_budgets, duplinbatch => $duplinbatch, + csv_profiles => [ Koha::CsvProfiles->search({ type => 'export_basket' }) ], ); } diff --git a/installer/data/mysql/atomicupdate/bug_8612.sql b/installer/data/mysql/atomicupdate/bug_8612.sql new file mode 100644 index 0000000000..37a643b346 --- /dev/null +++ b/installer/data/mysql/atomicupdate/bug_8612.sql @@ -0,0 +1 @@ +UPDATE export_format SET type = 'late_issues' WHERE type ='sql'; diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basket.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basket.tt index cc98f2385c..94c312ca25 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basket.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basket.tt @@ -1,3 +1,17 @@ +[% BLOCK csv_export %] +
+ Export as CSV + + +
+[% END %] [% USE KohaDates %] [% USE Branches %] [% USE Price %] @@ -121,6 +135,18 @@ e.preventDefault(); confirm_reopen(); }); + // Generates a dynamic link for exporting the selections data as CSV + $("#exportbutton, #export-csv-menu a").click(function() { + // Building the url from currently checked boxes + var url = '/cgi-bin/koha/acqui/basket.pl'; + url += $('#exportbutton').attr('href'); + if($(this).attr("data-value")) { + url += '&csv_profile=' + $(this).attr("data-value"); + } + // And redirecting to the CSV page + location.href = url; + return false; + }); }); function UserSearchPopup(f) { @@ -203,10 +229,13 @@ Close this basket [% END %] - + + [% PROCESS csv_export %] + [% IF ediaccount %] [% END %] + [% IF ( active && books_loop ) %]
@@ -218,7 +247,8 @@ [% END %]
[% END %] - + +