View | Details | Raw Unified | Return to bug 8612
Collapse All | Expand All

(-)a/C4/Acquisition.pm (-35 / +81 lines)
Lines 32-37 use Koha::Acquisition::Order; Link Here
32
use Koha::Acquisition::Booksellers;
32
use Koha::Acquisition::Booksellers;
33
use Koha::Number::Price;
33
use Koha::Number::Price;
34
use Koha::Libraries;
34
use Koha::Libraries;
35
use Koha::CsvProfiles;
35
36
36
use C4::Koha;
37
use C4::Koha;
37
38
Lines 276-282 $cgi parameter is needed for column name translation Link Here
276
=cut
277
=cut
277
278
278
sub GetBasketAsCSV {
279
sub GetBasketAsCSV {
279
    my ($basketno, $cgi) = @_;
280
    my ($basketno, $cgi, $csv_profile_id) = @_;
280
    my $basket = GetBasket($basketno);
281
    my $basket = GetBasket($basketno);
281
    my @orders = GetOrders($basketno);
282
    my @orders = GetOrders($basketno);
282
    my $contract = GetContract({
283
    my $contract = GetContract({
Lines 284-331 sub GetBasketAsCSV { Link Here
284
    });
285
    });
285
286
286
    my $template = C4::Templates::gettemplate("acqui/csv/basket.tt", "intranet", $cgi);
287
    my $template = C4::Templates::gettemplate("acqui/csv/basket.tt", "intranet", $cgi);
287
288
    my @rows;
288
    my @rows;
289
    foreach my $order (@orders) {
289
    if ($csv_profile_id) {
290
        my $bd = GetBiblioData( $order->{'biblionumber'} );
290
        my $csv_profile = Koha::CsvProfiles->find( $csv_profile_id );
291
        my $row = {
291
        die "There is no valid csv profile given" unless $csv_profile;
292
            contractname => $contract->{'contractname'},
292
293
            ordernumber => $order->{'ordernumber'},
293
        my $csv = Text::CSV_XS->new({'quote_char'=>'"','escape_char'=>'"','sep_char'=>$csv_profile->csv_separator,'binary'=>1});
294
            entrydate => $order->{'entrydate'},
294
        my $csv_profile_content = $csv_profile->content;
295
            isbn => $order->{'isbn'},
295
        my ( @headers, @fields );
296
            author => $bd->{'author'},
296
        while ( $csv_profile_content =~ /
297
            title => $bd->{'title'},
297
            ([^=]+) # header
298
            publicationyear => $bd->{'publicationyear'},
298
            =
299
            publishercode => $bd->{'publishercode'},
299
            ([^\|]+) # fieldname (table.row or row)
300
            collectiontitle => $bd->{'collectiontitle'},
300
            \|? /gxms
301
            notes => $order->{'order_vendornote'},
301
        ) {
302
            quantity => $order->{'quantity'},
302
            push @headers, $1;
303
            rrp => $order->{'rrp'},
303
            my $field = $2;
304
        };
304
            $field =~ s/[^\.]*\.?//; # Remove the table name if exists.
305
        for my $place ( qw( deliveryplace billingplace ) ) {
305
            push @fields, $field;
306
            if ( my $library = Koha::Libraries->find( $row->{deliveryplace} ) ) {
306
        }
307
                $row->{$place} = $library->branchname
307
        for my $order (@orders) {
308
            my @row;
309
            my $bd = GetBiblioData( $order->{'biblionumber'} );
310
            my @biblioitems = GetBiblioItemByBiblioNumber( $order->{'biblionumber'});
311
            for my $biblioitem (@biblioitems) {
312
                if ($biblioitem->{isbn} eq $order->{isbn}) {
313
                    $order = {%$order, %$biblioitem};
314
                }
315
            }
316
            if ($contract) {
317
                $order = {%$order, %$contract};
318
            }
319
            $order = {%$order, %$basket, %$bd};
320
            for my $field (@fields) {
321
                push @row, $order->{$field};
308
            }
322
            }
323
            push @rows, \@row;
309
        }
324
        }
310
        foreach(qw(
325
        my $content = join( $csv_profile->csv_separator, @headers ) . "\n";
311
            contractname author title publishercode collectiontitle notes
326
        for my $row ( @rows ) {
312
            deliveryplace billingplace
327
            $csv->combine(@$row);
313
        ) ) {
328
            my $string = $csv->string;
314
            # Double the quotes to not be interpreted as a field end
329
            $content .= $string . "\n";
315
            $row->{$_} =~ s/"/""/g if $row->{$_};
316
        }
330
        }
317
        push @rows, $row;
331
        return $content;
318
    }
332
    }
333
    else {
334
        foreach my $order (@orders) {
335
            my $bd = GetBiblioData( $order->{'biblionumber'} );
336
            my $row = {
337
                contractname => $contract->{'contractname'},
338
                ordernumber => $order->{'ordernumber'},
339
                entrydate => $order->{'entrydate'},
340
                isbn => $order->{'isbn'},
341
                author => $bd->{'author'},
342
                title => $bd->{'title'},
343
                publicationyear => $bd->{'publicationyear'},
344
                publishercode => $bd->{'publishercode'},
345
                collectiontitle => $bd->{'collectiontitle'},
346
                notes => $order->{'order_vendornote'},
347
                quantity => $order->{'quantity'},
348
                rrp => $order->{'rrp'},
349
            };
350
            for my $place ( qw( deliveryplace billingplace ) ) {
351
                if ( my $library = Koha::Libraries->find( $row->{deliveryplace} ) ) {
352
                    $row->{$place} = $library->branchname
353
                }
354
            }
355
            foreach(qw(
356
                contractname author title publishercode collectiontitle notes
357
                deliveryplace billingplace
358
            ) ) {
359
                # Double the quotes to not be interpreted as a field end
360
                $row->{$_} =~ s/"/""/g if $row->{$_};
361
            }
362
            push @rows, $row;
363
         }
319
364
320
    @rows = sort {
365
        @rows = sort {
321
        if(defined $a->{publishercode} and defined $b->{publishercode}) {
366
            if(defined $a->{publishercode} and defined $b->{publishercode}) {
322
            $a->{publishercode} cmp $b->{publishercode};
367
                $a->{publishercode} cmp $b->{publishercode};
323
        }
368
            }
324
    } @rows;
369
        } @rows;
325
370
326
    $template->param(rows => \@rows);
371
        $template->param(rows => \@rows);
327
372
328
    return $template->output;
373
        return $template->output;
374
    }
329
}
375
}
330
376
331
377
(-)a/acqui/basket.pl (-1 / +8 lines)
Lines 40-45 use C4::Letters qw/SendAlerts/; Link Here
40
use Date::Calc qw/Add_Delta_Days/;
40
use Date::Calc qw/Add_Delta_Days/;
41
use Koha::Database;
41
use Koha::Database;
42
use Koha::EDI qw( create_edi_order get_edifact_ean );
42
use Koha::EDI qw( create_edi_order get_edifact_ean );
43
use Koha::CsvProfiles;
43
44
44
=head1 NAME
45
=head1 NAME
45
46
Lines 168-174 if ( $op eq 'delete_confirm' ) { Link Here
168
        -type       => 'text/csv',
169
        -type       => 'text/csv',
169
        -attachment => 'basket' . $basket->{'basketno'} . '.csv',
170
        -attachment => 'basket' . $basket->{'basketno'} . '.csv',
170
    );
171
    );
