From 3cffaff50f3fa0cff984e611234b795306b19167 Mon Sep 17 00:00:00 2001 From: Matt Blenkinsop Date: Wed, 2 Apr 2025 08:01:03 +0000 Subject: [PATCH] Bug 39518: Update object methods and unit tests Test plan: Test plan: This test plan involves running a cronjob, not sure how easy this is in the sandboxes 1) In system preferences, click Search and then select the Acquisitions option from the left hand menu 2) Enable MarcOrderingAutomation 3) Paste the following into MarcFieldsToOrder price: 975$p quantity: 975$q budget_code: 975$h 4) Paste the following into MarcItemFieldsToOrder homebranch: 949$a holdingbranch: 949$b itype: 949$y nonpublic_note: 949$x public_note: 949$z loc: 949$c ccode: 949$8 notforloan: 949$7 uri: 949$u copyno: 949$t price: 949$g replacementprice: 949$v itemcallnumber: 949$o quantity: 949$k budget_code: 949$l Now save the sysprefs 5) In the administration homepage, under Acquisition parameters there should now be a link called "MARC order accounts" 6) Click on this and click the New account button 7) Choose a vendor and a budget 8) Enter a description and make sure you don't set a value in the 'Basket name field' input 9) Enter the following in download directory - "/var/lib/koha/kohadev/tmp/koha_kohadev_upload" 10) Select any record matching settings you want (not important for the test plan, this uses the same code as the marc file staging that already exists in Koha) 11) Check Yes under Check for embedded item record data 12) Click submit 13) We now need to upload a MARC file into the directory that we put in the account. The easiest way to do this is through the marc staging tool 14) Navigate to Cataloging > Stage MARC records for import 15) Upload the file attached to this bug using the Choose file button 16) Click Upload file. 17) Leave the page without completing the new form that appears, we don't want to stage this file. The file we uploaded is now in the directory ready for the cronjob to process as if it had been transferred via SFTP. 18) In the CLI run, perl misc/cronjobs/marc_ordering_process.pl -v -c 19) The logging should show that the file has been processed for that account 20) Navigate to Acquisitions 21) Search for the Vendor that you put in the MARC ordering account 22) There should now be a basket titled: '{random_hash}_orderstest.marcxml' 23) In the ordering account, set the 'Basket name field' to be 975$a 24) Repeat steps 14 -22, the basket should now be called "This is the basket name" which has been pulled from the file Signed-off-by: Nick Clemens --- Koha/MarcOrder.pm | 87 ++++++++++++++++++++++++++------- t/db_dependent/Koha/MarcOrder.t | 57 ++++++++++++++++++++- 2 files changed, 125 insertions(+), 19 deletions(-) diff --git a/Koha/MarcOrder.pm b/Koha/MarcOrder.pm index fa8cc831fe4..47e45f5973a 100644 --- a/Koha/MarcOrder.pm +++ b/Koha/MarcOrder.pm @@ -99,7 +99,9 @@ sub create_order_lines_from_file { my $basket_id = _create_basket_for_file( { filename => $filename, - vendor_id => $vendor_id + filepath => $filepath, + vendor_id => $vendor_id, + profile => $profile } ); @@ -223,7 +225,8 @@ sub import_record_and_create_order_lines { my $basket_id = _create_basket_for_file({ filename => $filename, - vendor_id => $vendor_id + vendor_id => $vendor_id, + profile => $profile }); Creates a basket ready to receive order lines based on the imported file @@ -236,8 +239,10 @@ sub _create_basket_for_file { my $filename = $args->{filename}; my $vendor_id = $args->{vendor_id}; + my $basket_name = _check_file_for_basket_name($args); + # aqbasketname.basketname has a max length of 50 characters so long file names will need to be truncated - my $basketname = length($filename) > 50 ? substr( $filename, 0, 50 ) : $filename; + my $basketname = length($basket_name) > 50 ? substr( $basket_name, 0, 50 ) : $basket_name; my $basketno = NewBasket( $vendor_id, 0, $basketname, q{}, @@ -543,23 +548,11 @@ sub add_items_from_import_record { sub match_file_to_account { my ( $self, $args ) = @_; - my $match = 0; - my $filename = $args->{filename}; - my $filepath = $args->{filepath}; - my $profile = $args->{profile}; - my $format = index( $filename, '.mrc' ) != -1 ? 'ISO2709' : 'MARCXML'; + my $profile = $args->{profile}; - my ( $errors, $marcrecords ); - if ( $format eq 'MARCXML' ) { - ( $errors, $marcrecords ) = C4::ImportBatch::RecordsFromMARCXMLFile( $filepath, $profile->encoding ); - } elsif ( $format eq 'ISO2709' ) { - ( $errors, $marcrecords ) = C4::ImportBatch::RecordsFromISO2709File( - $filepath, $profile->record_type, - $profile->encoding - ); - } + my $match = 0; + my $match_record = _retrieve_first_record_from_batch($args); - my $match_record = @{$marcrecords}[0]; my ( $field, $subfield ) = split /\$/, $profile->match_field; my $field_value = $match_record->subfield( $field, $subfield ) || ''; @@ -572,6 +565,37 @@ sub match_file_to_account { return $match; } +=head3 _check_file_for_basket_name + + my $basket_name = _check_file_for_basket_name({ + filename => $filename, + filepath => $filepath, + profile => $profile + }); + + Checks to see if the account has a basket name field assigned. + If yes, it retrieves this value to use as the name. + If not, to uses the filename. + +=cut + +sub _check_file_for_basket_name { + my ($args) = @_; + + my $profile = $args->{profile}; + + my $filename = $args->{filename}; + return $filename if !$profile->basket_name_field; + + my $first_record = _retrieve_first_record_from_batch($args); + + my ( $field, $subfield ) = split /\$/, $profile->basket_name_field; + + my $field_value = $first_record->subfield( $field, $subfield ) || ''; + + return $field_value ? $field_value : $filename; +} + =head3 import_batches_list Fetches import batches matching the batch to be added to the basket and returns these to the template @@ -1251,4 +1275,31 @@ sub _create_item_fields_from_syspref { return $item_fields; } +=head3 _retrieve_first_record_from_batch + +=cut + +sub _retrieve_first_record_from_batch { + my ($args) = @_; + + my $filename = $args->{filename}; + my $filepath = $args->{filepath}; + my $profile = $args->{profile}; + my $format = index( $filename, '.mrc' ) != -1 ? 'ISO2709' : 'MARCXML'; + + my ( $errors, $marcrecords ); + if ( $format eq 'MARCXML' ) { + ( $errors, $marcrecords ) = C4::ImportBatch::RecordsFromMARCXMLFile( $filepath, $profile->encoding ); + } elsif ( $format eq 'ISO2709' ) { + ( $errors, $marcrecords ) = C4::ImportBatch::RecordsFromISO2709File( + $filepath, $profile->record_type, + $profile->encoding + ); + } + + my $first_record = @{$marcrecords}[0]; + return $first_record; + +} + 1; diff --git a/t/db_dependent/Koha/MarcOrder.t b/t/db_dependent/Koha/MarcOrder.t index b9e05cfb546..58123c7e8b6 100755 --- a/t/db_dependent/Koha/MarcOrder.t +++ b/t/db_dependent/Koha/MarcOrder.t @@ -17,7 +17,7 @@ use Modern::Perl; -use Test::More tests => 5; +use Test::More tests => 6; use Koha::MarcOrder; use Koha::MarcOrderAccount; @@ -627,3 +627,58 @@ subtest 'match_file_to_account' => sub { $schema->storage->txn_rollback; }; + +subtest '_check_file_for_basket_name' => sub { + plan tests => 2; + + $schema->storage->txn_begin; + + my ( $fh, $name ) = tempfile( SUFFIX => '.marcxml' ); + + my $rec = MARC::Record->new; + my $fld = MARC::Field->new( '975', '', '', 'p', 'This is a basket' ); + $rec->append_fields($fld); + my $str = $rec->as_xml; + + print $fh $str; + + close $fh; + + my $account1 = Koha::MarcOrderAccount->new( + { + basket_name_field => '975$p', + encoding => 'UTF-8', + description => 'test', + } + )->store; + + my $basket_name = Koha::MarcOrder::_check_file_for_basket_name( + { + filename => $name, + filepath => $name, + profile => $account1, + } + ); + + is( $basket_name, "This is a basket", 'Basket name identified correctly' ); + + my $account2 = Koha::MarcOrderAccount->new( + { + basket_name_field => '975$z', + encoding => 'UTF-8', + description => 'test', + } + )->store; + + my $basket_name2 = Koha::MarcOrder::_check_file_for_basket_name( + { + filename => $name, + filepath => $name, + profile => $account2, + } + ); + + is( $basket_name2, $name, 'No filename provided in the file' ); + + $schema->storage->txn_rollback; +}; -- 2.39.5