Bugzilla – Attachment 188148 Details for
Bug 41020
Add ability to use file transports for MARC ordering accounts
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 41020: Add ability to use file transports for marc ordering accounts
Bug-41020-Add-ability-to-use-file-transports-for-m.patch (text/plain), 12.00 KB, created by
Martin Renvoize (ashimema)
on 2025-10-20 09:33:25 UTC
(
hide
)
Description:
Bug 41020: Add ability to use file transports for marc ordering accounts
Filename:
MIME Type:
Creator:
Martin Renvoize (ashimema)
Created:
2025-10-20 09:33:25 UTC
Size:
12.00 KB
patch
obsolete
>From 0d6bc078e810d065c8e4c3316cce2f80e6e3f24c Mon Sep 17 00:00:00 2001 >From: Kyle M Hall <kyle@bywatersolutions.com> >Date: Wed, 15 Oct 2025 10:03:46 -0400 >Subject: [PATCH] Bug 41020: Add ability to use file transports for marc > ordering accounts > >FTP and SFTP server management was added to Koha in bug 39190. This feature >should be made available to the marc order accounts feature so external >processes are not needed to downloading the marc order files. > >Test Plan: >1) Run updatedatabase.pl >2) Restart all the things! >3) Create one or more file transports >4) Attach those transports to one or more MARC order accounts >5) Run marc_order_accounts.tt, note the files are transferred from the > remove server to the "Download directory" of the MARC order account >6) Add another file to the remote server >7) Run script with "--rr dl" >8) Note the remote file has ".dl" append to the filename >9) Remove the .dl file extension from the remote file >10) Run script with "--dr" >11) Note the remote file is deleted > >Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk> >--- > admin/marc_order_accounts.pl | 9 +++ > .../data/mysql/atomicupdate/bug_41020.pl | 28 +++++++ > installer/data/mysql/kohastructure.sql | 4 +- > .../en/modules/admin/marc_order_accounts.tt | 14 ++++ > misc/cronjobs/marc_ordering_process.pl | 73 +++++++++++++++++-- > 5 files changed, 120 insertions(+), 8 deletions(-) > create mode 100755 installer/data/mysql/atomicupdate/bug_41020.pl > >diff --git a/admin/marc_order_accounts.pl b/admin/marc_order_accounts.pl >index 121ba0c5d8f..c4461b8df44 100755 >--- a/admin/marc_order_accounts.pl >+++ b/admin/marc_order_accounts.pl >@@ -38,6 +38,7 @@ use Koha::MarcOrderAccount; > use Koha::MarcOrderAccounts; > > my $input = CGI->new; >+our $schema = Koha::Database->new()->schema(); > > my ( $template, $loggedinuser, $cookie ) = get_template_and_user( > { >@@ -60,6 +61,13 @@ if ( $op eq 'acct_form' ) { > my @matchers = C4::Matcher::GetMatcherList(); > $template->param( available_matchers => \@matchers ); > >+ # Get available file transports for selection >+ my @file_transports = $schema->resultset('FileTransport')->search( >+ {}, >+ { order_by => { -asc => 'name' } } >+ ); >+ $template->param( file_transports => \@file_transports ); >+ > show_account( $input, $template ); > } elsif ( $op eq 'delete_acct' ) { > show_account( $input, $template ); >@@ -82,6 +90,7 @@ if ( $op eq 'acct_form' ) { > match_field => scalar $input->param('match_field'), > match_value => scalar $input->param('match_value'), > basket_name_field => scalar $input->param('basket_name_field'), >+ file_transport_id => scalar $input->param('file_transport_id') || undef, > }; > > if ( scalar $input->param('id') ) { >diff --git a/installer/data/mysql/atomicupdate/bug_41020.pl b/installer/data/mysql/atomicupdate/bug_41020.pl >new file mode 100755 >index 00000000000..4829c3412b7 >--- /dev/null >+++ b/installer/data/mysql/atomicupdate/bug_41020.pl >@@ -0,0 +1,28 @@ >+use Modern::Perl; >+use Koha::Installer::Output qw(say_warning say_success say_info); >+ >+return { >+ bug_number => "41020", >+ description => "Add file_transport_id to marc_order_accounts", >+ up => sub { >+ my ($args) = @_; >+ my ( $dbh, $out ) = @$args{qw(dbh out)}; >+ >+ if ( !column_exists( 'marc_order_accounts', 'file_transport_id' ) ) { >+ $dbh->do( >+ q{ >+ ALTER TABLE `marc_order_accounts` >+ ADD COLUMN `file_transport_id` int(11) DEFAULT NULL AFTER `basket_name_field`, >+ ADD KEY `marc_order_accounts_file_transport_id` (`file_transport_id`), >+ ADD CONSTRAINT `marc_order_accounts_ibfk_file_transport` >+ FOREIGN KEY (`file_transport_id`) >+ REFERENCES `file_transports` (`file_transport_id`) >+ ON DELETE SET NULL >+ ON UPDATE CASCADE; >+ } >+ ); >+ } >+ >+ say $out "Added column 'marc_order_accounts.file_transport_id'"; >+ }, >+}; >diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql >index ce39d6a933f..b81fde6412e 100644 >--- a/installer/data/mysql/kohastructure.sql >+++ b/installer/data/mysql/kohastructure.sql >@@ -4634,11 +4634,13 @@ CREATE TABLE `marc_order_accounts` ( > `match_field` varchar(10) DEFAULT NULL COMMENT 'the field that a vendor account has been mapped to in a marc record', > `match_value` varchar(50) DEFAULT NULL COMMENT 'the value to be matched against the marc record', > `basket_name_field` varchar(10) DEFAULT NULL COMMENT 'the field that a vendor can use to include a basket name that will be used to create the basket for the file', >+ `file_transport_id` int(11) DEFAULT NULL, > PRIMARY KEY (`id`), > KEY `marc_ordering_account_ibfk_1` (`vendor_id`), > KEY `marc_ordering_account_ibfk_2` (`budget_id`), > CONSTRAINT `marc_ordering_account_ibfk_1` FOREIGN KEY (`vendor_id`) REFERENCES `aqbooksellers` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, >- CONSTRAINT `marc_ordering_account_ibfk_2` FOREIGN KEY (`budget_id`) REFERENCES `aqbudgets` (`budget_id`) ON DELETE CASCADE ON UPDATE CASCADE >+ CONSTRAINT `marc_ordering_account_ibfk_2` FOREIGN KEY (`budget_id`) REFERENCES `aqbudgets` (`budget_id`) ON DELETE CASCADE ON UPDATE CASCADE, >+ CONSTRAINT `marc_order_accounts_ibfk_file_transport` FOREIGN KEY (`file_transport_id`) REFERENCES `file_transports` (`file_transport_id`) ON DELETE SET NULL ON UPDATE CASCADE > ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; > /*!40101 SET character_set_client = @saved_cs_client */; > >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/marc_order_accounts.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/marc_order_accounts.tt >index 53c4541a9b7..d94cf83f19e 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/marc_order_accounts.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/marc_order_accounts.tt >@@ -116,6 +116,20 @@ > <label for="description">Description: </label> > <input type="text" name="description" id="description" size="20" value="[% account.description | html %]" /> > </li> >+ <li> >+ <label for="file_transport_id">File transport: </label> >+ <select name="file_transport_id" id="file_transport_id"> >+ <option value="">Select a file transport configuration</option> >+ [% FOREACH transport IN file_transports %] >+ [% IF transport.file_transport_id == account.file_transport_id %] >+ <option value="[% transport.file_transport_id | html %]" selected="selected">[% transport.name | html %] ([% transport.transport | upper | html %] - [% transport.host | html %])</option> >+ [% ELSE %] >+ <option value="[% transport.file_transport_id | html %]">[% transport.name | html %] ([% transport.transport | upper | html %] - [% transport.host | html %])</option> >+ [% END %] >+ [% END %] >+ </select> >+ <div class="hint"> Select a file transport configuration for this EDI account. File transports can be managed in <a href="/cgi-bin/koha/admin/file_transports.pl">Administration › File transports</a>. </div> >+ </li> > <li> > <label for="download_directory">Download directory: </label> > <input type="text" name="download_directory" id="download_directory" size="20" value="[% account.download_directory | html %]" /> >diff --git a/misc/cronjobs/marc_ordering_process.pl b/misc/cronjobs/marc_ordering_process.pl >index 0e51cf7baf3..b61f89bc0e0 100755 >--- a/misc/cronjobs/marc_ordering_process.pl >+++ b/misc/cronjobs/marc_ordering_process.pl >@@ -23,7 +23,7 @@ marc_ordering_process.pl - cron script to retrieve MARC files and create order l > > =head1 SYNOPSIS > >-./marc_ordering_process.pl [-c|--confirm] [-v|--verbose] >+./marc_ordering_process.pl [-c|--confirm] [-v|--verbose] [--dr|--delete-remote] [--rr|--rename-remote] ext] > > or, in crontab: > # Once every day >@@ -50,6 +50,14 @@ Without this parameter no changes will be made > > Delete the file once it has been processed > >+=item B<--dr|--delete-remote> >+ >+Delete the remote file once it has been downloaded >+ >+=item B<-rr|--rename-remove ext> >+ >+Rename the remote file once it has been downloaded, adding the given file extension >+ > =back > > =cut >@@ -62,18 +70,21 @@ use File::Copy qw( copy move ); > use Koha::Script -cron; > use Koha::MarcOrder; > use Koha::MarcOrderAccounts; >+use Koha::File::Transports; > > use C4::Log qw( cronlogaction ); > > my $command_line_options = join( " ", @ARGV ); > cronlogaction( { info => $command_line_options } ); > >-my ( $help, $verbose, $confirm, $delete ); >+my ( $help, $verbose, $confirm, $delete, $rename_ext, $delete_remote ); > GetOptions( >- 'h|help' => \$help, >- 'v|verbose' => \$verbose, >- 'c|confirm' => \$confirm, >- 'd|delete' => \$delete, >+ 'h|help' => \$help, >+ 'v|verbose' => \$verbose, >+ 'c|confirm' => \$confirm, >+ 'd|delete' => \$delete, >+ 'dr|delete-remote' => \$delete_remote, >+ 'rr|rename-remote=s' => \$rename_ext, > ) || pod2usage(1); > > pod2usage(0) if $help; >@@ -91,6 +102,8 @@ if ( scalar(@accounts) == 0 ) { > print "No accounts found - you must create a MARC order account for this cronjob to run\n" if $verbose; > } > >+my $valid_file_extensions = qr/\.(mrc|marcxml|mrk)$/i; >+ > foreach my $acct (@accounts) { > if ($verbose) { > say sprintf "Starting MARC ordering process for %s", $acct->vendor->name; >@@ -98,8 +111,54 @@ foreach my $acct (@accounts) { > } > > my $working_dir = $acct->download_directory; >+ >+ my $file_transport = $acct->file_transport_id ? Koha::File::Transports->find( $acct->file_transport_id ) : undef; >+ if ($file_transport) { >+ if ( $file_transport->connect() ) { >+ my $download_dir = $file_transport->download_directory; >+ >+ my $success = $download_dir ? $file_transport->change_directory($download_dir) : 1; >+ if ( $download_dir && !$success ) { >+ say "Failed to change to download directory: $download_dir"; >+ } else { >+ >+ # Get file list >+ my $file_list = $file_transport->list_files(); >+ if ($file_list) { >+ >+ # Process files matching our criteria >+ foreach my $file ( @{$file_list} ) { >+ my $filename = $file->{filename}; >+ >+ if ( $filename =~ $valid_file_extensions ) { >+ >+ my $local_file = "$working_dir/$filename"; >+ >+ # Download the file >+ if ( $file_transport->download_file( $filename, $local_file ) ) { >+ if ($rename_ext) { >+ $file_transport->rename_file( $filename, "$filename.$rename_ext" ); >+ } elsif ($delete_remote) { >+ $file_transport->delete_file($filename); >+ } >+ } else { >+ say "Failed to download file: $filename"; >+ } >+ } >+ } >+ >+ } else { >+ say "Failed to get file list from transport"; >+ } >+ >+ } >+ } else { >+ say "Failed to connect to file transport: " . $file_transport->id; >+ } >+ } >+ > opendir my $dir, $working_dir or die "Can't open filepath"; >- my @files = grep { /\.(mrc|marcxml|mrk)/i } readdir $dir; >+ my @files = grep { /$valid_file_extensions/ } readdir $dir; > closedir $dir; > print "No new files found\n" if scalar(@files) == 0; > >-- >2.51.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 41020
:
187931
|
187932
|
187933
|
187934
|
187935
|
187936
|
187937
|
187938
|
187939
|
187940
|
187941
|
187942
|
188012
|
188013
|
188014
|
188015
|
188016
|
188017
|
188018
|
188030
|
188031
|
188032
|
188033
|
188034
|
188146
|
188147
|
188148
|
188149
|
188150
|
188153
|
188154
|
188155
|
188156
|
188157