171
    print GetBasketAsCSV($query->param('basketno'), $query);
172
    if ( $query->param('csv_profile') eq 'default'){
173
        print GetBasketAsCSV($query->param('basketno'), $query);
174
    } else {
175
        my $csv_profile_id = $query->param('csv_profile');
176
        print  GetBasketAsCSV($query->param('basketno'), $query, $csv_profile_id);
177
    }
172
    exit;
178
    exit;
173
} elsif ($op eq 'email') {
179
} elsif ($op eq 'email') {
174
    my $err = eval {
180
    my $err = eval {
Lines 424-429 if ( $op eq 'list' ) { Link Here
424
        unclosable           => @orders ? $basket->{is_standing} : 1,
430
        unclosable           => @orders ? $basket->{is_standing} : 1,
425
        has_budgets          => $has_budgets,
431
        has_budgets          => $has_budgets,
426
        duplinbatch          => $duplinbatch,
432
        duplinbatch          => $duplinbatch,
433
        csv_profiles         => [ Koha::CsvProfiles->search({ type => 'export_basket' }) ],
427
    );
434
    );
428
}
435
}
429
436
(-)a/installer/data/mysql/atomicupdate/bug_8612.sql (+1 lines)
Line 0 Link Here
1
UPDATE export_format SET type = 'late_issues' WHERE type ='sql';
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basket.tt (-3 / +36 lines)
Lines 1-3 Link Here
1
[% BLOCK csv_export %]
2
    <div class="btn-group">
