From f79c44b9b7c338656b89df063d67b4fa09ef8175 Mon Sep 17 00:00:00 2001 From: Martin Renvoize Date: Fri, 6 Mar 2026 10:28:47 +0000 Subject: [PATCH] Bug 42010: Escape EDIFACT special characters in BGM purchase order number Bug 20253 introduced the ability to use the basket name as a purchase order number in the BGM segment of an EDIFACT order message. However, the basket name was inserted into the BGM segment without escaping EDIFACT special characters (apostrophe, colon, plus, question mark). In EDIFACT, the apostrophe (') is the segment terminator, so any literal apostrophe in data must be escaped with the release character (?) as ?'. Without this, a basket name like "Children's Requests" would produce an invalid EDIFACT message. This fix applies encode_text() to the purchase order number in beginning_of_message() so all special characters are properly escaped. Test plan: - Run t/db_dependent/Koha/Edifact/Order.t - All tests should pass, including the new tests covering special character escaping in BGM segments --- Koha/Edifact/Order.pm | 4 +- t/db_dependent/Koha/Edifact/Order.t | 57 ++++++++++++++++++++++++++++- 2 files changed, 58 insertions(+), 3 deletions(-) diff --git a/Koha/Edifact/Order.pm b/Koha/Edifact/Order.pm index c6c98cee842..7ca3bace8e6 100644 --- a/Koha/Edifact/Order.pm +++ b/Koha/Edifact/Order.pm @@ -302,7 +302,9 @@ sub beginning_of_message { my $purchase_order_number = shift; # Use purchase order number if available, otherwise use basketno - my $document_message_no = $purchase_order_number ? $purchase_order_number : sprintf '%011d', $basketno; + my $document_message_no = $purchase_order_number + ? encode_text($purchase_order_number) + : sprintf '%011d', $basketno; # my $message_function = 9; # original 7 = retransmission # message_code values diff --git a/t/db_dependent/Koha/Edifact/Order.t b/t/db_dependent/Koha/Edifact/Order.t index 9b55274ce40..423a5cf39c4 100755 --- a/t/db_dependent/Koha/Edifact/Order.t +++ b/t/db_dependent/Koha/Edifact/Order.t @@ -32,7 +32,7 @@ my $schema = Koha::Database->new->schema; my $builder = t::lib::TestBuilder->new; subtest 'beggining_of_message tests' => sub { - plan tests => 3; + plan tests => 5; $schema->storage->txn_begin; @@ -63,6 +63,22 @@ subtest 'beggining_of_message tests' => sub { "When purchase order number provided, it's used in BGM segment instead of basketno" ); + # Bug 42010: EDIFACT special characters in purchase order number must be escaped + my $po_with_apostrophe = "Children's Requests 24/02/26 CB"; + $bgm = Koha::Edifact::Order::beginning_of_message( $basketno, $dbic_edi_vendor->standard, 1, $po_with_apostrophe ); + is( + $bgm, "BGM+22V+Children?'s Requests 24/02/26 CB+9'", + "Apostrophe in purchase order number is escaped with release character in BGM segment" + ); + + my $po_with_special_chars = "PO?+:' test"; + $bgm = + Koha::Edifact::Order::beginning_of_message( $basketno, $dbic_edi_vendor->standard, 1, $po_with_special_chars ); + is( + $bgm, "BGM+22V+PO???+?:?' test+9'", + "All EDIFACT special characters in purchase order number are escaped in BGM segment" + ); + $schema->storage->txn_rollback; }; @@ -299,7 +315,7 @@ subtest 'filename() tests' => sub { }; subtest 'RFF+ON purchase order number generation' => sub { - plan tests => 3; + plan tests => 4; $schema->storage->txn_begin; @@ -431,6 +447,43 @@ subtest 'RFF+ON purchase order number generation' => sub { 'Purchase order number included in BGM segment when purchase order number present' ); + # Bug 42010: basket name with apostrophe must be escaped in BGM segment + my $basket_apostrophe = $builder->build( + { + source => 'Aqbasket', + value => { + basketname => "Children's Requests 24/02/26 CB", + booksellerid => $vendor_po->{vendor_id}, + } + } + ); + my $order_apostrophe = $builder->build( + { + source => 'Aqorder', + value => { + basketno => $basket_apostrophe->{basketno}, + biblionumber => $biblio_po->biblionumber, + orderstatus => 'new', + quantity => 1, + listprice => '10.00', + } + } + ); + my @orderlines_apostrophe = + $schema->resultset('Aqorder')->search( { basketno => $basket_apostrophe->{basketno} } ); + my $order_obj_apostrophe = Koha::Edifact::Order->new( + { + orderlines => \@orderlines_apostrophe, + vendor => $dbic_vendor_po, + ean => $dbic_ean, + } + ); + my $transmission_apostrophe = $order_obj_apostrophe->encode(); + like( + $transmission_apostrophe, qr/BGM\+220\+Children\?'s Requests 24\/02\/26 CB\+9'/, + 'Apostrophe in basket name is escaped with release character in BGM segment (Bug 42010)' + ); + $schema->storage->txn_rollback; }; -- 2.53.0