Bug 24163: Allow to define CSV profile for late orders export
authorJonathan Druart <jonathan.druart@bugs.koha-community.org>
Wed, 18 Dec 2019 16:24:17 +0000 (17:24 +0100)
committerMartin Renvoize <martin.renvoize@ptfs-europe.com>
Tue, 5 May 2020 10:08:21 +0000 (11:08 +0100)
This new enhancement adds the ability to create a CSV profile for the late
orders export.
Prior to this, the CSV profile was hardcoded in a template and not
editable (unless you modify the .tt file of course).

The main difficulty of the request was to make the multiple claims dates
accessible from the CSV profile. So far we only accept columns from the
database. However we would like to use the Koha::Acquisition::Order
object to make things easier (it had a ->claims method to access the
different claims).
To acchieve this, we are going to accept the TT syntax for that CSV profile.
It means that only CSV profiles created for 'late_orders' will have the
capability to use the TT syntax (can be extended later of course if
needed).
The alternative was to use specific placeholders, like %claims_count%,
%claimed_date%, but it sounded more powerful and flexible to allow the
TT syntax instead.

Note that the former export (template based) still exists and is the
default option.

Test plan:
0. Apply the patches and execute the update database entry
1. Create some orders, close the basket
2. Claim some of the orders
3. Note the new button at the bottom of the table that have several
entries.
=> The first entry will generate a CSV file using the previous method
=> The second entry will generate it using the new CSV profile, note
that the number of claims as well as the different claims date are
displayed.

4. Bonus point: Edit the CSV profile (Home › Tools › CSV export
profiles) that is named "Late orders (csv profile)", or create a new
one, and modify it.
Export the late orders using this CSV profile and confirm that the
generated CSV file is the one you expect.

Sponsored-by: Institute of Technology Tralee
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Angela O'Connor Desmond <angela.oconnordesmond@staff.ittralee.ie>
Signed-off-by: Katrin Fischer <katrin.fischer.83@web.de>
Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>

acqui/lateorders-export.pl
acqui/lateorders.pl
koha-tmpl/intranet-tmpl/prog/en/modules/acqui/lateorders.tt
koha-tmpl/intranet-tmpl/prog/en/modules/tools/csv-profiles.tt

index eb04ba7..31e21a8 100755 (executable)
@@ -33,40 +33,61 @@ my ($template, $loggedinuser, $cookie) = get_template_and_user({
 });
 my @ordernumbers = $input->multi_param('ordernumber');
 
