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

(-)a/t/Edifact.t (-2 / +72 lines)
Lines 3-12 use strict; Link Here
3
use warnings;
3
use warnings;
4
use FindBin qw( $Bin );
4
use FindBin qw( $Bin );
5
5
6
use Test::More tests => 41;
6
use Test::More tests => 45;
7
use Koha::EDI;
7
use Koha::EDI;
8
8
9
BEGIN { use_ok('Koha::Edifact') }
9
BEGIN {
10
    use_ok('Koha::Edifact');
11
    use_ok('Koha::Edifact::Message');
12
}
10
13
11
my $filename = "$Bin/edi_testfiles/prquotes_73050_20140430.CEQ";
14
my $filename = "$Bin/edi_testfiles/prquotes_73050_20140430.CEQ";
12
15
Lines 138-140 is( $dp, 9.0, 'Discount calculated with discount = 0' ); Link Here
138
141
139
$dp = Koha::EDI::_discounted_price( 0.0, 9, 8.0 );
142
$dp = Koha::EDI::_discounted_price( 0.0, 9, 8.0 );
140
is( $dp, 8.0, 'Discount overridden by incoming calculated value' );
143
is( $dp, 8.0, 'Discount overridden by incoming calculated value' );
144
145
# Test RFF+ON (Purchase Order Number) segment handling in EDIFACT messages
146
# Bug 20253: Optionally use buyer's purchase order number from EDIFACT quote in basket name
147
148
# Mock segment class for testing RFF+ON functionality
149
{
150
151
    package MockSegment;
152
153
    sub new {
154
        my ( $class, $tag, $elements ) = @_;
155
        return bless { tag => $tag, elements => $elements }, $class;
156
    }
157
158
    sub tag {
159
        my $self = shift;
160
        return $self->{tag};
161
    }
162
163
    sub elem {
164
        my ( $self, $comp_pos, $elem_pos ) = @_;
165
        return $self->{elements}->[$comp_pos]->[ $elem_pos // 0 ];
166
    }
167
}
168
169
# Test that message-level purchase order number is extracted correctly
170
my @datasegs = (
171
    MockSegment->new( 'NAD', [ ['BY'], [ '5030670137480', '', '', 'Buyer Name' ] ] ),
172
    MockSegment->new( 'RFF', [ [ 'ON', 'MSG_PO_12345' ] ] ),    # Message-level purchase order number
173
    MockSegment->new( 'NAD', [ ['SU'], [ '5013546027856', '', '', 'Supplier Name' ] ] ),
174
    MockSegment->new( 'LIN', [ ['1'], [ '', '' ], [ '9780123456789', 'EN' ] ] ),           # First line item
175
    MockSegment->new( 'QTY', [ [ '47', '1' ] ] ),
176
);
177
178
my $header = MockSegment->new( 'UNH', [ ['MQ09791'], [ 'QUOTES', 'D', '03B', 'UN', 'EAN008' ] ] );
179
my $bgm    = MockSegment->new( 'BGM', [ [ '310', 'Q741588', '9' ] ] );
180
181
my $message = Koha::Edifact::Message->new( [ $header, $bgm, @datasegs ] );
182
is(
183
    $message->purchase_order_number, 'MSG_PO_12345',
184
    'Message-level purchase order number extracted from RFF+ON segment'
185
);
186
187
# Test that RFF+ON processing stops at first LIN segment (message-level only)
188
@datasegs = (
189
    MockSegment->new( 'NAD', [ ['BY'], [ '5030670137480', '', '', 'Buyer Name' ] ] ),
190
    MockSegment->new( 'LIN', [ ['1'], [ '', '' ], [ '9780123456789', 'EN' ] ] ),        # First LIN
191
    MockSegment->new( 'RFF', [ [ 'ON', 'AFTER_LIN_PO' ] ] ),    # This should be ignored (line-level)
192
    MockSegment->new( 'QTY', [ [ '47', '1' ] ] ),
193
);
194
195
$message = Koha::Edifact::Message->new( [ $header, $bgm, @datasegs ] );
196
is( $message->purchase_order_number, undef, 'RFF+ON after LIN segment is ignored (message-level only)' );
197
198
# Test that correct RFF+ON is extracted when multiple RFF segments are present
199
@datasegs = (
200
    MockSegment->new( 'NAD', [ ['BY'], [ '5030670137480', '', '', 'Buyer Name' ] ] ),
201
    MockSegment->new( 'RFF', [ [ 'QLI', 'QUOTE_REF_123' ] ] ),     # Different RFF qualifier
202
    MockSegment->new( 'RFF', [ [ 'ON',  'CORRECT_PO_NUM' ] ] ),    # Purchase order number
203
    MockSegment->new( 'RFF', [ [ 'CT',  'CONTRACT_456' ] ] ),      # Another different RFF qualifier
204
    MockSegment->new( 'NAD', [ ['SU'], [ '5013546027856', '', '', 'Supplier Name' ] ] ),
205
    MockSegment->new( 'LIN', [ ['1'], [ '', '' ], [ '9780123456789', 'EN' ] ] ),
206
    MockSegment->new( 'QTY', [ [ '47', '1' ] ] ),
207
);
208
209
$message = Koha::Edifact::Message->new( [ $header, $bgm, @datasegs ] );
210
is( $message->purchase_order_number, 'CORRECT_PO_NUM', 'Correct RFF+ON extracted when multiple RFF segments present' );
(-)a/t/db_dependent/Koha/EDI.t (-10 / +115 lines)
Lines 38-44 my $builder = t::lib::TestBuilder->new; Link Here
38
my $logger  = t::lib::Mocks::Logger->new();
38
my $logger  = t::lib::Mocks::Logger->new();
39
39
40
subtest 'process_quote' => sub {
40
subtest 'process_quote' => sub {
41
    plan tests => 5;
41
    plan tests => 6;
42
42
43
    $schema->storage->txn_begin;
43
    $schema->storage->txn_begin;
44
44
Lines 63-74 subtest 'process_quote' => sub { Link Here
63
            {
63
            {
64
                source => 'VendorEdiAccount',
64
                source => 'VendorEdiAccount',
65
                value  => {
65
                value  => {
66
                    description    => 'test vendor',
66
                    description      => 'test vendor',
67
                    transport      => 'FILE',
67
                    transport        => 'FILE',
68
                    plugin         => '',
68
                    plugin           => '',
69
                    san            => $test_san,
69
                    san              => $test_san,
70
                    orders_enabled => 1,
70
                    orders_enabled   => 1,
71
                    auto_orders    => 0,
71
                    auto_orders      => 0,
72
                    po_is_basketname => 0
72
                }
73
                }
73
            }
74
            }
74
        );
75
        );
Lines 584-591 subtest 'process_quote' => sub { Link Here
584
            {
585
            {
585
                source => 'VendorEdiAccount',
586
                source => 'VendorEdiAccount',
586
                value  => {
587
                value  => {
587
                    description => 'error test vendor',
588
                    description      => 'error test vendor',
588
                    transport   => 'FILE',
589
                    transport        => 'FILE',
590
                    po_is_basketname => 0
589
                }
591
                }
590
            }
592
            }
591
        );
593
        );
Lines 634-639 subtest 'process_quote' => sub { Link Here
634
        $schema->storage->txn_rollback;
636
        $schema->storage->txn_rollback;
635
    };
637
    };
