From 9dce8b6d6a3ae85db1ecfaaca020cd3e1b5d9e9c Mon Sep 17 00:00:00 2001 From: Martin Renvoize Date: Tue, 8 Jul 2025 15:19:10 +0100 Subject: [PATCH] Bug 20253: (follow-up) Add RFF+ON segments to outgoing ORDER messages When vendors are configured to use purchase order numbers for basket naming, the purchase order number should be included in outgoing ORDER messages as an RFF+ON (Reference - Order Number) segment for proper EDI workflow continuity. This follow-up ensures that: 1. Purchase order numbers from incoming QUOTE messages are preserved 2. The same purchase order numbers are sent back in ORDER messages 3. Vendors receive the reference numbers they expect for order processing Implementation: - Added _get_purchase_order_number() method to extract PO number from basket name when vendor is configured with basket_name_source = 'purchase_order_number' - Modified order_msg_header() to include RFF+ON segment when PO number available - Added comprehensive tests for RFF+ON segment generation in ORDER messages Test Plan: 1. Apply patches 2. Configure a vendor EDI account with "Basket name source" = "Purchase order number" 3. Process a QUOTE message containing RFF+ON segment 4. Verify basket is created with purchase order number as name 5. Generate ORDER message from the basket 6. Verify ORDER message contains RFF+ON segment with the purchase order number 7. Run tests: prove t/db_dependent/Koha/Edifact/Order.t This completes the round-trip EDI workflow for purchase order number handling. --- Koha/Edifact/Order.pm | 25 +++++ t/db_dependent/Koha/Edifact/Order.t | 142 +++++++++++++++++++++++++++- 2 files changed, 165 insertions(+), 2 deletions(-) diff --git a/Koha/Edifact/Order.pm b/Koha/Edifact/Order.pm index 0bf67829cae..f298d39d31d 100644 --- a/Koha/Edifact/Order.pm +++ b/Koha/Edifact/Order.pm @@ -73,6 +73,10 @@ sub new { $self->{schema} = $database->schema; bless $self, $class; + + # Extract purchase order number for RFF+ON segment (after blessing) + $self->{purchase_order_number} = $self->_get_purchase_order_number(); + return $self; } @@ -283,6 +287,11 @@ sub order_msg_header { $self->{recipient}->id_code_qualifier ); + # RFF Purchase order number (if configured) + if ( $self->{purchase_order_number} ) { + push @header, "RFF+ON:$self->{purchase_order_number}$seg_terminator"; + } + # repeat for for other relevant parties # CUX currency @@ -693,6 +702,22 @@ sub encode_text { return $string; } +sub _get_purchase_order_number { + my $self = shift; + + # If the vendor EDI account is configured to use purchase order numbers for basket names, + # then the basket name IS the purchase order number + my $vendor_config = $self->{recipient}; + if ( $vendor_config + && $vendor_config->basket_name_source + && $vendor_config->basket_name_source eq 'purchase_order_number' ) + { + return $self->{basket}->basketname; + } + + return; +} + 1; __END__ diff --git a/t/db_dependent/Koha/Edifact/Order.t b/t/db_dependent/Koha/Edifact/Order.t index 3a565a93bff..5d74fa7e917 100755 --- a/t/db_dependent/Koha/Edifact/Order.t +++ b/t/db_dependent/Koha/Edifact/Order.t @@ -20,7 +20,7 @@ use Modern::Perl; use Test::NoWarnings; -use Test::More tests => 4; +use Test::More tests => 5; use Koha::Edifact::Order; @@ -264,10 +264,12 @@ subtest 'filename() tests' => sub { my @orders = $schema->resultset('Aqorder')->search( { basketno => $order->basket->basketno } )->all; + my $dbic_vendor = $schema->resultset('VendorEdiAccount')->find( $vendor->{id} ); + my $edi_order = Koha::Edifact::Order->new( { orderlines => \@orders, - vendor => $vendor, + vendor => $dbic_vendor, ean => $ean } ); @@ -280,3 +282,139 @@ subtest 'filename() tests' => sub { $schema->storage->txn_rollback; }; + +subtest 'RFF+ON purchase order number generation' => sub { + plan tests => 3; + + $schema->storage->txn_begin; + + # Create vendor with basket_name_source set to purchase_order_number + my $vendor_po = $builder->build( + { + source => 'VendorEdiAccount', + value => { + description => 'Test vendor PO mode', + basket_name_source => 'purchase_order_number', + standard => 'EUR', + } + } + ); + + # Create vendor with basket_name_source set to filename (default) + my $vendor_filename = $builder->build( + { + source => 'VendorEdiAccount', + value => { + description => 'Test vendor filename mode', + basket_name_source => 'filename', + standard => 'EUR', + } + } + ); + + # Create baskets with different naming schemes + my $basket_po = $builder->build( + { + source => 'Aqbasket', + value => { + basketname => 'PO123456789', # Purchase order number + booksellerid => $vendor_po->{vendor_id}, + } + } + ); + + my $basket_filename = $builder->build( + { + source => 'Aqbasket', + value => { + basketname => 'quote_file.ceq', # Filename + booksellerid => $vendor_filename->{vendor_id}, + } + } + ); + + # Create biblio records for the orders + my $biblio_po = $builder->build_sample_biblio(); + my $biblio_filename = $builder->build_sample_biblio(); + + # Create orders for the baskets + my $order_po = $builder->build( + { + source => 'Aqorder', + value => { + basketno => $basket_po->{basketno}, + biblionumber => $biblio_po->biblionumber, + orderstatus => 'new', + quantity => 1, + listprice => '10.00', + } + } + ); + + my $order_filename = $builder->build( + { + source => 'Aqorder', + value => { + basketno => $basket_filename->{basketno}, + biblionumber => $biblio_filename->biblionumber, + orderstatus => 'new', + quantity => 1, + listprice => '10.00', + } + } + ); + + # Create EAN object + my $ean = $builder->build( + { + source => 'EdifactEan', + value => { ean => '1234567890123' } + } + ); + + # Get database objects + my $dbic_vendor_po = $schema->resultset('VendorEdiAccount')->find( $vendor_po->{id} ); + my $dbic_vendor_filename = $schema->resultset('VendorEdiAccount')->find( $vendor_filename->{id} ); + my $dbic_ean = $schema->resultset('EdifactEan')->find( $ean->{ee_id} ); + my @orderlines_po = $schema->resultset('Aqorder')->search( { basketno => $basket_po->{basketno} } ); + my @orderlines_filename = $schema->resultset('Aqorder')->search( { basketno => $basket_filename->{basketno} } ); + + # Test order generation with purchase order number + my $order_obj_po = Koha::Edifact::Order->new( + { + orderlines => \@orderlines_po, + vendor => $dbic_vendor_po, + ean => $dbic_ean, + } + ); + + # Test order generation with filename + my $order_obj_filename = Koha::Edifact::Order->new( + { + orderlines => \@orderlines_filename, + vendor => $dbic_vendor_filename, + ean => $dbic_ean, + } + ); + + # Test that purchase order number is extracted correctly + is( + $order_obj_po->{purchase_order_number}, 'PO123456789', + 'Purchase order number extracted from basket name when vendor configured for PO mode' + ); + + # Test that no purchase order number is extracted when vendor uses filename mode + is( + $order_obj_filename->{purchase_order_number}, undef, + 'No purchase order number when vendor configured for filename mode' + ); + + # Test that RFF+ON segment is included in order header when purchase order number present + my $transmission = $order_obj_po->encode(); + like( + $transmission, qr/RFF\+ON:PO123456789'/, + 'RFF+ON segment included in ORDER message when purchase order number present' + ); + + $schema->storage->txn_rollback; +}; -- 2.50.0