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

(-)a/C4/Acquisition.pm (-35 / +81 lines)
Lines 33-38 use Koha::Acquisition::Booksellers; Link Here
33
use Koha::Biblios;
33
use Koha::Biblios;
34
use Koha::Number::Price;
34
use Koha::Number::Price;
35
use Koha::Libraries;
35
use Koha::Libraries;
36
use Koha::CsvProfiles;
36
37
37
use C4::Koha;
38
use C4::Koha;
38
39
Lines 277-283 $cgi parameter is needed for column name translation Link Here
277
=cut
278
=cut
278
279
279
sub GetBasketAsCSV {
280
sub GetBasketAsCSV {
280
    my ($basketno, $cgi) = @_;
281
    my ($basketno, $cgi, $csv_profile_id) = @_;
281
    my $basket = GetBasket($basketno);
282
    my $basket = GetBasket($basketno);
282
    my @orders = GetOrders($basketno);
283
    my @orders = GetOrders($basketno);
283
    my $contract = GetContract({
284
    my $contract = GetContract({
Lines 285-332 sub GetBasketAsCSV { Link Here
285
    });
286
    });
286
287
287
    my $template = C4::Templates::gettemplate("acqui/csv/basket.tt", "intranet", $cgi);
288
    my $template = C4::Templates::gettemplate("acqui/csv/basket.tt", "intranet", $cgi);
288
289
    my @rows;
289
    my @rows;
290
    foreach my $order (@orders) {
290
    if ($csv_profile_id) {
291
        my $bd = GetBiblioData( $order->{'biblionumber'} );
291
        my $csv_profile = Koha::CsvProfiles->find( $csv_profile_id );
292
        my $row = {
292
        die "There is no valid csv profile given" unless $csv_profile;
293
            contractname => $contract->{'contractname'},
293
294
            ordernumber => $order->{'ordernumber'},
294
        my $csv = Text::CSV_XS->new({'quote_char'=>'"','escape_char'=>'"','sep_char'=>$csv_profile->csv_separator,'binary'=>1});
295
            entrydate => $order->{'entrydate'},
295
        my $csv_profile_content = $csv_profile->content;
296
            isbn => $order->{'isbn'},
296
        my ( @headers, @fields );
297
            author => $bd->{'author'},
297
        while ( $csv_profile_content =~ /
298
            title => $bd->{'title'},
298
            ([^=]+) # header
299
            publicationyear => $bd->{'publicationyear'},
299
            =
300
            publishercode => $bd->{'publishercode'},
300
            ([^\|]+) # fieldname (table.row or row)
301
            collectiontitle => $bd->{'collectiontitle'},
301
            \|? /gxms
302
            notes => $order->{'order_vendornote'},
302
        ) {
303
            quantity => $order->{'quantity'},
303
            push @headers, $1;
304
            rrp => $order->{'rrp'},
304
            my $field = $2;
305
        };
305
            $field =~ s/[^\.]*\.?//; # Remove the table name if exists.
306
        for my $place ( qw( deliveryplace billingplace ) ) {
306
            push @fields, $field;
307
            if ( my $library = Koha::Libraries->find( $row->{deliveryplace} ) ) {
307
        }
308
                $row->{$place} = $library->branchname
308
        for my $order (@orders) {
309
            my @row;
310
            my $bd = GetBiblioData( $order->{'biblionumber'} );
311
            my @biblioitems = GetBiblioItemByBiblioNumber( $order->{'biblionumber'});
312
            for my $biblioitem (@biblioitems) {
313
                if ($biblioitem->{isbn} eq $order->{isbn}) {
314
                    $order = {%$order, %$biblioitem};
315
                }
316
            }
317
            if ($contract) {
318
                $order = {%$order, %$contract};
319
            }
320
            $order = {%$order, %$basket, %$bd};
321
            for my $field (@fields) {
322
                push @row, $order->{$field};
309
            }
323
            }
324
            push @rows, \@row;
310
        }
325
        }
311
        foreach(qw(
326
        my $content = join( $csv_profile->csv_separator, @headers ) . "\n";
312
            contractname author title publishercode collectiontitle notes
327
        for my $row ( @rows ) {
313
            deliveryplace billingplace
328
            $csv->combine(@$row);
314
        ) ) {
329
            my $string = $csv->string;
315
            # Double the quotes to not be interpreted as a field end
330
            $content .= $string . "\n";
316
            $row->{$_} =~ s/"/""/g if $row->{$_};
317
        }
331
        }
318
        push @rows, $row;
332
        return $content;
319
    }
333
    }
334
    else {
335
        foreach my $order (@orders) {
336
            my $bd = GetBiblioData( $order->{'biblionumber'} );
337
            my $row = {
338
                contractname => $contract->{'contractname'},
339
                ordernumber => $order->{'ordernumber'},
340
                entrydate => $order->{'entrydate'},
341
                isbn => $order->{'isbn'},
342
                author => $bd->{'author'},
343
                title => $bd->{'title'},
344
                publicationyear => $bd->{'publicationyear'},
345
                publishercode => $bd->{'publishercode'},
346
                collectiontitle => $bd->{'collectiontitle'},
347
                notes => $order->{'order_vendornote'},
348
                quantity => $order->{'quantity'},
349
                rrp => $order->{'rrp'},
350
            };
351
            for my $place ( qw( deliveryplace billingplace ) ) {
352
                if ( my $library = Koha::Libraries->find( $row->{deliveryplace} ) ) {
353
                    $row->{$place} = $library->branchname
354
                }
355
            }
356
            foreach(qw(
357
                contractname author title publishercode collectiontitle notes
358
                deliveryplace billingplace
359
            ) ) {
360
                # Double the quotes to not be interpreted as a field end
361
                $row->{$_} =~ s/"/""/g if $row->{$_};
362
            }
363
            push @rows, $row;
364
         }
320
365
321
    @rows = sort {
366
        @rows = sort {
322
        if(defined $a->{publishercode} and defined $b->{publishercode}) {
367
            if(defined $a->{publishercode} and defined $b->{publishercode}) {
323
            $a->{publishercode} cmp $b->{publishercode};
368
                $a->{publishercode} cmp $b->{publishercode};
324
        }
369
            }
325
    } @rows;
370
        } @rows;
326
371
327
    $template->param(rows => \@rows);
372
        $template->param(rows => \@rows);
328
373
329
    return $template->output;
374
        return $template->output;
375
    }
330
}
376
}
331
377
332
378
(-)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 169-175 if ( $op eq 'delete_confirm' ) { Link Here
169
        -type       => 'text/csv',
170
        -type       => 'text/csv',
170
        -attachment => 'basket' . $basket->{'basketno'} . '.csv',
171
        -attachment => 'basket' . $basket->{'basketno'} . '.csv',
171
    );
172
    );
172
    print GetBasketAsCSV($query->param('basketno'), $query);
173
    if ( $query->param('csv_profile') eq 'default'){
174
        print GetBasketAsCSV($query->param('basketno'), $query);
175
    } else {
176
        my $csv_profile_id = $query->param('csv_profile');
177
        print  GetBasketAsCSV($query->param('basketno'), $query, $csv_profile_id);
178
    }
173
    exit;
179
    exit;
174
} elsif ($op eq 'email') {
180
} elsif ($op eq 'email') {
175
    my $err = eval {
181
    my $err = eval {
Lines 425-430 if ( $op eq 'list' ) { Link Here
425
        unclosable           => @orders ? $basket->{is_standing} : 1,
431
        unclosable           => @orders ? $basket->{is_standing} : 1,
426
        has_budgets          => $has_budgets,
432
        has_budgets          => $has_budgets,
427
        duplinbatch          => $duplinbatch,
433
        duplinbatch          => $duplinbatch,
434
        csv_profiles         => [ Koha::CsvProfiles->search({ type => 'export_basket' }) ],
428
    );
435
    );
429
}
436
}
430
437
(-)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