636
638
639
    # Test 6: Basket naming configuration
640
    subtest 'basket_naming_configuration' => sub {
641
        plan tests => 5;
642
643
        $schema->storage->txn_begin;
644
645
        # Create vendor EDI account with po_is_basketname set to false (default)
646
        my $account_filename = $builder->build(
647
            {
648
                source => 'VendorEdiAccount',
649
                value  => {
650
                    description      => 'test vendor filename',
651
                    transport        => 'FILE',
652
                    plugin           => '',
653
                    san              => $test_san,
654
                    quotes_enabled   => 1,
655
                    auto_orders      => 0,
656
                    po_is_basketname => 0,
657
                }
658
            }
659
        );
660
661
        # Create vendor EDI account with po_is_basketname set to true
662
        my $account_po = $builder->build(
663
            {
664
                source => 'VendorEdiAccount',
665
                value  => {
666
                    description      => 'test vendor purchase order',
667
                    transport        => 'FILE',
668
                    plugin           => '',
669
                    san              => $test_san,
670
                    quotes_enabled   => 1,
671
                    auto_orders      => 0,
672
                    po_is_basketname => 1,
673
                }
674
            }
675
        );
676
677
        # Test database field storage
678
        my $account = $schema->resultset('VendorEdiAccount')->find( $account_filename->{id} );
679
        is( $account->po_is_basketname, 0, 'po_is_basketname field stores false value' );
680
681
        $account = $schema->resultset('VendorEdiAccount')->find( $account_po->{id} );
682
        is( $account->po_is_basketname, 1, 'po_is_basketname field stores true value' );
683
684
        # Test boolean constraint - valid values
685
        eval { $account->update( { po_is_basketname => 0 } ); };
686
        is( $@, '', 'false is accepted as valid boolean value' );
687
688
        eval { $account->update( { po_is_basketname => 1 } ); };
689
        is( $@, '', 'true is accepted as valid boolean value' );
690
691
        # Mock NewBasket to capture basket name
692
        my $captured_basket_name;
693
        my $mock_acquisition = Test::MockModule->new( 'C4::Acquisition', no_auto => 1 );
694
        $mock_acquisition->mock(
695
            'NewBasket',
696
            sub {
697
                my ( $vendor_id, $authorisedby, $basketname, $basketnote, $basketbooksellernote ) = @_;
698
                $captured_basket_name = $basketname;
699
                return 1;    # Return a basket ID
700
            }
701
        );
702
703
        # Mock message with purchase order number
704
        my $mock_message = Test::MockModule->new('Koha::Edifact::Message');
705
        $mock_message->mock( 'purchase_order_number', sub { return 'TEST_PO_123456'; } );
706
        $mock_message->mock( 'lineitems',             sub { return []; } );
707
        $mock_message->mock( 'buyer_ean',             sub { return $test_san; } );
708
709
        # Create a quote message for testing
710
        my $quote_message = $builder->build(
711
            {
712
                source => 'EdifactMessage',
713
                value  => {
714
                    message_type => 'QUOTE',
715
                    vendor_id    => $account_po->{vendor_id},
716
                    filename     => 'test_basket_naming.ceq',
717
                    status       => 'recmsg',
718
                }
719
            }
720
        );
721
722
        # Test that the logic would use purchase order number when configured
723
        # (This tests the logic in process_quote without running the full process)
724
        my $v = $schema->resultset('VendorEdiAccount')->search( { vendor_id => $account_po->{vendor_id} } )->single;
725
        my $quote_obj   = $schema->resultset('EdifactMessage')->find( $quote_message->{id} );
726
        my $basket_name = $quote_obj->filename;
727
728
        if ( $v && $v->po_is_basketname ) {
729
            my $purchase_order_number = 'TEST_PO_123456';    # Simulated from mock
730
            if ($purchase_order_number) {
731
                $basket_name = $purchase_order_number;
732
            }
733
        }
734
735
        is(
736
            $basket_name, 'TEST_PO_123456',
737
            'Basket naming logic correctly uses purchase order number when configured'
738
        );
739
740
        $schema->storage->txn_rollback;
741
    };
742
637
    # Clean up
743
    # Clean up
638
    $logger->clear();
744
    $logger->clear();
639
    $schema->storage->txn_rollback;
745
    $schema->storage->txn_rollback;
640
- 

Return to bug 20253