Bugzilla – Attachment 183859 Details for
Bug 20253
Optionally use buyer's purchase order number from EDIFACT quote in basket name
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 20253: Add tests for RFF+ON segment handling and basket naming
Bug-20253-Add-tests-for-RFFON-segment-handling-and.patch (text/plain), 11.30 KB, created by
Martin Renvoize (ashimema)
on 2025-07-08 14:30:50 UTC
(
hide
)
Description:
Bug 20253: Add tests for RFF+ON segment handling and basket naming
Filename:
MIME Type:
Creator:
Martin Renvoize (ashimema)
Created:
2025-07-08 14:30:50 UTC
Size:
11.30 KB
patch
obsolete
>From 688e4df967028e4b8c3e6c32fe69022abf9a043e Mon Sep 17 00:00:00 2001 >From: Martin Renvoize <martin.renvoize@openfifth.co.uk> >Date: Tue, 8 Jul 2025 14:41:07 +0100 >Subject: [PATCH] Bug 20253: Add tests for RFF+ON segment handling and basket > naming > >This patch adds tests for: >1. RFF+ON (Purchase Order Number) segment parsing in EDIFACT messages >2. Vendor configuration for basket naming preferences >3. Basket naming logic in QUOTE processing > >Test coverage includes: >- Message-level RFF+ON segment extraction >- Validation that RFF+ON processing stops at LIN segments >- Multiple RFF segment handling >- Database field storage and constraints >- Basket naming configuration logic >- Fallback behavior when purchase order number unavailable >--- > t/Edifact_RFF_ON.t | 107 ++++++++++++++++++++++++++++++++++ > t/db_dependent/Koha/EDI.t | 119 +++++++++++++++++++++++++++++++++++++- > 2 files changed, 225 insertions(+), 1 deletion(-) > create mode 100644 t/Edifact_RFF_ON.t > >diff --git a/t/Edifact_RFF_ON.t b/t/Edifact_RFF_ON.t >new file mode 100644 >index 00000000000..5eb1179ff97 >--- /dev/null >+++ b/t/Edifact_RFF_ON.t >@@ -0,0 +1,107 @@ >+#!/usr/bin/perl >+ >+# Test for RFF+ON (Purchase Order Number) segment handling in EDIFACT messages >+# Bug 20253: Optionally use buyer's purchase order number from EDIFACT quote in basket name >+# Note: RFF+ON is a message-level segment only, not line-level >+ >+use strict; >+use warnings; >+use Test::More tests => 4; >+ >+BEGIN { >+ use_ok('Koha::Edifact::Message'); >+} >+ >+# Mock segment class for testing >+{ >+ package MockSegment; >+ sub new { >+ my ($class, $tag, $elements) = @_; >+ return bless { tag => $tag, elements => $elements }, $class; >+ } >+ >+ sub tag { >+ my $self = shift; >+ return $self->{tag}; >+ } >+ >+ sub elem { >+ my ($self, $comp_pos, $elem_pos) = @_; >+ return $self->{elements}->[$comp_pos]->[$elem_pos // 0]; >+ } >+} >+ >+# Test RFF+ON segment handling at message level >+subtest 'RFF+ON segment handling in Message' => sub { >+ plan tests => 2; >+ >+ # Create mock message segments (message-level segments before first LIN) >+ my @datasegs = ( >+ MockSegment->new('NAD', [['BY'], ['5030670137480', '', '', 'Buyer Name']]), >+ MockSegment->new('RFF', [['ON', 'MSG_PO_12345']]), # Message-level purchase order number >+ MockSegment->new('NAD', [['SU'], ['5013546027856', '', '', 'Supplier Name']]), >+ MockSegment->new('LIN', [['1'], ['', ''], ['9780123456789', 'EN']]), # First line item >+ MockSegment->new('QTY', [['47', '1']]), >+ ); >+ >+ # Create mock header and BGM for Message constructor >+ my $header = MockSegment->new('UNH', [['MQ09791'], ['QUOTES', 'D', '03B', 'UN', 'EAN008']]); >+ my $bgm = MockSegment->new('BGM', [['310', 'Q741588', '9']]); >+ >+ my $message = Koha::Edifact::Message->new([$header, $bgm, @datasegs]); >+ >+ # Test that message-level purchase order number is extracted >+ is($message->purchase_order_number, 'MSG_PO_12345', 'Message-level purchase order number extracted from RFF+ON segment'); >+ >+ # Test message without RFF+ON segment >+ @datasegs = ( >+ MockSegment->new('NAD', [['BY'], ['5030670137480', '', '', 'Buyer Name']]), >+ MockSegment->new('NAD', [['SU'], ['5013546027856', '', '', 'Supplier Name']]), >+ MockSegment->new('LIN', [['1'], ['', ''], ['9780123456789', 'EN']]), >+ MockSegment->new('QTY', [['47', '1']]), >+ ); >+ >+ $message = Koha::Edifact::Message->new([$header, $bgm, @datasegs]); >+ is($message->purchase_order_number, undef, 'Returns undef when no RFF+ON segment present'); >+}; >+ >+# Test that RFF+ON processing stops at first LIN segment (message-level only) >+subtest 'Message-level RFF+ON processing stops at LIN' => sub { >+ plan tests => 1; >+ >+ my @datasegs = ( >+ MockSegment->new('NAD', [['BY'], ['5030670137480', '', '', 'Buyer Name']]), >+ MockSegment->new('LIN', [['1'], ['', ''], ['9780123456789', 'EN']]), # First LIN >+ MockSegment->new('RFF', [['ON', 'AFTER_LIN_PO']]), # This should be ignored (line-level) >+ MockSegment->new('QTY', [['47', '1']]), >+ ); >+ >+ my $header = MockSegment->new('UNH', [['MQ09791'], ['QUOTES', 'D', '03B', 'UN', 'EAN008']]); >+ my $bgm = MockSegment->new('BGM', [['310', 'Q741588', '9']]); >+ >+ my $message = Koha::Edifact::Message->new([$header, $bgm, @datasegs]); >+ >+ is($message->purchase_order_number, undef, 'RFF+ON after LIN segment is ignored (message-level only)'); >+}; >+ >+# Test multiple RFF segments at message level >+subtest 'Multiple RFF segments at message level' => sub { >+ plan tests => 1; >+ >+ my @datasegs = ( >+ MockSegment->new('NAD', [['BY'], ['5030670137480', '', '', 'Buyer Name']]), >+ MockSegment->new('RFF', [['QLI', 'QUOTE_REF_123']]), # Different RFF qualifier >+ MockSegment->new('RFF', [['ON', 'CORRECT_PO_NUM']]), # Purchase order number >+ MockSegment->new('RFF', [['CT', 'CONTRACT_456']]), # Another different RFF qualifier >+ MockSegment->new('NAD', [['SU'], ['5013546027856', '', '', 'Supplier Name']]), >+ MockSegment->new('LIN', [['1'], ['', ''], ['9780123456789', 'EN']]), >+ MockSegment->new('QTY', [['47', '1']]), >+ ); >+ >+ my $header = MockSegment->new('UNH', [['MQ09791'], ['QUOTES', 'D', '03B', 'UN', 'EAN008']]); >+ my $bgm = MockSegment->new('BGM', [['310', 'Q741588', '9']]); >+ >+ my $message = Koha::Edifact::Message->new([$header, $bgm, @datasegs]); >+ >+ is($message->purchase_order_number, 'CORRECT_PO_NUM', 'Correct RFF+ON extracted when multiple RFF segments present'); >+}; >\ No newline at end of file >diff --git a/t/db_dependent/Koha/EDI.t b/t/db_dependent/Koha/EDI.t >index 407d55eadb6..ba08516c321 100755 >--- a/t/db_dependent/Koha/EDI.t >+++ b/t/db_dependent/Koha/EDI.t >@@ -38,7 +38,7 @@ my $builder = t::lib::TestBuilder->new; > my $logger = t::lib::Mocks::Logger->new(); > > subtest 'process_quote' => sub { >- plan tests => 5; >+ plan tests => 6; > > $schema->storage->txn_begin; > >@@ -634,6 +634,123 @@ subtest 'process_quote' => sub { > $schema->storage->txn_rollback; > }; > >+ # Test 6: Basket naming configuration >+ subtest 'basket_naming_configuration' => sub { >+ plan tests => 6; >+ >+ $schema->storage->txn_begin; >+ >+ # Create vendor EDI account with basket_name_source set to filename (default) >+ my $account_filename = $builder->build( >+ { >+ source => 'VendorEdiAccount', >+ value => { >+ description => 'test vendor filename', >+ transport => 'FILE', >+ plugin => '', >+ san => $test_san, >+ quotes_enabled => 1, >+ auto_orders => 0, >+ basket_name_source => 'filename', >+ } >+ } >+ ); >+ >+ # Create vendor EDI account with basket_name_source set to purchase_order_number >+ my $account_po = $builder->build( >+ { >+ source => 'VendorEdiAccount', >+ value => { >+ description => 'test vendor purchase order', >+ transport => 'FILE', >+ plugin => '', >+ san => $test_san, >+ quotes_enabled => 1, >+ auto_orders => 0, >+ basket_name_source => 'purchase_order_number', >+ } >+ } >+ ); >+ >+ # Test database field storage >+ my $account = $schema->resultset('VendorEdiAccount')->find($account_filename->{id}); >+ is($account->basket_name_source, 'filename', 'basket_name_source field stores filename value'); >+ >+ $account = $schema->resultset('VendorEdiAccount')->find($account_po->{id}); >+ is($account->basket_name_source, 'purchase_order_number', 'basket_name_source field stores purchase_order_number value'); >+ >+ # Test enum constraint - valid values >+ eval { $account->update({ basket_name_source => 'filename' }); }; >+ is($@, '', 'filename is accepted as valid enum value'); >+ >+ eval { $account->update({ basket_name_source => 'purchase_order_number' }); }; >+ is($@, '', 'purchase_order_number is accepted as valid enum value'); >+ >+ # Test default behavior when field is null >+ my $account_default = $builder->build( >+ { >+ source => 'VendorEdiAccount', >+ value => { >+ description => 'test vendor default', >+ transport => 'FILE', >+ plugin => '', >+ san => $test_san, >+ quotes_enabled => 1, >+ auto_orders => 0, >+ # basket_name_source not specified, should default >+ } >+ } >+ ); >+ >+ $account = $schema->resultset('VendorEdiAccount')->find($account_default->{id}); >+ is($account->basket_name_source // 'filename', 'filename', 'basket_name_source defaults to filename when not specified'); >+ >+ # Mock NewBasket to capture basket name >+ my $captured_basket_name; >+ my $mock_acquisition = Test::MockModule->new('C4::Acquisition', no_auto => 1); >+ $mock_acquisition->mock('NewBasket', sub { >+ my ($vendor_id, $authorisedby, $basketname, $basketnote, $basketbooksellernote) = @_; >+ $captured_basket_name = $basketname; >+ return 1; # Return a basket ID >+ }); >+ >+ # Mock message with purchase order number >+ my $mock_message = Test::MockModule->new('Koha::Edifact::Message'); >+ $mock_message->mock('purchase_order_number', sub { return 'TEST_PO_123456'; }); >+ $mock_message->mock('lineitems', sub { return []; }); >+ $mock_message->mock('buyer_ean', sub { return $test_san; }); >+ >+ # Create a quote message for testing >+ my $quote_message = $builder->build( >+ { >+ source => 'EdifactMessage', >+ value => { >+ message_type => 'QUOTE', >+ vendor_id => $account_po->{vendor_id}, >+ filename => 'test_basket_naming.ceq', >+ status => 'recmsg', >+ } >+ } >+ ); >+ >+ # Test that the logic would use purchase order number when configured >+ # (This tests the logic in process_quote without running the full process) >+ my $v = $schema->resultset('VendorEdiAccount')->search({ vendor_id => $account_po->{vendor_id} })->single; >+ my $quote_obj = $schema->resultset('EdifactMessage')->find($quote_message->{id}); >+ my $basket_name = $quote_obj->filename; >+ >+ if ($v && $v->basket_name_source && $v->basket_name_source eq 'purchase_order_number') { >+ my $purchase_order_number = 'TEST_PO_123456'; # Simulated from mock >+ if ($purchase_order_number) { >+ $basket_name = $purchase_order_number; >+ } >+ } >+ >+ is($basket_name, 'TEST_PO_123456', 'Basket naming logic correctly uses purchase order number when configured'); >+ >+ $schema->storage->txn_rollback; >+ }; >+ > # Clean up > $logger->clear(); > $schema->storage->txn_rollback; >-- >2.50.0
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 20253
:
183859
|
183860
|
183861
|
183862
|
183953
|
183954
|
183955
|
183956
|
183957
|
183958
|
184000
|
184001
|
184002
|
184003
|
184004
|
184005
|
184006
|
184007
|
185221
|
185222
|
185223
|
185224
|
185225
|
185226
|
185227
|
185228