-my @orders;
-for my $ordernumber ( @ordernumbers ) {
-    my $order = GetOrder $ordernumber;
-    my $order_object = Koha::Acquisition::Orders->find($ordernumber);
-    my $claims = $order_object->claims;
-    push @orders, {
-            orderdate => $order->{orderdate},
-            latesince => $order->{latesince},
-            estimateddeliverydate => $order->{estimateddeliverydate},
-            supplier => $order->{supplier},
-            supplierid => $order->{supplierid},
-            title => $order->{title},
-            author => $order->{author},
-            publisher => $order->{publisher},
-            unitpricesupplier => $order->{unitpricesupplier},
-            quantity_to_receive => $order->{quantity_to_receive},
-            subtotal => $order->{subtotal},
-            budget => $order->{budget},
-            basketname => $order->{basketname},
-            basketno => $order->{basketno},
-            claims_count => $claims->count,
-            claimed_date => $claims->count ? $claims->last->claimed_on : undef,
-            internalnote => $order->{order_internalnote},
-            vendornote   => $order->{order_vendornote},
-            isbn => $order->{isbn},
-        }
-    ;
-}
+my $csv_profile_id = $input->param('csv_profile');
+
+unless ( $csv_profile_id ) {
+    my @orders;
+    for my $ordernumber ( @ordernumbers ) {
+        my $order = GetOrder $ordernumber;
+        my $order_object = Koha::Acquisition::Orders->find($ordernumber);
+        my $claims = $order_object->claims;
+        push @orders, {
+                orderdate => $order->{orderdate},
+                latesince => $order->{latesince},
+                estimateddeliverydate => $order->{estimateddeliverydate},
+                supplier => $order->{supplier},
+                supplierid => $order->{supplierid},
+                title => $order->{title},
+                author => $order->{author},
+                publisher => $order->{publisher},
+                unitpricesupplier => $order->{unitpricesupplier},
+                quantity_to_receive => $order->{quantity_to_receive},
+                subtotal => $order->{subtotal},
+                budget => $order->{budget},
+                basketname => $order->{basketname},
+                basketno => $order->{basketno},
+                claims_count => $claims->count,
+                claimed_date => $claims->count ? $claims->last->claimed_on : undef,
+                internalnote => $order->{order_internalnote},
+                vendornote   => $order->{order_vendornote},
+                isbn => $order->{isbn},
+            }
+        ;
+    }
+
+    # We want to export using the default profile, using the template acqui/csv/lateorders.tt
+    print $input->header(
+        -type       => 'text/csv',
+        -attachment => 'lateorders.csv',
+    );
+    $template->param( orders => \@orders );
+    for my $line ( split '\n', $template->output ) {
+        print "$line\n" unless $line =~ m|^\s*$|;
+    }
+    exit;
+} else {
+    my $csv_profile = Koha::CsvProfiles->find($csv_profile_id);
+    my $content = '[% SET separator = "'.$csv_profile->csv_separator.'" ~%]' . $csv_profile->content;
+
+    my $csv = C4::Letters::_process_tt({
+        content => $content,
+        loops => { aqorders => \@ordernumbers },
+    });
 
-print $input->header(
-    -type       => 'text/csv',
-    -attachment => 'lateorders.csv',
-);
-$template->param( orders => \@orders );
-for my $line ( split '\n', $template->output ) {
-    print "$line\n" unless $line =~ m|^\s*$|;
+    print $input->header(
+        -type       => 'text/csv',
+        -attachment => 'lateorders.csv',
+    );
+    print $csv;
+    exit;
 }
index 1367e17..66ac704 100755 (executable)
@@ -54,6 +54,7 @@ use C4::Acquisition;
 use C4::Letters;
 use Koha::DateUtils;
 use Koha::Acquisition::Orders;
+use Koha::CsvProfiles;
 
 my $input = new CGI;
 my ($template, $loggedinuser, $cookie) = get_template_and_user(
@@ -172,5 +173,6 @@ $template->param(
     estimateddeliverydatefrom => $estimateddeliverydatefrom,
     estimateddeliverydateto   => $estimateddeliverydateto,
        intranetcolorstylesheet => C4::Context->preference("intranetcolorstylesheet"),
+    csv_profiles         => [ Koha::CsvProfiles->search({ type => 'sql', used_for => 'late_orders' }) ],
 );
 output_html_with_http_headers $input, $cookie, $template->output;
index a3f2f0a..60e3168 100644 (file)
     <div class="spacer"></div>
 
     <p style="display:block;">
-        <input type="button" value="Export as CSV" id="ExportSelected" />
-        <input type="submit"  value="Claim order" />
+        <div class="btn-group">
+          <a id="exportbutton" class="btn btn-default" href="/cgi-bin/koha/acqui/lateorders-export.pl"><i class="fa fa-download"></i> Export as CSV</a>
+          <a class="btn btn-default dropdown-toggle" data-toggle="dropdown"><span class="caret"></span></a>
+          <ul class="dropdown-menu" id="export-csv-menu">
+              <li><a href="#">Default</a></li>
+              [% IF csv_profiles %]
+                  [% FOR csv IN csv_profiles %]
+                    <li><a href="#" data-value="[% csv.export_format_id | html %]">[% csv.profile | html %]</a></li>
+                  [% END %]
+              [% END %]
+           </ul>
+        </div>
+
+        <input type="submit"  class="btn btn-default" value="Claim order" />
     </p>
 </form>
 [% ELSE %]<p>There are no late orders.</p>
             $('#CheckNone').click(function(){ $(late_orderst.fnGetNodes()).find("td").unCheckCheckboxes();});
 
             // Generates a dynamic link for exporting the selection's data as CSV
-            $("#ExportSelected").click(function() {
+            $("#exportbutton, #export-csv-menu a").click(function() {
                 var all_nodes = $(late_orderst.fnGetNodes());
                 var selected = $(all_nodes).find("input[name='ordernumber']:checked");
 
                     return false;
                 }
 
+                var url = $('#exportbutton').attr('href') + '?';
                 // Building the url from currently checked boxes
-                var url = '/cgi-bin/koha/acqui/lateorders-export.pl?op=export';
                 for (var i = 0; i < selected.length; i++) {
                     url += '&amp;ordernumber=' + selected[i].value;
                 }
+                if($(this).attr("data-value")) {
+                    url += '&amp;csv_profile=' + $(this).attr("data-value");
+                }
                 // And redirecting to the CSV page
                 location.href = url;
                 return false;
index 8a1bea4..6365ede 100644 (file)
@@ -92,6 +92,7 @@
 [% BLOCK used_for_description %]
     [% IF used_for_code == 'export_records' %] Export records
     [% ELSIF used_for_code == 'late_issues' %] Late serial issues claims
+    [% ELSIF used_for_code == 'late_orders' %] Export late orders
     [% ELSIF used_for_code == 'export_basket' %] Basket export in acquisition
     [% ELSIF used_for_code == 'export_lost_items' %] Export lost items in report
     [% ELSE %] Unknown usage
                 <li class="sql_specific">
                     <label for="used_for_sql">Usage: </label>
                     <select id="used_for_sql" name="used_for_sql">
-                        [% FOREACH used_for IN [ 'late_issues' 'export_basket' 'export_lost_items' ] %]
+                        [% FOREACH used_for IN [ 'late_issues' 'late_orders', 'export_basket' 'export_lost_items' ] %]
                         [% IF csv_profile.used_for == used_for %]
                             <option value="[% used_for | html %]" selected="selected">[% PROCESS used_for_description used_for_code = used_for %]</option>
                         [% ELSE %]
                 </li>
 
                 <li class="sql_specific">
-                    <label for="late_issues_content" class="required">Profile SQL fields: </label>
+                    <label for="sql_content" class="required">Profile SQL fields: </label>
                     <textarea cols="50" rows="2" name="sql_content" id="sql_content">[% csv_profile.content | html %]</textarea>
                     <p>You have to define which fields you want to export, separated by pipes.</p>
                     <p>You can also use your own headers (instead of the ones from Koha) by prefixing the field name with an header, followed by the equal sign.</p>
                     <p>Example: Name=subscription.name|Title=subscription.title|Issue number=serial.serialseq</p>
                     <p>For late issues claims you can use data from following tables: serial, subscription, biblio, biblioitems and aqbookseller.</p>
                     <p>For basket exports you can use data from following tables: biblio, biblioitems, aqorders, aqbudgets and aqbasket.</p>
+                    <p>For late orders exports you must provide a Template Toolkit syntax that will generate the whole CSV file..</p>
                 </li>
             </ol>
         </fieldset>
                     <td>[% csv_profile.export_format_id | html %]</td>
                     <td>[% csv_profile.profile | html %]</td>
                     <td>[% csv_profile.description | html %]</td>
-                    <td>[% csv_profile.content | html %]</td>
+                    <td>[% csv_profile.content | html | html_line_break %]</td>
                     <td>[% csv_profile.csv_separator | html %]</td>
                     <td>[% PROCESS type_description type_code = csv_profile.type %]</td>
                     <td>[% PROCESS used_for_description used_for_code = csv_profile.used_for %]</td>