3
        <a id="exportbutton" class="btn btn-default btn-sm" href="[% script_name %]?op=export&amp;basketno=[% basketno %]&amp;booksellerid=[% booksellerid %]"><i class="fa fa-download"></i> Export as CSV</a>
4
      <a class="btn btn-default btn-sm dropdown-toggle" data-toggle="dropdown"><span class="caret"></span></a>
5
      <ul class="dropdown-menu" id="export-csv-menu">
6
          <li><a href="#">Default</a></li>
7
          [% IF csv_profiles %]
8
              [% FOR csv IN csv_profiles %]
9
                <li><a href="#" data-value="[% csv.export_format_id %]">[% csv.profile %]</a></li>
10
              [% END %]
11
          [% END %]
12
       </ul>
13
    </div>
14
[% END %]
1
[% USE KohaDates %]
15
[% USE KohaDates %]
2
[% USE Branches %]
16
[% USE Branches %]
3
[% USE Price %]
17
[% USE Price %]
Lines 121-126 Link Here
121
            e.preventDefault();
135
            e.preventDefault();
122
            confirm_reopen();
136
            confirm_reopen();
123
        });
137
        });
138
        // Generates a dynamic link for exporting the selections data as CSV
139
        $("#exportbutton, #export-csv-menu a").click(function() {
140
            // Building the url from currently checked boxes
141
            var url = '/cgi-bin/koha/acqui/basket.pl';
142
            url += $('#exportbutton').attr('href');
143
            if($(this).attr("data-value")) {
144
                url += '&amp;csv_profile=' + $(this).attr("data-value");
145
            }
146
            // And redirecting to the CSV page
147
            location.href = url;
148
            return false;
149
        });
124
    });
150
    });
