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

(-)a/t/db_dependent/Koha/EDI.t (-235 / +555 lines)
Lines 20-26 Link Here
20
use Modern::Perl;
20
use Modern::Perl;
21
use FindBin qw( $Bin );
21
use FindBin qw( $Bin );
22
22
23
use Test::More tests => 3;
23
use Test::More tests => 2;
24
use Test::Warn;
24
use Test::Warn;
25
use Test::MockModule;
25
use Test::MockModule;
26
26
Lines 30-334 use t::lib::TestBuilder; Link Here
30
30
31
use Koha::EDI qw(process_quote process_invoice);
31
use Koha::EDI qw(process_quote process_invoice);
32
use Koha::Edifact::Transport;
32
use Koha::Edifact::Transport;
33
use Koha::Edifact::File::Errors;
34
use Koha::DateUtils qw(dt_from_string);
33
35
34
my $schema  = Koha::Database->new->schema;
36
my $schema  = Koha::Database->new->schema;
35
my $builder = t::lib::TestBuilder->new;
37
my $builder = t::lib::TestBuilder->new;
36
my $logger  = t::lib::Mocks::Logger->new();
38
my $logger  = t::lib::Mocks::Logger->new();
37
39
38
subtest 'process_quote' => sub {
40
subtest 'process_quote' => sub {
39
    plan tests => 16;
41
    plan tests => 5;
40
42
41
    $schema->storage->txn_begin;
43
    $schema->storage->txn_begin;
42
44
43
    # Add our test quote file to the database for testing against
45
    # Common setup for all test cases
44
    my $account = $builder->build(
46
    my $test_san      = '5013546098818';
45
        {
47
    my $dirname       = ( $Bin =~ /^(.*\/t\/)/ ? $1 . 'edi_testfiles/' : q{} );
46
            source => 'VendorEdiAccount',
47
            value  => {
48
                description => 'test vendor', transport => 'FILE',
49
            }
50
        }
51
    );
52
    my $dirname  = ( $Bin =~ /^(.*\/t\/)/ ? $1 . 'edi_testfiles/' : q{} );
53
    my $filename = 'QUOTES_SMALL.CEQ';
54
    ok( -e $dirname . $filename, 'File QUOTES_SMALL.CEQ found' );
55
56
    my $trans = Koha::Edifact::Transport->new( $account->{id} );
57
    $trans->working_directory($dirname);
58
59
    my $mhash = $trans->message_hash();
60
    $mhash->{message_type} = 'QUOTE';
61
    $trans->ingest( $mhash, $filename );
62
63
    my $quote = $schema->resultset('EdifactMessage')->find( { filename => $filename } );
64
65
    # Test quote expects REF to be a valid and active fund code
66
    my $active_period = $builder->build(
48
    my $active_period = $builder->build(
67
        {
49
        {
68
            source => 'Aqbudgetperiod',
50
            source => 'Aqbudgetperiod',
69
            value  => { budget_period_active => 1 }
51
            value  => { budget_period_active => 1 }
70
        }
52
        }
71
    );
53
    );
72
    my $fund = $builder->build(
54
    t::lib::Mocks::mock_preference( 'CataloguingLog', 0 );
73
        {
74
            source => 'Aqbudget',
75
            value  => {
76
                budget_code      => 'REF',
77
                budget_period_id => $active_period->{budget_period_id}
78
            }
79
        }
80
    );
81
55
82
    # The quote expects a ROT1 stock rotation roata to exist
56
    # Test 1: Basic Quote Processing
83
    my $rota = $builder->build_object(
57
    subtest 'basic_quote_processing' => sub {
84
        {
58
        plan tests => 27;
85
            class => 'Koha::StockRotationRotas',
59
86
            value => { title => 'ROT1' }
60
        $schema->storage->txn_begin;
87
        }
61
88
    );
62
        my $account = $builder->build(
89
    $builder->build(
63
            {
90
        {
64
                source => 'VendorEdiAccount',
91
            source => 'Stockrotationstage',
65
                value  => {
92
            value  => { rota_id => $rota->rota_id },
66
                    description    => 'test vendor',
93
        }
67
                    transport      => 'FILE',
94
    );
68
                    plugin         => '',
69
                    san            => $test_san,
70
                    orders_enabled => 1,
71
                    auto_orders    => 0,
72
                }
73
            }
74
        );
75
        my $ean = $builder->build(
76
            {
77
                source => 'EdifactEan',
78
                value  => {
79
                    description => 'test ean',
80
                    branchcode  => undef,
81
                    ean         => $test_san
82
                }
83
            }
84
        );
85
86
        my $filename = 'QUOTES_SMALL.CEQ';
87
        ok( -e $dirname . $filename, 'File QUOTES_SMALL.CEQ found' );
88
89
        # Setup the fund code
90
        my $fund = $builder->build(
91
            {
92
                source => 'Aqbudget',
93
                value  => {
94
                    budget_code      => 'REF',
95
                    budget_period_id => $active_period->{budget_period_id}
96
                }
97
            }
98
        );
95
99
96
    t::lib::Mocks::mock_preference( 'CataloguingLog', 0 );
100
        # Setup stock rotation
101
        my $rota = $builder->build_object(
102
            {
103
                class => 'Koha::StockRotationRotas',
104
                value => { title => 'ROT1' }
105
            }
106
        );
107
        $builder->build(
108
            {
109
                source => 'Stockrotationstage',
110
                value  => { rota_id => $rota->rota_id },
111
            }
112
        );
113
114
        my $trans = Koha::Edifact::Transport->new( $account->{id} );
115
        $trans->working_directory($dirname);
116
117
        my $mhash = $trans->message_hash();
118
        $mhash->{message_type} = 'QUOTE';
119
        $trans->ingest( $mhash, $filename );
120
121
        my $quote = $schema->resultset('EdifactMessage')->find( { filename => $filename } );
122
123
        ok( $quote, 'Quote message created in database' );
124
        is( $quote->status, 'new', 'Initial quote status is new' );
125
126
        t::lib::Mocks::mock_preference( 'AcqCreateItem', 'ordering' );
127
128
        # Process quote and check results
129
        my $die;
130
        eval {
131
            process_quote($quote);
132
            1;
133
        } or do {
134
            $die = $@;
135
        };
136
        ok( !$die, 'Basic quote processed without dying' );
137
138
        # Test for expected logs for the passed quote file
139
        is( $logger->count, 8, "8 log lines recorded for passed quote file" );
140
141
        #$logger->diag();
142
        $logger->trace_like(
143
            qr/Created basket:.*/,
144
            "Trace recorded adding basket"
145
        )->trace_like(
146
            qr/Checking db for matches.*/,
147
            "Trace recorded checking db for matches"
148
        )->trace_like(
149
            qr/Added biblio:.*/,
150
            "Trace recoded adding new biblio"
151
        )->trace_like(
152
            qr/Order created:.*/,
153
            "Trace recorded adding order"
154
        )->trace_like(
155
            qr/Added item:.*/,
156
            "Trace recorded adding new item"
157
        )->trace_like(
158
            qr/Item added to rota.*/,
159
            "Trace recrded adding item to rota"
160
        )->debug_like(
161
            qr/.*specialUpdate biblioserver$/,
162
            "Trace recorded biblioserver index"
163
        )->clear();
164
165
        # No errors expected for QUOTE_SMALL
166
        my $errors = Koha::Edifact::File::Errors->search();
167
        is( $errors->count, 0, '0 errors recorded for simple quote' );
168
169
        # Status changed to received
170
        $quote->get_from_storage;
171
        is( $quote->status, 'received', 'Quote status set to received' );
172
173
        # Generate basket
174
        my $baskets = Koha::Acquisition::Baskets->search( { booksellerid => $account->{vendor_id} } );
175
        is( $baskets->count, 1, "One basket created for single message quote file" );
176
177
        my $basket = $baskets->next;
178
        is( $basket->basketname, $filename, "Basket uses EDI filename for name" );
179
180
        # Order lines
181
        my $orders = $basket->orders;
182
        is( $orders->count, 1, "One order line created for single record quote file" );
183
184
        my $order = $orders->next;
185
        ok( $order->biblionumber, 'Biblionumber assigned to order' );
186
        is( $order->entrydate, dt_from_string()->ymd(), 'Entry date set correctly' );
187
188
        # Fund allocation
189
        $fund = $order->fund;
190
        ok( $fund, 'Fund allocated to order' );
191
        is( $fund->budget_code, 'REF', 'Correct fund allocated for order' );
192
193
        # Test 008 handling
194
        my $biblio       = $order->biblio;
195
        my $record       = $biblio->record;
196
        my $record_field = $record->field('008');
197
        is( exists( $record_field->{_data} ), 1, '008 field added when missing from quote' );
198
199
        # Item allocation
200
        my $items = $order->items;
201
        is(
202
            $items->count, 1,
203
            "One item created when AcqCreateItem is set to 'ordering' for single record, single quantity quote file"
204
        );
205
206
        # Test stock rotation handling
207
        my $item    = $items->next;
208
        my $on_rota = Koha::StockRotationItems->search( { itemnumber_id => $item->itemnumber } );
209
        is( $on_rota->count,                 1,         "Item added to rotation" );
210
        is( $on_rota->next->stage->rota->id, $rota->id, "Correct rotation assigned" );
211
212
        # Confirm no ORDER message generated for 'auto_orders => 0'
213
        is( $basket->closedate, undef, 'Basket left open for auto_orders disabled' );
214
        my $edi_orders = $schema->resultset('EdifactMessage')->search(
215
            {
216
                message_type => 'ORDERS',
217
                basketno     => $basket->basketno,
218
            }
219
        );
220
        is( $edi_orders->count, 0, 'ORDER message not created for auto_orders disabled' );
97
221
98
    # Process the test quote file
222
        $logger->clear();
99
    my $error;
223
        $schema->storage->txn_rollback;
100
    eval {
101
        process_quote($quote);
102
        1;
103
    } or do {
104
        $error = $@;
105
    };
224
    };
106
    ok( !$error, 'process_quote completed without dying' );
107
108
    # Test for expected warnings for the passed quote file
109
    is( $logger->count, 8, "8 log lines recorded for passed quote file" );
110
225
111
    #$logger->diag();
226
    # Test 2: Auto Orders Processing
112
    $logger->trace_like(
227
    subtest 'auto_orders_processing' => sub {
113
        qr/Created basket:.*/,
228
        plan tests => 7;
114
        "Trace recorded adding basket"
229
115
    )->trace_like(
230
        $schema->storage->txn_begin;
116
        qr/Checking db for matches.*/,
231
        my $account = $builder->build(
117
        "Trace recorded checking db for matches"
232
            {
118
    )->trace_like(
233
                source => 'VendorEdiAccount',
119
        qr/New biblio added.*/,
234
                value  => {
120
        "Trace recoded adding new biblio"
235
                    description    => 'auto order vendor',
121
    )->trace_like(
236
                    transport      => 'FILE',
122
        qr/Order created:.*/,
237
                    plugin         => '',
123
        "Trace recorded adding order"
238
                    san            => $test_san,
124
    )->trace_like(
239
                    orders_enabled => 1,
125
        qr/Added item:.*/,
240
                    auto_orders    => 1,
126
        "Trace recorded adding new item"
241
                }
127
    )->trace_like(
242
            }
128
        qr/Item added to rota.*/,
243
        );
129
        "Trace recrded adding item to rota"
244
        my $ean = $builder->build(
130
    )->debug_like(
245
            {
131
        qr/.*specialUpdate biblioserver$/,
246
                source => 'EdifactEan',
132
        "Trace recorded biblioserver index"
247
                value  => {
133
    )->clear();
248
                    description => 'test ean',
249
                    branchcode  => undef,
250
                    ean         => $test_san
251
                }
252
            }
253
        );
254
255
        # Setup the fund
256
        $builder->build(
257
            {
258
                source => 'Aqbudget',
259
                value  => {
260
                    budget_code      => 'REF',
261
                    budget_period_id => $active_period->{budget_period_id}
262
                }
263
            }
264
        );
134
265
135
    # Test for quote status change
266
        my $filename = 'QUOTES_SMALL.CEQ';
136
    $quote->get_from_storage;
267
        my $trans    = Koha::Edifact::Transport->new( $account->{id} );
137
    is( $quote->status, 'received', 'Quote status was set to received' );
268
        $trans->working_directory($dirname);
138
269
139
    # Tests for generated basket for passed quote file
270
        my $mhash = $trans->message_hash();
140
    my $baskets = Koha::Acquisition::Baskets->search( { booksellerid => $account->{vendor_id} } );
271
        $mhash->{message_type} = 'QUOTE';
141
    is( $baskets->count, 1, "1 basket created for a single quote file" );
272
        $trans->ingest( $mhash, $filename );
142
    my $basket = $baskets->next;
143
273
144
    my $orders = $basket->orders;
274
        my $quote = $schema->resultset('EdifactMessage')->find( { filename => $filename } );
145
    is( $orders->count, 1, "1 order line attached to basket when only 1 order is in the edi message" );
146
    my $order = $orders->next;
147
275
148
    my $biblio = $order->biblio;
276
        # Process quote and check results
277
        my $die;
278
        eval {
279
            process_quote($quote);
280
            1;
281
        } or do {
282
            $die = $@;
283
        };
284
        ok( !$die, 'Basic quote processed, with auto_orders enabled, without dying' );
149
285
150
    my $items = $order->items;
286
        my $baskets = Koha::Acquisition::Baskets->search( { booksellerid => $account->{vendor_id} } );
151
    is( $items->count, 1, "1 item added when AcqCreateItem eq ordering and 1 item is in the EDI quote" );
287
        is( $baskets->count, 1, "Basket created" );
152
    my $item = $items->next;
153
288
154
    # Test that item is added to rota appropriately
289
        my $basket = $baskets->next;
155
    my $on_rota = Koha::StockRotationItems->search( { itemnumber_id => $item->itemnumber } );
290
        ok( $basket->closedate, 'Basket automatically closed for auto_orders' );
156
    is( $on_rota->count, 1, "Item added to stockrotation rota" );
157
291
158
    my $rota_item = $on_rota->next;
292
        my $orders = $basket->orders;
159
    is( $rota_item->stage->rota->id, $rota->id, "Item is on correct rota" );
293
        is( $orders->count, 1, "One order created" );
160
294
161
    $schema->storage->txn_rollback;
295
        my $order = $orders->next;
162
};
296
        ok( $order->biblionumber, 'Biblionumber assigned to order' );
163
297
164
subtest '_handle_008_field' => sub {
298
        # Check EDI order generation
165
    plan tests => 4;
299
        my $edi_orders = $schema->resultset('EdifactMessage')->search(
300
            {
301
                message_type => 'ORDERS',
302
                basketno     => $basket->basketno,
303
            }
304
        );
305
        is( $edi_orders->count,        1,         'EDI order message created' );
306
        is( $edi_orders->next->status, 'Pending', 'EDI order status is Pending' );
166
307
167
    $schema->storage->txn_begin;
308
        $logger->clear();
309
        $schema->storage->txn_rollback;
310
    };
168
311
169
    # Add our test quote file to the database for testing against
312
    # Test 3: Multiple item quote
170
    my $account = $builder->build(
313
    subtest 'multi-item quote' => sub {
171
        {
314
        plan tests => 18;
172
            source => 'VendorEdiAccount',
315
173
            value  => {
316
        $schema->storage->txn_begin;
174
                description => 'test vendor', transport => 'FILE',
317
318
        # Create vendor EDI account
319
        my $account = $builder->build(
320
            {
321
                source => 'VendorEdiAccount',
322
                value  => {
323
                    description => 'multi-item vendor',
324
                    transport   => 'FILE',
325
                    plugin      => '',
326
                }
175
            }
327
            }
328
        );
329
        my $ean = $builder->build(
330
            {
331
                source => 'EdifactEan',
332
                value  => {
333
                    description => 'test ean',
334
                    branchcode  => undef,
335
                    ean         => $test_san
336
                }
337
            }
338
        );
339
340
        # Setup multiple funds
341
        my %funds;
342
        for my $code (qw(REF LOAN)) {
343
            $funds{$code} = $builder->build(
344
                {
345
                    source => 'Aqbudget',
346
                    value  => {
347
                        budget_code      => $code,
348
                        budget_period_id => $active_period->{budget_period_id}
349
                    }
350
                }
351
            );
176
        }
352
        }
177
    );
178
    my $dirname  = ( $Bin =~ /^(.*\/t\/)/ ? $1 . 'edi_testfiles/' : q{} );
179
    my $filename = 'QUOTES_SMALL.CEQ';
180
    ok( -e $dirname . $filename, 'File QUOTES_SMALL.CEQ found' );
181
353
182
    my $trans = Koha::Edifact::Transport->new( $account->{id} );
354
        # Setup multiple rota
183
    $trans->working_directory($dirname);
355
        my %rota;
356
        for my $title (qw(TEST FAST SLOW)) {
357
            $rota{$title} = $builder->build_object(
358
                {
359
                    class => 'Koha::StockRotationRotas',
360
                    value => { title => $title }
361
                }
362
            );
363
            $builder->build(
364
                {
365
                    source => 'Stockrotationstage',
366
                    value  => { rota_id => $rota{$title}->rota_id },
367
                }
368
            );
369
        }
184
370
185
    my $mhash = $trans->message_hash();
371
        my $description = <<~"END";
186
    $mhash->{message_type} = 'QUOTE';
372
            Loaded QUOTE file with 1 Message that contains 2 LIN segments with the first
187
    $trans->ingest( $mhash, $filename );
373
            consistent of 1 item and the second with 3 items with 2 different funds.
374
        END
375
        diag($description);
188
376
189
    my $quote = $schema->resultset('EdifactMessage')->find( { filename => $filename } );
377
        my $filename = 'QUOTES_MULTI.CEQ';
378
        my $trans    = Koha::Edifact::Transport->new( $account->{id} );
379
        $trans->working_directory($dirname);
380
        my $mhash = $trans->message_hash();
381
        $mhash->{message_type} = 'QUOTE';
382
        $trans->ingest( $mhash, $filename );
190
383
191
    # Test quote expects REF to be a valid and active fund code
384
        my $quote = $schema->resultset('EdifactMessage')->find( { filename => $filename } );
192
    my $active_period = $builder->build(
385
        process_quote($quote);
193
        {
386
194
            source => 'Aqbudgetperiod',
387
        #$logger->diag();
195
            value  => { budget_period_active => 1 }
388
196
        }
389
        my $baskets = Koha::Acquisition::Baskets->search( { booksellerid => $account->{vendor_id} } );
197
    );
390
        is( $baskets->count, 1, "One basket created for quote" );
198
    my $fund = $builder->build(
391
199
        {
392
        my $basket = $baskets->next;
200
            source => 'Aqbudget',
393
        my $orders = $basket->orders;
201
            value  => {
394
        is( $orders->count, 3, "Three order lines created for quote" );
202
                budget_code      => 'REF',
395
203
                budget_period_id => $active_period->{budget_period_id}
396
        my %biblios;
397
        my $orderline = 0;
398
        while ( my $order = $orders->next ) {
399
            $orderline++;
400
            diag( "Looking at order: " . $orderline );
401
            if ( $orderline == 1 ) {
402
403
                # Fund allocation
404
                my $fund = $order->fund;
405
                is( $fund->budget_code, 'REF', 'Correct fund allocated for first orderline' );
406
407
                # Check biblio
408
                ok( $order->biblionumber, 'Biblionumber assigned to order' );
409
                $biblios{ $order->biblionumber }++;
410
411
                # Check items created
412
                my $items = $order->items;
413
                is( $items->count, 1, 'One item created for the first orderline' );
414
415
                # Check first order GIR details
416
                my $item = $items->next;
417
                my $rota = $item->stockrotationitem;
418
                ok( $rota, 'Item was assigned to a rota' );
419
                is( $rota->stage->rota->title, 'TEST', "Item was assigned to the correct rota" );
420
421
            } elsif ( $orderline == 2 ) {
422
423
                # Fund allocation
424
                my $fund = $order->fund;
425
                is( $fund->budget_code, 'LOAN', 'Correct fund allocated for second orderline' );
426
427
                # Check biblio
428
                ok( $order->biblionumber, 'Biblionumber assigned to order' );
429
                $biblios{ $order->biblionumber }++;
430
431
                # Check items created
432
                my $items = $order->items;
433
                is( $items->count, 2, 'Two items created for the second orderline' );
434
435
                # Check second order GIR details
436
                my %rotas;
437
                while ( my $item = $items->next ) {
438
                    my $rota = $item->stockrotationitem;
439
                    ok( $rota, 'Item was assigned to a rota' );
440
                    $rotas{ $rota->stage->rota->title }++;
441
                }
442
                is( $rotas{'FAST'}, 1, "One item added to 'FAST' rota" );
443
                is( $rotas{'SLOW'}, 1, "One item added to 'SLOW' rota" );
444
            } elsif ( $orderline == 3 ) {
445
                diag("Second LIN split into 2 Orderlines, one for each Fund");
446
447
                # Fund allocation
448
                my $fund = $order->fund;
449
                is( $fund->budget_code, 'REF', 'Correct fund allocated for third orderline' );
450
451
                # Check biblio
452
                ok( $order->biblionumber, 'Biblionumber assigned to order' );
453
                $biblios{ $order->biblionumber }++;
454
455
                # Check items created
456
                my $items = $order->items;
457
                is( $items->count, 1, 'One item created for the third orderline' );
458
459
                # Check first order GIR details
460
                my $item = $items->next;
461
                my $rota = $item->stockrotationitem;
462
                ok( !$rota, 'Item was not assigned to a rota' );
204
            }
463
            }
205
        }
464
        }
206
    );
207
465
208
    # The quote expects a ROT1 stock rotation roata to exist
466
        $logger->clear();
209
    my $rota = $builder->build_object(
467
        $schema->storage->txn_rollback;
210
        {
468
    };
211
            class => 'Koha::StockRotationRotas',
212
            value => { title => 'ROT1' }
213
        }
214
    );
215
    $builder->build(
216
        {
217
            source => 'Stockrotationstage',
218
            value  => { rota_id => $rota->rota_id },
219
        }
220
    );
221
469
222
    # Process the test quote file
470
    # Test 4: Invalid Fund Error Handling
223
    process_quote($quote);
471
    subtest 'invalid_fund_handling' => sub {
472
        plan tests => 21;
224
473
225
    $quote->get_from_storage;
474
        $schema->storage->txn_begin;
226
475
227
    # Tests for generated basket for passed quote file
476
        my $account = $builder->build(
228
    my $baskets = Koha::Acquisition::Baskets->search( { booksellerid => $account->{vendor_id} } );
477
            {
229
    my $basket  = $baskets->next;
478
                source => 'VendorEdiAccount',
479
                value  => {
480
                    description => 'error test vendor',
481
                    transport   => 'FILE',
482
                }
483
            }
484
        );
485
        my $ean = $builder->build(
486
            {
487
                source => 'EdifactEan',
488
                value  => {
489
                    description => 'test ean',
490
                    branchcode  => undef,
491
                    ean         => $test_san
492
                }
493
            }
494
        );
230
495
231
    my $orders = $basket->orders;
496
        my $description = <<~"END";
232
    my $order  = $orders->next;
497
            Loading QUOTE file with 1 Message that contains 2 LIN segments with the first
498
            consistent of 1 item and the second with 3 items with 2 different undefined funds.
499
        END
500
        diag($description);
233
501
234
    my $biblio       = $order->biblio;
502
        my $filename = 'QUOTES_MULTI.CEQ';
235
    my $record       = $biblio->record;
503
        my $trans    = Koha::Edifact::Transport->new( $account->{id} );
236
    my $record_field = $record->field('008');
504
        $trans->working_directory($dirname);
237
505
238
    is( exists( $record_field->{_data} ), 1, 'Field has been added' );
506
        my $mhash = $trans->message_hash();
507
        $mhash->{message_type} = 'QUOTE';
508
        $trans->ingest( $mhash, $filename );
239
509
240
    # Test without calling the 008 handler
510
        my $quote = $schema->resultset('EdifactMessage')->find( { filename => $filename } );
241
    $account = $builder->build(
242
        {
243
            source => 'VendorEdiAccount',
244
            value  => {
245
                description => 'test vendor', transport => 'FILE',
246
            }
247
        }
248
    );
249
    $dirname  = ( $Bin =~ /^(.*\/t\/)/ ? $1 . 'edi_testfiles/' : q{} );
250
    $filename = 'QUOTES_SMALL_2.CEQ';
251
    ok( -e $dirname . $filename, 'File QUOTES_SMALL_2.CEQ found' );
252
511
253
    $trans = Koha::Edifact::Transport->new( $account->{id} );
512
        process_quote($quote);
254
    $trans->working_directory($dirname);
255
513
256
    $mhash = $trans->message_hash();
514
        #$logger->diag();
257
    $mhash->{message_type} = 'QUOTE';
515
        $logger->trace_like(
258
    $trans->ingest( $mhash, $filename );
516
            qr/Created basket:.*/,
517
            "Trace recorded basket added"
518
        )->trace_is(
519
            qq/Checking db for matches with 9781529923766/,
520
            "Trace recorded isbn lookup"
521
        )->trace_like(
522
            qr/Added biblio:.*/,
523
            "Trace recorded adding new biblio"
524
        )->trace_is(
525
            qq/Skipping orderline with invalid budget: REF/,
526
            "Trace recorded skipping orderline with invalid fund"
527
        )->trace_is(
528
            qq/Checking db for matches with 9781785044342/,
529
            "Trace recorded isbn lookup"
530
        )->trace_like(
531
            qr/Added biblio:.*/,
532
            "Trace recorded adding new biblio"
533
        )->trace_is(
534
            qq/Skipping item with invalid budget: LOAN/,
535
            "Trace recorded skipping item with invalid fund"
536
        )->trace_is(
537
            qq/Skipping item with invalid budget: REF/,
538
            "Trace recorded skipping item with invalid fund"
539
        )->trace_is(
540
            qq/Skipping item with invalid budget: LOAN/,
541
            "Trace recorded skipping item with invalid fund"
542
        );
543
544
        # Errors should be recorded for skipped sections
545
        my $errors = Koha::Edifact::File::Errors->search();
546
        is( $errors->count, 4, '4 errors recorded for missing funds in quote' );
547
548
        my $error = $errors->next;
549
        ok( $error->section, 'First error section is present' );
550
        is( $error->details, 'Skipped orderline line with invalid budget: REF', 'First error details is correct' );
551
552
        $error = $errors->next;
553
        ok( $error->section, 'Second error section is present' );
554
        is( $error->details, 'Skipped GIR line with invalid budget: LOAN', 'Second error details is correct' );
555
556
        $error = $errors->next;
557
        ok( $error->section, 'Third error section is present' );
558
        is( $error->details, 'Invalid budget REF found', 'Third error details is correct' );
559
560
        $error = $errors->next;
561
        ok( $error->section, 'Fourth error section is present' );
562
        is( $error->details, 'Invalid budget LOAN found', 'Fourth error details is correct' );
563
564
        $quote->get_from_storage;
565
        is( $quote->status, 'error', 'Quote status set to error for invalid fund' );
566
567
        my $baskets = Koha::Acquisition::Baskets->search( { booksellerid => $account->{vendor_id} } );
568
        is( $baskets->count, 1, 'Basket still created despite errors' );
569
570
        my $orders = $baskets->next->orders;
571
        is( $orders->count, 0, 'No orders created with invalid fund' );
572
573
        $logger->clear();
574
        $schema->storage->txn_rollback;
575
    };
259
576
260
    $quote = $schema->resultset('EdifactMessage')->find( { filename => $filename } );
577
    # Test 5: Multiple message quote file
578
    subtest 'multiple_message_handling' => sub {
579
        plan tests => 3;
261
580
262
    # Test quote expects REF to be a valid and active fund code
581
        $schema->storage->txn_begin;
263
    $active_period = $builder->build(
582
264
        {
583
        my $account = $builder->build(
265
            source => 'Aqbudgetperiod',
584
            {
266
            value  => { budget_period_active => 1 }
585
                source => 'VendorEdiAccount',
267
        }
586
                value  => {
268
    );
587
                    description => 'error test vendor',
269
    $fund = $builder->build(
588
                    transport   => 'FILE',
270
        {
589
                }
271
            source => 'Aqbudget',
272
            value  => {
273
                budget_code      => 'REF2',
274
                budget_period_id => $active_period->{budget_period_id}
275
            }
590
            }
276
        }
591
        );
277
    );
592
        my $ean = $builder->build(
593
            {
594
                source => 'EdifactEan',
595
                value  => {
596
                    description => 'test ean',
597
                    branchcode  => undef,
598
                    ean         => $test_san
599
                }
600
            }
601
        );
278
602
279
    # The quote expects a ROT1 stock rotation roata to exist
603
        my $description = <<~"END";
280
    $rota = $builder->build_object(
604
            Loading QUOTE file with 2 messages
281
        {
605
        END
282
            class => 'Koha::StockRotationRotas',
606
        diag($description);
283
            value => { title => 'ROT2' }
284
        }
285
    );
286
    $builder->build(
287
        {
288
            source => 'Stockrotationstage',
289
            value  => { rota_id => $rota->rota_id },
290
        }
291
    );
292
607
293
    # Process the test quote file
608
        my $filename = 'QUOTES_BIG.CEQ';
294
    my $edi_module = Test::MockModule->new('Koha::EDI');
609
        my $trans    = Koha::Edifact::Transport->new( $account->{id} );
295
    $edi_module->mock(
610
        $trans->working_directory($dirname);
296
        '_check_for_existing_bib',
611
297
        sub {
612
        my $mhash = $trans->message_hash();
298
            my $bib_record = shift;
613
        $mhash->{message_type} = 'QUOTE';
299
            return;
614
        $trans->ingest( $mhash, $filename );
300
        }
301
    );
302
    $edi_module->mock(
303
        '_handle_008_field',
304
        sub {
305
            my $bib_record = shift;
306
            return $bib_record;
307
        }
308
    );
309
    process_quote($quote);
310
615
311
    $quote->get_from_storage;
616
        my $quote = $schema->resultset('EdifactMessage')->find( { filename => $filename } );
617
618
        process_quote($quote);
312
619
313
    # Tests for generated basket for passed quote file
620
        #$logger->diag();
314
    $baskets = Koha::Acquisition::Baskets->search( { booksellerid => $account->{vendor_id} } );
315
    $basket  = $baskets->next;
316
621
317
    $orders = $basket->orders;
622
        my $baskets = Koha::Acquisition::Baskets->search( { booksellerid => $account->{vendor_id} } );
318
    $order  = $orders->next;
623
        is( $baskets->count, 2, 'Two baskets added for file containing 2 messages' );
319
624
320
    $biblio       = $order->biblio;
625
        # First basket
321
    $record       = $biblio->record;
626
        my $basket = $baskets->next;
322
    $record_field = $record->field('008');
627
        is( $basket->basketname, $filename, "Basket uses EDI filename for name" );
323
628
324
    is( $record_field->{_data}, undef, 'Field has not been added' );
629
        # Second basket
630
        $basket = $baskets->next;
631
        is( $basket->basketname, $filename, "Basket uses EDI filename for name" );
325
632
633
        $logger->clear();
634
        $schema->storage->txn_rollback;
635
    };
636
637
    # Clean up
326
    $logger->clear();
638
    $logger->clear();
327
    $schema->storage->txn_rollback;
639
    $schema->storage->txn_rollback;
328
};
640
};
329
641
330
subtest 'process_invoice' => sub {
642
subtest 'process_invoice' => sub {
331
    plan tests => 19;
643
    plan tests => 20;
332
644
333
    $schema->storage->txn_begin;
645
    $schema->storage->txn_begin;
334
646
Lines 403-408 subtest 'process_invoice' => sub { Link Here
403
        1;
715
        1;
404
    } or do {
716
    } or do {
405
        $error = $@;
717
        $error = $@;
718
        diag($error);
406
    };
719
    };
407
    ok( !$error, 'process_invoice completed without dying' );
720
    ok( !$error, 'process_invoice completed without dying' );
408
721
Lines 453-458 subtest 'process_invoice' => sub { Link Here
453
        'Warn recorded for unmatched item'
766
        'Warn recorded for unmatched item'
454
    )->clear();
767
    )->clear();
