From 4e97c0d87f1ffb15a10607b8b1b82fb459be226e Mon Sep 17 00:00:00 2001 From: Martin Renvoize Date: Mon, 13 Jan 2025 18:12:39 +0000 Subject: [PATCH] Bug 38689: Improve test coverage This patch drastically enhances the existing tests. We add tests for the various codepaths for handling EDI QUOTES including LIN segment splitting for multi-fund orders. --- t/db_dependent/Koha/EDI.t | 790 ++++++++++++++++++++++--------- t/edi_testfiles/QUOTES_BIG.CEQ | 1 + t/edi_testfiles/QUOTES_MULTI.CEQ | 1 + 3 files changed, 557 insertions(+), 235 deletions(-) create mode 100644 t/edi_testfiles/QUOTES_BIG.CEQ create mode 100644 t/edi_testfiles/QUOTES_MULTI.CEQ diff --git a/t/db_dependent/Koha/EDI.t b/t/db_dependent/Koha/EDI.t index e9016014de8..4f87260716a 100755 --- a/t/db_dependent/Koha/EDI.t +++ b/t/db_dependent/Koha/EDI.t @@ -20,7 +20,7 @@ use Modern::Perl; use FindBin qw( $Bin ); -use Test::More tests => 3; +use Test::More tests => 2; use Test::Warn; use Test::MockModule; @@ -30,305 +30,617 @@ use t::lib::TestBuilder; use Koha::EDI qw(process_quote process_invoice); use Koha::Edifact::Transport; +use Koha::Edifact::File::Errors; +use Koha::DateUtils qw(dt_from_string); my $schema = Koha::Database->new->schema; my $builder = t::lib::TestBuilder->new; my $logger = t::lib::Mocks::Logger->new(); subtest 'process_quote' => sub { - plan tests => 16; + plan tests => 5; $schema->storage->txn_begin; - # Add our test quote file to the database for testing against - my $account = $builder->build( - { - source => 'VendorEdiAccount', - value => { - description => 'test vendor', transport => 'FILE', - } - } - ); - my $dirname = ( $Bin =~ /^(.*\/t\/)/ ? $1 . 'edi_testfiles/' : q{} ); - my $filename = 'QUOTES_SMALL.CEQ'; - ok( -e $dirname . $filename, 'File QUOTES_SMALL.CEQ found' ); - - my $trans = Koha::Edifact::Transport->new( $account->{id} ); - $trans->working_directory($dirname); - - my $mhash = $trans->message_hash(); - $mhash->{message_type} = 'QUOTE'; - $trans->ingest( $mhash, $filename ); - - my $quote = $schema->resultset('EdifactMessage')->find( { filename => $filename } ); - - # Test quote expects REF to be a valid and active fund code + # Common setup for all test cases + my $test_san = '5013546098818'; + my $dirname = ( $Bin =~ /^(.*\/t\/)/ ? $1 . 'edi_testfiles/' : q{} ); my $active_period = $builder->build( { source => 'Aqbudgetperiod', value => { budget_period_active => 1 } } ); - my $fund = $builder->build( - { - source => 'Aqbudget', - value => { - budget_code => 'REF', - budget_period_id => $active_period->{budget_period_id} - } - } - ); + t::lib::Mocks::mock_preference( 'CataloguingLog', 0 ); - # The quote expects a ROT1 stock rotation roata to exist - my $rota = $builder->build_object( - { - class => 'Koha::StockRotationRotas', - value => { title => 'ROT1' } - } - ); - $builder->build( - { - source => 'Stockrotationstage', - value => { rota_id => $rota->rota_id }, - } - ); + # Test 1: Basic Quote Processing + subtest 'basic_quote_processing' => sub { + plan tests => 27; + + $schema->storage->txn_begin; + + my $account = $builder->build( + { + source => 'VendorEdiAccount', + value => { + description => 'test vendor', + transport => 'FILE', + plugin => '', + san => $test_san, + orders_enabled => 1, + auto_orders => 0, + } + } + ); + my $ean = $builder->build( + { + source => 'EdifactEan', + value => { + description => 'test ean', + branchcode => undef, + ean => $test_san + } + } + ); + + my $filename = 'QUOTES_SMALL.CEQ'; + ok( -e $dirname . $filename, 'File QUOTES_SMALL.CEQ found' ); + + # Setup the fund code + my $fund = $builder->build( + { + source => 'Aqbudget', + value => { + budget_code => 'REF', + budget_period_id => $active_period->{budget_period_id} + } + } + ); - t::lib::Mocks::mock_preference( 'CataloguingLog', 0 ); + # Setup stock rotation + my $rota = $builder->build_object( + { + class => 'Koha::StockRotationRotas', + value => { title => 'ROT1' } + } + ); + $builder->build( + { + source => 'Stockrotationstage', + value => { rota_id => $rota->rota_id }, + } + ); + + my $trans = Koha::Edifact::Transport->new( $account->{id} ); + $trans->working_directory($dirname); + + my $mhash = $trans->message_hash(); + $mhash->{message_type} = 'QUOTE'; + $trans->ingest( $mhash, $filename ); + + my $quote = $schema->resultset('EdifactMessage')->find( { filename => $filename } ); + + ok( $quote, 'Quote message created in database' ); + is( $quote->status, 'new', 'Initial quote status is new' ); + + t::lib::Mocks::mock_preference( 'AcqCreateItem', 'ordering' ); + + # Process quote and check results + my $die; + eval { + process_quote($quote); + 1; + } or do { + $die = $@; + }; + ok( !$die, 'Basic quote processed without dying' ); + + # Test for expected logs for the passed quote file + is( $logger->count, 8, "8 log lines recorded for passed quote file" ); + + #$logger->diag(); + $logger->trace_like( + qr/Created basket:.*/, + "Trace recorded adding basket" + )->trace_like( + qr/Checking db for matches.*/, + "Trace recorded checking db for matches" + )->trace_like( + qr/Added biblio:.*/, + "Trace recoded adding new biblio" + )->trace_like( + qr/Order created:.*/, + "Trace recorded adding order" + )->trace_like( + qr/Added item:.*/, + "Trace recorded adding new item" + )->trace_like( + qr/Item added to rota.*/, + "Trace recrded adding item to rota" + )->debug_like( + qr/.*specialUpdate biblioserver$/, + "Trace recorded biblioserver index" + )->clear(); + + # No errors expected for QUOTE_SMALL + my $errors = Koha::Edifact::File::Errors->search(); + is( $errors->count, 0, '0 errors recorded for simple quote' ); + + # Status changed to received + $quote->get_from_storage; + is( $quote->status, 'received', 'Quote status set to received' ); + + # Generate basket + my $baskets = Koha::Acquisition::Baskets->search( { booksellerid => $account->{vendor_id} } ); + is( $baskets->count, 1, "One basket created for single message quote file" ); + + my $basket = $baskets->next; + is( $basket->basketname, $filename, "Basket uses EDI filename for name" ); + + # Order lines + my $orders = $basket->orders; + is( $orders->count, 1, "One order line created for single record quote file" ); + + my $order = $orders->next; + ok( $order->biblionumber, 'Biblionumber assigned to order' ); + is( $order->entrydate, dt_from_string()->ymd(), 'Entry date set correctly' ); + + # Fund allocation + $fund = $order->fund; + ok( $fund, 'Fund allocated to order' ); + is( $fund->budget_code, 'REF', 'Correct fund allocated for order' ); + + # Test 008 handling + my $biblio = $order->biblio; + my $record = $biblio->record; + my $record_field = $record->field('008'); + is( exists( $record_field->{_data} ), 1, '008 field added when missing from quote' ); + + # Item allocation + my $items = $order->items; + is( + $items->count, 1, + "One item created when AcqCreateItem is set to 'ordering' for single record, single quantity quote file" + ); + + # Test stock rotation handling + my $item = $items->next; + my $on_rota = Koha::StockRotationItems->search( { itemnumber_id => $item->itemnumber } ); + is( $on_rota->count, 1, "Item added to rotation" ); + is( $on_rota->next->stage->rota->id, $rota->id, "Correct rotation assigned" ); + + # Confirm no ORDER message generated for 'auto_orders => 0' + is( $basket->closedate, undef, 'Basket left open for auto_orders disabled' ); + my $edi_orders = $schema->resultset('EdifactMessage')->search( + { + message_type => 'ORDERS', + basketno => $basket->basketno, + } + ); + is( $edi_orders->count, 0, 'ORDER message not created for auto_orders disabled' ); - # Process the test quote file - my $error; - eval { - process_quote($quote); - 1; - } or do { - $error = $@; + $logger->clear(); + $schema->storage->txn_rollback; }; - ok( !$error, 'process_quote completed without dying' ); - - # Test for expected warnings for the passed quote file - is( $logger->count, 8, "8 log lines recorded for passed quote file" ); - #$logger->diag(); - $logger->trace_like( - qr/Created basket:.*/, - "Trace recorded adding basket" - )->trace_like( - qr/Checking db for matches.*/, - "Trace recorded checking db for matches" - )->trace_like( - qr/New biblio added.*/, - "Trace recoded adding new biblio" - )->trace_like( - qr/Order created:.*/, - "Trace recorded adding order" - )->trace_like( - qr/Added item:.*/, - "Trace recorded adding new item" - )->trace_like( - qr/Item added to rota.*/, - "Trace recrded adding item to rota" - )->debug_like( - qr/.*specialUpdate biblioserver$/, - "Trace recorded biblioserver index" - )->clear(); + # Test 2: Auto Orders Processing + subtest 'auto_orders_processing' => sub { + plan tests => 7; + + $schema->storage->txn_begin; + my $account = $builder->build( + { + source => 'VendorEdiAccount', + value => { + description => 'auto order vendor', + transport => 'FILE', + plugin => '', + san => $test_san, + orders_enabled => 1, + auto_orders => 1, + } + } + ); + my $ean = $builder->build( + { + source => 'EdifactEan', + value => { + description => 'test ean', + branchcode => undef, + ean => $test_san + } + } + ); + + # Setup the fund + $builder->build( + { + source => 'Aqbudget', + value => { + budget_code => 'REF', + budget_period_id => $active_period->{budget_period_id} + } + } + ); - # Test for quote status change - $quote->get_from_storage; - is( $quote->status, 'received', 'Quote status was set to received' ); + my $filename = 'QUOTES_SMALL.CEQ'; + my $trans = Koha::Edifact::Transport->new( $account->{id} ); + $trans->working_directory($dirname); - # Tests for generated basket for passed quote file - my $baskets = Koha::Acquisition::Baskets->search( { booksellerid => $account->{vendor_id} } ); - is( $baskets->count, 1, "1 basket created for a single quote file" ); - my $basket = $baskets->next; + my $mhash = $trans->message_hash(); + $mhash->{message_type} = 'QUOTE'; + $trans->ingest( $mhash, $filename ); - my $orders = $basket->orders; - is( $orders->count, 1, "1 order line attached to basket when only 1 order is in the edi message" ); - my $order = $orders->next; + my $quote = $schema->resultset('EdifactMessage')->find( { filename => $filename } ); - my $biblio = $order->biblio; + # Process quote and check results + my $die; + eval { + process_quote($quote); + 1; + } or do { + $die = $@; + }; + ok( !$die, 'Basic quote processed, with auto_orders enabled, without dying' ); - my $items = $order->items; - is( $items->count, 1, "1 item added when AcqCreateItem eq ordering and 1 item is in the EDI quote" ); - my $item = $items->next; + my $baskets = Koha::Acquisition::Baskets->search( { booksellerid => $account->{vendor_id} } ); + is( $baskets->count, 1, "Basket created" ); - # Test that item is added to rota appropriately - my $on_rota = Koha::StockRotationItems->search( { itemnumber_id => $item->itemnumber } ); - is( $on_rota->count, 1, "Item added to stockrotation rota" ); + my $basket = $baskets->next; + ok( $basket->closedate, 'Basket automatically closed for auto_orders' ); - my $rota_item = $on_rota->next; - is( $rota_item->stage->rota->id, $rota->id, "Item is on correct rota" ); + my $orders = $basket->orders; + is( $orders->count, 1, "One order created" ); - $schema->storage->txn_rollback; -}; + my $order = $orders->next; + ok( $order->biblionumber, 'Biblionumber assigned to order' ); -subtest '_handle_008_field' => sub { - plan tests => 4; + # Check EDI order generation + my $edi_orders = $schema->resultset('EdifactMessage')->search( + { + message_type => 'ORDERS', + basketno => $basket->basketno, + } + ); + is( $edi_orders->count, 1, 'EDI order message created' ); + is( $edi_orders->next->status, 'Pending', 'EDI order status is Pending' ); - $schema->storage->txn_begin; + $logger->clear(); + $schema->storage->txn_rollback; + }; - # Add our test quote file to the database for testing against - my $account = $builder->build( - { - source => 'VendorEdiAccount', - value => { - description => 'test vendor', transport => 'FILE', + # Test 3: Multiple item quote + subtest 'multi-item quote' => sub { + plan tests => 18; + + $schema->storage->txn_begin; + + # Create vendor EDI account + my $account = $builder->build( + { + source => 'VendorEdiAccount', + value => { + description => 'multi-item vendor', + transport => 'FILE', + plugin => '', + } } + ); + my $ean = $builder->build( + { + source => 'EdifactEan', + value => { + description => 'test ean', + branchcode => undef, + ean => $test_san + } + } + ); + + # Setup multiple funds + my %funds; + for my $code (qw(REF LOAN)) { + $funds{$code} = $builder->build( + { + source => 'Aqbudget', + value => { + budget_code => $code, + budget_period_id => $active_period->{budget_period_id} + } + } + ); } - ); - my $dirname = ( $Bin =~ /^(.*\/t\/)/ ? $1 . 'edi_testfiles/' : q{} ); - my $filename = 'QUOTES_SMALL.CEQ'; - ok( -e $dirname . $filename, 'File QUOTES_SMALL.CEQ found' ); - my $trans = Koha::Edifact::Transport->new( $account->{id} ); - $trans->working_directory($dirname); + # Setup multiple rota + my %rota; + for my $title (qw(TEST FAST SLOW)) { + $rota{$title} = $builder->build_object( + { + class => 'Koha::StockRotationRotas', + value => { title => $title } + } + ); + $builder->build( + { + source => 'Stockrotationstage', + value => { rota_id => $rota{$title}->rota_id }, + } + ); + } - my $mhash = $trans->message_hash(); - $mhash->{message_type} = 'QUOTE'; - $trans->ingest( $mhash, $filename ); + my $description = <<~"END"; + Loaded QUOTE file with 1 Message that contains 2 LIN segments with the first + consistent of 1 item and the second with 3 items with 2 different funds. + END + diag($description); - my $quote = $schema->resultset('EdifactMessage')->find( { filename => $filename } ); + my $filename = 'QUOTES_MULTI.CEQ'; + my $trans = Koha::Edifact::Transport->new( $account->{id} ); + $trans->working_directory($dirname); + my $mhash = $trans->message_hash(); + $mhash->{message_type} = 'QUOTE'; + $trans->ingest( $mhash, $filename ); - # Test quote expects REF to be a valid and active fund code - my $active_period = $builder->build( - { - source => 'Aqbudgetperiod', - value => { budget_period_active => 1 } - } - ); - my $fund = $builder->build( - { - source => 'Aqbudget', - value => { - budget_code => 'REF', - budget_period_id => $active_period->{budget_period_id} + my $quote = $schema->resultset('EdifactMessage')->find( { filename => $filename } ); + process_quote($quote); + + #$logger->diag(); + + my $baskets = Koha::Acquisition::Baskets->search( { booksellerid => $account->{vendor_id} } ); + is( $baskets->count, 1, "One basket created for quote" ); + + my $basket = $baskets->next; + my $orders = $basket->orders; + is( $orders->count, 3, "Three order lines created for quote" ); + + my %biblios; + my $orderline = 0; + while ( my $order = $orders->next ) { + $orderline++; + diag( "Looking at order: " . $orderline ); + if ( $orderline == 1 ) { + + # Fund allocation + my $fund = $order->fund; + is( $fund->budget_code, 'REF', 'Correct fund allocated for first orderline' ); + + # Check biblio + ok( $order->biblionumber, 'Biblionumber assigned to order' ); + $biblios{ $order->biblionumber }++; + + # Check items created + my $items = $order->items; + is( $items->count, 1, 'One item created for the first orderline' ); + + # Check first order GIR details + my $item = $items->next; + my $rota = $item->stockrotationitem; + ok( $rota, 'Item was assigned to a rota' ); + is( $rota->stage->rota->title, 'TEST', "Item was assigned to the correct rota" ); + + } elsif ( $orderline == 2 ) { + + # Fund allocation + my $fund = $order->fund; + is( $fund->budget_code, 'LOAN', 'Correct fund allocated for second orderline' ); + + # Check biblio + ok( $order->biblionumber, 'Biblionumber assigned to order' ); + $biblios{ $order->biblionumber }++; + + # Check items created + my $items = $order->items; + is( $items->count, 2, 'Two items created for the second orderline' ); + + # Check second order GIR details + my %rotas; + while ( my $item = $items->next ) { + my $rota = $item->stockrotationitem; + ok( $rota, 'Item was assigned to a rota' ); + $rotas{ $rota->stage->rota->title }++; + } + is( $rotas{'FAST'}, 1, "One item added to 'FAST' rota" ); + is( $rotas{'SLOW'}, 1, "One item added to 'SLOW' rota" ); + } elsif ( $orderline == 3 ) { + diag("Second LIN split into 2 Orderlines, one for each Fund"); + + # Fund allocation + my $fund = $order->fund; + is( $fund->budget_code, 'REF', 'Correct fund allocated for third orderline' ); + + # Check biblio + ok( $order->biblionumber, 'Biblionumber assigned to order' ); + $biblios{ $order->biblionumber }++; + + # Check items created + my $items = $order->items; + is( $items->count, 1, 'One item created for the third orderline' ); + + # Check first order GIR details + my $item = $items->next; + my $rota = $item->stockrotationitem; + ok( !$rota, 'Item was not assigned to a rota' ); } } - ); - # The quote expects a ROT1 stock rotation roata to exist - my $rota = $builder->build_object( - { - class => 'Koha::StockRotationRotas', - value => { title => 'ROT1' } - } - ); - $builder->build( - { - source => 'Stockrotationstage', - value => { rota_id => $rota->rota_id }, - } - ); + $logger->clear(); + $schema->storage->txn_rollback; + }; - # Process the test quote file - process_quote($quote); + # Test 4: Invalid Fund Error Handling + subtest 'invalid_fund_handling' => sub { + plan tests => 21; - $quote->get_from_storage; + $schema->storage->txn_begin; - # Tests for generated basket for passed quote file - my $baskets = Koha::Acquisition::Baskets->search( { booksellerid => $account->{vendor_id} } ); - my $basket = $baskets->next; + my $account = $builder->build( + { + source => 'VendorEdiAccount', + value => { + description => 'error test vendor', + transport => 'FILE', + } + } + ); + my $ean = $builder->build( + { + source => 'EdifactEan', + value => { + description => 'test ean', + branchcode => undef, + ean => $test_san + } + } + ); - my $orders = $basket->orders; - my $order = $orders->next; + my $description = <<~"END"; + Loading QUOTE file with 1 Message that contains 2 LIN segments with the first + consistent of 1 item and the second with 3 items with 2 different undefined funds. + END + diag($description); - my $biblio = $order->biblio; - my $record = $biblio->record; - my $record_field = $record->field('008'); + my $filename = 'QUOTES_MULTI.CEQ'; + my $trans = Koha::Edifact::Transport->new( $account->{id} ); + $trans->working_directory($dirname); - is( exists( $record_field->{_data} ), 1, 'Field has been added' ); + my $mhash = $trans->message_hash(); + $mhash->{message_type} = 'QUOTE'; + $trans->ingest( $mhash, $filename ); - # Test without calling the 008 handler - $account = $builder->build( - { - source => 'VendorEdiAccount', - value => { - description => 'test vendor', transport => 'FILE', - } - } - ); - $dirname = ( $Bin =~ /^(.*\/t\/)/ ? $1 . 'edi_testfiles/' : q{} ); - $filename = 'QUOTES_SMALL_2.CEQ'; - ok( -e $dirname . $filename, 'File QUOTES_SMALL_2.CEQ found' ); + my $quote = $schema->resultset('EdifactMessage')->find( { filename => $filename } ); - $trans = Koha::Edifact::Transport->new( $account->{id} ); - $trans->working_directory($dirname); + process_quote($quote); - $mhash = $trans->message_hash(); - $mhash->{message_type} = 'QUOTE'; - $trans->ingest( $mhash, $filename ); + #$logger->diag(); + $logger->trace_like( + qr/Created basket:.*/, + "Trace recorded basket added" + )->trace_is( + qq/Checking db for matches with 9781529923766/, + "Trace recorded isbn lookup" + )->trace_like( + qr/Added biblio:.*/, + "Trace recorded adding new biblio" + )->trace_is( + qq/Skipping orderline with invalid budget: REF/, + "Trace recorded skipping orderline with invalid fund" + )->trace_is( + qq/Checking db for matches with 9781785044342/, + "Trace recorded isbn lookup" + )->trace_like( + qr/Added biblio:.*/, + "Trace recorded adding new biblio" + )->trace_is( + qq/Skipping item with invalid budget: LOAN/, + "Trace recorded skipping item with invalid fund" + )->trace_is( + qq/Skipping item with invalid budget: REF/, + "Trace recorded skipping item with invalid fund" + )->trace_is( + qq/Skipping item with invalid budget: LOAN/, + "Trace recorded skipping item with invalid fund" + ); + + # Errors should be recorded for skipped sections + my $errors = Koha::Edifact::File::Errors->search(); + is( $errors->count, 4, '4 errors recorded for missing funds in quote' ); + + my $error = $errors->next; + ok( $error->section, 'First error section is present' ); + is( $error->details, 'Skipped orderline line with invalid budget: REF', 'First error details is correct' ); + + $error = $errors->next; + ok( $error->section, 'Second error section is present' ); + is( $error->details, 'Skipped GIR line with invalid budget: LOAN', 'Second error details is correct' ); + + $error = $errors->next; + ok( $error->section, 'Third error section is present' ); + is( $error->details, 'Invalid budget REF found', 'Third error details is correct' ); + + $error = $errors->next; + ok( $error->section, 'Fourth error section is present' ); + is( $error->details, 'Invalid budget LOAN found', 'Fourth error details is correct' ); + + $quote->get_from_storage; + is( $quote->status, 'error', 'Quote status set to error for invalid fund' ); + + my $baskets = Koha::Acquisition::Baskets->search( { booksellerid => $account->{vendor_id} } ); + is( $baskets->count, 1, 'Basket still created despite errors' ); + + my $orders = $baskets->next->orders; + is( $orders->count, 0, 'No orders created with invalid fund' ); + + $logger->clear(); + $schema->storage->txn_rollback; + }; - $quote = $schema->resultset('EdifactMessage')->find( { filename => $filename } ); + # Test 5: Multiple message quote file + subtest 'multiple_message_handling' => sub { + plan tests => 3; - # Test quote expects REF to be a valid and active fund code - $active_period = $builder->build( - { - source => 'Aqbudgetperiod', - value => { budget_period_active => 1 } - } - ); - $fund = $builder->build( - { - source => 'Aqbudget', - value => { - budget_code => 'REF2', - budget_period_id => $active_period->{budget_period_id} + $schema->storage->txn_begin; + + my $account = $builder->build( + { + source => 'VendorEdiAccount', + value => { + description => 'error test vendor', + transport => 'FILE', + } } - } - ); + ); + my $ean = $builder->build( + { + source => 'EdifactEan', + value => { + description => 'test ean', + branchcode => undef, + ean => $test_san + } + } + ); - # The quote expects a ROT1 stock rotation roata to exist - $rota = $builder->build_object( - { - class => 'Koha::StockRotationRotas', - value => { title => 'ROT2' } - } - ); - $builder->build( - { - source => 'Stockrotationstage', - value => { rota_id => $rota->rota_id }, - } - ); + my $description = <<~"END"; + Loading QUOTE file with 2 messages + END + diag($description); - # Process the test quote file - my $edi_module = Test::MockModule->new('Koha::EDI'); - $edi_module->mock( - '_check_for_existing_bib', - sub { - my $bib_record = shift; - return; - } - ); - $edi_module->mock( - '_handle_008_field', - sub { - my $bib_record = shift; - return $bib_record; - } - ); - process_quote($quote); + my $filename = 'QUOTES_BIG.CEQ'; + my $trans = Koha::Edifact::Transport->new( $account->{id} ); + $trans->working_directory($dirname); + + my $mhash = $trans->message_hash(); + $mhash->{message_type} = 'QUOTE'; + $trans->ingest( $mhash, $filename ); - $quote->get_from_storage; + my $quote = $schema->resultset('EdifactMessage')->find( { filename => $filename } ); + + process_quote($quote); - # Tests for generated basket for passed quote file - $baskets = Koha::Acquisition::Baskets->search( { booksellerid => $account->{vendor_id} } ); - $basket = $baskets->next; + #$logger->diag(); - $orders = $basket->orders; - $order = $orders->next; + my $baskets = Koha::Acquisition::Baskets->search( { booksellerid => $account->{vendor_id} } ); + is( $baskets->count, 2, 'Two baskets added for file containing 2 messages' ); - $biblio = $order->biblio; - $record = $biblio->record; - $record_field = $record->field('008'); + # First basket + my $basket = $baskets->next; + is( $basket->basketname, $filename, "Basket uses EDI filename for name" ); - is( $record_field->{_data}, undef, 'Field has not been added' ); + # Second basket + $basket = $baskets->next; + is( $basket->basketname, $filename, "Basket uses EDI filename for name" ); + $logger->clear(); + $schema->storage->txn_rollback; + }; + + # Clean up $logger->clear(); $schema->storage->txn_rollback; }; subtest 'process_invoice' => sub { - plan tests => 19; + plan tests => 20; $schema->storage->txn_begin; @@ -403,6 +715,7 @@ subtest 'process_invoice' => sub { 1; } or do { $error = $@; + diag($error); }; ok( !$error, 'process_invoice completed without dying' ); @@ -453,6 +766,13 @@ subtest 'process_invoice' => sub { 'Warn recorded for unmatched item' )->clear(); + # Errors should be recorded for skipped sections + my $errors = Koha::Edifact::File::Errors->search(); + is( $errors->count, 6, '6 errors recorded for invoice' ); + while ( my $error = $errors->next ) { + diag( $error->details ); + } + my $invoice3 = Koha::Acquisition::Invoices->search( { invoicenumber => 'INV00003' }, { rows => 1 } )->single; ok( $invoice3, "Invoice added to database" ); is( $invoice3->booksellerid, $account->{vendor_id}, 'Invoice has test booksellerid' ); diff --git a/t/edi_testfiles/QUOTES_BIG.CEQ b/t/edi_testfiles/QUOTES_BIG.CEQ new file mode 100644 index 00000000000..0613a17d149 --- /dev/null +++ b/t/edi_testfiles/QUOTES_BIG.CEQ @@ -0,0 +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' diff --git a/t/edi_testfiles/QUOTES_MULTI.CEQ b/t/edi_testfiles/QUOTES_MULTI.CEQ new file mode 100644 index 00000000000..2393cd44fa3 --- /dev/null +++ b/t/edi_testfiles/QUOTES_MULTI.CEQ @@ -0,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' -- 2.47.1