125
151
126
    function UserSearchPopup(f) {
152
    function UserSearchPopup(f) {
Lines 203-212 Link Here
203
                            <a href="/cgi-bin/koha/acqui/basket.pl?op=close&amp;basketno=[% basketno %]&amp;booksellerid=[% booksellerid %]" class="btn btn-default btn-sm" id="closebutton"><i class="fa fa-times-circle"></i> Close this basket</a>
229
                            <a href="/cgi-bin/koha/acqui/basket.pl?op=close&amp;basketno=[% basketno %]&amp;booksellerid=[% booksellerid %]" class="btn btn-default btn-sm" id="closebutton"><i class="fa fa-times-circle"></i> Close this basket</a>
204
                        </div>
230
                        </div>
205
                    [% END %]
231
                    [% END %]
206
                        <div class="btn-group"><a href="/cgi-bin/koha/acqui/basket.pl?op=export&amp;basketno=[% basketno %]&amp;booksellerid=[% booksellerid %]" class="btn btn-default btn-sm" id="exportbutton"><i class="fa fa-download"></i> Export this basket as CSV</a></div>
232
233
                    [% PROCESS csv_export %]
234
207
                        [% IF ediaccount %]
235
                        [% IF ediaccount %]
208
                        <div class="btn-group"><a href="/cgi-bin/koha/acqui/edi_ean.pl?op=ediorder&amp;basketno=[% basketno %]&amp;booksellerid=[% booksellerid %]" class="btn btn-default btn-sm" id="ediorderbutton"><i class="fa fa-download"></i> Create EDIFACT order</a></div>
236
                        <div class="btn-group"><a href="/cgi-bin/koha/acqui/edi_ean.pl?op=ediorder&amp;basketno=[% basketno %]&amp;booksellerid=[% booksellerid %]" class="btn btn-default btn-sm" id="ediorderbutton"><i class="fa fa-download"></i> Create EDIFACT order</a></div>
209
                        [% END %]
237
                        [% END %]
238
210
                        [% IF ( active && books_loop ) %]
239
                        [% IF ( active && books_loop ) %]
211
                            <div class="btn-group">
240
                            <div class="btn-group">
212
                                <form action="/cgi-bin/koha/acqui/basket.pl" method="post">
241
                                <form action="/cgi-bin/koha/acqui/basket.pl" method="post">
Lines 218-224 Link Here
218
                        [% END %]
247
                        [% END %]
219
                </div>
248
                </div>
220
            [% END %]
249
            [% END %]
221
<!-- Modal for confirm deletion box-->
250
251
            <!-- Modal for confirm deletion box-->
222
                <div class="modal" id="deleteBasketModal" tabindex="-1" role="dialog" aria-labelledby="delbasketModalLabel" aria-hidden="true">
252
                <div class="modal" id="deleteBasketModal" tabindex="-1" role="dialog" aria-labelledby="delbasketModalLabel" aria-hidden="true">
223
                    <div class="modal-dialog">
253
                    <div class="modal-dialog">
224
                    <div class="modal-content">
254
                    <div class="modal-content">
Lines 275-282 Link Here
275
            [% ELSE %]
305
            [% ELSE %]
276
                [% UNLESS ( grouped ) %]
306
                [% UNLESS ( grouped ) %]
277
                <div id="toolbar" class="btn-toolbar">
307
                <div id="toolbar" class="btn-toolbar">
308
278
                    <div class="btn-group"><a href="#" class="btn btn-default btn-sm" id="reopenbutton"><i class="fa fa-refresh"></i> Reopen this basket</a></div>
309
                    <div class="btn-group"><a href="#" class="btn btn-default btn-sm" id="reopenbutton"><i class="fa fa-refresh"></i> Reopen this basket</a></div>
279
                    <div class="btn-group"><a href="/cgi-bin/koha/acqui/basket.pl?op=export&amp;basketno=[% basketno %]&amp;booksellerid=[% booksellerid %]" class="btn btn-default btn-sm" id="exportbutton"><i class="fa fa-download"></i> Export this basket as CSV</a></div>
310
311
                    [% PROCESS csv_export %]
312
280
                </div>
313
                </div>
281
                [% END %]
314
                [% END %]
282
            [% END %]
315
            [% END %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/csv-profiles.tt (-15 / +21 lines)
Lines 101-106 function reloadPage(p) { Link Here
101
    [% END %]
101
    [% END %]
102
[% END %]
102
[% END %]
103
103
104
[% BLOCK type_description %]
105
    [% IF type_code == 'marc' %] MARC for export records
106
    [% ELSIF type_code == 'late_issues' %] SQL for late serial issues claims
107
    [% ELSIF type_code == 'export_basket' %] SQL for basket export in acquisition
108
    [% ELSE %] Uknown type
109
    [% END %]
110
[% END %]
111
104
[% IF op == 'add_form' %]
112
[% IF op == 'add_form' %]
105
    [% IF csv_profile %]
113
    [% IF csv_profile %]
106
        <h1>Modify a CSV profile</h1>
114
        <h1>Modify a CSV profile</h1>
Lines 124-135 function reloadPage(p) { Link Here
124
                <li>
132
                <li>
125
                    <label for="type" class="required">Profile type: </label>
133
                    <label for="type" class="required">Profile type: </label>
126
                    <select id="type" name="type">
134
                    <select id="type" name="type">
127
                        [% IF csv_profile.type == 'sql' %]
135
                        [% FOREACH type IN [ 'marc' 'late_issues' 'export_basket'] %]
128
                            <option value="marc">MARC</option>
136
                        [% IF csv_profile.type == type %]
129
                            <option value="sql" selected="selected">SQL</option>
137
                            <option value="[% type %]" selected="selected">[% PROCESS type_description type_code = type %]</option>
130
                        [% ELSE %]
138
                        [% ELSE %]
131
                            <option value="marc" selected="selected">MARC</option>
139
                            <option value="[% type %]">[% PROCESS type_description type_code = type %]</option>
132
                            <option value="sql">SQL</option>
140
                        [% END %]
133
                        [% END %]
141
                        [% END %]
134
                    </select>
142
                    </select>
135
                    <span class="required">Required</span>
143
                    <span class="required">Required</span>
Lines 182-192 function reloadPage(p) { Link Here
182
                </li>
190
                </li>
183
191
184
                <li class="sql_specific">
192
                <li class="sql_specific">
185
                  <label for="sql_content" class="required">Profile SQL fields: </label>
193
                    <label for="late_issues_content" class="required">Profile SQL fields: </label>
186
                  <textarea cols="50" rows="2" name="sql_content" id="sql_content">[% csv_profile.content %]</textarea>
194
                    <textarea cols="50" rows="2" name="sql_content" id="sql_content">[% csv_profile.content %]</textarea>
187
                  <p>You have to define which fields you want to export, separated by pipes.</p>
195
                    <p>You have to define which fields you want to export, separated by pipes.</p>
188
                  <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>
196
                    <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>
189
                  <p>Example: Name=subscription.name|Title=subscription.title|Issue number=serial.serialseq</p>
197
                    <p>Example: Name=subscription.name|Title=subscription.title|Issue number=serial.serialseq</p>
198
                    <p>For late issues claims you can use data from following tables: serial, subscription, biblio, biblioitems and aqbookseller.</p>
199
                    <p>For basket exports you can use data from following tables: biblio, biblioitems, aqorders, aqbudgets and aqbasket.</p>
190
                </li>
200
                </li>
191
            </ol>
201
            </ol>
192
        </fieldset>
202
        </fieldset>
Lines 243-253 function reloadPage(p) { Link Here
243
                    <td>[% csv_profile.description %]</td>
253
                    <td>[% csv_profile.description %]</td>
244
                    <td>[% csv_profile.content %]</td>
254
                    <td>[% csv_profile.content %]</td>
245
                    <td>[% csv_profile.csv_separator %]</td>
255
                    <td>[% csv_profile.csv_separator %]</td>
246
                    [% IF csv_profile.type == 'sql' %]
256
                    <td>[% PROCESS type_description type_code = csv_profile.type %]</td>
247
                        <td>SQL</td>
248
                    [% ELSE %]
249
                        <td>MARC</td>
250
                    [% END %]
251
                    <td><a href="/cgi-bin/koha/tools/csv-profiles.pl?op=add_form&amp;export_format_id=[% csv_profile.export_format_id %]">Edit</a></td>
257
                    <td><a href="/cgi-bin/koha/tools/csv-profiles.pl?op=add_form&amp;export_format_id=[% csv_profile.export_format_id %]">Edit</a></td>
252
                    <td><a href="/cgi-bin/koha/tools/csv-profiles.pl?op=delete_confirm&amp;export_format_id=[% csv_profile.export_format_id %]">Delete</a></td>
258
                    <td><a href="/cgi-bin/koha/tools/csv-profiles.pl?op=delete_confirm&amp;export_format_id=[% csv_profile.export_format_id %]">Delete</a></td>
253
                </tr>
259
                </tr>
(-)a/serials/claims.pl (-1 / +1 lines)
Lines 104-110 $template->param( Link Here
104
        supplierid => $supplierid,
104
        supplierid => $supplierid,
105
        claimletter => $claimletter,
105
        claimletter => $claimletter,
106
        additional_fields_for_subscription => $additional_fields,
106
        additional_fields_for_subscription => $additional_fields,
107
        csv_profiles => [ Koha::CsvProfiles->search({ type => 'sql' }) ],
107
        csv_profiles => [ Koha::CsvProfiles->search({ type => 'late_issues' }) ],
108
        letters => $letters,
108
        letters => $letters,
109
        (uc(C4::Context->preference("marcflavour"))) => 1
109
        (uc(C4::Context->preference("marcflavour"))) => 1
110
        );
110
        );
(-)a/t/db_dependent/Acquisition/GetBasketAsCSV.t (+76 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
use Modern::Perl;
4
5
use CGI;
6
7
use Test::More tests => 2;
8
9
use C4::Acquisition;
10
use C4::Biblio;
11
use Koha::Database;
12
use Koha::CsvProfile;
13
14
use Koha::Acquisition::Order;
15
16
my $schema = Koha::Database->new()->schema();
17
$schema->storage->txn_begin();
18
19
my $dbh = C4::Context->dbh;
20
$dbh->{RaiseError} = 1;
21
22
my $query = CGI->new();
23
24
my $vendor = Koha::Acquisition::Bookseller->new({
25
    name => 'my vendor',
26
    address1 => 'vendor address',
27
    active => 1,
28
    deliverytime => 5,
29
})->store;
30
31
my $budget_id = C4::Budgets::AddBudget({
32
    budget_code => 'my_budget_code',
33
    budget_name => 'My budget name',
34
});
35
my $budget = C4::Budgets::GetBudget( $budget_id );
36
37
my $csv_profile = Koha::CsvProfile->new({
38
    profile => 'my user profile',
39
    type => 'export_basket',
40
    csv_separator => ',',
41
    content => 'autor=biblio.author|title=biblio.title|quantity=aqorders.quantity',
42
})->store;
43
44
my $basketno;
45
$basketno = NewBasket($vendor->id, 1);
46
47
my $biblio = MARC::Record->new();
48
$biblio->append_fields(
49
    MARC::Field->new( '100', ' ', ' ', a => 'King, Stephen' ),
50
    MARC::Field->new( '245', ' ', ' ', a => 'Test Record' ),
51
);
52
my ($biblionumber, $biblioitemnumber) = AddBiblio($biblio, '');
53
54
my $order = Koha::Acquisition::Order->new({
55
    basketno => $basketno,
56
    quantity => 3,
57
    biblionumber => $biblionumber,
58
    budget_id => $budget_id,
59
    entrydate => '2016-01-02',
60
})->insert;
61
62
# Use user CSV profile
63
my $basket_csv1 = C4::Acquisition::GetBasketAsCSV($basketno, $query, $csv_profile->export_format_id);
64
is($basket_csv1, 'autor,title,quantity
65
"King, Stephen","Test Record",3
66
', 'CSV should be generated with user profile');
67
68
# Use defautl template
69
my $basket_csv2 = C4::Acquisition::GetBasketAsCSV($basketno, $query);
70
is($basket_csv2, 'Contract name,Order number,Entry date,ISBN,Author,Title,Publication year,Publisher,Collection title,Note for vendor,Quantity,RRP,Delivery place,Billing place
71
72
"",' . $order->{ordernumber}  . ',2016-01-02,,"King, Stephen","Test Record",,"","","",3,,"",""
73
74
', 'CSV should be generated with default template');
75
76
$schema->storage->txn_rollback();
(-)a/t/db_dependent/Koha/CsvProfiles.t (-2 / +1 lines)
Lines 35-41 my $nb_of_csv_profiles = Koha::CsvProfiles->search->count; Link Here
35
my $new_csv_profile_1 = Koha::CsvProfile->new({
35
my $new_csv_profile_1 = Koha::CsvProfile->new({
36
    profile => 'my_csv_profile_name_for_test_1',
36
    profile => 'my_csv_profile_name_for_test_1',
37
    description => 'my_csv_profile_description_for_test_1',
37
    description => 'my_csv_profile_description_for_test_1',
38
    type => 'sql'
38
    type => 'late_issues'
39
})->store;
39
})->store;
40
my $new_csv_profile_2 = Koha::CsvProfile->new({
40
my $new_csv_profile_2 = Koha::CsvProfile->new({
41
    profile => 'my_csv_profile_name_for_test_2',
41
    profile => 'my_csv_profile_name_for_test_2',
42
- 

Return to bug 8612