455
768
769
    # Errors should be recorded for skipped sections
770
    my $errors = Koha::Edifact::File::Errors->search();
771
    is( $errors->count, 6, '6 errors recorded for invoice' );
772
    while ( my $error = $errors->next ) {
773
        diag( $error->details );
774
    }
775
456
    my $invoice3 = Koha::Acquisition::Invoices->search( { invoicenumber => 'INV00003' }, { rows => 1 } )->single;
776
    my $invoice3 = Koha::Acquisition::Invoices->search( { invoicenumber => 'INV00003' }, { rows => 1 } )->single;
457
    ok( $invoice3, "Invoice added to database" );
777
    ok( $invoice3, "Invoice added to database" );
458
    is( $invoice3->booksellerid, $account->{vendor_id}, 'Invoice has test booksellerid' );
778
    is( $invoice3->booksellerid, $account->{vendor_id}, 'Invoice has test booksellerid' );
(-)a/t/edi_testfiles/QUOTES_BIG.CEQ (+1 lines)
Line 0 Link Here
1
UNA:+.? 'UNB+UNOC:3+5013546027173+5013546098818+240123:0945+1044416+ASKEDI:+QUOTES++++'UNH+1044416001+QUOTES:D:96A:UN:EAN002'BGM+31C::28+WO0800131+9'DTM+137:20240123:102'RFF+ON:orders 23/1'CUX+2:GBP:12'NAD+BY+5013546098818::9'NAD+SU+5013546027173::9'LIN+1++9781529923766:EN'PIA+5+152992376X:IB'IMD+L+010+:::Thompson'IMD+L+011+:::Louise'IMD+L+050+:::Lucky'IMD+L+060+:::learning to live again'IMD+L+120+:::Ebury Spotlight'IMD+L+170+:::2024'IMD+L+180+:::304'IMD+L+220+:::Hbk'IMD+L+230+:::791.45'IMD+L+250+:::AN'QTY+1:1'GIR+001+BOOK:LST+ANF:LSQ+CPL:LLO+REF:LFN+791.45:LCL'GIR+001+22.00:LCV'GIR+001+ROT1:LRP'PRI+AAE:22.00'RFF+QLI:WO0800131000001'UNS+S'CNT+2:1'UNT+27+1044416001'UNZ+1+1044416'UNA:+.? 'UNB+UNOC:3+5013546027173+5013546098818+230713:1031+1044417+ASKEDI+QUOTES++++'UNH+1+QUOTES:D:96A:UN:EAN002'BGM+31C::28+WO0800132+9'DTM+137:20230713:102'NAD+BY+5412345000013::9'NAD+SU+4012345000094::9'CUX+2:GBP:9'LIN+1++9781529923766:EN'PIA+1+152992376X:SA'IMD+L+010+:::Thompson'IMD+L+011+:::Louise'IMD+L+050+:::Lucky'IMD+L+060+:::Learning to live again'GIR+001+BOOK:LST+ANF:LSQ+CPL:LLO+REF:LFN+791.45:LCL'GIR+001+22.00:LCV'GIR+001+TEST:LRP'QTY+21:1:PCE'MOA+203:25.99'RFF+ABO:REF'LIN+2++9781785044342:EN'PIA+5+1785044346:IB'IMD+L+010+:::Hansen'IMD+L+011+:::Anders'IMD+L+050+:::The attention fix'IMD+L+060+:::how to focus in a world that wants to distract you'QTY+1:3'GIR+001+BOOK:LST+ANF:LSQ+CPL:LLO+LOAN:LFN+153.733:LCL'GIR+001+14.99:LCV'GIR+001+FAST:LRP'GIR+002+BOOK:LST+ANF:LSQ+FFL:LLO+REF:LFN+153.733:LCL'GIR+002+14.99:LCV'GIR+003+BOOK:LST+ANF:LSQ+FPL:LLO+LOAN:LFN+153.733:LCL'GIR+003+14.99:LCV'GIR+003+SLOW:LRP'PRI+AAE:14.99'RFF+QLI:WO0774049000002'UNS+S'MOA+86:87.97'UNT+34+1'UNZ+1+1'
(-)a/t/edi_testfiles/QUOTES_MULTI.CEQ (-1 / +1 lines)
Line 0 Link Here
0
- 
1
UNA:+.? 'UNB+UNOC:3+5013546027173+5013546098818+230713:1031+1044417+ASKEDI+QUOTES++++'UNH+1+QUOTES:D:96A:UN:EAN002'BGM+31C::28+WO0800132+9'DTM+137:20230713:102'NAD+BY+5412345000013::9'NAD+SU+4012345000094::9'CUX+2:GBP:9'LIN+1++9781529923766:EN'PIA+1+152992376X:SA'IMD+L+010+:::Thompson'IMD+L+011+:::Louise'IMD+L+050+:::Lucky'IMD+L+060+:::Learning to live again'GIR+001+BOOK:LST+ANF:LSQ+CPL:LLO+REF:LFN+791.45:LCL'GIR+001+22.00:LCV'GIR+001+TEST:LRP'QTY+21:1:PCE'MOA+203:25.99'RFF+ABO:REF'LIN+2++9781785044342:EN'PIA+5+1785044346:IB'IMD+L+010+:::Hansen'IMD+L+011+:::Anders'IMD+L+050+:::The attention fix'IMD+L+060+:::how to focus in a world that wants to distract you'QTY+1:3'GIR+001+BOOK:LST+ANF:LSQ+CPL:LLO+LOAN:LFN+153.733:LCL'GIR+001+14.99:LCV'GIR+001+FAST:LRP'GIR+002+BOOK:LST+ANF:LSQ+FFL:LLO+REF:LFN+153.733:LCL'GIR+002+14.99:LCV'GIR+003+BOOK:LST+ANF:LSQ+FPL:LLO+LOAN:LFN+153.733:LCL'GIR+003+14.99:LCV'GIR+003+SLOW:LRP'PRI+AAE:14.99'RFF+QLI:WO0774049000002'UNS+S'MOA+86:87.97'UNT+34+1'UNZ+1+1'

Return to bug 38689